aboutsummaryrefslogtreecommitdiff
path: root/C/Ppmd7aDec.c
diff options
context:
space:
mode:
authorIgor Pavlov <87184205+ip7z@users.noreply.github.com>2021-12-27 00:00:00 +0000
committerIgor Pavlov <87184205+ip7z@users.noreply.github.com>2022-03-18 15:35:13 +0500
commitf19f813537c7aea1c20749c914e756b54a9c3cf5 (patch)
tree816ba62ca7c0fa19f2eb46d9e9d6f7dd7c3a744d /C/Ppmd7aDec.c
parent98e06a519b63b81986abe76d28887f6984a7732b (diff)
download7zip-21.07.tar.gz
7zip-21.07.tar.bz2
7zip-21.07.zip
'21.07'21.07
Diffstat (limited to '')
-rw-r--r--C/Ppmd7aDec.c279
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
22021-04-13 : Igor Pavlov : Public domain
3This 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
16BoolInt 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
40MY_FORCE_INLINE
41// MY_NO_INLINE
42static 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))
57typedef CPpmd7_Context * CTX_PTR;
58#define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p)
59void Ppmd7_UpdateModel(CPpmd7 *p);
60
61#define MASK(sym) ((unsigned char *)charMask)[sym]
62
63
64int 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}