]> git.ipfire.org Git - thirdparty/cups.git/blame - pdftops/JArithmeticDecoder.cxx
Merge changes from CUPS 1.4svn-r7199.
[thirdparty/cups.git] / pdftops / JArithmeticDecoder.cxx
CommitLineData
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
23JArithmeticDecoderStats::JArithmeticDecoderStats(int contextSizeA) {
24 contextSize = contextSizeA;
25 cxTab = (Guchar *)gmallocn(contextSize, sizeof(Guchar));
26 reset();
27}
28
29JArithmeticDecoderStats::~JArithmeticDecoderStats() {
30 gfree(cxTab);
31}
32
33JArithmeticDecoderStats *JArithmeticDecoderStats::copy() {
34 JArithmeticDecoderStats *stats;
35
36 stats = new JArithmeticDecoderStats(contextSize);
37 memcpy(stats->cxTab, cxTab, contextSize);
38 return stats;
39}
40
41void JArithmeticDecoderStats::reset() {
42 memset(cxTab, 0, contextSize);
43}
44
45void JArithmeticDecoderStats::copyFrom(JArithmeticDecoderStats *stats) {
46 memcpy(cxTab, stats->cxTab, contextSize);
47}
48
49void JArithmeticDecoderStats::setEntry(Guint cx, int i, int mps) {
50 cxTab[cx] = (i << 1) + mps;
51}
52
53//------------------------------------------------------------------------
54// JArithmeticDecoder
55//------------------------------------------------------------------------
56
57Guint 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
72int 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
78int 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
84int 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
90JArithmeticDecoder::JArithmeticDecoder() {
91 str = NULL;
92 dataLen = 0;
93 limitStream = gFalse;
94}
95
96inline 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
106JArithmeticDecoder::~JArithmeticDecoder() {
107 cleanup();
108}
109
110void 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
122void 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
135void JArithmeticDecoder::cleanup() {
136 if (limitStream) {
137 while (dataLen > 0) {
138 buf0 = buf1;
139 buf1 = readByte();
140 }
141 }
142}
143
144int 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
208int 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
220GBool 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
281int 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
293Guint 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
306void 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}