diff options
Diffstat (limited to 'C/Ppmd7Dec.c')
-rw-r--r-- | C/Ppmd7Dec.c | 297 |
1 files changed, 297 insertions, 0 deletions
diff --git a/C/Ppmd7Dec.c b/C/Ppmd7Dec.c new file mode 100644 index 0000000..55d74ff --- /dev/null +++ b/C/Ppmd7Dec.c | |||
@@ -0,0 +1,297 @@ | |||
1 | /* Ppmd7Dec.c -- Ppmd7z (PPMdH with 7z Range Coder) Decoder | ||
2 | 2021-04-13 : 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 (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 | MY_FORCE_INLINE | ||
41 | // MY_NO_INLINE | ||
42 | static void RangeDec_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) RangeDec_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) ((unsigned char *)charMask)[sym] | ||
62 | // MY_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 | 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 | unsigned sym0 = s2[0].Symbol; | ||
124 | 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 | CTX_PTR 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 & (unsigned)(MASK(s->Symbol))) & (0 - (UInt32)num); | ||
213 | s += num; | ||
214 | p->MinContext = mc; | ||
215 | |||
216 | do | ||
217 | { | ||
218 | unsigned sym0 = s[0].Symbol; | ||
219 | unsigned sym1 = s[1].Symbol; | ||
220 | s += 2; | ||
221 | hiCnt += (s[-2].Freq & (unsigned)(MASK(sym0))); | ||
222 | hiCnt += (s[-1].Freq & (unsigned)(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 & (unsigned)(MASK(s->Symbol)); | ||
242 | // if ((Int32)count >= 0) | ||
243 | { | ||
244 | for (;;) | ||
245 | { | ||
246 | count -= s->Freq & (unsigned)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break; | ||
247 | // count -= s->Freq & (unsigned)(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 | */ | ||