aboutsummaryrefslogtreecommitdiff
path: root/C/Ppmd7Dec.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/Ppmd7Dec.c
parent98e06a519b63b81986abe76d28887f6984a7732b (diff)
download7zip-21.07.tar.gz
7zip-21.07.tar.bz2
7zip-21.07.zip
'21.07'21.07
Diffstat (limited to 'C/Ppmd7Dec.c')
-rw-r--r--C/Ppmd7Dec.c297
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
22021-04-13 : Igor Pavlov : Public domain
3This 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
16BoolInt 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
40MY_FORCE_INLINE
41// MY_NO_INLINE
42static 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))
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// MY_FORCE_INLINE
63// static
64int 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/*
282Byte *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*/