Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/dep/lzma/src/Ppmd7Dec.c
4253 views
1
/* Ppmd7Dec.c -- Ppmd7z (PPMdH with 7z Range Coder) Decoder
2
2023-09-07 : Igor Pavlov : Public domain
3
This code is based on:
4
PPMd var.H (2001): Dmitry Shkarin : Public domain */
5
6
7
#include "Precomp.h"
8
9
#include "Ppmd7.h"
10
11
#define kTopValue ((UInt32)1 << 24)
12
13
14
#define READ_BYTE(p) IByteIn_Read((p)->Stream)
15
16
BoolInt Ppmd7z_RangeDec_Init(CPpmd7_RangeDec *p)
17
{
18
unsigned i;
19
p->Code = 0;
20
p->Range = 0xFFFFFFFF;
21
if (READ_BYTE(p) != 0)
22
return False;
23
for (i = 0; i < 4; i++)
24
p->Code = (p->Code << 8) | READ_BYTE(p);
25
return (p->Code < 0xFFFFFFFF);
26
}
27
28
#define RC_NORM_BASE(p) if ((p)->Range < kTopValue) \
29
{ (p)->Code = ((p)->Code << 8) | READ_BYTE(p); (p)->Range <<= 8;
30
31
#define RC_NORM_1(p) RC_NORM_BASE(p) }
32
#define RC_NORM(p) RC_NORM_BASE(p) RC_NORM_BASE(p) }}
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
#define RC_NORM_REMOTE(p) RC_NORM(p)
37
38
#define R (&p->rc.dec)
39
40
Z7_FORCE_INLINE
41
// Z7_NO_INLINE
42
static void Ppmd7z_RD_Decode(CPpmd7 *p, UInt32 start, UInt32 size)
43
{
44
45
46
R->Code -= start * R->Range;
47
R->Range *= size;
48
RC_NORM_LOCAL(R)
49
}
50
51
#define RC_Decode(start, size) Ppmd7z_RD_Decode(p, start, size);
52
#define RC_DecodeFinal(start, size) RC_Decode(start, size) RC_NORM_REMOTE(R)
53
#define RC_GetThreshold(total) (R->Code / (R->Range /= (total)))
54
55
56
#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref))
57
// typedef CPpmd7_Context * CTX_PTR;
58
#define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p)
59
void Ppmd7_UpdateModel(CPpmd7 *p);
60
61
#define MASK(sym) ((Byte *)charMask)[sym]
62
// Z7_FORCE_INLINE
63
// static
64
int Ppmd7z_DecodeSymbol(CPpmd7 *p)
65
{
66
size_t charMask[256 / sizeof(size_t)];
67
68
if (p->MinContext->NumStats != 1)
69
{
70
CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
71
unsigned i;
72
UInt32 count, hiCnt;
73
const UInt32 summFreq = p->MinContext->Union2.SummFreq;
74
75
76
77
78
count = RC_GetThreshold(summFreq);
79
hiCnt = count;
80
81
if ((Int32)(count -= s->Freq) < 0)
82
{
83
Byte sym;
84
RC_DecodeFinal(0, s->Freq)
85
p->FoundState = s;
86
sym = s->Symbol;
87
Ppmd7_Update1_0(p);
88
return sym;
89
}
90
91
p->PrevSuccess = 0;
92
i = (unsigned)p->MinContext->NumStats - 1;
93
94
do
95
{
96
if ((Int32)(count -= (++s)->Freq) < 0)
97
{
98
Byte sym;
99
RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq)
100
p->FoundState = s;
101
sym = s->Symbol;
102
Ppmd7_Update1(p);
103
return sym;
104
}
105
}
106
while (--i);
107
108
if (hiCnt >= summFreq)
109
return PPMD7_SYM_ERROR;
110
111
hiCnt -= count;
112
RC_Decode(hiCnt, summFreq - hiCnt)
113
114
p->HiBitsFlag = PPMD7_HiBitsFlag_3(p->FoundState->Symbol);
115
PPMD_SetAllBitsIn256Bytes(charMask)
116
// i = p->MinContext->NumStats - 1;
117
// do { MASK((--s)->Symbol) = 0; } while (--i);
118
{
119
CPpmd_State *s2 = Ppmd7_GetStats(p, p->MinContext);
120
MASK(s->Symbol) = 0;
121
do
122
{
123
const unsigned sym0 = s2[0].Symbol;
124
const unsigned sym1 = s2[1].Symbol;
125
s2 += 2;
126
MASK(sym0) = 0;
127
MASK(sym1) = 0;
128
}
129
while (s2 < s);
130
}
131
}
132
else
133
{
134
CPpmd_State *s = Ppmd7Context_OneState(p->MinContext);
135
UInt16 *prob = Ppmd7_GetBinSumm(p);
136
UInt32 pr = *prob;
137
UInt32 size0 = (R->Range >> 14) * pr;
138
pr = PPMD_UPDATE_PROB_1(pr);
139
140
if (R->Code < size0)
141
{
142
Byte sym;
143
*prob = (UInt16)(pr + (1 << PPMD_INT_BITS));
144
145
// RangeDec_DecodeBit0(size0);
146
R->Range = size0;
147
RC_NORM_1(R)
148
/* we can use single byte normalization here because of
149
(min(BinSumm[][]) = 95) > (1 << (14 - 8)) */
150
151
// sym = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol;
152
// Ppmd7_UpdateBin(p);
153
{
154
unsigned freq = s->Freq;
155
CPpmd7_Context *c = CTX(SUCCESSOR(s));
156
sym = s->Symbol;
157
p->FoundState = s;
158
p->PrevSuccess = 1;
159
p->RunLength++;
160
s->Freq = (Byte)(freq + (freq < 128));
161
// NextContext(p);
162
if (p->OrderFall == 0 && (const Byte *)c > p->Text)
163
p->MaxContext = p->MinContext = c;
164
else
165
Ppmd7_UpdateModel(p);
166
}
167
return sym;
168
}
169
170
*prob = (UInt16)pr;
171
p->InitEsc = p->ExpEscape[pr >> 10];
172
173
// RangeDec_DecodeBit1(size0);
174
175
R->Code -= size0;
176
R->Range -= size0;
177
RC_NORM_LOCAL(R)
178
179
PPMD_SetAllBitsIn256Bytes(charMask)
180
MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0;
181
p->PrevSuccess = 0;
182
}
183
184
for (;;)
185
{
186
CPpmd_State *s, *s2;
187
UInt32 freqSum, count, hiCnt;
188
189
CPpmd_See *see;
190
CPpmd7_Context *mc;
191
unsigned numMasked;
192
RC_NORM_REMOTE(R)
193
mc = p->MinContext;
194
numMasked = mc->NumStats;
195
196
do
197
{
198
p->OrderFall++;
199
if (!mc->Suffix)
200
return PPMD7_SYM_END;
201
mc = Ppmd7_GetContext(p, mc->Suffix);
202
}
203
while (mc->NumStats == numMasked);
204
205
s = Ppmd7_GetStats(p, mc);
206
207
{
208
unsigned num = mc->NumStats;
209
unsigned num2 = num / 2;
210
211
num &= 1;
212
hiCnt = (s->Freq & (UInt32)(MASK(s->Symbol))) & (0 - (UInt32)num);
213
s += num;
214
p->MinContext = mc;
215
216
do
217
{
218
const unsigned sym0 = s[0].Symbol;
219
const unsigned sym1 = s[1].Symbol;
220
s += 2;
221
hiCnt += (s[-2].Freq & (UInt32)(MASK(sym0)));
222
hiCnt += (s[-1].Freq & (UInt32)(MASK(sym1)));
223
}
224
while (--num2);
225
}
226
227
see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum);
228
freqSum += hiCnt;
229
230
231
232
233
count = RC_GetThreshold(freqSum);
234
235
if (count < hiCnt)
236
{
237
Byte sym;
238
239
s = Ppmd7_GetStats(p, p->MinContext);
240
hiCnt = count;
241
// count -= s->Freq & (UInt32)(MASK(s->Symbol));
242
// if ((Int32)count >= 0)
243
{
244
for (;;)
245
{
246
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
}
249
}
250
s--;
251
RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq)
252
253
// new (see->Summ) value can overflow over 16-bits in some rare cases
254
Ppmd_See_UPDATE(see)
255
p->FoundState = s;
256
sym = s->Symbol;
257
Ppmd7_Update2(p);
258
return sym;
259
}
260
261
if (count >= freqSum)
262
return PPMD7_SYM_ERROR;
263
264
RC_Decode(hiCnt, freqSum - 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
see->Summ = (UInt16)(see->Summ + freqSum);
269
270
s = Ppmd7_GetStats(p, p->MinContext);
271
s2 = s + p->MinContext->NumStats;
272
do
273
{
274
MASK(s->Symbol) = 0;
275
s++;
276
}
277
while (s != s2);
278
}
279
}
280
281
/*
282
Byte *Ppmd7z_DecodeSymbols(CPpmd7 *p, Byte *buf, const Byte *lim)
283
{
284
int sym = 0;
285
if (buf != lim)
286
do
287
{
288
sym = Ppmd7z_DecodeSymbol(p);
289
if (sym < 0)
290
break;
291
*buf = (Byte)sym;
292
}
293
while (++buf < lim);
294
p->LastSymbol = sym;
295
return buf;
296
}
297
*/
298
299
#undef kTopValue
300
#undef READ_BYTE
301
#undef RC_NORM_BASE
302
#undef RC_NORM_1
303
#undef RC_NORM
304
#undef RC_NORM_LOCAL
305
#undef RC_NORM_REMOTE
306
#undef R
307
#undef RC_Decode
308
#undef RC_DecodeFinal
309
#undef RC_GetThreshold
310
#undef CTX
311
#undef SUCCESSOR
312
#undef MASK
313
314