diff options
Diffstat (limited to 'C/Ppmd7aDec.c')
-rw-r--r-- | C/Ppmd7aDec.c | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/C/Ppmd7aDec.c b/C/Ppmd7aDec.c new file mode 100644 index 0000000..c424578 --- /dev/null +++ b/C/Ppmd7aDec.c | |||
@@ -0,0 +1,279 @@ | |||
1 | /* Ppmd7aDec.c -- PPMd7a (PPMdH) 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 | Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ | ||
6 | |||
7 | #include "Precomp.h" | ||
8 | |||
9 | #include "Ppmd7.h" | ||
10 | |||
11 | #define kTop (1 << 24) | ||
12 | #define kBot (1 << 15) | ||
13 | |||
14 | #define READ_BYTE(p) IByteIn_Read((p)->Stream) | ||
15 | |||
16 | BoolInt Ppmd7a_RangeDec_Init(CPpmd7_RangeDec *p) | ||
17 | { | ||
18 | unsigned i; | ||
19 | p->Code = 0; | ||
20 | p->Range = 0xFFFFFFFF; | ||
21 | p->Low = 0; | ||
22 | |||
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(p) \ | ||
29 | while ((p->Low ^ (p->Low + p->Range)) < kTop \ | ||
30 | || (p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1))) { \ | ||
31 | p->Code = (p->Code << 8) | READ_BYTE(p); \ | ||
32 | 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 | #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 | start *= R->Range; | ||
45 | R->Low += start; | ||
46 | R->Code -= start; | ||
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 | |||
63 | |||
64 | int Ppmd7a_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 | if (summFreq > R->Range) | ||
76 | return PPMD7_SYM_ERROR; | ||
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(R) | ||
148 | |||
149 | |||
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 | R->Low += size0; | ||
175 | R->Code -= size0; | ||
176 | R->Range = (R->Range & ~((UInt32)PPMD_BIN_SCALE - 1)) - 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 | if (freqSum > R->Range) | ||
231 | return PPMD7_SYM_ERROR; | ||
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 | } | ||