/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 | 0 | #define kTop ((UInt32)1 << 24) |
12 | 0 | #define kBot ((UInt32)1 << 15) |
13 | | |
14 | 0 | #define READ_BYTE(p) IByteIn_Read((p)->Stream.In) |
15 | | |
16 | | BoolInt Ppmd8_Init_RangeDec(CPpmd8 *p) |
17 | 0 | { |
18 | 0 | unsigned i; |
19 | 0 | p->Code = 0; |
20 | 0 | p->Range = 0xFFFFFFFF; |
21 | 0 | p->Low = 0; |
22 | | |
23 | 0 | for (i = 0; i < 4; i++) |
24 | 0 | p->Code = (p->Code << 8) | READ_BYTE(p); |
25 | 0 | return (p->Code < 0xFFFFFFFF); |
26 | 0 | } |
27 | | |
28 | | #define RC_NORM(p) \ |
29 | 0 | while ((p->Low ^ (p->Low + p->Range)) < kTop \ |
30 | 0 | || (p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1))) { \ |
31 | 0 | p->Code = (p->Code << 8) | READ_BYTE(p); \ |
32 | 0 | 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 | 0 | #define RC_NORM_REMOTE(p) RC_NORM(p) |
37 | | |
38 | 0 | #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 | 0 | { |
44 | 0 | start *= R->Range; |
45 | 0 | R->Low += start; |
46 | 0 | R->Code -= start; |
47 | 0 | R->Range *= size; |
48 | 0 | RC_NORM_LOCAL(R) |
49 | 0 | } |
50 | | |
51 | 0 | #define RC_Decode(start, size) Ppmd8_RD_Decode(p, start, size); |
52 | 0 | #define RC_DecodeFinal(start, size) RC_Decode(start, size) RC_NORM_REMOTE(R) |
53 | 0 | #define RC_GetThreshold(total) (R->Code / (R->Range /= (total))) |
54 | | |
55 | | |
56 | 0 | #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 | 0 | #define MASK(sym) ((Byte *)charMask)[sym] |
62 | | |
63 | | |
64 | | int Ppmd8_DecodeSymbol(CPpmd8 *p) |
65 | 0 | { |
66 | 0 | size_t charMask[256 / sizeof(size_t)]; |
67 | |
|
68 | 0 | if (p->MinContext->NumStats != 0) |
69 | 0 | { |
70 | 0 | CPpmd_State *s = Ppmd8_GetStats(p, p->MinContext); |
71 | 0 | unsigned i; |
72 | 0 | UInt32 count, hiCnt; |
73 | 0 | UInt32 summFreq = p->MinContext->Union2.SummFreq; |
74 | |
|
75 | 0 | PPMD8_CORRECT_SUM_RANGE(p, summFreq) |
76 | | |
77 | |
|
78 | 0 | count = RC_GetThreshold(summFreq); |
79 | 0 | hiCnt = count; |
80 | | |
81 | 0 | if ((Int32)(count -= s->Freq) < 0) |
82 | 0 | { |
83 | 0 | Byte sym; |
84 | 0 | RC_DecodeFinal(0, s->Freq) |
85 | 0 | p->FoundState = s; |
86 | 0 | sym = s->Symbol; |
87 | 0 | Ppmd8_Update1_0(p); |
88 | 0 | return sym; |
89 | 0 | } |
90 | | |
91 | 0 | p->PrevSuccess = 0; |
92 | 0 | i = p->MinContext->NumStats; |
93 | | |
94 | 0 | do |
95 | 0 | { |
96 | 0 | if ((Int32)(count -= (++s)->Freq) < 0) |
97 | 0 | { |
98 | 0 | Byte sym; |
99 | 0 | RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq) |
100 | 0 | p->FoundState = s; |
101 | 0 | sym = s->Symbol; |
102 | 0 | Ppmd8_Update1(p); |
103 | 0 | return sym; |
104 | 0 | } |
105 | 0 | } |
106 | 0 | while (--i); |
107 | | |
108 | 0 | if (hiCnt >= summFreq) |
109 | 0 | return PPMD8_SYM_ERROR; |
110 | | |
111 | 0 | hiCnt -= count; |
112 | 0 | RC_Decode(hiCnt, summFreq - hiCnt) |
113 | | |
114 | | |
115 | 0 | PPMD_SetAllBitsIn256Bytes(charMask) |
116 | | // i = p->MinContext->NumStats - 1; |
117 | | // do { MASK((--s)->Symbol) = 0; } while (--i); |
118 | 0 | { |
119 | 0 | CPpmd_State *s2 = Ppmd8_GetStats(p, p->MinContext); |
120 | 0 | MASK(s->Symbol) = 0; |
121 | 0 | do |
122 | 0 | { |
123 | 0 | const unsigned sym0 = s2[0].Symbol; |
124 | 0 | const unsigned sym1 = s2[1].Symbol; |
125 | 0 | s2 += 2; |
126 | 0 | MASK(sym0) = 0; |
127 | 0 | MASK(sym1) = 0; |
128 | 0 | } |
129 | 0 | while (s2 < s); |
130 | 0 | } |
131 | 0 | } |
132 | 0 | else |
133 | 0 | { |
134 | 0 | CPpmd_State *s = Ppmd8Context_OneState(p->MinContext); |
135 | 0 | UInt16 *prob = Ppmd8_GetBinSumm(p); |
136 | 0 | UInt32 pr = *prob; |
137 | 0 | UInt32 size0 = (R->Range >> 14) * pr; |
138 | 0 | pr = PPMD_UPDATE_PROB_1(pr); |
139 | | |
140 | 0 | if (R->Code < size0) |
141 | 0 | { |
142 | 0 | Byte sym; |
143 | 0 | *prob = (UInt16)(pr + (1 << PPMD_INT_BITS)); |
144 | | |
145 | | // RangeDec_DecodeBit0(size0); |
146 | 0 | R->Range = size0; |
147 | 0 | RC_NORM(R) |
148 | | |
149 | | |
150 | | |
151 | | // sym = (p->FoundState = Ppmd8Context_OneState(p->MinContext))->Symbol; |
152 | | // Ppmd8_UpdateBin(p); |
153 | 0 | { |
154 | 0 | unsigned freq = s->Freq; |
155 | 0 | CPpmd8_Context *c = CTX(SUCCESSOR(s)); |
156 | 0 | sym = s->Symbol; |
157 | 0 | p->FoundState = s; |
158 | 0 | p->PrevSuccess = 1; |
159 | 0 | p->RunLength++; |
160 | 0 | s->Freq = (Byte)(freq + (freq < 196)); |
161 | | // NextContext(p); |
162 | 0 | if (p->OrderFall == 0 && (const Byte *)c >= p->UnitsStart) |
163 | 0 | p->MaxContext = p->MinContext = c; |
164 | 0 | else |
165 | 0 | Ppmd8_UpdateModel(p); |
166 | 0 | } |
167 | 0 | return sym; |
168 | 0 | } |
169 | | |
170 | 0 | *prob = (UInt16)pr; |
171 | 0 | p->InitEsc = p->ExpEscape[pr >> 10]; |
172 | | |
173 | | // RangeDec_DecodeBit1(rc2, size0); |
174 | 0 | R->Low += size0; |
175 | 0 | R->Code -= size0; |
176 | 0 | R->Range = (R->Range & ~((UInt32)PPMD_BIN_SCALE - 1)) - size0; |
177 | 0 | RC_NORM_LOCAL(R) |
178 | | |
179 | 0 | PPMD_SetAllBitsIn256Bytes(charMask) |
180 | 0 | MASK(Ppmd8Context_OneState(p->MinContext)->Symbol) = 0; |
181 | 0 | p->PrevSuccess = 0; |
182 | 0 | } |
183 | | |
184 | 0 | for (;;) |
185 | 0 | { |
186 | 0 | CPpmd_State *s, *s2; |
187 | 0 | UInt32 freqSum, count, hiCnt; |
188 | 0 | UInt32 freqSum2; |
189 | 0 | CPpmd_See *see; |
190 | 0 | CPpmd8_Context *mc; |
191 | 0 | unsigned numMasked; |
192 | 0 | RC_NORM_REMOTE(R) |
193 | 0 | mc = p->MinContext; |
194 | 0 | numMasked = mc->NumStats; |
195 | | |
196 | 0 | do |
197 | 0 | { |
198 | 0 | p->OrderFall++; |
199 | 0 | if (!mc->Suffix) |
200 | 0 | return PPMD8_SYM_END; |
201 | 0 | mc = Ppmd8_GetContext(p, mc->Suffix); |
202 | 0 | } |
203 | 0 | while (mc->NumStats == numMasked); |
204 | | |
205 | 0 | s = Ppmd8_GetStats(p, mc); |
206 | |
|
207 | 0 | { |
208 | 0 | unsigned num = (unsigned)mc->NumStats + 1; |
209 | 0 | unsigned num2 = num / 2; |
210 | |
|
211 | 0 | num &= 1; |
212 | 0 | hiCnt = (s->Freq & (UInt32)(MASK(s->Symbol))) & (0 - (UInt32)num); |
213 | 0 | s += num; |
214 | 0 | p->MinContext = mc; |
215 | |
|
216 | 0 | do |
217 | 0 | { |
218 | 0 | const unsigned sym0 = s[0].Symbol; |
219 | 0 | const unsigned sym1 = s[1].Symbol; |
220 | 0 | s += 2; |
221 | 0 | hiCnt += (s[-2].Freq & (UInt32)(MASK(sym0))); |
222 | 0 | hiCnt += (s[-1].Freq & (UInt32)(MASK(sym1))); |
223 | 0 | } |
224 | 0 | while (--num2); |
225 | 0 | } |
226 | | |
227 | 0 | see = Ppmd8_MakeEscFreq(p, numMasked, &freqSum); |
228 | 0 | freqSum += hiCnt; |
229 | 0 | freqSum2 = freqSum; |
230 | 0 | PPMD8_CORRECT_SUM_RANGE(R, freqSum2) |
231 | | |
232 | |
|
233 | 0 | count = RC_GetThreshold(freqSum2); |
234 | | |
235 | 0 | if (count < hiCnt) |
236 | 0 | { |
237 | 0 | Byte sym; |
238 | | // Ppmd_See_UPDATE(see) // new (see->Summ) value can overflow over 16-bits in some rare cases |
239 | 0 | s = Ppmd8_GetStats(p, p->MinContext); |
240 | 0 | hiCnt = count; |
241 | | |
242 | | |
243 | 0 | { |
244 | 0 | for (;;) |
245 | 0 | { |
246 | 0 | 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 | 0 | } |
249 | 0 | } |
250 | 0 | s--; |
251 | 0 | RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq) |
252 | | |
253 | | // new (see->Summ) value can overflow over 16-bits in some rare cases |
254 | 0 | Ppmd_See_UPDATE(see) |
255 | 0 | p->FoundState = s; |
256 | 0 | sym = s->Symbol; |
257 | 0 | Ppmd8_Update2(p); |
258 | 0 | return sym; |
259 | 0 | } |
260 | | |
261 | 0 | if (count >= freqSum2) |
262 | 0 | return PPMD8_SYM_ERROR; |
263 | | |
264 | 0 | 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 | 0 | see->Summ = (UInt16)(see->Summ + freqSum); |
269 | | |
270 | 0 | s = Ppmd8_GetStats(p, p->MinContext); |
271 | 0 | s2 = s + p->MinContext->NumStats + 1; |
272 | 0 | do |
273 | 0 | { |
274 | 0 | MASK(s->Symbol) = 0; |
275 | 0 | s++; |
276 | 0 | } |
277 | 0 | while (s != s2); |
278 | 0 | } |
279 | 0 | } |
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 |