Coverage Report

Created: 2026-02-26 07:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/minizip-ng/third_party/ppmd/C/Ppmd8Enc.c
Line
Count
Source
1
/* Ppmd8Enc.c -- Ppmd8 (PPMdI) Encoder
2
2023-09-07 : Igor Pavlov : Public domain
3
This code is based on:
4
  PPMd var.I (2002): Dmitry Shkarin : Public domain
5
  Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
6
7
#include "Precomp.h"
8
9
#include "Ppmd8.h"
10
11
574M
#define kTop ((UInt32)1 << 24)
12
393M
#define kBot ((UInt32)1 << 15)
13
14
90.7M
#define WRITE_BYTE(p) IByteOut_Write(p->Stream.Out, (Byte)(p->Low >> 24))
15
16
void Ppmd8_Flush_RangeEnc(CPpmd8 *p)
17
2.02k
{
18
2.02k
  unsigned i;
19
10.1k
  for (i = 0; i < 4; i++, p->Low <<= 8 )
20
8.10k
    WRITE_BYTE(p);
21
2.02k
}
22
23
24
25
26
27
28
#define RC_NORM(p) \
29
287M
  while ((p->Low ^ (p->Low + p->Range)) < kTop \
30
287M
    || (p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1))) \
31
196M
    { WRITE_BYTE(p); p->Range <<= 8; p->Low <<= 8; }
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// we must use only one type of Normalization from two: LOCAL or REMOTE
46
#define RC_NORM_LOCAL(p)    // RC_NORM(p)
47
181M
#define RC_NORM_REMOTE(p)   RC_NORM(p)
48
49
// #define RC_PRE(total) p->Range /= total;
50
// #define RC_PRE(total)
51
52
596M
#define R p
53
54
55
56
57
Z7_FORCE_INLINE
58
// Z7_NO_INLINE
59
static void Ppmd8_RangeEnc_Encode(CPpmd8 *p, UInt32 start, UInt32 size, UInt32 total)
60
158M
{
61
158M
  R->Low += start * (R->Range /= total);
62
158M
  R->Range *= size;
63
158M
  RC_NORM_LOCAL(R)
64
158M
}
65
66
67
68
69
70
71
72
73
74
75
158M
#define RC_Encode(start, size, total)  Ppmd8_RangeEnc_Encode(p, start, size, total);
76
93.8M
#define RC_EncodeFinal(start, size, total)  RC_Encode(start, size, total)  RC_NORM_REMOTE(p)
77
78
14.9M
#define CTX(ref) ((CPpmd8_Context *)Ppmd8_GetContext(p, ref))
79
80
// typedef CPpmd8_Context * CTX_PTR;
81
#define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p)
82
83
void Ppmd8_UpdateModel(CPpmd8 *p);
84
85
21.3G
#define MASK(sym)  ((Byte *)charMask)[sym]
86
87
// Z7_FORCE_INLINE
88
// static
89
void Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol)
90
108M
{
91
108M
  size_t charMask[256 / sizeof(size_t)];
92
  
93
108M
  if (p->MinContext->NumStats != 0)
94
71.2M
  {
95
71.2M
    CPpmd_State *s = Ppmd8_GetStats(p, p->MinContext);
96
71.2M
    UInt32 sum;
97
71.2M
    unsigned i;
98
71.2M
    UInt32 summFreq = p->MinContext->Union2.SummFreq;
99
    
100
71.2M
    PPMD8_CORRECT_SUM_RANGE(p, summFreq)
101
102
    // RC_PRE(summFreq);
103
104
71.2M
    if (s->Symbol == symbol)
105
3.46M
    {
106
107
3.46M
      RC_EncodeFinal(0, s->Freq, summFreq)
108
3.46M
      p->FoundState = s;
109
3.46M
      Ppmd8_Update1_0(p);
110
3.46M
      return;
111
3.46M
    }
112
67.8M
    p->PrevSuccess = 0;
113
67.8M
    sum = s->Freq;
114
67.8M
    i = p->MinContext->NumStats;
115
67.8M
    do
116
2.88G
    {
117
2.88G
      if ((++s)->Symbol == symbol)
118
19.0M
      {
119
120
19.0M
        RC_EncodeFinal(sum, s->Freq, summFreq)
121
19.0M
        p->FoundState = s;
122
19.0M
        Ppmd8_Update1(p);
123
19.0M
        return;
124
19.0M
      }
125
2.86G
      sum += s->Freq;
126
2.86G
    }
127
2.86G
    while (--i);
128
    
129
    
130
48.7M
    RC_Encode(sum, summFreq - sum, summFreq)
131
    
132
    
133
48.7M
    PPMD_SetAllBitsIn256Bytes(charMask)
134
    // MASK(s->Symbol) = 0;
135
    // i = p->MinContext->NumStats;
136
    // do { MASK((--s)->Symbol) = 0; } while (--i);
137
48.7M
    {
138
48.7M
      CPpmd_State *s2 = Ppmd8_GetStats(p, p->MinContext);
139
48.7M
      MASK(s->Symbol) = 0;
140
48.7M
      do
141
989M
      {
142
989M
        const unsigned sym0 = s2[0].Symbol;
143
989M
        const unsigned sym1 = s2[1].Symbol;
144
989M
        s2 += 2;
145
989M
        MASK(sym0) = 0;
146
989M
        MASK(sym1) = 0;
147
989M
      }
148
989M
      while (s2 < s);
149
48.7M
    }
150
48.7M
  }
151
37.5M
  else
152
37.5M
  {
153
37.5M
    UInt16 *prob = Ppmd8_GetBinSumm(p);
154
37.5M
    CPpmd_State *s = Ppmd8Context_OneState(p->MinContext);
155
37.5M
    UInt32 pr = *prob;
156
37.5M
    const UInt32 bound = (R->Range >> 14) * pr;
157
37.5M
    pr = PPMD_UPDATE_PROB_1(pr);
158
37.5M
    if (s->Symbol == symbol)
159
14.9M
    {
160
14.9M
      *prob = (UInt16)(pr + (1 << PPMD_INT_BITS));
161
      // RangeEnc_EncodeBit_0(p, bound);
162
14.9M
      R->Range = bound;
163
14.9M
      RC_NORM(R)
164
165
      // p->FoundState = s;
166
      // Ppmd8_UpdateBin(p);
167
14.9M
      {
168
14.9M
        const unsigned freq = s->Freq;
169
14.9M
        CPpmd8_Context *c = CTX(SUCCESSOR(s));
170
14.9M
        p->FoundState = s;
171
14.9M
        p->PrevSuccess = 1;
172
14.9M
        p->RunLength++;
173
14.9M
        s->Freq = (Byte)(freq + (freq < 196)); // Ppmd8 (196)
174
        // NextContext(p);
175
14.9M
        if (p->OrderFall == 0 && (const Byte *)c >= p->UnitsStart)
176
5.49M
          p->MaxContext = p->MinContext = c;
177
9.48M
        else
178
9.48M
          Ppmd8_UpdateModel(p);
179
14.9M
      }
180
14.9M
      return;
181
14.9M
    }
182
183
22.5M
    *prob = (UInt16)pr;
184
22.5M
    p->InitEsc = p->ExpEscape[pr >> 10];
185
    // RangeEnc_EncodeBit_1(p, bound);
186
22.5M
    R->Low += bound;
187
22.5M
    R->Range = (R->Range & ~((UInt32)PPMD_BIN_SCALE - 1)) - bound;
188
22.5M
    RC_NORM_LOCAL(R)
189
190
22.5M
    PPMD_SetAllBitsIn256Bytes(charMask)
191
22.5M
    MASK(s->Symbol) = 0;
192
22.5M
    p->PrevSuccess = 0;
193
22.5M
  }
194
195
71.2M
  for (;;)
196
87.6M
  {
197
87.6M
    CPpmd_See *see;
198
87.6M
    CPpmd_State *s;
199
87.6M
    UInt32 sum, escFreq;
200
87.6M
    CPpmd8_Context *mc;
201
87.6M
    unsigned i, numMasked;
202
203
87.6M
    RC_NORM_REMOTE(p)
204
205
87.6M
    mc = p->MinContext;
206
87.6M
    numMasked = mc->NumStats;
207
208
87.6M
    do
209
88.7M
    {
210
88.7M
      p->OrderFall++;
211
88.7M
      if (!mc->Suffix)
212
2.02k
        return; /* EndMarker (symbol = -1) */
213
88.7M
      mc = Ppmd8_GetContext(p, mc->Suffix);
214
215
88.7M
    }
216
88.7M
    while (mc->NumStats == numMasked);
217
    
218
87.6M
    p->MinContext = mc;
219
220
87.6M
    see = Ppmd8_MakeEscFreq(p, numMasked, &escFreq);
221
    
222
    
223
    
224
    
225
    
226
    
227
    
228
    
229
    
230
231
    
232
    
233
    
234
    
235
    
236
    
237
238
    
239
    
240
    
241
    
242
    
243
    
244
    
245
87.6M
    s = Ppmd8_GetStats(p, p->MinContext);
246
87.6M
    sum = 0;
247
87.6M
    i = (unsigned)p->MinContext->NumStats + 1;
248
249
87.6M
    do
250
9.62G
    {
251
9.62G
      const unsigned cur = s->Symbol;
252
9.62G
      if ((int)cur == symbol)
253
71.2M
      {
254
71.2M
        const UInt32 low = sum;
255
71.2M
        const UInt32 freq = s->Freq;
256
71.2M
        unsigned num2;
257
258
71.2M
        Ppmd_See_UPDATE(see)
259
71.2M
        p->FoundState = s;
260
71.2M
        sum += escFreq;
261
262
71.2M
        num2 = i / 2;
263
71.2M
        i &= 1;
264
71.2M
        sum += freq & (0 - (UInt32)i);
265
71.2M
        if (num2 != 0)
266
70.7M
        {
267
70.7M
          s += i;
268
70.7M
          do
269
3.95G
          {
270
3.95G
            const unsigned sym0 = s[0].Symbol;
271
3.95G
            const unsigned sym1 = s[1].Symbol;
272
3.95G
            s += 2;
273
3.95G
            sum += (s[-2].Freq & (unsigned)(MASK(sym0)));
274
3.95G
            sum += (s[-1].Freq & (unsigned)(MASK(sym1)));
275
3.95G
          }
276
3.95G
          while (--num2);
277
70.7M
        }
278
279
71.2M
        PPMD8_CORRECT_SUM_RANGE(p, sum)
280
281
71.2M
        RC_EncodeFinal(low, freq, sum)
282
71.2M
        Ppmd8_Update2(p);
283
71.2M
        return;
284
71.2M
      }
285
9.55G
      sum += (s->Freq & (unsigned)(MASK(cur)));
286
9.55G
      s++;
287
9.55G
    }
288
9.55G
    while (--i);
289
    
290
16.4M
    {
291
16.4M
      UInt32 total = sum + escFreq;
292
16.4M
      see->Summ = (UInt16)(see->Summ + total);
293
16.4M
      PPMD8_CORRECT_SUM_RANGE(p, total)
294
295
16.4M
      RC_Encode(sum, total - sum, total)
296
16.4M
    }
297
298
16.4M
    {
299
16.4M
      const CPpmd_State *s2 = Ppmd8_GetStats(p, p->MinContext);
300
16.4M
      s--;
301
16.4M
      MASK(s->Symbol) = 0;
302
16.4M
      do
303
897M
      {
304
897M
        const unsigned sym0 = s2[0].Symbol;
305
897M
        const unsigned sym1 = s2[1].Symbol;
306
897M
        s2 += 2;
307
897M
        MASK(sym0) = 0;
308
897M
        MASK(sym1) = 0;
309
897M
      }
310
897M
      while (s2 < s);
311
16.4M
    }
312
16.4M
  }
313
71.2M
}
314
315
316
317
318
319
320
321
322
323
#undef kTop
324
#undef kBot
325
#undef WRITE_BYTE
326
#undef RC_NORM_BASE
327
#undef RC_NORM_1
328
#undef RC_NORM
329
#undef RC_NORM_LOCAL
330
#undef RC_NORM_REMOTE
331
#undef R
332
#undef RC_Encode
333
#undef RC_EncodeFinal
334
335
#undef CTX
336
#undef SUCCESSOR
337
#undef MASK