| /* Delta.c -- Delta converter |
| 2021-02-09 : Igor Pavlov : Public domain */ |
| |
| #include "Precomp.h" |
| |
| #include "Delta.h" |
| |
| void Delta_Init(Byte *state) |
| { |
| unsigned i; |
| for (i = 0; i < DELTA_STATE_SIZE; i++) |
| state[i] = 0; |
| } |
| |
| |
| void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size) |
| { |
| Byte temp[DELTA_STATE_SIZE]; |
| |
| if (size == 0) |
| return; |
| |
| { |
| unsigned i = 0; |
| do |
| temp[i] = state[i]; |
| while (++i != delta); |
| } |
| |
| if (size <= delta) |
| { |
| unsigned i = 0, k; |
| do |
| { |
| Byte b = *data; |
| *data++ = (Byte)(b - temp[i]); |
| temp[i] = b; |
| } |
| while (++i != size); |
| |
| k = 0; |
| |
| do |
| { |
| if (i == delta) |
| i = 0; |
| state[k] = temp[i++]; |
| } |
| while (++k != delta); |
| |
| return; |
| } |
| |
| { |
| Byte *p = data + size - delta; |
| { |
| unsigned i = 0; |
| do |
| state[i] = *p++; |
| while (++i != delta); |
| } |
| { |
| const Byte *lim = data + delta; |
| ptrdiff_t dif = -(ptrdiff_t)delta; |
| |
| if (((ptrdiff_t)size + dif) & 1) |
| { |
| --p; *p = (Byte)(*p - p[dif]); |
| } |
| |
| while (p != lim) |
| { |
| --p; *p = (Byte)(*p - p[dif]); |
| --p; *p = (Byte)(*p - p[dif]); |
| } |
| |
| dif = -dif; |
| |
| do |
| { |
| --p; *p = (Byte)(*p - temp[--dif]); |
| } |
| while (dif != 0); |
| } |
| } |
| } |
| |
| |
| void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size) |
| { |
| unsigned i; |
| const Byte *lim; |
| |
| if (size == 0) |
| return; |
| |
| i = 0; |
| lim = data + size; |
| |
| if (size <= delta) |
| { |
| do |
| *data = (Byte)(*data + state[i++]); |
| while (++data != lim); |
| |
| for (; delta != i; state++, delta--) |
| *state = state[i]; |
| data -= i; |
| } |
| else |
| { |
| /* |
| #define B(n) b ## n |
| #define I(n) Byte B(n) = state[n]; |
| #define U(n) { B(n) = (Byte)((B(n)) + *data++); data[-1] = (B(n)); } |
| #define F(n) if (data != lim) { U(n) } |
| |
| if (delta == 1) |
| { |
| I(0) |
| if ((lim - data) & 1) { U(0) } |
| while (data != lim) { U(0) U(0) } |
| data -= 1; |
| } |
| else if (delta == 2) |
| { |
| I(0) I(1) |
| lim -= 1; while (data < lim) { U(0) U(1) } |
| lim += 1; F(0) |
| data -= 2; |
| } |
| else if (delta == 3) |
| { |
| I(0) I(1) I(2) |
| lim -= 2; while (data < lim) { U(0) U(1) U(2) } |
| lim += 2; F(0) F(1) |
| data -= 3; |
| } |
| else if (delta == 4) |
| { |
| I(0) I(1) I(2) I(3) |
| lim -= 3; while (data < lim) { U(0) U(1) U(2) U(3) } |
| lim += 3; F(0) F(1) F(2) |
| data -= 4; |
| } |
| else |
| */ |
| { |
| do |
| { |
| *data = (Byte)(*data + state[i++]); |
| data++; |
| } |
| while (i != delta); |
| |
| { |
| ptrdiff_t dif = -(ptrdiff_t)delta; |
| do |
| *data = (Byte)(*data + data[dif]); |
| while (++data != lim); |
| data += dif; |
| } |
| } |
| } |
| |
| do |
| *state++ = *data; |
| while (++data != lim); |
| } |