fd297445b278ba8fb276fb7f7b8c71682241304f
[swftools.git] / pdf2swf / xpdf / JArithmeticDecoder.cc
1 //========================================================================
2 //
3 // JArithmeticDecoder.cc
4 //
5 // Copyright 2002-2004 Glyph & Cog, LLC
6 //
7 //========================================================================
8
9 #include <aconf.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 *)gmalloc(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 }
93
94 JArithmeticDecoder::~JArithmeticDecoder() {
95   while (dataLen > 0) {
96     readByte();
97   }
98 }
99
100 inline Guint JArithmeticDecoder::readByte() {
101   if (dataLen == 0) {
102     return 0xff;
103   }
104   if (dataLen > 0) {
105     --dataLen;
106   }
107   return (Guint)str->getChar() & 0xff;
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 int JArithmeticDecoder::decodeBit(Guint context,
123                                   JArithmeticDecoderStats *stats) {
124   int bit;
125   Guint qe;
126   int iCX, mpsCX;
127
128   iCX = stats->cxTab[context] >> 1;
129   mpsCX = stats->cxTab[context] & 1;
130   qe = qeTab[iCX];
131   a -= qe;
132   if (c < a) {
133     if (a & 0x80000000) {
134       bit = mpsCX;
135     } else {
136       // MPS_EXCHANGE
137       if (a < qe) {
138         bit = 1 - mpsCX;
139         if (switchTab[iCX]) {
140           stats->cxTab[context] = (nlpsTab[iCX] << 1) | (1 - mpsCX);
141         } else {
142           stats->cxTab[context] = (nlpsTab[iCX] << 1) | mpsCX;
143         }
144       } else {
145         bit = mpsCX;
146         stats->cxTab[context] = (nmpsTab[iCX] << 1) | mpsCX;
147       }
148       // RENORMD
149       do {
150         if (ct == 0) {
151           byteIn();
152         }
153         a <<= 1;
154         c <<= 1;
155         --ct;
156       } while (!(a & 0x80000000));
157     }
158   } else {
159     c -= a;
160     // LPS_EXCHANGE
161     if (a < qe) {
162       bit = mpsCX;
163       stats->cxTab[context] = (nmpsTab[iCX] << 1) | mpsCX;
164     } else {
165       bit = 1 - mpsCX;
166       if (switchTab[iCX]) {
167         stats->cxTab[context] = (nlpsTab[iCX] << 1) | (1 - mpsCX);
168       } else {
169         stats->cxTab[context] = (nlpsTab[iCX] << 1) | mpsCX;
170       }
171     }
172     a = qe;
173     // RENORMD
174     do {
175       if (ct == 0) {
176         byteIn();
177       }
178       a <<= 1;
179       c <<= 1;
180       --ct;
181     } while (!(a & 0x80000000));
182   }
183   return bit;
184 }
185
186 int JArithmeticDecoder::decodeByte(Guint context,
187                                    JArithmeticDecoderStats *stats) {
188   int byte;
189   int i;
190
191   byte = 0;
192   for (i = 0; i < 8; ++i) {
193     byte = (byte << 1) | decodeBit(context, stats);
194   }
195   return byte;
196 }
197
198 GBool JArithmeticDecoder::decodeInt(int *x, JArithmeticDecoderStats *stats) {
199   int s;
200   Guint v;
201   int i;
202
203   prev = 1;
204   s = decodeIntBit(stats);
205   if (decodeIntBit(stats)) {
206     if (decodeIntBit(stats)) {
207       if (decodeIntBit(stats)) {
208         if (decodeIntBit(stats)) {
209           if (decodeIntBit(stats)) {
210             v = 0;
211             for (i = 0; i < 32; ++i) {
212               v = (v << 1) | decodeIntBit(stats);
213             }
214             v += 4436;
215           } else {
216             v = 0;
217             for (i = 0; i < 12; ++i) {
218               v = (v << 1) | decodeIntBit(stats);
219             }
220             v += 340;
221           }
222         } else {
223           v = 0;
224           for (i = 0; i < 8; ++i) {
225             v = (v << 1) | decodeIntBit(stats);
226           }
227           v += 84;
228         }
229       } else {
230         v = 0;
231         for (i = 0; i < 6; ++i) {
232           v = (v << 1) | decodeIntBit(stats);
233         }
234         v += 20;
235       }
236     } else {
237       v = decodeIntBit(stats);
238       v = (v << 1) | decodeIntBit(stats);
239       v = (v << 1) | decodeIntBit(stats);
240       v = (v << 1) | decodeIntBit(stats);
241       v += 4;
242     }
243   } else {
244     v = decodeIntBit(stats);
245     v = (v << 1) | decodeIntBit(stats);
246   }
247
248   if (s) {
249     if (v == 0) {
250       return gFalse;
251     }
252     *x = -(int)v;
253   } else {
254     *x = (int)v;
255   }
256   return gTrue;
257 }
258
259 int JArithmeticDecoder::decodeIntBit(JArithmeticDecoderStats *stats) {
260   int bit;
261
262   bit = decodeBit(prev, stats);
263   if (prev < 0x100) {
264     prev = (prev << 1) | bit;
265   } else {
266     prev = (((prev << 1) | bit) & 0x1ff) | 0x100;
267   }
268   return bit;
269 }
270
271 Guint JArithmeticDecoder::decodeIAID(Guint codeLen,
272                                      JArithmeticDecoderStats *stats) {
273   Guint i;
274   int bit;
275
276   prev = 1;
277   for (i = 0; i < codeLen; ++i) {
278     bit = decodeBit(prev, stats);
279     prev = (prev << 1) | bit;
280   }
281   return prev - (1 << codeLen);
282 }
283
284 void JArithmeticDecoder::byteIn() {
285   if (buf0 == 0xff) {
286     if (buf1 > 0x8f) {
287       ct = 8;
288     } else {
289       buf0 = buf1;
290       buf1 = readByte();
291       c = c + 0xfe00 - (buf0 << 9);
292       ct = 7;
293     }
294   } else {
295     buf0 = buf1;
296     buf1 = readByte();
297     c = c + 0xff00 - (buf0 << 8);
298     ct = 8;
299   }
300 }