f535537f |
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 | } |