diff options
author | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2021-12-27 00:00:00 +0000 |
---|---|---|
committer | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2022-03-18 15:35:13 +0500 |
commit | f19f813537c7aea1c20749c914e756b54a9c3cf5 (patch) | |
tree | 816ba62ca7c0fa19f2eb46d9e9d6f7dd7c3a744d /C/Delta.c | |
parent | 98e06a519b63b81986abe76d28887f6984a7732b (diff) | |
download | 7zip-21.07.tar.gz 7zip-21.07.tar.bz2 7zip-21.07.zip |
'21.07'21.07
Diffstat (limited to '')
-rw-r--r-- | C/Delta.c | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/C/Delta.c b/C/Delta.c new file mode 100644 index 0000000..c4a4499 --- /dev/null +++ b/C/Delta.c | |||
@@ -0,0 +1,169 @@ | |||
1 | /* Delta.c -- Delta converter | ||
2 | 2021-02-09 : Igor Pavlov : Public domain */ | ||
3 | |||
4 | #include "Precomp.h" | ||
5 | |||
6 | #include "Delta.h" | ||
7 | |||
8 | void Delta_Init(Byte *state) | ||
9 | { | ||
10 | unsigned i; | ||
11 | for (i = 0; i < DELTA_STATE_SIZE; i++) | ||
12 | state[i] = 0; | ||
13 | } | ||
14 | |||
15 | |||
16 | void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size) | ||
17 | { | ||
18 | Byte temp[DELTA_STATE_SIZE]; | ||
19 | |||
20 | if (size == 0) | ||
21 | return; | ||
22 | |||
23 | { | ||
24 | unsigned i = 0; | ||
25 | do | ||
26 | temp[i] = state[i]; | ||
27 | while (++i != delta); | ||
28 | } | ||
29 | |||
30 | if (size <= delta) | ||
31 | { | ||
32 | unsigned i = 0, k; | ||
33 | do | ||
34 | { | ||
35 | Byte b = *data; | ||
36 | *data++ = (Byte)(b - temp[i]); | ||
37 | temp[i] = b; | ||
38 | } | ||
39 | while (++i != size); | ||
40 | |||
41 | k = 0; | ||
42 | |||
43 | do | ||
44 | { | ||
45 | if (i == delta) | ||
46 | i = 0; | ||
47 | state[k] = temp[i++]; | ||
48 | } | ||
49 | while (++k != delta); | ||
50 | |||
51 | return; | ||
52 | } | ||
53 | |||
54 | { | ||
55 | Byte *p = data + size - delta; | ||
56 | { | ||
57 | unsigned i = 0; | ||
58 | do | ||
59 | state[i] = *p++; | ||
60 | while (++i != delta); | ||
61 | } | ||
62 | { | ||
63 | const Byte *lim = data + delta; | ||
64 | ptrdiff_t dif = -(ptrdiff_t)delta; | ||
65 | |||
66 | if (((ptrdiff_t)size + dif) & 1) | ||
67 | { | ||
68 | --p; *p = (Byte)(*p - p[dif]); | ||
69 | } | ||
70 | |||
71 | while (p != lim) | ||
72 | { | ||
73 | --p; *p = (Byte)(*p - p[dif]); | ||
74 | --p; *p = (Byte)(*p - p[dif]); | ||
75 | } | ||
76 | |||
77 | dif = -dif; | ||
78 | |||
79 | do | ||
80 | { | ||
81 | --p; *p = (Byte)(*p - temp[--dif]); | ||
82 | } | ||
83 | while (dif != 0); | ||
84 | } | ||
85 | } | ||
86 | } | ||
87 | |||
88 | |||
89 | void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size) | ||
90 | { | ||
91 | unsigned i; | ||
92 | const Byte *lim; | ||
93 | |||
94 | if (size == 0) | ||
95 | return; | ||
96 | |||
97 | i = 0; | ||
98 | lim = data + size; | ||
99 | |||
100 | if (size <= delta) | ||
101 | { | ||
102 | do | ||
103 | *data = (Byte)(*data + state[i++]); | ||
104 | while (++data != lim); | ||
105 | |||
106 | for (; delta != i; state++, delta--) | ||
107 | *state = state[i]; | ||
108 | data -= i; | ||
109 | } | ||
110 | else | ||
111 | { | ||
112 | /* | ||
113 | #define B(n) b ## n | ||
114 | #define I(n) Byte B(n) = state[n]; | ||
115 | #define U(n) { B(n) = (Byte)((B(n)) + *data++); data[-1] = (B(n)); } | ||
116 | #define F(n) if (data != lim) { U(n) } | ||
117 | |||
118 | if (delta == 1) | ||
119 | { | ||
120 | I(0) | ||
121 | if ((lim - data) & 1) { U(0) } | ||
122 | while (data != lim) { U(0) U(0) } | ||
123 | data -= 1; | ||
124 | } | ||
125 | else if (delta == 2) | ||
126 | { | ||
127 | I(0) I(1) | ||
128 | lim -= 1; while (data < lim) { U(0) U(1) } | ||
129 | lim += 1; F(0) | ||
130 | data -= 2; | ||
131 | } | ||
132 | else if (delta == 3) | ||
133 | { | ||
134 | I(0) I(1) I(2) | ||
135 | lim -= 2; while (data < lim) { U(0) U(1) U(2) } | ||
136 | lim += 2; F(0) F(1) | ||
137 | data -= 3; | ||
138 | } | ||
139 | else if (delta == 4) | ||
140 | { | ||
141 | I(0) I(1) I(2) I(3) | ||
142 | lim -= 3; while (data < lim) { U(0) U(1) U(2) U(3) } | ||
143 | lim += 3; F(0) F(1) F(2) | ||
144 | data -= 4; | ||
145 | } | ||
146 | else | ||
147 | */ | ||
148 | { | ||
149 | do | ||
150 | { | ||
151 | *data = (Byte)(*data + state[i++]); | ||
152 | data++; | ||
153 | } | ||
154 | while (i != delta); | ||
155 | |||
156 | { | ||
157 | ptrdiff_t dif = -(ptrdiff_t)delta; | ||
158 | do | ||
159 | *data = (Byte)(*data + data[dif]); | ||
160 | while (++data != lim); | ||
161 | data += dif; | ||
162 | } | ||
163 | } | ||
164 | } | ||
165 | |||
166 | do | ||
167 | *state++ = *data; | ||
168 | while (++data != lim); | ||
169 | } | ||