]>
Commit | Line | Data |
---|---|---|
ef416fc2 | 1 | //======================================================================== |
2 | // | |
3 | // JArithmeticDecoder.cc | |
4 | // | |
5 | // Copyright 2002-2004 Glyph & Cog, LLC | |
6 | // | |
7 | //======================================================================== | |
8 | ||
9 | #include <config.h> | |
10 | ||
11 | #ifdef USE_GCC_PRAGMAS | |
12 | #pragma implementation | |
13 | #endif | |
14 | ||
15 | #include "Object.h" | |
16 | #include "Stream.h" | |
17 | #include "JArithmeticDecoder.h" | |
18 | ||
19 | //------------------------------------------------------------------------ | |
20 | // JArithmeticDecoderStates | |
21 | //------------------------------------------------------------------------ | |
22 | ||
23 | JArithmeticDecoderStats::JArithmeticDecoderStats(int contextSizeA) { | |
24 | contextSize = contextSizeA; | |
25 | cxTab = (Guchar *)gmallocn(contextSize, sizeof(Guchar)); | |
26 | reset(); | |
27 | } | |
28 | ||
29 | JArithmeticDecoderStats::~JArithmeticDecoderStats() { | |
30 | gfree(cxTab); | |
31 | } | |
32 | ||
33 | JArithmeticDecoderStats *JArithmeticDecoderStats::copy() { | |
34 | JArithmeticDecoderStats *stats; | |
35 | ||
36 | stats = new JArithmeticDecoderStats(contextSize); | |
37 | memcpy(stats->cxTab, cxTab, contextSize); | |
38 | return stats; | |
39 | } | |
40 | ||
41 | void JArithmeticDecoderStats::reset() { | |
42 | memset(cxTab, 0, contextSize); | |
43 | } | |
44 | ||
45 | void JArithmeticDecoderStats::copyFrom(JArithmeticDecoderStats *stats) { | |
46 | memcpy(cxTab, stats->cxTab, contextSize); | |
47 | } | |
48 | ||
49 | void JArithmeticDecoderStats::setEntry(Guint cx, int i, int mps) { | |
50 | cxTab[cx] = (i << 1) + mps; | |
51 | } | |
52 | ||
53 | //------------------------------------------------------------------------ | |
54 | // JArithmeticDecoder | |
55 | //------------------------------------------------------------------------ | |
56 | ||
57 | Guint JArithmeticDecoder::qeTab[47] = { | |
58 | 0x56010000, 0x34010000, 0x18010000, 0x0AC10000, | |
59 | 0x05210000, 0x02210000, 0x56010000, 0x54010000, | |
60 | 0x48010000, 0x38010000, 0x30010000, 0x24010000, | |
61 | 0x1C010000, 0x16010000, 0x56010000, 0x54010000, | |
62 | 0x51010000, 0x48010000, 0x38010000, 0x34010000, | |
63 | 0x30010000, 0x28010000, 0x24010000, 0x22010000, | |
64 | 0x1C010000, 0x18010000, 0x16010000, 0x14010000, | |
65 | 0x12010000, 0x11010000, 0x0AC10000, 0x09C10000, | |
66 | 0x08A10000, 0x05210000, 0x04410000, 0x02A10000, | |
67 | 0x02210000, 0x01410000, 0x01110000, 0x00850000, | |
68 | 0x00490000, 0x00250000, 0x00150000, 0x00090000, | |
69 | 0x00050000, 0x00010000, 0x56010000 | |
70 | }; | |
71 | ||
72 | int JArithmeticDecoder::nmpsTab[47] = { | |
73 | 1, 2, 3, 4, 5, 38, 7, 8, 9, 10, 11, 12, 13, 29, 15, 16, | |
74 | 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, | |
75 | 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 45, 46 | |
76 | }; | |
77 | ||
78 | int JArithmeticDecoder::nlpsTab[47] = { | |
79 | 1, 6, 9, 12, 29, 33, 6, 14, 14, 14, 17, 18, 20, 21, 14, 14, | |
80 | 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, | |
81 | 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 46 | |
82 | }; | |
83 | ||
84 | int JArithmeticDecoder::switchTab[47] = { | |
85 | 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, | |
86 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
87 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | |
88 | }; | |
89 | ||
90 | JArithmeticDecoder::JArithmeticDecoder() { | |
91 | str = NULL; | |
92 | dataLen = 0; | |
93 | limitStream = gFalse; | |
94 | } | |
95 | ||
96 | inline Guint JArithmeticDecoder::readByte() { | |
97 | if (limitStream) { | |
98 | --dataLen; | |
99 | if (dataLen < 0) { | |
100 | return 0xff; | |
101 | } | |
102 | } | |
103 | return (Guint)str->getChar() & 0xff; | |
104 | } | |
105 | ||
106 | JArithmeticDecoder::~JArithmeticDecoder() { | |
107 | cleanup(); | |
108 | } | |
109 | ||
110 | void JArithmeticDecoder::start() { | |
111 | buf0 = readByte(); | |
112 | buf1 = readByte(); | |
113 | ||
114 | // INITDEC | |
115 | c = (buf0 ^ 0xff) << 16; | |
116 | byteIn(); | |
117 | c <<= 7; | |
118 | ct -= 7; | |
119 | a = 0x80000000; | |
120 | } | |
121 | ||
122 | void JArithmeticDecoder::restart(int dataLenA) { | |
123 | int oldDataLen; | |
124 | ||
125 | oldDataLen = dataLen; | |
126 | dataLen = dataLenA; | |
127 | if (oldDataLen == -1) { | |
128 | buf1 = readByte(); | |
129 | } else if (oldDataLen <= -2) { | |
130 | buf0 = readByte(); | |
131 | buf1 = readByte(); | |
132 | } | |
133 | } | |
134 | ||
135 | void JArithmeticDecoder::cleanup() { | |
136 | if (limitStream) { | |
137 | while (dataLen > 0) { | |
138 | buf0 = buf1; | |
139 | buf1 = readByte(); | |
140 | } | |
141 | } | |
142 | } | |
143 | ||
144 | int JArithmeticDecoder::decodeBit(Guint context, | |
145 | JArithmeticDecoderStats *stats) { | |
146 | int bit; | |
147 | Guint qe; | |
148 | int iCX, mpsCX; | |
149 | ||
150 | iCX = stats->cxTab[context] >> 1; | |
151 | mpsCX = stats->cxTab[context] & 1; | |
152 | qe = qeTab[iCX]; | |
153 | a -= qe; | |
154 | if (c < a) { | |
155 | if (a & 0x80000000) { | |
156 | bit = mpsCX; | |
157 | } else { | |
158 | // MPS_EXCHANGE | |
159 | if (a < qe) { | |
160 | bit = 1 - mpsCX; | |
161 | if (switchTab[iCX]) { | |
162 | stats->cxTab[context] = (nlpsTab[iCX] << 1) | (1 - mpsCX); | |
163 | } else { | |
164 | stats->cxTab[context] = (nlpsTab[iCX] << 1) | mpsCX; | |
165 | } | |
166 | } else { | |
167 | bit = mpsCX; | |
168 | stats->cxTab[context] = (nmpsTab[iCX] << 1) | mpsCX; | |
169 | } | |
170 | // RENORMD | |
171 | do { | |
172 | if (ct == 0) { | |
173 | byteIn(); | |
174 | } | |
175 | a <<= 1; | |
176 | c <<= 1; | |
177 | --ct; | |
178 | } while (!(a & 0x80000000)); | |
179 | } | |
180 | } else { | |
181 | c -= a; | |
182 | // LPS_EXCHANGE | |
183 | if (a < qe) { | |
184 | bit = mpsCX; | |
185 | stats->cxTab[context] = (nmpsTab[iCX] << 1) | mpsCX; | |
186 | } else { | |
187 | bit = 1 - mpsCX; | |
188 | if (switchTab[iCX]) { | |
189 | stats->cxTab[context] = (nlpsTab[iCX] << 1) | (1 - mpsCX); | |
190 | } else { | |
191 | stats->cxTab[context] = (nlpsTab[iCX] << 1) | mpsCX; | |
192 | } | |
193 | } | |
194 | a = qe; | |
195 | // RENORMD | |
196 | do { | |
197 | if (ct == 0) { | |
198 | byteIn(); | |
199 | } | |
200 | a <<= 1; | |
201 | c <<= 1; | |
202 | --ct; | |
203 | } while (!(a & 0x80000000)); | |
204 | } | |
205 | return bit; | |
206 | } | |
207 | ||
208 | int JArithmeticDecoder::decodeByte(Guint context, | |
209 | JArithmeticDecoderStats *stats) { | |
210 | int byte; | |
211 | int i; | |
212 | ||
213 | byte = 0; | |
214 | for (i = 0; i < 8; ++i) { | |
215 | byte = (byte << 1) | decodeBit(context, stats); | |
216 | } | |
217 | return byte; | |
218 | } | |
219 | ||
220 | GBool JArithmeticDecoder::decodeInt(int *x, JArithmeticDecoderStats *stats) { | |
221 | int s; | |
222 | Guint v; | |
223 | int i; | |
224 | ||
225 | prev = 1; | |
226 | s = decodeIntBit(stats); | |
227 | if (decodeIntBit(stats)) { | |
228 | if (decodeIntBit(stats)) { | |
229 | if (decodeIntBit(stats)) { | |
230 | if (decodeIntBit(stats)) { | |
231 | if (decodeIntBit(stats)) { | |
232 | v = 0; | |
233 | for (i = 0; i < 32; ++i) { | |
234 | v = (v << 1) | decodeIntBit(stats); | |
235 | } | |
236 | v += 4436; | |
237 | } else { | |
238 | v = 0; | |
239 | for (i = 0; i < 12; ++i) { | |
240 | v = (v << 1) | decodeIntBit(stats); | |
241 | } | |
242 | v += 340; | |
243 | } | |
244 | } else { | |
245 | v = 0; | |
246 | for (i = 0; i < 8; ++i) { | |
247 | v = (v << 1) | decodeIntBit(stats); | |
248 | } | |
249 | v += 84; | |
250 | } | |
251 | } else { | |
252 | v = 0; | |
253 | for (i = 0; i < 6; ++i) { | |
254 | v = (v << 1) | decodeIntBit(stats); | |
255 | } | |
256 | v += 20; | |
257 | } | |
258 | } else { | |
259 | v = decodeIntBit(stats); | |
260 | v = (v << 1) | decodeIntBit(stats); | |
261 | v = (v << 1) | decodeIntBit(stats); | |
262 | v = (v << 1) | decodeIntBit(stats); | |
263 | v += 4; | |
264 | } | |
265 | } else { | |
266 | v = decodeIntBit(stats); | |
267 | v = (v << 1) | decodeIntBit(stats); | |
268 | } | |
269 | ||
270 | if (s) { | |
271 | if (v == 0) { | |
272 | return gFalse; | |
273 | } | |
274 | *x = -(int)v; | |
275 | } else { | |
276 | *x = (int)v; | |
277 | } | |
278 | return gTrue; | |
279 | } | |
280 | ||
281 | int JArithmeticDecoder::decodeIntBit(JArithmeticDecoderStats *stats) { | |
282 | int bit; | |
283 | ||
284 | bit = decodeBit(prev, stats); | |
285 | if (prev < 0x100) { | |
286 | prev = (prev << 1) | bit; | |
287 | } else { | |
288 | prev = (((prev << 1) | bit) & 0x1ff) | 0x100; | |
289 | } | |
290 | return bit; | |
291 | } | |
292 | ||
293 | Guint JArithmeticDecoder::decodeIAID(Guint codeLen, | |
294 | JArithmeticDecoderStats *stats) { | |
295 | Guint i; | |
296 | int bit; | |
297 | ||
298 | prev = 1; | |
299 | for (i = 0; i < codeLen; ++i) { | |
300 | bit = decodeBit(prev, stats); | |
301 | prev = (prev << 1) | bit; | |
302 | } | |
303 | return prev - (1 << codeLen); | |
304 | } | |
305 | ||
306 | void JArithmeticDecoder::byteIn() { | |
307 | if (buf0 == 0xff) { | |
308 | if (buf1 > 0x8f) { | |
309 | ct = 8; | |
310 | } else { | |
311 | buf0 = buf1; | |
312 | buf1 = readByte(); | |
313 | c = c + 0xfe00 - (buf0 << 9); | |
314 | ct = 7; | |
315 | } | |
316 | } else { | |
317 | buf0 = buf1; | |
318 | buf1 = readByte(); | |
319 | c = c + 0xff00 - (buf0 << 8); | |
320 | ct = 8; | |
321 | } | |
322 | } |