/src/xpdf-4.06/xpdf/JArithmeticDecoder.cc
Line | Count | Source |
1 | | //======================================================================== |
2 | | // |
3 | | // JArithmeticDecoder.cc |
4 | | // |
5 | | // Copyright 2002-2004 Glyph & Cog, LLC |
6 | | // |
7 | | //======================================================================== |
8 | | |
9 | | #include <aconf.h> |
10 | | |
11 | | #include "gmempp.h" |
12 | | #include "Object.h" |
13 | | #include "Stream.h" |
14 | | #include "JArithmeticDecoder.h" |
15 | | |
16 | | //------------------------------------------------------------------------ |
17 | | // JArithmeticDecoderStates |
18 | | //------------------------------------------------------------------------ |
19 | | |
20 | 4.70M | JArithmeticDecoderStats::JArithmeticDecoderStats(int contextSizeA) { |
21 | 4.70M | contextSize = contextSizeA; |
22 | 4.70M | cxTab = (Guchar *)gmallocn(contextSize, sizeof(Guchar)); |
23 | 4.70M | reset(); |
24 | 4.70M | } |
25 | | |
26 | 4.69M | JArithmeticDecoderStats::~JArithmeticDecoderStats() { |
27 | 4.69M | gfree(cxTab); |
28 | 4.69M | } |
29 | | |
30 | 3.92k | JArithmeticDecoderStats *JArithmeticDecoderStats::copy() { |
31 | 3.92k | JArithmeticDecoderStats *stats; |
32 | | |
33 | 3.92k | stats = new JArithmeticDecoderStats(contextSize); |
34 | 3.92k | memcpy(stats->cxTab, cxTab, contextSize); |
35 | 3.92k | return stats; |
36 | 3.92k | } |
37 | | |
38 | 6.38M | void JArithmeticDecoderStats::reset() { |
39 | 6.38M | memset(cxTab, 0, contextSize); |
40 | 6.38M | } |
41 | | |
42 | 0 | void JArithmeticDecoderStats::copyFrom(JArithmeticDecoderStats *stats) { |
43 | 0 | memcpy(cxTab, stats->cxTab, contextSize); |
44 | 0 | } |
45 | | |
46 | 5.70M | void JArithmeticDecoderStats::setEntry(Guint cx, int i, int mps) { |
47 | 5.70M | cxTab[cx] = (Guchar)((i << 1) + mps); |
48 | 5.70M | } |
49 | | |
50 | | //------------------------------------------------------------------------ |
51 | | // JArithmeticDecoder |
52 | | //------------------------------------------------------------------------ |
53 | | |
54 | | Guint JArithmeticDecoder::qeTab[47] = { |
55 | | 0x56010000, 0x34010000, 0x18010000, 0x0AC10000, |
56 | | 0x05210000, 0x02210000, 0x56010000, 0x54010000, |
57 | | 0x48010000, 0x38010000, 0x30010000, 0x24010000, |
58 | | 0x1C010000, 0x16010000, 0x56010000, 0x54010000, |
59 | | 0x51010000, 0x48010000, 0x38010000, 0x34010000, |
60 | | 0x30010000, 0x28010000, 0x24010000, 0x22010000, |
61 | | 0x1C010000, 0x18010000, 0x16010000, 0x14010000, |
62 | | 0x12010000, 0x11010000, 0x0AC10000, 0x09C10000, |
63 | | 0x08A10000, 0x05210000, 0x04410000, 0x02A10000, |
64 | | 0x02210000, 0x01410000, 0x01110000, 0x00850000, |
65 | | 0x00490000, 0x00250000, 0x00150000, 0x00090000, |
66 | | 0x00050000, 0x00010000, 0x56010000 |
67 | | }; |
68 | | |
69 | | int JArithmeticDecoder::nmpsTab[47] = { |
70 | | 1, 2, 3, 4, 5, 38, 7, 8, 9, 10, 11, 12, 13, 29, 15, 16, |
71 | | 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, |
72 | | 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 45, 46 |
73 | | }; |
74 | | |
75 | | int JArithmeticDecoder::nlpsTab[47] = { |
76 | | 1, 6, 9, 12, 29, 33, 6, 14, 14, 14, 17, 18, 20, 21, 14, 14, |
77 | | 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, |
78 | | 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 46 |
79 | | }; |
80 | | |
81 | | int JArithmeticDecoder::switchTab[47] = { |
82 | | 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, |
83 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
84 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
85 | | }; |
86 | | |
87 | 580k | JArithmeticDecoder::JArithmeticDecoder() { |
88 | 580k | str = NULL; |
89 | 580k | dataLen = 0; |
90 | 580k | limitStream = gFalse; |
91 | 580k | nBytesRead = 0; |
92 | 580k | readBufNext = 0; |
93 | 580k | readBufLength = 0; |
94 | 580k | } |
95 | | |
96 | 8.50M | inline Guint JArithmeticDecoder::readByte() { |
97 | 8.50M | if (limitStream) { |
98 | 7.34M | if (readBufNext < readBufLength) { |
99 | 1.31M | return readBuf[readBufNext++]; |
100 | 1.31M | } |
101 | 6.02M | --dataLen; |
102 | 6.02M | if (dataLen < 0) { |
103 | 3.68M | return 0xff; |
104 | 3.68M | } |
105 | 6.02M | } |
106 | 3.51M | ++nBytesRead; |
107 | 3.51M | return (Guint)str->getChar() & 0xff; |
108 | 8.50M | } |
109 | | |
110 | 579k | JArithmeticDecoder::~JArithmeticDecoder() { |
111 | 579k | cleanup(); |
112 | 579k | } |
113 | | |
114 | 823k | void JArithmeticDecoder::start() { |
115 | 823k | buf0 = readByte(); |
116 | 823k | buf1 = readByte(); |
117 | | |
118 | | // INITDEC |
119 | 823k | c = (buf0 ^ 0xff) << 16; |
120 | 823k | byteIn(); |
121 | 823k | c <<= 7; |
122 | 823k | ct -= 7; |
123 | 823k | a = 0x80000000; |
124 | 823k | } |
125 | | |
126 | 40.0k | void JArithmeticDecoder::restart(int dataLenA) { |
127 | 40.0k | Guint cAdd; |
128 | 40.0k | GBool prevFF; |
129 | 40.0k | int k, nBits; |
130 | | |
131 | 40.0k | if (dataLen >= 0) { |
132 | 25.2k | dataLen = dataLenA; |
133 | 25.2k | } else if (dataLen == -1) { |
134 | 1.71k | dataLen = dataLenA; |
135 | 1.71k | buf1 = readByte(); |
136 | 13.1k | } else { |
137 | 13.1k | k = (-dataLen - 1) * 8 - ct; |
138 | 13.1k | dataLen = dataLenA; |
139 | 13.1k | cAdd = 0; |
140 | 13.1k | prevFF = gFalse; |
141 | 529k | while (k > 0) { |
142 | 516k | buf0 = readByte(); |
143 | 516k | if (prevFF) { |
144 | 403k | cAdd += 0xfe00 - (buf0 << 9); |
145 | 403k | nBits = 7; |
146 | 403k | } else { |
147 | 113k | cAdd += 0xff00 - (buf0 << 8); |
148 | 113k | nBits = 8; |
149 | 113k | } |
150 | 516k | prevFF = buf0 == 0xff; |
151 | 516k | if (k > nBits) { |
152 | 503k | cAdd <<= nBits; |
153 | 503k | k -= nBits; |
154 | 503k | } else { |
155 | 13.1k | cAdd <<= k; |
156 | 13.1k | ct = nBits - k; |
157 | 13.1k | k = 0; |
158 | 13.1k | } |
159 | 516k | } |
160 | 13.1k | c += cAdd; |
161 | 13.1k | buf1 = readByte(); |
162 | 13.1k | } |
163 | 40.0k | } |
164 | | |
165 | 1.57M | void JArithmeticDecoder::cleanup() { |
166 | 1.57M | if (limitStream) { |
167 | | // This saves up to sizeof(readBuf) extra bytes of data from the |
168 | | // end of packet i, to be used in packet i+1. It's not clear from |
169 | | // the JPEG 2000 spec exactly how this should work, but this |
170 | | // kludge does seem to fix decode of some problematic JPEG 2000 |
171 | | // streams. The buffer may need to larger, but I haven't run into |
172 | | // that case. (And the buffer was originally just one byte, which |
173 | | // works for almost all cases.) |
174 | 1.30M | readBufLength = 0; |
175 | 6.21G | while (dataLen > 0) { |
176 | 6.21G | if (readBufLength < (int)sizeof(readBuf)) { |
177 | 9.30M | readBuf[readBufLength++] = (Guchar)str->getChar(); |
178 | 9.30M | ++nBytesRead; |
179 | 9.30M | } |
180 | 6.21G | --dataLen; |
181 | 6.21G | } |
182 | 1.30M | readBufNext = 0; |
183 | 1.30M | } |
184 | 1.57M | } |
185 | | |
186 | | int JArithmeticDecoder::decodeBit(Guint context, |
187 | 476M | JArithmeticDecoderStats *stats) { |
188 | 476M | int bit; |
189 | 476M | Guint qe; |
190 | 476M | int iCX, mpsCX; |
191 | | |
192 | 476M | iCX = stats->cxTab[context] >> 1; |
193 | 476M | mpsCX = stats->cxTab[context] & 1; |
194 | 476M | qe = qeTab[iCX]; |
195 | 476M | a -= qe; |
196 | 476M | if (c < a) { |
197 | 437M | if (a & 0x80000000) { |
198 | 394M | bit = mpsCX; |
199 | 394M | } else { |
200 | | // MPS_EXCHANGE |
201 | 43.3M | if (a < qe) { |
202 | 6.71M | bit = 1 - mpsCX; |
203 | 6.71M | if (switchTab[iCX]) { |
204 | 3.85M | stats->cxTab[context] = (Guchar)((nlpsTab[iCX] << 1) | (1 - mpsCX)); |
205 | 3.85M | } else { |
206 | 2.86M | stats->cxTab[context] = (Guchar)((nlpsTab[iCX] << 1) | mpsCX); |
207 | 2.86M | } |
208 | 36.6M | } else { |
209 | 36.6M | bit = mpsCX; |
210 | 36.6M | stats->cxTab[context] = (Guchar)((nmpsTab[iCX] << 1) | mpsCX); |
211 | 36.6M | } |
212 | | // RENORMD |
213 | 46.0M | do { |
214 | 46.0M | if (ct == 0) { |
215 | 5.81M | byteIn(); |
216 | 5.81M | } |
217 | 46.0M | a <<= 1; |
218 | 46.0M | c <<= 1; |
219 | 46.0M | --ct; |
220 | 46.0M | } while (!(a & 0x80000000)); |
221 | 43.3M | } |
222 | 437M | } else { |
223 | 39.0M | c -= a; |
224 | | // LPS_EXCHANGE |
225 | 39.0M | if (a < qe) { |
226 | 7.77M | bit = mpsCX; |
227 | 7.77M | stats->cxTab[context] = (Guchar)((nmpsTab[iCX] << 1) | mpsCX); |
228 | 31.2M | } else { |
229 | 31.2M | bit = 1 - mpsCX; |
230 | 31.2M | if (switchTab[iCX]) { |
231 | 5.58M | stats->cxTab[context] = (Guchar)((nlpsTab[iCX] << 1) | (1 - mpsCX)); |
232 | 25.6M | } else { |
233 | 25.6M | stats->cxTab[context] = (Guchar)((nlpsTab[iCX] << 1) | mpsCX); |
234 | 25.6M | } |
235 | 31.2M | } |
236 | 39.0M | a = qe; |
237 | | // RENORMD |
238 | 60.6M | do { |
239 | 60.6M | if (ct == 0) { |
240 | 7.65M | byteIn(); |
241 | 7.65M | } |
242 | 60.6M | a <<= 1; |
243 | 60.6M | c <<= 1; |
244 | 60.6M | --ct; |
245 | 60.6M | } while (!(a & 0x80000000)); |
246 | 39.0M | } |
247 | 476M | return bit; |
248 | 476M | } |
249 | | |
250 | | int JArithmeticDecoder::decodeByte(Guint context, |
251 | 0 | JArithmeticDecoderStats *stats) { |
252 | 0 | int byte; |
253 | 0 | int i; |
254 | |
|
255 | 0 | byte = 0; |
256 | 0 | for (i = 0; i < 8; ++i) { |
257 | 0 | byte = (byte << 1) | decodeBit(context, stats); |
258 | 0 | } |
259 | 0 | return byte; |
260 | 0 | } |
261 | | |
262 | 4.28M | GBool JArithmeticDecoder::decodeInt(int *x, JArithmeticDecoderStats *stats) { |
263 | 4.28M | int s; |
264 | 4.28M | Guint v; |
265 | 4.28M | int i; |
266 | | |
267 | 4.28M | prev = 1; |
268 | 4.28M | s = decodeIntBit(stats); |
269 | 4.28M | if (decodeIntBit(stats)) { |
270 | 1.72M | if (decodeIntBit(stats)) { |
271 | 421k | if (decodeIntBit(stats)) { |
272 | 110k | if (decodeIntBit(stats)) { |
273 | 70.9k | if (decodeIntBit(stats)) { |
274 | 15.8k | v = 0; |
275 | 524k | for (i = 0; i < 32; ++i) { |
276 | 508k | v = (v << 1) | decodeIntBit(stats); |
277 | 508k | } |
278 | 15.8k | v += 4436; |
279 | 55.0k | } else { |
280 | 55.0k | v = 0; |
281 | 716k | for (i = 0; i < 12; ++i) { |
282 | 661k | v = (v << 1) | decodeIntBit(stats); |
283 | 661k | } |
284 | 55.0k | v += 340; |
285 | 55.0k | } |
286 | 70.9k | } else { |
287 | 39.5k | v = 0; |
288 | 355k | for (i = 0; i < 8; ++i) { |
289 | 316k | v = (v << 1) | decodeIntBit(stats); |
290 | 316k | } |
291 | 39.5k | v += 84; |
292 | 39.5k | } |
293 | 310k | } else { |
294 | 310k | v = 0; |
295 | 2.17M | for (i = 0; i < 6; ++i) { |
296 | 1.86M | v = (v << 1) | decodeIntBit(stats); |
297 | 1.86M | } |
298 | 310k | v += 20; |
299 | 310k | } |
300 | 1.29M | } else { |
301 | 1.29M | v = decodeIntBit(stats); |
302 | 1.29M | v = (v << 1) | decodeIntBit(stats); |
303 | 1.29M | v = (v << 1) | decodeIntBit(stats); |
304 | 1.29M | v = (v << 1) | decodeIntBit(stats); |
305 | 1.29M | v += 4; |
306 | 1.29M | } |
307 | 2.56M | } else { |
308 | 2.56M | v = decodeIntBit(stats); |
309 | 2.56M | v = (v << 1) | decodeIntBit(stats); |
310 | 2.56M | } |
311 | | |
312 | 4.28M | if (s) { |
313 | 1.71M | if (v == 0) { |
314 | 1.17M | return gFalse; |
315 | 1.17M | } |
316 | 537k | *x = -(int)v; |
317 | 2.56M | } else { |
318 | 2.56M | *x = (int)v; |
319 | 2.56M | } |
320 | 3.10M | return gTrue; |
321 | 4.28M | } |
322 | | |
323 | 24.5M | int JArithmeticDecoder::decodeIntBit(JArithmeticDecoderStats *stats) { |
324 | 24.5M | int bit; |
325 | | |
326 | 24.5M | bit = decodeBit(prev, stats); |
327 | 24.5M | if (prev < 0x100) { |
328 | 22.7M | prev = (prev << 1) | bit; |
329 | 22.7M | } else { |
330 | 1.84M | prev = (((prev << 1) | bit) & 0x1ff) | 0x100; |
331 | 1.84M | } |
332 | 24.5M | return bit; |
333 | 24.5M | } |
334 | | |
335 | | Guint JArithmeticDecoder::decodeIAID(Guint codeLen, |
336 | 619k | JArithmeticDecoderStats *stats) { |
337 | 619k | Guint i; |
338 | 619k | int bit; |
339 | | |
340 | 619k | prev = 1; |
341 | 7.98M | for (i = 0; i < codeLen; ++i) { |
342 | 7.36M | bit = decodeBit(prev, stats); |
343 | 7.36M | prev = (prev << 1) | bit; |
344 | 7.36M | } |
345 | 619k | return prev - (1 << codeLen); |
346 | 619k | } |
347 | | |
348 | 14.2M | void JArithmeticDecoder::byteIn() { |
349 | 14.2M | if (buf0 == 0xff) { |
350 | 11.2M | if (buf1 > 0x8f) { |
351 | 11.2M | if (limitStream) { |
352 | 3.28M | buf0 = buf1; |
353 | 3.28M | buf1 = readByte(); |
354 | 3.28M | c = c + 0xff00 - (buf0 << 8); |
355 | 3.28M | } |
356 | 11.2M | ct = 8; |
357 | 11.2M | } else { |
358 | 21.6k | buf0 = buf1; |
359 | 21.6k | buf1 = readByte(); |
360 | 21.6k | c = c + 0xfe00 - (buf0 << 9); |
361 | 21.6k | ct = 7; |
362 | 21.6k | } |
363 | 11.2M | } else { |
364 | 3.02M | buf0 = buf1; |
365 | 3.02M | buf1 = readByte(); |
366 | 3.02M | c = c + 0xff00 - (buf0 << 8); |
367 | 3.02M | ct = 8; |
368 | 3.02M | } |
369 | 14.2M | } |