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/Ppmd8Dec.c
Line
Count
Source
1
/* Ppmd8Dec.c -- Ppmd8 (PPMdI) Decoder
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
19.2M
#define kTop ((UInt32)1 << 24)
12
14.8M
#define kBot ((UInt32)1 << 15)
13
14
2.21M
#define READ_BYTE(p) IByteIn_Read((p)->Stream.In)
15
16
BoolInt Ppmd8_Init_RangeDec(CPpmd8 *p)
17
9.23k
{
18
9.23k
  unsigned i;
19
9.23k
  p->Code = 0;
20
9.23k
  p->Range = 0xFFFFFFFF;
21
9.23k
  p->Low = 0;
22
  
23
46.1k
  for (i = 0; i < 4; i++)
24
36.9k
    p->Code = (p->Code << 8) | READ_BYTE(p);
25
9.23k
  return (p->Code < 0xFFFFFFFF);
26
9.23k
}
27
28
#define RC_NORM(p) \
29
9.60M
  while ((p->Low ^ (p->Low + p->Range)) < kTop \
30
9.60M
    || (p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1))) { \
31
2.17M
      p->Code = (p->Code << 8) | READ_BYTE(p); \
32
2.17M
      p->Range <<= 8; p->Low <<= 8; }
33
34
// we must use only one type of Normalization from two: LOCAL or REMOTE
35
#define RC_NORM_LOCAL(p)    // RC_NORM(p)
36
5.21M
#define RC_NORM_REMOTE(p)   RC_NORM(p)
37
38
37.9M
#define R p
39
40
Z7_FORCE_INLINE
41
// Z7_NO_INLINE
42
static void Ppmd8_RD_Decode(CPpmd8 *p, UInt32 start, UInt32 size)
43
4.45M
{
44
4.45M
  start *= R->Range;
45
4.45M
  R->Low += start;
46
4.45M
  R->Code -= start;
47
4.45M
  R->Range *= size;
48
4.45M
  RC_NORM_LOCAL(R)
49
4.45M
}
50
51
4.45M
#define RC_Decode(start, size)  Ppmd8_RD_Decode(p, start, size);
52
3.14M
#define RC_DecodeFinal(start, size)  RC_Decode(start, size)  RC_NORM_REMOTE(R)
53
4.45M
#define RC_GetThreshold(total)  (R->Code / (R->Range /= (total)))
54
55
56
2.21M
#define CTX(ref) ((CPpmd8_Context *)Ppmd8_GetContext(p, ref))
57
// typedef CPpmd8_Context * CTX_PTR;
58
#define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p)
59
void Ppmd8_UpdateModel(CPpmd8 *p);
60
61
464M
#define MASK(sym)  ((Byte *)charMask)[sym]
62
63
64
int Ppmd8_DecodeSymbol(CPpmd8 *p)
65
5.36M
{
66
5.36M
  size_t charMask[256 / sizeof(size_t)];
67
68
5.36M
  if (p->MinContext->NumStats != 0)
69
2.38M
  {
70
2.38M
    CPpmd_State *s = Ppmd8_GetStats(p, p->MinContext);
71
2.38M
    unsigned i;
72
2.38M
    UInt32 count, hiCnt;
73
2.38M
    UInt32 summFreq = p->MinContext->Union2.SummFreq;
74
75
2.38M
    PPMD8_CORRECT_SUM_RANGE(p, summFreq)
76
77
78
2.38M
    count = RC_GetThreshold(summFreq);
79
2.38M
    hiCnt = count;
80
    
81
2.38M
    if ((Int32)(count -= s->Freq) < 0)
82
695k
    {
83
695k
      Byte sym;
84
695k
      RC_DecodeFinal(0, s->Freq)
85
695k
      p->FoundState = s;
86
695k
      sym = s->Symbol;
87
695k
      Ppmd8_Update1_0(p);
88
695k
      return sym;
89
695k
    }
90
    
91
1.68M
    p->PrevSuccess = 0;
92
1.68M
    i = p->MinContext->NumStats;
93
    
94
1.68M
    do
95
64.5M
    {
96
64.5M
      if ((Int32)(count -= (++s)->Freq) < 0)
97
919k
      {
98
919k
        Byte sym;
99
919k
        RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq)
100
919k
        p->FoundState = s;
101
919k
        sym = s->Symbol;
102
919k
        Ppmd8_Update1(p);
103
919k
        return sym;
104
919k
      }
105
64.5M
    }
106
63.5M
    while (--i);
107
    
108
770k
    if (hiCnt >= summFreq)
109
103
      return PPMD8_SYM_ERROR;
110
111
769k
    hiCnt -= count;
112
769k
    RC_Decode(hiCnt, summFreq - hiCnt)
113
    
114
    
115
769k
    PPMD_SetAllBitsIn256Bytes(charMask)
116
    // i = p->MinContext->NumStats - 1;
117
    // do { MASK((--s)->Symbol) = 0; } while (--i);
118
769k
    {
119
769k
      CPpmd_State *s2 = Ppmd8_GetStats(p, p->MinContext);
120
769k
      MASK(s->Symbol) = 0;
121
769k
      do
122
1.49M
      {
123
1.49M
        const unsigned sym0 = s2[0].Symbol;
124
1.49M
        const unsigned sym1 = s2[1].Symbol;
125
1.49M
        s2 += 2;
126
1.49M
        MASK(sym0) = 0;
127
1.49M
        MASK(sym1) = 0;
128
1.49M
      }
129
1.49M
      while (s2 < s);
130
769k
    }
131
769k
  }
132
2.97M
  else
133
2.97M
  {
134
2.97M
    CPpmd_State *s = Ppmd8Context_OneState(p->MinContext);
135
2.97M
    UInt16 *prob = Ppmd8_GetBinSumm(p);
136
2.97M
    UInt32 pr = *prob;
137
2.97M
    UInt32 size0 = (R->Range >> 14) * pr;
138
2.97M
    pr = PPMD_UPDATE_PROB_1(pr);
139
    
140
2.97M
    if (R->Code < size0)
141
2.21M
    {
142
2.21M
      Byte sym;
143
2.21M
      *prob = (UInt16)(pr + (1 << PPMD_INT_BITS));
144
      
145
      // RangeDec_DecodeBit0(size0);
146
2.21M
      R->Range = size0;
147
2.21M
      RC_NORM(R)
148
      
149
      
150
        
151
      // sym = (p->FoundState = Ppmd8Context_OneState(p->MinContext))->Symbol;
152
      // Ppmd8_UpdateBin(p);
153
2.21M
      {
154
2.21M
        unsigned freq = s->Freq;
155
2.21M
        CPpmd8_Context *c = CTX(SUCCESSOR(s));
156
2.21M
        sym = s->Symbol;
157
2.21M
        p->FoundState = s;
158
2.21M
        p->PrevSuccess = 1;
159
2.21M
        p->RunLength++;
160
2.21M
        s->Freq = (Byte)(freq + (freq < 196));
161
        // NextContext(p);
162
2.21M
        if (p->OrderFall == 0 && (const Byte *)c >= p->UnitsStart)
163
1.15M
          p->MaxContext = p->MinContext = c;
164
1.05M
        else
165
1.05M
          Ppmd8_UpdateModel(p);
166
2.21M
      }
167
2.21M
      return sym;
168
2.21M
    }
169
    
170
766k
    *prob = (UInt16)pr;
171
766k
    p->InitEsc = p->ExpEscape[pr >> 10];
172
    
173
    // RangeDec_DecodeBit1(rc2, size0);
174
766k
    R->Low += size0;
175
766k
    R->Code -= size0;
176
766k
    R->Range = (R->Range & ~((UInt32)PPMD_BIN_SCALE - 1)) - size0;
177
766k
    RC_NORM_LOCAL(R)
178
    
179
766k
    PPMD_SetAllBitsIn256Bytes(charMask)
180
766k
    MASK(Ppmd8Context_OneState(p->MinContext)->Symbol) = 0;
181
766k
    p->PrevSuccess = 0;
182
766k
  }
183
  
184
1.53M
  for (;;)
185
2.06M
  {
186
2.06M
    CPpmd_State *s, *s2;
187
2.06M
    UInt32 freqSum, count, hiCnt;
188
2.06M
    UInt32 freqSum2;
189
2.06M
    CPpmd_See *see;
190
2.06M
    CPpmd8_Context *mc;
191
2.06M
    unsigned numMasked;
192
2.06M
    RC_NORM_REMOTE(R)
193
2.06M
    mc = p->MinContext;
194
2.06M
    numMasked = mc->NumStats;
195
    
196
2.06M
    do
197
2.93M
    {
198
2.93M
      p->OrderFall++;
199
2.93M
      if (!mc->Suffix)
200
2.16k
        return PPMD8_SYM_END;
201
2.93M
      mc = Ppmd8_GetContext(p, mc->Suffix);
202
2.93M
    }
203
2.93M
    while (mc->NumStats == numMasked);
204
    
205
2.06M
    s = Ppmd8_GetStats(p, mc);
206
207
2.06M
    {
208
2.06M
      unsigned num = (unsigned)mc->NumStats + 1;
209
2.06M
      unsigned num2 = num / 2;
210
211
2.06M
      num &= 1;
212
2.06M
      hiCnt = (s->Freq & (UInt32)(MASK(s->Symbol))) & (0 - (UInt32)num);
213
2.06M
      s += num;
214
2.06M
      p->MinContext = mc;
215
216
2.06M
      do
217
154M
      {
218
154M
        const unsigned sym0 = s[0].Symbol;
219
154M
        const unsigned sym1 = s[1].Symbol;
220
154M
        s += 2;
221
154M
        hiCnt += (s[-2].Freq & (UInt32)(MASK(sym0)));
222
154M
        hiCnt += (s[-1].Freq & (UInt32)(MASK(sym1)));
223
154M
      }
224
154M
      while (--num2);
225
2.06M
    }
226
    
227
2.06M
    see = Ppmd8_MakeEscFreq(p, numMasked, &freqSum);
228
2.06M
    freqSum += hiCnt;
229
2.06M
    freqSum2 = freqSum;
230
2.06M
    PPMD8_CORRECT_SUM_RANGE(R, freqSum2)
231
232
233
2.06M
    count = RC_GetThreshold(freqSum2);
234
    
235
2.06M
    if (count < hiCnt)
236
1.53M
    {
237
1.53M
      Byte sym;
238
      // Ppmd_See_UPDATE(see) // new (see->Summ) value can overflow over 16-bits in some rare cases
239
1.53M
      s = Ppmd8_GetStats(p, p->MinContext);
240
1.53M
      hiCnt = count;
241
242
      
243
1.53M
      {
244
1.53M
        for (;;)
245
144M
        {
246
144M
          count -= s->Freq & (UInt32)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break;
247
          // count -= s->Freq & (UInt32)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break;
248
144M
        }
249
1.53M
      }
250
1.53M
      s--;
251
1.53M
      RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq)
252
253
      // new (see->Summ) value can overflow over 16-bits in some rare cases
254
1.53M
      Ppmd_See_UPDATE(see)
255
1.53M
      p->FoundState = s;
256
1.53M
      sym = s->Symbol;
257
1.53M
      Ppmd8_Update2(p);
258
1.53M
      return sym;
259
1.53M
    }
260
261
532k
    if (count >= freqSum2)
262
100
      return PPMD8_SYM_ERROR;
263
    
264
532k
    RC_Decode(hiCnt, freqSum2 - hiCnt)
265
    
266
    // We increase (see->Summ) for sum of Freqs of all non_Masked symbols.
267
    // new (see->Summ) value can overflow over 16-bits in some rare cases
268
532k
    see->Summ = (UInt16)(see->Summ + freqSum);
269
    
270
532k
    s = Ppmd8_GetStats(p, p->MinContext);
271
532k
    s2 = s + p->MinContext->NumStats + 1;
272
532k
    do
273
3.41M
    {
274
3.41M
      MASK(s->Symbol) = 0;
275
3.41M
      s++;
276
3.41M
    }
277
3.41M
    while (s != s2);
278
532k
  }
279
1.53M
}
280
281
#undef kTop
282
#undef kBot
283
#undef READ_BYTE
284
#undef RC_NORM_BASE
285
#undef RC_NORM_1
286
#undef RC_NORM
287
#undef RC_NORM_LOCAL
288
#undef RC_NORM_REMOTE
289
#undef R
290
#undef RC_Decode
291
#undef RC_DecodeFinal
292
#undef RC_GetThreshold
293
#undef CTX
294
#undef SUCCESSOR
295
#undef MASK