xref: /aosp_15_r20/external/lzma/C/Delta.c (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker /* Delta.c -- Delta converter
2*f6dc9357SAndroid Build Coastguard Worker 2021-02-09 : Igor Pavlov : Public domain */
3*f6dc9357SAndroid Build Coastguard Worker 
4*f6dc9357SAndroid Build Coastguard Worker #include "Precomp.h"
5*f6dc9357SAndroid Build Coastguard Worker 
6*f6dc9357SAndroid Build Coastguard Worker #include "Delta.h"
7*f6dc9357SAndroid Build Coastguard Worker 
Delta_Init(Byte * state)8*f6dc9357SAndroid Build Coastguard Worker void Delta_Init(Byte *state)
9*f6dc9357SAndroid Build Coastguard Worker {
10*f6dc9357SAndroid Build Coastguard Worker   unsigned i;
11*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < DELTA_STATE_SIZE; i++)
12*f6dc9357SAndroid Build Coastguard Worker     state[i] = 0;
13*f6dc9357SAndroid Build Coastguard Worker }
14*f6dc9357SAndroid Build Coastguard Worker 
15*f6dc9357SAndroid Build Coastguard Worker 
Delta_Encode(Byte * state,unsigned delta,Byte * data,SizeT size)16*f6dc9357SAndroid Build Coastguard Worker void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size)
17*f6dc9357SAndroid Build Coastguard Worker {
18*f6dc9357SAndroid Build Coastguard Worker   Byte temp[DELTA_STATE_SIZE];
19*f6dc9357SAndroid Build Coastguard Worker 
20*f6dc9357SAndroid Build Coastguard Worker   if (size == 0)
21*f6dc9357SAndroid Build Coastguard Worker     return;
22*f6dc9357SAndroid Build Coastguard Worker 
23*f6dc9357SAndroid Build Coastguard Worker   {
24*f6dc9357SAndroid Build Coastguard Worker     unsigned i = 0;
25*f6dc9357SAndroid Build Coastguard Worker     do
26*f6dc9357SAndroid Build Coastguard Worker       temp[i] = state[i];
27*f6dc9357SAndroid Build Coastguard Worker     while (++i != delta);
28*f6dc9357SAndroid Build Coastguard Worker   }
29*f6dc9357SAndroid Build Coastguard Worker 
30*f6dc9357SAndroid Build Coastguard Worker   if (size <= delta)
31*f6dc9357SAndroid Build Coastguard Worker   {
32*f6dc9357SAndroid Build Coastguard Worker     unsigned i = 0, k;
33*f6dc9357SAndroid Build Coastguard Worker     do
34*f6dc9357SAndroid Build Coastguard Worker     {
35*f6dc9357SAndroid Build Coastguard Worker       Byte b = *data;
36*f6dc9357SAndroid Build Coastguard Worker       *data++ = (Byte)(b - temp[i]);
37*f6dc9357SAndroid Build Coastguard Worker       temp[i] = b;
38*f6dc9357SAndroid Build Coastguard Worker     }
39*f6dc9357SAndroid Build Coastguard Worker     while (++i != size);
40*f6dc9357SAndroid Build Coastguard Worker 
41*f6dc9357SAndroid Build Coastguard Worker     k = 0;
42*f6dc9357SAndroid Build Coastguard Worker 
43*f6dc9357SAndroid Build Coastguard Worker     do
44*f6dc9357SAndroid Build Coastguard Worker     {
45*f6dc9357SAndroid Build Coastguard Worker       if (i == delta)
46*f6dc9357SAndroid Build Coastguard Worker         i = 0;
47*f6dc9357SAndroid Build Coastguard Worker       state[k] = temp[i++];
48*f6dc9357SAndroid Build Coastguard Worker     }
49*f6dc9357SAndroid Build Coastguard Worker     while (++k != delta);
50*f6dc9357SAndroid Build Coastguard Worker 
51*f6dc9357SAndroid Build Coastguard Worker     return;
52*f6dc9357SAndroid Build Coastguard Worker   }
53*f6dc9357SAndroid Build Coastguard Worker 
54*f6dc9357SAndroid Build Coastguard Worker   {
55*f6dc9357SAndroid Build Coastguard Worker     Byte *p = data + size - delta;
56*f6dc9357SAndroid Build Coastguard Worker     {
57*f6dc9357SAndroid Build Coastguard Worker       unsigned i = 0;
58*f6dc9357SAndroid Build Coastguard Worker       do
59*f6dc9357SAndroid Build Coastguard Worker         state[i] = *p++;
60*f6dc9357SAndroid Build Coastguard Worker       while (++i != delta);
61*f6dc9357SAndroid Build Coastguard Worker     }
62*f6dc9357SAndroid Build Coastguard Worker     {
63*f6dc9357SAndroid Build Coastguard Worker       const Byte *lim = data + delta;
64*f6dc9357SAndroid Build Coastguard Worker       ptrdiff_t dif = -(ptrdiff_t)delta;
65*f6dc9357SAndroid Build Coastguard Worker 
66*f6dc9357SAndroid Build Coastguard Worker       if (((ptrdiff_t)size + dif) & 1)
67*f6dc9357SAndroid Build Coastguard Worker       {
68*f6dc9357SAndroid Build Coastguard Worker         --p;  *p = (Byte)(*p - p[dif]);
69*f6dc9357SAndroid Build Coastguard Worker       }
70*f6dc9357SAndroid Build Coastguard Worker 
71*f6dc9357SAndroid Build Coastguard Worker       while (p != lim)
72*f6dc9357SAndroid Build Coastguard Worker       {
73*f6dc9357SAndroid Build Coastguard Worker         --p;  *p = (Byte)(*p - p[dif]);
74*f6dc9357SAndroid Build Coastguard Worker         --p;  *p = (Byte)(*p - p[dif]);
75*f6dc9357SAndroid Build Coastguard Worker       }
76*f6dc9357SAndroid Build Coastguard Worker 
77*f6dc9357SAndroid Build Coastguard Worker       dif = -dif;
78*f6dc9357SAndroid Build Coastguard Worker 
79*f6dc9357SAndroid Build Coastguard Worker       do
80*f6dc9357SAndroid Build Coastguard Worker       {
81*f6dc9357SAndroid Build Coastguard Worker         --p;  *p = (Byte)(*p - temp[--dif]);
82*f6dc9357SAndroid Build Coastguard Worker       }
83*f6dc9357SAndroid Build Coastguard Worker       while (dif != 0);
84*f6dc9357SAndroid Build Coastguard Worker     }
85*f6dc9357SAndroid Build Coastguard Worker   }
86*f6dc9357SAndroid Build Coastguard Worker }
87*f6dc9357SAndroid Build Coastguard Worker 
88*f6dc9357SAndroid Build Coastguard Worker 
Delta_Decode(Byte * state,unsigned delta,Byte * data,SizeT size)89*f6dc9357SAndroid Build Coastguard Worker void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size)
90*f6dc9357SAndroid Build Coastguard Worker {
91*f6dc9357SAndroid Build Coastguard Worker   unsigned i;
92*f6dc9357SAndroid Build Coastguard Worker   const Byte *lim;
93*f6dc9357SAndroid Build Coastguard Worker 
94*f6dc9357SAndroid Build Coastguard Worker   if (size == 0)
95*f6dc9357SAndroid Build Coastguard Worker     return;
96*f6dc9357SAndroid Build Coastguard Worker 
97*f6dc9357SAndroid Build Coastguard Worker   i = 0;
98*f6dc9357SAndroid Build Coastguard Worker   lim = data + size;
99*f6dc9357SAndroid Build Coastguard Worker 
100*f6dc9357SAndroid Build Coastguard Worker   if (size <= delta)
101*f6dc9357SAndroid Build Coastguard Worker   {
102*f6dc9357SAndroid Build Coastguard Worker     do
103*f6dc9357SAndroid Build Coastguard Worker       *data = (Byte)(*data + state[i++]);
104*f6dc9357SAndroid Build Coastguard Worker     while (++data != lim);
105*f6dc9357SAndroid Build Coastguard Worker 
106*f6dc9357SAndroid Build Coastguard Worker     for (; delta != i; state++, delta--)
107*f6dc9357SAndroid Build Coastguard Worker       *state = state[i];
108*f6dc9357SAndroid Build Coastguard Worker     data -= i;
109*f6dc9357SAndroid Build Coastguard Worker   }
110*f6dc9357SAndroid Build Coastguard Worker   else
111*f6dc9357SAndroid Build Coastguard Worker   {
112*f6dc9357SAndroid Build Coastguard Worker     /*
113*f6dc9357SAndroid Build Coastguard Worker     #define B(n) b ## n
114*f6dc9357SAndroid Build Coastguard Worker     #define I(n) Byte B(n) = state[n];
115*f6dc9357SAndroid Build Coastguard Worker     #define U(n) { B(n) = (Byte)((B(n)) + *data++); data[-1] = (B(n)); }
116*f6dc9357SAndroid Build Coastguard Worker     #define F(n) if (data != lim) { U(n) }
117*f6dc9357SAndroid Build Coastguard Worker 
118*f6dc9357SAndroid Build Coastguard Worker     if (delta == 1)
119*f6dc9357SAndroid Build Coastguard Worker     {
120*f6dc9357SAndroid Build Coastguard Worker       I(0)
121*f6dc9357SAndroid Build Coastguard Worker       if ((lim - data) & 1) { U(0) }
122*f6dc9357SAndroid Build Coastguard Worker       while (data != lim) { U(0) U(0) }
123*f6dc9357SAndroid Build Coastguard Worker       data -= 1;
124*f6dc9357SAndroid Build Coastguard Worker     }
125*f6dc9357SAndroid Build Coastguard Worker     else if (delta == 2)
126*f6dc9357SAndroid Build Coastguard Worker     {
127*f6dc9357SAndroid Build Coastguard Worker       I(0) I(1)
128*f6dc9357SAndroid Build Coastguard Worker       lim -= 1; while (data < lim) { U(0) U(1) }
129*f6dc9357SAndroid Build Coastguard Worker       lim += 1; F(0)
130*f6dc9357SAndroid Build Coastguard Worker       data -= 2;
131*f6dc9357SAndroid Build Coastguard Worker     }
132*f6dc9357SAndroid Build Coastguard Worker     else if (delta == 3)
133*f6dc9357SAndroid Build Coastguard Worker     {
134*f6dc9357SAndroid Build Coastguard Worker       I(0) I(1) I(2)
135*f6dc9357SAndroid Build Coastguard Worker       lim -= 2; while (data < lim) { U(0) U(1) U(2) }
136*f6dc9357SAndroid Build Coastguard Worker       lim += 2; F(0) F(1)
137*f6dc9357SAndroid Build Coastguard Worker       data -= 3;
138*f6dc9357SAndroid Build Coastguard Worker     }
139*f6dc9357SAndroid Build Coastguard Worker     else if (delta == 4)
140*f6dc9357SAndroid Build Coastguard Worker     {
141*f6dc9357SAndroid Build Coastguard Worker       I(0) I(1) I(2) I(3)
142*f6dc9357SAndroid Build Coastguard Worker       lim -= 3; while (data < lim) { U(0) U(1) U(2) U(3) }
143*f6dc9357SAndroid Build Coastguard Worker       lim += 3; F(0) F(1) F(2)
144*f6dc9357SAndroid Build Coastguard Worker       data -= 4;
145*f6dc9357SAndroid Build Coastguard Worker     }
146*f6dc9357SAndroid Build Coastguard Worker     else
147*f6dc9357SAndroid Build Coastguard Worker     */
148*f6dc9357SAndroid Build Coastguard Worker     {
149*f6dc9357SAndroid Build Coastguard Worker       do
150*f6dc9357SAndroid Build Coastguard Worker       {
151*f6dc9357SAndroid Build Coastguard Worker         *data = (Byte)(*data + state[i++]);
152*f6dc9357SAndroid Build Coastguard Worker         data++;
153*f6dc9357SAndroid Build Coastguard Worker       }
154*f6dc9357SAndroid Build Coastguard Worker       while (i != delta);
155*f6dc9357SAndroid Build Coastguard Worker 
156*f6dc9357SAndroid Build Coastguard Worker       {
157*f6dc9357SAndroid Build Coastguard Worker         ptrdiff_t dif = -(ptrdiff_t)delta;
158*f6dc9357SAndroid Build Coastguard Worker         do
159*f6dc9357SAndroid Build Coastguard Worker           *data = (Byte)(*data + data[dif]);
160*f6dc9357SAndroid Build Coastguard Worker         while (++data != lim);
161*f6dc9357SAndroid Build Coastguard Worker         data += dif;
162*f6dc9357SAndroid Build Coastguard Worker       }
163*f6dc9357SAndroid Build Coastguard Worker     }
164*f6dc9357SAndroid Build Coastguard Worker   }
165*f6dc9357SAndroid Build Coastguard Worker 
166*f6dc9357SAndroid Build Coastguard Worker   do
167*f6dc9357SAndroid Build Coastguard Worker     *state++ = *data;
168*f6dc9357SAndroid Build Coastguard Worker   while (++data != lim);
169*f6dc9357SAndroid Build Coastguard Worker }
170