1 | //======================================================================== |
2 | // |
3 | // JArithmeticDecoder.cc |
4 | // |
5 | // Copyright 2002-2004 Glyph & Cog, LLC |
6 | // |
7 | //======================================================================== |
8 | |
9 | //======================================================================== |
10 | // |
11 | // Modified under the Poppler project - http://poppler.freedesktop.org |
12 | // |
13 | // All changes made under the Poppler project to this file are licensed |
14 | // under GPL version 2 or later |
15 | // |
16 | // Copyright (C) 2019 Volker Krause <vkrause@kde.org> |
17 | // Copyright (C) 2020 Even Rouault <even.rouault@spatialys.com> |
18 | // |
19 | // To see a description of the changes please see the Changelog file that |
20 | // came with your tarball or type make ChangeLog if you are building from git |
21 | // |
22 | //======================================================================== |
23 | |
24 | #include <config.h> |
25 | |
26 | #include "Object.h" |
27 | #include "Stream.h" |
28 | #include "JArithmeticDecoder.h" |
29 | |
30 | //------------------------------------------------------------------------ |
31 | // JArithmeticDecoderStates |
32 | //------------------------------------------------------------------------ |
33 | |
34 | JArithmeticDecoderStats::JArithmeticDecoderStats(int contextSizeA) |
35 | { |
36 | contextSize = contextSizeA; |
37 | cxTab = (unsigned char *)gmallocn_checkoverflow(count: contextSize, size: sizeof(unsigned char)); |
38 | if (cxTab) { |
39 | reset(); |
40 | } |
41 | } |
42 | |
43 | JArithmeticDecoderStats::~JArithmeticDecoderStats() |
44 | { |
45 | gfree(p: cxTab); |
46 | } |
47 | |
48 | JArithmeticDecoderStats *JArithmeticDecoderStats::copy() |
49 | { |
50 | JArithmeticDecoderStats *stats; |
51 | |
52 | stats = new JArithmeticDecoderStats(contextSize); |
53 | memcpy(dest: stats->cxTab, src: cxTab, n: contextSize); |
54 | return stats; |
55 | } |
56 | |
57 | void JArithmeticDecoderStats::reset() |
58 | { |
59 | memset(s: cxTab, c: 0, n: contextSize); |
60 | } |
61 | |
62 | void JArithmeticDecoderStats::copyFrom(JArithmeticDecoderStats *stats) |
63 | { |
64 | memcpy(dest: cxTab, src: stats->cxTab, n: contextSize); |
65 | } |
66 | |
67 | void JArithmeticDecoderStats::setEntry(unsigned int cx, int i, int mps) |
68 | { |
69 | cxTab[cx] = (i << 1) + mps; |
70 | } |
71 | |
72 | //------------------------------------------------------------------------ |
73 | // JArithmeticDecoder |
74 | //------------------------------------------------------------------------ |
75 | |
76 | unsigned const int JArithmeticDecoder::qeTab[47] = { 0x56010000, 0x34010000, 0x18010000, 0x0AC10000, 0x05210000, 0x02210000, 0x56010000, 0x54010000, 0x48010000, 0x38010000, 0x30010000, 0x24010000, |
77 | 0x1C010000, 0x16010000, 0x56010000, 0x54010000, 0x51010000, 0x48010000, 0x38010000, 0x34010000, 0x30010000, 0x28010000, 0x24010000, 0x22010000, |
78 | 0x1C010000, 0x18010000, 0x16010000, 0x14010000, 0x12010000, 0x11010000, 0x0AC10000, 0x09C10000, 0x08A10000, 0x05210000, 0x04410000, 0x02A10000, |
79 | 0x02210000, 0x01410000, 0x01110000, 0x00850000, 0x00490000, 0x00250000, 0x00150000, 0x00090000, 0x00050000, 0x00010000, 0x56010000 }; |
80 | |
81 | const int JArithmeticDecoder::nmpsTab[47] = { 1, 2, 3, 4, 5, 38, 7, 8, 9, 10, 11, 12, 13, 29, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 45, 46 }; |
82 | |
83 | const int JArithmeticDecoder::nlpsTab[47] = { 1, 6, 9, 12, 29, 33, 6, 14, 14, 14, 17, 18, 20, 21, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 46 }; |
84 | |
85 | const int JArithmeticDecoder::switchTab[47] = { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; |
86 | |
87 | JArithmeticDecoder::JArithmeticDecoder() |
88 | { |
89 | str = nullptr; |
90 | dataLen = 0; |
91 | limitStream = false; |
92 | nBytesRead = 0; |
93 | } |
94 | |
95 | inline unsigned int JArithmeticDecoder::readByte() |
96 | { |
97 | if (limitStream) { |
98 | --dataLen; |
99 | if (dataLen < 0) { |
100 | return 0xff; |
101 | } |
102 | } |
103 | ++nBytesRead; |
104 | return (unsigned int)str->getChar() & 0xff; |
105 | } |
106 | |
107 | JArithmeticDecoder::~JArithmeticDecoder() |
108 | { |
109 | cleanup(); |
110 | } |
111 | |
112 | void JArithmeticDecoder::start() |
113 | { |
114 | buf0 = readByte(); |
115 | buf1 = readByte(); |
116 | |
117 | // INITDEC |
118 | c = (buf0 ^ 0xff) << 16; |
119 | byteIn(); |
120 | c <<= 7; |
121 | ct -= 7; |
122 | a = 0x80000000; |
123 | } |
124 | |
125 | void JArithmeticDecoder::restart(int dataLenA) |
126 | { |
127 | unsigned int cAdd; |
128 | bool prevFF; |
129 | int k, nBits; |
130 | |
131 | if (dataLen >= 0) { |
132 | dataLen = dataLenA; |
133 | } else if (dataLen == -1) { |
134 | dataLen = dataLenA; |
135 | buf1 = readByte(); |
136 | } else { |
137 | k = (-dataLen - 1) * 8 - ct; |
138 | dataLen = dataLenA; |
139 | cAdd = 0; |
140 | prevFF = false; |
141 | while (k > 0) { |
142 | buf0 = readByte(); |
143 | if (prevFF) { |
144 | cAdd += 0xfe00 - (buf0 << 9); |
145 | nBits = 7; |
146 | } else { |
147 | cAdd += 0xff00 - (buf0 << 8); |
148 | nBits = 8; |
149 | } |
150 | prevFF = buf0 == 0xff; |
151 | if (k > nBits) { |
152 | cAdd <<= nBits; |
153 | k -= nBits; |
154 | } else { |
155 | cAdd <<= k; |
156 | ct = nBits - k; |
157 | k = 0; |
158 | } |
159 | } |
160 | c += cAdd; |
161 | buf1 = readByte(); |
162 | } |
163 | } |
164 | |
165 | void JArithmeticDecoder::cleanup() |
166 | { |
167 | if (limitStream) { |
168 | while (dataLen > 0) { |
169 | buf0 = buf1; |
170 | buf1 = readByte(); |
171 | } |
172 | } |
173 | } |
174 | |
175 | int JArithmeticDecoder::decodeBit(unsigned int context, JArithmeticDecoderStats *stats) |
176 | { |
177 | int bit; |
178 | unsigned int qe; |
179 | int iCX, mpsCX; |
180 | |
181 | iCX = stats->cxTab[context] >> 1; |
182 | mpsCX = stats->cxTab[context] & 1; |
183 | qe = qeTab[iCX]; |
184 | a -= qe; |
185 | if (c < a) { |
186 | if (a & 0x80000000) { |
187 | bit = mpsCX; |
188 | } else { |
189 | // MPS_EXCHANGE |
190 | if (a < qe) { |
191 | bit = 1 - mpsCX; |
192 | if (switchTab[iCX]) { |
193 | stats->cxTab[context] = (nlpsTab[iCX] << 1) | (1 - mpsCX); |
194 | } else { |
195 | stats->cxTab[context] = (nlpsTab[iCX] << 1) | mpsCX; |
196 | } |
197 | } else { |
198 | bit = mpsCX; |
199 | stats->cxTab[context] = (nmpsTab[iCX] << 1) | mpsCX; |
200 | } |
201 | // RENORMD |
202 | do { |
203 | if (ct == 0) { |
204 | byteIn(); |
205 | } |
206 | a <<= 1; |
207 | c <<= 1; |
208 | --ct; |
209 | } while (!(a & 0x80000000)); |
210 | } |
211 | } else { |
212 | c -= a; |
213 | // LPS_EXCHANGE |
214 | if (a < qe) { |
215 | bit = mpsCX; |
216 | stats->cxTab[context] = (nmpsTab[iCX] << 1) | mpsCX; |
217 | } else { |
218 | bit = 1 - mpsCX; |
219 | if (switchTab[iCX]) { |
220 | stats->cxTab[context] = (nlpsTab[iCX] << 1) | (1 - mpsCX); |
221 | } else { |
222 | stats->cxTab[context] = (nlpsTab[iCX] << 1) | mpsCX; |
223 | } |
224 | } |
225 | a = qe; |
226 | // RENORMD |
227 | do { |
228 | if (ct == 0) { |
229 | byteIn(); |
230 | } |
231 | a <<= 1; |
232 | c <<= 1; |
233 | --ct; |
234 | } while (!(a & 0x80000000)); |
235 | } |
236 | return bit; |
237 | } |
238 | |
239 | int JArithmeticDecoder::decodeByte(unsigned int context, JArithmeticDecoderStats *stats) |
240 | { |
241 | int byte; |
242 | int i; |
243 | |
244 | byte = 0; |
245 | for (i = 0; i < 8; ++i) { |
246 | byte = (byte << 1) | decodeBit(context, stats); |
247 | } |
248 | return byte; |
249 | } |
250 | |
251 | bool JArithmeticDecoder::decodeInt(int *x, JArithmeticDecoderStats *stats) |
252 | { |
253 | int s; |
254 | unsigned int v; |
255 | int i; |
256 | |
257 | prev = 1; |
258 | s = decodeIntBit(stats); |
259 | if (decodeIntBit(stats)) { |
260 | if (decodeIntBit(stats)) { |
261 | if (decodeIntBit(stats)) { |
262 | if (decodeIntBit(stats)) { |
263 | if (decodeIntBit(stats)) { |
264 | v = 0; |
265 | for (i = 0; i < 32; ++i) { |
266 | v = (v << 1) | decodeIntBit(stats); |
267 | } |
268 | v += 4436; |
269 | } else { |
270 | v = 0; |
271 | for (i = 0; i < 12; ++i) { |
272 | v = (v << 1) | decodeIntBit(stats); |
273 | } |
274 | v += 340; |
275 | } |
276 | } else { |
277 | v = 0; |
278 | for (i = 0; i < 8; ++i) { |
279 | v = (v << 1) | decodeIntBit(stats); |
280 | } |
281 | v += 84; |
282 | } |
283 | } else { |
284 | v = 0; |
285 | for (i = 0; i < 6; ++i) { |
286 | v = (v << 1) | decodeIntBit(stats); |
287 | } |
288 | v += 20; |
289 | } |
290 | } else { |
291 | v = decodeIntBit(stats); |
292 | v = (v << 1) | decodeIntBit(stats); |
293 | v = (v << 1) | decodeIntBit(stats); |
294 | v = (v << 1) | decodeIntBit(stats); |
295 | v += 4; |
296 | } |
297 | } else { |
298 | v = decodeIntBit(stats); |
299 | v = (v << 1) | decodeIntBit(stats); |
300 | } |
301 | |
302 | if (s) { |
303 | if (v == 0) { |
304 | return false; |
305 | } |
306 | *x = -(int)v; |
307 | } else { |
308 | *x = (int)v; |
309 | } |
310 | return true; |
311 | } |
312 | |
313 | int JArithmeticDecoder::decodeIntBit(JArithmeticDecoderStats *stats) |
314 | { |
315 | int bit; |
316 | |
317 | bit = decodeBit(context: prev, stats); |
318 | if (prev < 0x100) { |
319 | prev = (prev << 1) | bit; |
320 | } else { |
321 | prev = (((prev << 1) | bit) & 0x1ff) | 0x100; |
322 | } |
323 | return bit; |
324 | } |
325 | |
326 | unsigned int JArithmeticDecoder::decodeIAID(unsigned int codeLen, JArithmeticDecoderStats *stats) |
327 | { |
328 | unsigned int i; |
329 | int bit; |
330 | |
331 | prev = 1; |
332 | for (i = 0; i < codeLen; ++i) { |
333 | bit = decodeBit(context: prev, stats); |
334 | prev = (prev << 1) | bit; |
335 | } |
336 | return prev - (1 << codeLen); |
337 | } |
338 | |
339 | void JArithmeticDecoder::byteIn() |
340 | { |
341 | if (buf0 == 0xff) { |
342 | if (buf1 > 0x8f) { |
343 | if (limitStream) { |
344 | buf0 = buf1; |
345 | buf1 = readByte(); |
346 | c = c + 0xff00 - (buf0 << 8); |
347 | } |
348 | ct = 8; |
349 | } else { |
350 | buf0 = buf1; |
351 | buf1 = readByte(); |
352 | c = c + 0xfe00 - (buf0 << 9); |
353 | ct = 7; |
354 | } |
355 | } else { |
356 | buf0 = buf1; |
357 | buf1 = readByte(); |
358 | c = c + 0xff00 - (buf0 << 8); |
359 | ct = 8; |
360 | } |
361 | } |
362 | |