source: trunk/poppler/mypoppler/poppler/JArithmeticDecoder.cc @ 461

Last change on this file since 461 was 2, checked in by Eugene Romanenko, 16 years ago

First import

File size: 7.0 KB
Line 
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}
Note: See TracBrowser for help on using the repository browser.