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