xref: /aosp_15_r20/external/lzma/C/Ppmd7Enc.c (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker /* Ppmd7Enc.c -- Ppmd7z (PPMdH with 7z Range Coder) Encoder
2*f6dc9357SAndroid Build Coastguard Worker 2023-09-07 : Igor Pavlov : Public domain
3*f6dc9357SAndroid Build Coastguard Worker This code is based on:
4*f6dc9357SAndroid Build Coastguard Worker   PPMd var.H (2001): Dmitry Shkarin : Public domain */
5*f6dc9357SAndroid Build Coastguard Worker 
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include "Precomp.h"
8*f6dc9357SAndroid Build Coastguard Worker 
9*f6dc9357SAndroid Build Coastguard Worker #include "Ppmd7.h"
10*f6dc9357SAndroid Build Coastguard Worker 
11*f6dc9357SAndroid Build Coastguard Worker #define kTopValue ((UInt32)1 << 24)
12*f6dc9357SAndroid Build Coastguard Worker 
13*f6dc9357SAndroid Build Coastguard Worker #define R (&p->rc.enc)
14*f6dc9357SAndroid Build Coastguard Worker 
Ppmd7z_Init_RangeEnc(CPpmd7 * p)15*f6dc9357SAndroid Build Coastguard Worker void Ppmd7z_Init_RangeEnc(CPpmd7 *p)
16*f6dc9357SAndroid Build Coastguard Worker {
17*f6dc9357SAndroid Build Coastguard Worker   R->Low = 0;
18*f6dc9357SAndroid Build Coastguard Worker   R->Range = 0xFFFFFFFF;
19*f6dc9357SAndroid Build Coastguard Worker   R->Cache = 0;
20*f6dc9357SAndroid Build Coastguard Worker   R->CacheSize = 1;
21*f6dc9357SAndroid Build Coastguard Worker }
22*f6dc9357SAndroid Build Coastguard Worker 
23*f6dc9357SAndroid Build Coastguard Worker Z7_NO_INLINE
Ppmd7z_RangeEnc_ShiftLow(CPpmd7 * p)24*f6dc9357SAndroid Build Coastguard Worker static void Ppmd7z_RangeEnc_ShiftLow(CPpmd7 *p)
25*f6dc9357SAndroid Build Coastguard Worker {
26*f6dc9357SAndroid Build Coastguard Worker   if ((UInt32)R->Low < (UInt32)0xFF000000 || (unsigned)(R->Low >> 32) != 0)
27*f6dc9357SAndroid Build Coastguard Worker   {
28*f6dc9357SAndroid Build Coastguard Worker     Byte temp = R->Cache;
29*f6dc9357SAndroid Build Coastguard Worker     do
30*f6dc9357SAndroid Build Coastguard Worker     {
31*f6dc9357SAndroid Build Coastguard Worker       IByteOut_Write(R->Stream, (Byte)(temp + (Byte)(R->Low >> 32)));
32*f6dc9357SAndroid Build Coastguard Worker       temp = 0xFF;
33*f6dc9357SAndroid Build Coastguard Worker     }
34*f6dc9357SAndroid Build Coastguard Worker     while (--R->CacheSize != 0);
35*f6dc9357SAndroid Build Coastguard Worker     R->Cache = (Byte)((UInt32)R->Low >> 24);
36*f6dc9357SAndroid Build Coastguard Worker   }
37*f6dc9357SAndroid Build Coastguard Worker   R->CacheSize++;
38*f6dc9357SAndroid Build Coastguard Worker   R->Low = (UInt32)((UInt32)R->Low << 8);
39*f6dc9357SAndroid Build Coastguard Worker }
40*f6dc9357SAndroid Build Coastguard Worker 
41*f6dc9357SAndroid Build Coastguard Worker #define RC_NORM_BASE(p) if (R->Range < kTopValue) { R->Range <<= 8;  Ppmd7z_RangeEnc_ShiftLow(p);
42*f6dc9357SAndroid Build Coastguard Worker #define RC_NORM_1(p)    RC_NORM_BASE(p) }
43*f6dc9357SAndroid Build Coastguard Worker #define RC_NORM(p)      RC_NORM_BASE(p)  RC_NORM_BASE(p) }}
44*f6dc9357SAndroid Build Coastguard Worker 
45*f6dc9357SAndroid Build Coastguard Worker // we must use only one type of Normalization from two: LOCAL or REMOTE
46*f6dc9357SAndroid Build Coastguard Worker #define RC_NORM_LOCAL(p)    // RC_NORM(p)
47*f6dc9357SAndroid Build Coastguard Worker #define RC_NORM_REMOTE(p)   RC_NORM(p)
48*f6dc9357SAndroid Build Coastguard Worker 
49*f6dc9357SAndroid Build Coastguard Worker /*
50*f6dc9357SAndroid Build Coastguard Worker #define Ppmd7z_RangeEnc_Encode(p, start, _size_) \
51*f6dc9357SAndroid Build Coastguard Worker   { UInt32 size = _size_; \
52*f6dc9357SAndroid Build Coastguard Worker     R->Low += start * R->Range; \
53*f6dc9357SAndroid Build Coastguard Worker     R->Range *= size; \
54*f6dc9357SAndroid Build Coastguard Worker     RC_NORM_LOCAL(p); }
55*f6dc9357SAndroid Build Coastguard Worker */
56*f6dc9357SAndroid Build Coastguard Worker 
57*f6dc9357SAndroid Build Coastguard Worker Z7_FORCE_INLINE
58*f6dc9357SAndroid Build Coastguard Worker // Z7_NO_INLINE
Ppmd7z_RangeEnc_Encode(CPpmd7 * p,UInt32 start,UInt32 size)59*f6dc9357SAndroid Build Coastguard Worker static void Ppmd7z_RangeEnc_Encode(CPpmd7 *p, UInt32 start, UInt32 size)
60*f6dc9357SAndroid Build Coastguard Worker {
61*f6dc9357SAndroid Build Coastguard Worker   R->Low += start * R->Range;
62*f6dc9357SAndroid Build Coastguard Worker   R->Range *= size;
63*f6dc9357SAndroid Build Coastguard Worker   RC_NORM_LOCAL(p)
64*f6dc9357SAndroid Build Coastguard Worker }
65*f6dc9357SAndroid Build Coastguard Worker 
Ppmd7z_Flush_RangeEnc(CPpmd7 * p)66*f6dc9357SAndroid Build Coastguard Worker void Ppmd7z_Flush_RangeEnc(CPpmd7 *p)
67*f6dc9357SAndroid Build Coastguard Worker {
68*f6dc9357SAndroid Build Coastguard Worker   unsigned i;
69*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < 5; i++)
70*f6dc9357SAndroid Build Coastguard Worker     Ppmd7z_RangeEnc_ShiftLow(p);
71*f6dc9357SAndroid Build Coastguard Worker }
72*f6dc9357SAndroid Build Coastguard Worker 
73*f6dc9357SAndroid Build Coastguard Worker 
74*f6dc9357SAndroid Build Coastguard Worker 
75*f6dc9357SAndroid Build Coastguard Worker #define RC_Encode(start, size)  Ppmd7z_RangeEnc_Encode(p, start, size);
76*f6dc9357SAndroid Build Coastguard Worker #define RC_EncodeFinal(start, size)  RC_Encode(start, size) RC_NORM_REMOTE(p)
77*f6dc9357SAndroid Build Coastguard Worker 
78*f6dc9357SAndroid Build Coastguard Worker #define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref))
79*f6dc9357SAndroid Build Coastguard Worker #define SUFFIX(ctx) CTX((ctx)->Suffix)
80*f6dc9357SAndroid Build Coastguard Worker // typedef CPpmd7_Context * CTX_PTR;
81*f6dc9357SAndroid Build Coastguard Worker #define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p)
82*f6dc9357SAndroid Build Coastguard Worker 
83*f6dc9357SAndroid Build Coastguard Worker void Ppmd7_UpdateModel(CPpmd7 *p);
84*f6dc9357SAndroid Build Coastguard Worker 
85*f6dc9357SAndroid Build Coastguard Worker #define MASK(sym)  ((Byte *)charMask)[sym]
86*f6dc9357SAndroid Build Coastguard Worker 
87*f6dc9357SAndroid Build Coastguard Worker Z7_FORCE_INLINE
88*f6dc9357SAndroid Build Coastguard Worker static
Ppmd7z_EncodeSymbol(CPpmd7 * p,int symbol)89*f6dc9357SAndroid Build Coastguard Worker void Ppmd7z_EncodeSymbol(CPpmd7 *p, int symbol)
90*f6dc9357SAndroid Build Coastguard Worker {
91*f6dc9357SAndroid Build Coastguard Worker   size_t charMask[256 / sizeof(size_t)];
92*f6dc9357SAndroid Build Coastguard Worker 
93*f6dc9357SAndroid Build Coastguard Worker   if (p->MinContext->NumStats != 1)
94*f6dc9357SAndroid Build Coastguard Worker   {
95*f6dc9357SAndroid Build Coastguard Worker     CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
96*f6dc9357SAndroid Build Coastguard Worker     UInt32 sum;
97*f6dc9357SAndroid Build Coastguard Worker     unsigned i;
98*f6dc9357SAndroid Build Coastguard Worker 
99*f6dc9357SAndroid Build Coastguard Worker 
100*f6dc9357SAndroid Build Coastguard Worker 
101*f6dc9357SAndroid Build Coastguard Worker 
102*f6dc9357SAndroid Build Coastguard Worker     R->Range /= p->MinContext->Union2.SummFreq;
103*f6dc9357SAndroid Build Coastguard Worker 
104*f6dc9357SAndroid Build Coastguard Worker     if (s->Symbol == symbol)
105*f6dc9357SAndroid Build Coastguard Worker     {
106*f6dc9357SAndroid Build Coastguard Worker       // R->Range /= p->MinContext->Union2.SummFreq;
107*f6dc9357SAndroid Build Coastguard Worker       RC_EncodeFinal(0, s->Freq)
108*f6dc9357SAndroid Build Coastguard Worker       p->FoundState = s;
109*f6dc9357SAndroid Build Coastguard Worker       Ppmd7_Update1_0(p);
110*f6dc9357SAndroid Build Coastguard Worker       return;
111*f6dc9357SAndroid Build Coastguard Worker     }
112*f6dc9357SAndroid Build Coastguard Worker     p->PrevSuccess = 0;
113*f6dc9357SAndroid Build Coastguard Worker     sum = s->Freq;
114*f6dc9357SAndroid Build Coastguard Worker     i = (unsigned)p->MinContext->NumStats - 1;
115*f6dc9357SAndroid Build Coastguard Worker     do
116*f6dc9357SAndroid Build Coastguard Worker     {
117*f6dc9357SAndroid Build Coastguard Worker       if ((++s)->Symbol == symbol)
118*f6dc9357SAndroid Build Coastguard Worker       {
119*f6dc9357SAndroid Build Coastguard Worker         // R->Range /= p->MinContext->Union2.SummFreq;
120*f6dc9357SAndroid Build Coastguard Worker         RC_EncodeFinal(sum, s->Freq)
121*f6dc9357SAndroid Build Coastguard Worker         p->FoundState = s;
122*f6dc9357SAndroid Build Coastguard Worker         Ppmd7_Update1(p);
123*f6dc9357SAndroid Build Coastguard Worker         return;
124*f6dc9357SAndroid Build Coastguard Worker       }
125*f6dc9357SAndroid Build Coastguard Worker       sum += s->Freq;
126*f6dc9357SAndroid Build Coastguard Worker     }
127*f6dc9357SAndroid Build Coastguard Worker     while (--i);
128*f6dc9357SAndroid Build Coastguard Worker 
129*f6dc9357SAndroid Build Coastguard Worker     // R->Range /= p->MinContext->Union2.SummFreq;
130*f6dc9357SAndroid Build Coastguard Worker     RC_Encode(sum, p->MinContext->Union2.SummFreq - sum)
131*f6dc9357SAndroid Build Coastguard Worker 
132*f6dc9357SAndroid Build Coastguard Worker     p->HiBitsFlag = PPMD7_HiBitsFlag_3(p->FoundState->Symbol);
133*f6dc9357SAndroid Build Coastguard Worker     PPMD_SetAllBitsIn256Bytes(charMask)
134*f6dc9357SAndroid Build Coastguard Worker     // MASK(s->Symbol) = 0;
135*f6dc9357SAndroid Build Coastguard Worker     // i = p->MinContext->NumStats - 1;
136*f6dc9357SAndroid Build Coastguard Worker     // do { MASK((--s)->Symbol) = 0; } while (--i);
137*f6dc9357SAndroid Build Coastguard Worker     {
138*f6dc9357SAndroid Build Coastguard Worker       CPpmd_State *s2 = Ppmd7_GetStats(p, p->MinContext);
139*f6dc9357SAndroid Build Coastguard Worker       MASK(s->Symbol) = 0;
140*f6dc9357SAndroid Build Coastguard Worker       do
141*f6dc9357SAndroid Build Coastguard Worker       {
142*f6dc9357SAndroid Build Coastguard Worker         const unsigned sym0 = s2[0].Symbol;
143*f6dc9357SAndroid Build Coastguard Worker         const unsigned sym1 = s2[1].Symbol;
144*f6dc9357SAndroid Build Coastguard Worker         s2 += 2;
145*f6dc9357SAndroid Build Coastguard Worker         MASK(sym0) = 0;
146*f6dc9357SAndroid Build Coastguard Worker         MASK(sym1) = 0;
147*f6dc9357SAndroid Build Coastguard Worker       }
148*f6dc9357SAndroid Build Coastguard Worker       while (s2 < s);
149*f6dc9357SAndroid Build Coastguard Worker     }
150*f6dc9357SAndroid Build Coastguard Worker   }
151*f6dc9357SAndroid Build Coastguard Worker   else
152*f6dc9357SAndroid Build Coastguard Worker   {
153*f6dc9357SAndroid Build Coastguard Worker     UInt16 *prob = Ppmd7_GetBinSumm(p);
154*f6dc9357SAndroid Build Coastguard Worker     CPpmd_State *s = Ppmd7Context_OneState(p->MinContext);
155*f6dc9357SAndroid Build Coastguard Worker     UInt32 pr = *prob;
156*f6dc9357SAndroid Build Coastguard Worker     const UInt32 bound = (R->Range >> 14) * pr;
157*f6dc9357SAndroid Build Coastguard Worker     pr = PPMD_UPDATE_PROB_1(pr);
158*f6dc9357SAndroid Build Coastguard Worker     if (s->Symbol == symbol)
159*f6dc9357SAndroid Build Coastguard Worker     {
160*f6dc9357SAndroid Build Coastguard Worker       *prob = (UInt16)(pr + (1 << PPMD_INT_BITS));
161*f6dc9357SAndroid Build Coastguard Worker       // RangeEnc_EncodeBit_0(p, bound);
162*f6dc9357SAndroid Build Coastguard Worker       R->Range = bound;
163*f6dc9357SAndroid Build Coastguard Worker       RC_NORM_1(p)
164*f6dc9357SAndroid Build Coastguard Worker 
165*f6dc9357SAndroid Build Coastguard Worker       // p->FoundState = s;
166*f6dc9357SAndroid Build Coastguard Worker       // Ppmd7_UpdateBin(p);
167*f6dc9357SAndroid Build Coastguard Worker       {
168*f6dc9357SAndroid Build Coastguard Worker         const unsigned freq = s->Freq;
169*f6dc9357SAndroid Build Coastguard Worker         CPpmd7_Context *c = CTX(SUCCESSOR(s));
170*f6dc9357SAndroid Build Coastguard Worker         p->FoundState = s;
171*f6dc9357SAndroid Build Coastguard Worker         p->PrevSuccess = 1;
172*f6dc9357SAndroid Build Coastguard Worker         p->RunLength++;
173*f6dc9357SAndroid Build Coastguard Worker         s->Freq = (Byte)(freq + (freq < 128));
174*f6dc9357SAndroid Build Coastguard Worker         // NextContext(p);
175*f6dc9357SAndroid Build Coastguard Worker         if (p->OrderFall == 0 && (const Byte *)c > p->Text)
176*f6dc9357SAndroid Build Coastguard Worker           p->MaxContext = p->MinContext = c;
177*f6dc9357SAndroid Build Coastguard Worker         else
178*f6dc9357SAndroid Build Coastguard Worker           Ppmd7_UpdateModel(p);
179*f6dc9357SAndroid Build Coastguard Worker       }
180*f6dc9357SAndroid Build Coastguard Worker       return;
181*f6dc9357SAndroid Build Coastguard Worker     }
182*f6dc9357SAndroid Build Coastguard Worker 
183*f6dc9357SAndroid Build Coastguard Worker     *prob = (UInt16)pr;
184*f6dc9357SAndroid Build Coastguard Worker     p->InitEsc = p->ExpEscape[pr >> 10];
185*f6dc9357SAndroid Build Coastguard Worker     // RangeEnc_EncodeBit_1(p, bound);
186*f6dc9357SAndroid Build Coastguard Worker     R->Low += bound;
187*f6dc9357SAndroid Build Coastguard Worker     R->Range -= bound;
188*f6dc9357SAndroid Build Coastguard Worker     RC_NORM_LOCAL(p)
189*f6dc9357SAndroid Build Coastguard Worker 
190*f6dc9357SAndroid Build Coastguard Worker     PPMD_SetAllBitsIn256Bytes(charMask)
191*f6dc9357SAndroid Build Coastguard Worker     MASK(s->Symbol) = 0;
192*f6dc9357SAndroid Build Coastguard Worker     p->PrevSuccess = 0;
193*f6dc9357SAndroid Build Coastguard Worker   }
194*f6dc9357SAndroid Build Coastguard Worker 
195*f6dc9357SAndroid Build Coastguard Worker   for (;;)
196*f6dc9357SAndroid Build Coastguard Worker   {
197*f6dc9357SAndroid Build Coastguard Worker     CPpmd_See *see;
198*f6dc9357SAndroid Build Coastguard Worker     CPpmd_State *s;
199*f6dc9357SAndroid Build Coastguard Worker     UInt32 sum, escFreq;
200*f6dc9357SAndroid Build Coastguard Worker     CPpmd7_Context *mc;
201*f6dc9357SAndroid Build Coastguard Worker     unsigned i, numMasked;
202*f6dc9357SAndroid Build Coastguard Worker 
203*f6dc9357SAndroid Build Coastguard Worker     RC_NORM_REMOTE(p)
204*f6dc9357SAndroid Build Coastguard Worker 
205*f6dc9357SAndroid Build Coastguard Worker     mc = p->MinContext;
206*f6dc9357SAndroid Build Coastguard Worker     numMasked = mc->NumStats;
207*f6dc9357SAndroid Build Coastguard Worker 
208*f6dc9357SAndroid Build Coastguard Worker     do
209*f6dc9357SAndroid Build Coastguard Worker     {
210*f6dc9357SAndroid Build Coastguard Worker       p->OrderFall++;
211*f6dc9357SAndroid Build Coastguard Worker       if (!mc->Suffix)
212*f6dc9357SAndroid Build Coastguard Worker         return; /* EndMarker (symbol = -1) */
213*f6dc9357SAndroid Build Coastguard Worker       mc = Ppmd7_GetContext(p, mc->Suffix);
214*f6dc9357SAndroid Build Coastguard Worker       i = mc->NumStats;
215*f6dc9357SAndroid Build Coastguard Worker     }
216*f6dc9357SAndroid Build Coastguard Worker     while (i == numMasked);
217*f6dc9357SAndroid Build Coastguard Worker 
218*f6dc9357SAndroid Build Coastguard Worker     p->MinContext = mc;
219*f6dc9357SAndroid Build Coastguard Worker 
220*f6dc9357SAndroid Build Coastguard Worker     // see = Ppmd7_MakeEscFreq(p, numMasked, &escFreq);
221*f6dc9357SAndroid Build Coastguard Worker     {
222*f6dc9357SAndroid Build Coastguard Worker       if (i != 256)
223*f6dc9357SAndroid Build Coastguard Worker       {
224*f6dc9357SAndroid Build Coastguard Worker         unsigned nonMasked = i - numMasked;
225*f6dc9357SAndroid Build Coastguard Worker         see = p->See[(unsigned)p->NS2Indx[(size_t)nonMasked - 1]]
226*f6dc9357SAndroid Build Coastguard Worker             + p->HiBitsFlag
227*f6dc9357SAndroid Build Coastguard Worker             + (nonMasked < (unsigned)SUFFIX(mc)->NumStats - i)
228*f6dc9357SAndroid Build Coastguard Worker             + 2 * (unsigned)(mc->Union2.SummFreq < 11 * i)
229*f6dc9357SAndroid Build Coastguard Worker             + 4 * (unsigned)(numMasked > nonMasked);
230*f6dc9357SAndroid Build Coastguard Worker         {
231*f6dc9357SAndroid Build Coastguard Worker           // if (see->Summ) field is larger than 16-bit, we need only low 16 bits of Summ
232*f6dc9357SAndroid Build Coastguard Worker           unsigned summ = (UInt16)see->Summ; // & 0xFFFF
233*f6dc9357SAndroid Build Coastguard Worker           unsigned r = (summ >> see->Shift);
234*f6dc9357SAndroid Build Coastguard Worker           see->Summ = (UInt16)(summ - r);
235*f6dc9357SAndroid Build Coastguard Worker           escFreq = r + (r == 0);
236*f6dc9357SAndroid Build Coastguard Worker         }
237*f6dc9357SAndroid Build Coastguard Worker       }
238*f6dc9357SAndroid Build Coastguard Worker       else
239*f6dc9357SAndroid Build Coastguard Worker       {
240*f6dc9357SAndroid Build Coastguard Worker         see = &p->DummySee;
241*f6dc9357SAndroid Build Coastguard Worker         escFreq = 1;
242*f6dc9357SAndroid Build Coastguard Worker       }
243*f6dc9357SAndroid Build Coastguard Worker     }
244*f6dc9357SAndroid Build Coastguard Worker 
245*f6dc9357SAndroid Build Coastguard Worker     s = Ppmd7_GetStats(p, mc);
246*f6dc9357SAndroid Build Coastguard Worker     sum = 0;
247*f6dc9357SAndroid Build Coastguard Worker     // i = mc->NumStats;
248*f6dc9357SAndroid Build Coastguard Worker 
249*f6dc9357SAndroid Build Coastguard Worker     do
250*f6dc9357SAndroid Build Coastguard Worker     {
251*f6dc9357SAndroid Build Coastguard Worker       const unsigned cur = s->Symbol;
252*f6dc9357SAndroid Build Coastguard Worker       if ((int)cur == symbol)
253*f6dc9357SAndroid Build Coastguard Worker       {
254*f6dc9357SAndroid Build Coastguard Worker         const UInt32 low = sum;
255*f6dc9357SAndroid Build Coastguard Worker         const UInt32 freq = s->Freq;
256*f6dc9357SAndroid Build Coastguard Worker         unsigned num2;
257*f6dc9357SAndroid Build Coastguard Worker 
258*f6dc9357SAndroid Build Coastguard Worker         Ppmd_See_UPDATE(see)
259*f6dc9357SAndroid Build Coastguard Worker         p->FoundState = s;
260*f6dc9357SAndroid Build Coastguard Worker         sum += escFreq;
261*f6dc9357SAndroid Build Coastguard Worker 
262*f6dc9357SAndroid Build Coastguard Worker         num2 = i / 2;
263*f6dc9357SAndroid Build Coastguard Worker         i &= 1;
264*f6dc9357SAndroid Build Coastguard Worker         sum += freq & (0 - (UInt32)i);
265*f6dc9357SAndroid Build Coastguard Worker         if (num2 != 0)
266*f6dc9357SAndroid Build Coastguard Worker         {
267*f6dc9357SAndroid Build Coastguard Worker           s += i;
268*f6dc9357SAndroid Build Coastguard Worker           do
269*f6dc9357SAndroid Build Coastguard Worker           {
270*f6dc9357SAndroid Build Coastguard Worker             const unsigned sym0 = s[0].Symbol;
271*f6dc9357SAndroid Build Coastguard Worker             const unsigned sym1 = s[1].Symbol;
272*f6dc9357SAndroid Build Coastguard Worker             s += 2;
273*f6dc9357SAndroid Build Coastguard Worker             sum += (s[-2].Freq & (unsigned)(MASK(sym0)));
274*f6dc9357SAndroid Build Coastguard Worker             sum += (s[-1].Freq & (unsigned)(MASK(sym1)));
275*f6dc9357SAndroid Build Coastguard Worker           }
276*f6dc9357SAndroid Build Coastguard Worker           while (--num2);
277*f6dc9357SAndroid Build Coastguard Worker         }
278*f6dc9357SAndroid Build Coastguard Worker 
279*f6dc9357SAndroid Build Coastguard Worker 
280*f6dc9357SAndroid Build Coastguard Worker         R->Range /= sum;
281*f6dc9357SAndroid Build Coastguard Worker         RC_EncodeFinal(low, freq)
282*f6dc9357SAndroid Build Coastguard Worker         Ppmd7_Update2(p);
283*f6dc9357SAndroid Build Coastguard Worker         return;
284*f6dc9357SAndroid Build Coastguard Worker       }
285*f6dc9357SAndroid Build Coastguard Worker       sum += (s->Freq & (unsigned)(MASK(cur)));
286*f6dc9357SAndroid Build Coastguard Worker       s++;
287*f6dc9357SAndroid Build Coastguard Worker     }
288*f6dc9357SAndroid Build Coastguard Worker     while (--i);
289*f6dc9357SAndroid Build Coastguard Worker 
290*f6dc9357SAndroid Build Coastguard Worker     {
291*f6dc9357SAndroid Build Coastguard Worker       const UInt32 total = sum + escFreq;
292*f6dc9357SAndroid Build Coastguard Worker       see->Summ = (UInt16)(see->Summ + total);
293*f6dc9357SAndroid Build Coastguard Worker 
294*f6dc9357SAndroid Build Coastguard Worker       R->Range /= total;
295*f6dc9357SAndroid Build Coastguard Worker       RC_Encode(sum, escFreq)
296*f6dc9357SAndroid Build Coastguard Worker     }
297*f6dc9357SAndroid Build Coastguard Worker 
298*f6dc9357SAndroid Build Coastguard Worker     {
299*f6dc9357SAndroid Build Coastguard Worker       const CPpmd_State *s2 = Ppmd7_GetStats(p, p->MinContext);
300*f6dc9357SAndroid Build Coastguard Worker       s--;
301*f6dc9357SAndroid Build Coastguard Worker       MASK(s->Symbol) = 0;
302*f6dc9357SAndroid Build Coastguard Worker       do
303*f6dc9357SAndroid Build Coastguard Worker       {
304*f6dc9357SAndroid Build Coastguard Worker         const unsigned sym0 = s2[0].Symbol;
305*f6dc9357SAndroid Build Coastguard Worker         const unsigned sym1 = s2[1].Symbol;
306*f6dc9357SAndroid Build Coastguard Worker         s2 += 2;
307*f6dc9357SAndroid Build Coastguard Worker         MASK(sym0) = 0;
308*f6dc9357SAndroid Build Coastguard Worker         MASK(sym1) = 0;
309*f6dc9357SAndroid Build Coastguard Worker       }
310*f6dc9357SAndroid Build Coastguard Worker       while (s2 < s);
311*f6dc9357SAndroid Build Coastguard Worker     }
312*f6dc9357SAndroid Build Coastguard Worker   }
313*f6dc9357SAndroid Build Coastguard Worker }
314*f6dc9357SAndroid Build Coastguard Worker 
315*f6dc9357SAndroid Build Coastguard Worker 
Ppmd7z_EncodeSymbols(CPpmd7 * p,const Byte * buf,const Byte * lim)316*f6dc9357SAndroid Build Coastguard Worker void Ppmd7z_EncodeSymbols(CPpmd7 *p, const Byte *buf, const Byte *lim)
317*f6dc9357SAndroid Build Coastguard Worker {
318*f6dc9357SAndroid Build Coastguard Worker   for (; buf < lim; buf++)
319*f6dc9357SAndroid Build Coastguard Worker   {
320*f6dc9357SAndroid Build Coastguard Worker     Ppmd7z_EncodeSymbol(p, *buf);
321*f6dc9357SAndroid Build Coastguard Worker   }
322*f6dc9357SAndroid Build Coastguard Worker }
323*f6dc9357SAndroid Build Coastguard Worker 
324*f6dc9357SAndroid Build Coastguard Worker #undef kTopValue
325*f6dc9357SAndroid Build Coastguard Worker #undef WRITE_BYTE
326*f6dc9357SAndroid Build Coastguard Worker #undef RC_NORM_BASE
327*f6dc9357SAndroid Build Coastguard Worker #undef RC_NORM_1
328*f6dc9357SAndroid Build Coastguard Worker #undef RC_NORM
329*f6dc9357SAndroid Build Coastguard Worker #undef RC_NORM_LOCAL
330*f6dc9357SAndroid Build Coastguard Worker #undef RC_NORM_REMOTE
331*f6dc9357SAndroid Build Coastguard Worker #undef R
332*f6dc9357SAndroid Build Coastguard Worker #undef RC_Encode
333*f6dc9357SAndroid Build Coastguard Worker #undef RC_EncodeFinal
334*f6dc9357SAndroid Build Coastguard Worker #undef SUFFIX
335*f6dc9357SAndroid Build Coastguard Worker #undef CTX
336*f6dc9357SAndroid Build Coastguard Worker #undef SUCCESSOR
337*f6dc9357SAndroid Build Coastguard Worker #undef MASK
338