]> www.fi.muni.cz Git - evince.git/blob - pdf/xpdf/JBIG2Stream.cc
716fee1cabff4aa80fc0697c523320762793fa13
[evince.git] / pdf / xpdf / JBIG2Stream.cc
1 //========================================================================
2 //
3 // JBIG2Stream.cc
4 //
5 // Copyright 2002 Glyph & Cog, LLC
6 //
7 //========================================================================
8
9 #include <aconf.h>
10
11 #ifdef USE_GCC_PRAGMAS
12 #pragma implementation
13 #endif
14
15 #include <stdlib.h>
16 #include "GList.h"
17 #include "Error.h"
18 #include "JBIG2Stream.h"
19
20 //~ share these tables
21 #include "Stream-CCITT.h"
22
23 //------------------------------------------------------------------------
24
25 static int contextSize[4] = { 16, 13, 10, 10 };
26 static int refContextSize[2] = { 13, 10 };
27
28 //------------------------------------------------------------------------
29 // JBIG2ArithmeticDecoderStats
30 //------------------------------------------------------------------------
31
32 class JBIG2ArithmeticDecoderStats {
33 public:
34
35   JBIG2ArithmeticDecoderStats(int contextSizeA);
36   ~JBIG2ArithmeticDecoderStats();
37   JBIG2ArithmeticDecoderStats *copy();
38   void reset();
39   int getContextSize() { return contextSize; }
40   void copyFrom(JBIG2ArithmeticDecoderStats *stats);
41
42 private:
43
44   Guchar *cxTab;                // cxTab[cx] = (i[cx] << 1) + mps[cx]
45   int contextSize;
46
47   friend class JBIG2ArithmeticDecoder;
48 };
49
50 JBIG2ArithmeticDecoderStats::JBIG2ArithmeticDecoderStats(int contextSizeA) {
51   contextSize = contextSizeA;
52   cxTab = (Guchar *)gmalloc((1 << contextSize) * sizeof(Guchar));
53   reset();
54 }
55
56 JBIG2ArithmeticDecoderStats::~JBIG2ArithmeticDecoderStats() {
57   gfree(cxTab);
58 }
59
60 JBIG2ArithmeticDecoderStats *JBIG2ArithmeticDecoderStats::copy() {
61   JBIG2ArithmeticDecoderStats *stats;
62
63   stats = new JBIG2ArithmeticDecoderStats(contextSize);
64   memcpy(stats->cxTab, cxTab, 1 << contextSize);
65   return stats;
66 }
67
68 void JBIG2ArithmeticDecoderStats::reset() {
69   memset(cxTab, 0, 1 << contextSize);
70 }
71
72 void JBIG2ArithmeticDecoderStats::copyFrom(
73                                       JBIG2ArithmeticDecoderStats *stats) {
74   memcpy(cxTab, stats->cxTab, 1 << contextSize);
75 }
76
77 //------------------------------------------------------------------------
78 // JBIG2ArithmeticDecoder
79 //------------------------------------------------------------------------
80
81 class JBIG2ArithmeticDecoder {
82 public:
83
84   JBIG2ArithmeticDecoder();
85   ~JBIG2ArithmeticDecoder();
86   void setStream(Stream *strA) { str = strA; }
87   void start();
88   int decodeBit(Guint context, JBIG2ArithmeticDecoderStats *stats);
89   int decodeByte(Guint context, JBIG2ArithmeticDecoderStats *stats);
90
91   // Returns false for OOB, otherwise sets *<x> and returns true.
92   GBool decodeInt(int *x, JBIG2ArithmeticDecoderStats *stats);
93
94   Guint decodeIAID(Guint codeLen,
95                    JBIG2ArithmeticDecoderStats *stats);
96
97 private:
98
99   int decodeIntBit(JBIG2ArithmeticDecoderStats *stats);
100   void byteIn();
101
102   static Guint qeTab[47];
103   static int nmpsTab[47];
104   static int nlpsTab[47];
105   static int switchTab[47];
106
107   Guint buf0, buf1;
108   Guint c, a;
109   int ct;
110
111   Guint prev;                   // for the integer decoder
112
113   Stream *str;
114 };
115
116 Guint JBIG2ArithmeticDecoder::qeTab[47] = {
117   0x56010000, 0x34010000, 0x18010000, 0x0AC10000,
118   0x05210000, 0x02210000, 0x56010000, 0x54010000,
119   0x48010000, 0x38010000, 0x30010000, 0x24010000,
120   0x1C010000, 0x16010000, 0x56010000, 0x54010000,
121   0x51010000, 0x48010000, 0x38010000, 0x34010000,
122   0x30010000, 0x28010000, 0x24010000, 0x22010000,
123   0x1C010000, 0x18010000, 0x16010000, 0x14010000,
124   0x12010000, 0x11010000, 0x0AC10000, 0x09C10000,
125   0x08A10000, 0x05210000, 0x04410000, 0x02A10000,
126   0x02210000, 0x01410000, 0x01110000, 0x00850000,
127   0x00490000, 0x00250000, 0x00150000, 0x00090000,
128   0x00050000, 0x00010000, 0x56010000
129 };
130
131 int JBIG2ArithmeticDecoder::nmpsTab[47] = {
132    1,  2,  3,  4,  5, 38,  7,  8,  9, 10, 11, 12, 13, 29, 15, 16,
133   17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
134   33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 45, 46
135 };
136
137 int JBIG2ArithmeticDecoder::nlpsTab[47] = {
138    1,  6,  9, 12, 29, 33,  6, 14, 14, 14, 17, 18, 20, 21, 14, 14,
139   15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
140   30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 46
141 };
142
143 int JBIG2ArithmeticDecoder::switchTab[47] = {
144   1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
145   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
146   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
147 };
148
149 JBIG2ArithmeticDecoder::JBIG2ArithmeticDecoder() {
150   str = NULL;
151 }
152
153 JBIG2ArithmeticDecoder::~JBIG2ArithmeticDecoder() {
154 }
155
156 void JBIG2ArithmeticDecoder::start() {
157   buf0 = (Guint)str->getChar() & 0xff;
158   buf1 = (Guint)str->getChar() & 0xff;
159
160   // INITDEC
161   c = (buf0 ^ 0xff) << 16;
162   byteIn();
163   c <<= 7;
164   ct -= 7;
165   a = 0x80000000;
166 }
167
168 int JBIG2ArithmeticDecoder::decodeBit(Guint context,
169                                       JBIG2ArithmeticDecoderStats *stats) {
170   int bit;
171   Guint qe;
172   int iCX, mpsCX;
173
174   iCX = stats->cxTab[context] >> 1;
175   mpsCX = stats->cxTab[context] & 1;
176   qe = qeTab[iCX];
177   a -= qe;
178   if (c < a) {
179     if (a & 0x80000000) {
180       bit = mpsCX;
181     } else {
182       // MPS_EXCHANGE
183       if (a < qe) {
184         bit = 1 - mpsCX;
185         if (switchTab[iCX]) {
186           stats->cxTab[context] = (nlpsTab[iCX] << 1) | (1 - mpsCX);
187         } else {
188           stats->cxTab[context] = (nlpsTab[iCX] << 1) | mpsCX;
189         }
190       } else {
191         bit = mpsCX;
192         stats->cxTab[context] = (nmpsTab[iCX] << 1) | mpsCX;
193       }
194       // RENORMD
195       do {
196         if (ct == 0) {
197           byteIn();
198         }
199         a <<= 1;
200         c <<= 1;
201         --ct;
202       } while (!(a & 0x80000000));
203     }
204   } else {
205     c -= a;
206     // LPS_EXCHANGE
207     if (a < qe) {
208       bit = mpsCX;
209       stats->cxTab[context] = (nmpsTab[iCX] << 1) | mpsCX;
210     } else {
211       bit = 1 - mpsCX;
212       if (switchTab[iCX]) {
213         stats->cxTab[context] = (nlpsTab[iCX] << 1) | (1 - mpsCX);
214       } else {
215         stats->cxTab[context] = (nlpsTab[iCX] << 1) | mpsCX;
216       }
217     }
218     a = qe;
219     // RENORMD
220     do {
221       if (ct == 0) {
222         byteIn();
223       }
224       a <<= 1;
225       c <<= 1;
226       --ct;
227     } while (!(a & 0x80000000));
228   }
229   return bit;
230 }
231
232 int JBIG2ArithmeticDecoder::decodeByte(Guint context,
233                                        JBIG2ArithmeticDecoderStats *stats) {
234   int byte;
235   int i;
236
237   byte = 0;
238   for (i = 0; i < 8; ++i) {
239     byte = (byte << 1) | decodeBit(context, stats);
240   }
241   return byte;
242 }
243
244 GBool JBIG2ArithmeticDecoder::decodeInt(int *x,
245                                         JBIG2ArithmeticDecoderStats *stats) {
246   int s;
247   Guint v;
248   int i;
249
250   prev = 1;
251   s = decodeIntBit(stats);
252   if (decodeIntBit(stats)) {
253     if (decodeIntBit(stats)) {
254       if (decodeIntBit(stats)) {
255         if (decodeIntBit(stats)) {
256           if (decodeIntBit(stats)) {
257             v = 0;
258             for (i = 0; i < 32; ++i) {
259               v = (v << 1) | decodeIntBit(stats);
260             }
261             v += 4436;
262           } else {
263             v = 0;
264             for (i = 0; i < 12; ++i) {
265               v = (v << 1) | decodeIntBit(stats);
266             }
267             v += 340;
268           }
269         } else {
270           v = 0;
271           for (i = 0; i < 8; ++i) {
272             v = (v << 1) | decodeIntBit(stats);
273           }
274           v += 84;
275         }
276       } else {
277         v = 0;
278         for (i = 0; i < 6; ++i) {
279           v = (v << 1) | decodeIntBit(stats);
280         }
281         v += 20;
282       }
283     } else {
284       v = decodeIntBit(stats);
285       v = (v << 1) | decodeIntBit(stats);
286       v = (v << 1) | decodeIntBit(stats);
287       v = (v << 1) | decodeIntBit(stats);
288       v += 4;
289     }
290   } else {
291     v = decodeIntBit(stats);
292     v = (v << 1) | decodeIntBit(stats);
293   }
294
295   if (s) {
296     if (v == 0) {
297       return gFalse;
298     }
299     *x = -(int)v;
300   } else {
301     *x = (int)v;
302   }
303   return gTrue;
304 }
305
306 int JBIG2ArithmeticDecoder::decodeIntBit(JBIG2ArithmeticDecoderStats *stats) {
307   int bit;
308
309   bit = decodeBit(prev, stats);
310   if (prev < 0x100) {
311     prev = (prev << 1) | bit;
312   } else {
313     prev = (((prev << 1) | bit) & 0x1ff) | 0x100;
314   }
315   return bit;
316 }
317
318 Guint JBIG2ArithmeticDecoder::decodeIAID(Guint codeLen,
319                                          JBIG2ArithmeticDecoderStats *stats) {
320   Guint i;
321   int bit;
322
323   prev = 1;
324   for (i = 0; i < codeLen; ++i) {
325     bit = decodeBit(prev, stats);
326     prev = (prev << 1) | bit;
327   }
328   return prev - (1 << codeLen);
329 }
330
331 void JBIG2ArithmeticDecoder::byteIn() {
332   if (buf0 == 0xff) {
333     if (buf1 > 0x8f) {
334       ct = 8;
335     } else {
336       buf0 = buf1;
337       buf1 = (Guint)str->getChar() & 0xff;
338       c = c + 0xfe00 - (buf0 << 9);
339       ct = 7;
340     }
341   } else {
342     buf0 = buf1;
343     buf1 = (Guint)str->getChar() & 0xff;
344     c = c + 0xff00 - (buf0 << 8);
345     ct = 8;
346   }
347 }
348
349 //------------------------------------------------------------------------
350 // JBIG2HuffmanTable
351 //------------------------------------------------------------------------
352
353 #define jbig2HuffmanLOW 0xfffffffd
354 #define jbig2HuffmanOOB 0xfffffffe
355 #define jbig2HuffmanEOT 0xffffffff
356
357 struct JBIG2HuffmanTable {
358   int val;
359   Guint prefixLen;
360   Guint rangeLen;               // can also be LOW, OOB, or EOT
361   Guint prefix;
362 };
363
364 JBIG2HuffmanTable huffTableA[] = {
365   {     0, 1,  4,              0x000 },
366   {    16, 2,  8,              0x002 },
367   {   272, 3, 16,              0x006 },
368   { 65808, 3, 32,              0x007 },
369   {     0, 0, jbig2HuffmanEOT, 0     }
370 };
371
372 JBIG2HuffmanTable huffTableB[] = {
373   {     0, 1,  0,              0x000 },
374   {     1, 2,  0,              0x002 },
375   {     2, 3,  0,              0x006 },
376   {     3, 4,  3,              0x00e },
377   {    11, 5,  6,              0x01e },
378   {    75, 6, 32,              0x03e },
379   {     0, 6, jbig2HuffmanOOB, 0x03f },
380   {     0, 0, jbig2HuffmanEOT, 0     }
381 };
382
383 JBIG2HuffmanTable huffTableC[] = {
384   {     0, 1,  0,              0x000 },
385   {     1, 2,  0,              0x002 },
386   {     2, 3,  0,              0x006 },
387   {     3, 4,  3,              0x00e },
388   {    11, 5,  6,              0x01e },
389   {     0, 6, jbig2HuffmanOOB, 0x03e },
390   {    75, 7, 32,              0x0fe },
391   {  -256, 8,  8,              0x0fe },
392   {  -257, 8, jbig2HuffmanLOW, 0x0ff },
393   {     0, 0, jbig2HuffmanEOT, 0     }
394 };
395
396 JBIG2HuffmanTable huffTableD[] = {
397   {     1, 1,  0,              0x000 },
398   {     2, 2,  0,              0x002 },
399   {     3, 3,  0,              0x006 },
400   {     4, 4,  3,              0x00e },
401   {    12, 5,  6,              0x01e },
402   {    76, 5, 32,              0x01f },
403   {     0, 0, jbig2HuffmanEOT, 0     }
404 };
405
406 JBIG2HuffmanTable huffTableE[] = {
407   {     1, 1,  0,              0x000 },
408   {     2, 2,  0,              0x002 },
409   {     3, 3,  0,              0x006 },
410   {     4, 4,  3,              0x00e },
411   {    12, 5,  6,              0x01e },
412   {    76, 6, 32,              0x03e },
413   {  -255, 7,  8,              0x07e },
414   {  -256, 7, jbig2HuffmanLOW, 0x07f },
415   {     0, 0, jbig2HuffmanEOT, 0     }
416 };
417
418 JBIG2HuffmanTable huffTableF[] = {
419   {     0, 2,  7,              0x000 },
420   {   128, 3,  7,              0x002 },
421   {   256, 3,  8,              0x003 },
422   { -1024, 4,  9,              0x008 },
423   {  -512, 4,  8,              0x009 },
424   {  -256, 4,  7,              0x00a },
425   {   -32, 4,  5,              0x00b },
426   {   512, 4,  9,              0x00c },
427   {  1024, 4, 10,              0x00d },
428   { -2048, 5, 10,              0x01c },
429   {  -128, 5,  6,              0x01d },
430   {   -64, 5,  5,              0x01e },
431   { -2049, 6, jbig2HuffmanLOW, 0x03e },
432   {  2048, 6, 32,              0x03f },
433   {     0, 0, jbig2HuffmanEOT, 0     }
434 };
435
436 JBIG2HuffmanTable huffTableG[] = {
437   {  -512, 3,  8,              0x000 },
438   {   256, 3,  8,              0x001 },
439   {   512, 3,  9,              0x002 },
440   {  1024, 3, 10,              0x003 },
441   { -1024, 4,  9,              0x008 },
442   {  -256, 4,  7,              0x009 },
443   {   -32, 4,  5,              0x00a },
444   {     0, 4,  5,              0x00b },
445   {   128, 4,  7,              0x00c },
446   {  -128, 5,  6,              0x01a },
447   {   -64, 5,  5,              0x01b },
448   {    32, 5,  5,              0x01c },
449   {    64, 5,  6,              0x01d },
450   { -1025, 5, jbig2HuffmanLOW, 0x01e },
451   {  2048, 5, 32,              0x01f },
452   {     0, 0, jbig2HuffmanEOT, 0     }
453 };
454
455 JBIG2HuffmanTable huffTableH[] = {
456   {     0, 2,  1,              0x000 },
457   {     0, 2, jbig2HuffmanOOB, 0x001 },
458   {     4, 3,  4,              0x004 },
459   {    -1, 4,  0,              0x00a },
460   {    22, 4,  4,              0x00b },
461   {    38, 4,  5,              0x00c },
462   {     2, 5,  0,              0x01a },
463   {    70, 5,  6,              0x01b },
464   {   134, 5,  7,              0x01c },
465   {     3, 6,  0,              0x03a },
466   {    20, 6,  1,              0x03b },
467   {   262, 6,  7,              0x03c },
468   {   646, 6, 10,              0x03d },
469   {    -2, 7,  0,              0x07c },
470   {   390, 7,  8,              0x07d },
471   {   -15, 8,  3,              0x0fc },
472   {    -5, 8,  1,              0x0fd },
473   {    -7, 9,  1,              0x1fc },
474   {    -3, 9,  0,              0x1fd },
475   {   -16, 9, jbig2HuffmanLOW, 0x1fe },
476   {  1670, 9, 32,              0x1ff },
477   {     0, 0, jbig2HuffmanEOT, 0     }
478 };
479
480 JBIG2HuffmanTable huffTableI[] = {
481   {     0, 2, jbig2HuffmanOOB, 0x000 },
482   {    -1, 3,  1,              0x002 },
483   {     1, 3,  1,              0x003 },
484   {     7, 3,  5,              0x004 },
485   {    -3, 4,  1,              0x00a },
486   {    43, 4,  5,              0x00b },
487   {    75, 4,  6,              0x00c },
488   {     3, 5,  1,              0x01a },
489   {   139, 5,  7,              0x01b },
490   {   267, 5,  8,              0x01c },
491   {     5, 6,  1,              0x03a },
492   {    39, 6,  2,              0x03b },
493   {   523, 6,  8,              0x03c },
494   {  1291, 6, 11,              0x03d },
495   {    -5, 7,  1,              0x07c },
496   {   779, 7,  9,              0x07d },
497   {   -31, 8,  4,              0x0fc },
498   {   -11, 8,  2,              0x0fd },
499   {   -15, 9,  2,              0x1fc },
500   {    -7, 9,  1,              0x1fd },
501   {   -32, 9, jbig2HuffmanLOW, 0x1fe },
502   {  3339, 9, 32,              0x1ff },
503   {     0, 0, jbig2HuffmanEOT, 0     }
504 };
505
506 JBIG2HuffmanTable huffTableJ[] = {
507   {    -2, 2,  2,              0x000 },
508   {     6, 2,  6,              0x001 },
509   {     0, 2, jbig2HuffmanOOB, 0x002 },
510   {    -3, 5,  0,              0x018 },
511   {     2, 5,  0,              0x019 },
512   {    70, 5,  5,              0x01a },
513   {     3, 6,  0,              0x036 },
514   {   102, 6,  5,              0x037 },
515   {   134, 6,  6,              0x038 },
516   {   198, 6,  7,              0x039 },
517   {   326, 6,  8,              0x03a },
518   {   582, 6,  9,              0x03b },
519   {  1094, 6, 10,              0x03c },
520   {   -21, 7,  4,              0x07a },
521   {    -4, 7,  0,              0x07b },
522   {     4, 7,  0,              0x07c },
523   {  2118, 7, 11,              0x07d },
524   {    -5, 8,  0,              0x0fc },
525   {     5, 8,  0,              0x0fd },
526   {   -22, 8, jbig2HuffmanLOW, 0x0fe },
527   {  4166, 8, 32,              0x0ff },
528   {     0, 0, jbig2HuffmanEOT, 0     }
529 };
530
531 JBIG2HuffmanTable huffTableK[] = {
532   {     1, 1,  0,              0x000 },
533   {     2, 2,  1,              0x002 },
534   {     4, 4,  0,              0x00c },
535   {     5, 4,  1,              0x00d },
536   {     7, 5,  1,              0x01c },
537   {     9, 5,  2,              0x01d },
538   {    13, 6,  2,              0x03c },
539   {    17, 7,  2,              0x07a },
540   {    21, 7,  3,              0x07b },
541   {    29, 7,  4,              0x07c },
542   {    45, 7,  5,              0x07d },
543   {    77, 7,  6,              0x07e },
544   {   141, 7, 32,              0x07f },
545   {     0, 0, jbig2HuffmanEOT, 0     }
546 };
547
548 JBIG2HuffmanTable huffTableL[] = {
549   {     1, 1,  0,              0x000 },
550   {     2, 2,  0,              0x002 },
551   {     3, 3,  1,              0x006 },
552   {     5, 5,  0,              0x01c },
553   {     6, 5,  1,              0x01d },
554   {     8, 6,  1,              0x03c },
555   {    10, 7,  0,              0x07a },
556   {    11, 7,  1,              0x07b },
557   {    13, 7,  2,              0x07c },
558   {    17, 7,  3,              0x07d },
559   {    25, 7,  4,              0x07e },
560   {    41, 8,  5,              0x0fe },
561   {    73, 8, 32,              0x0ff },
562   {     0, 0, jbig2HuffmanEOT, 0     }
563 };
564
565 JBIG2HuffmanTable huffTableM[] = {
566   {     1, 1,  0,              0x000 },
567   {     2, 3,  0,              0x004 },
568   {     7, 3,  3,              0x005 },
569   {     3, 4,  0,              0x00c },
570   {     5, 4,  1,              0x00d },
571   {     4, 5,  0,              0x01c },
572   {    15, 6,  1,              0x03a },
573   {    17, 6,  2,              0x03b },
574   {    21, 6,  3,              0x03c },
575   {    29, 6,  4,              0x03d },
576   {    45, 6,  5,              0x03e },
577   {    77, 7,  6,              0x07e },
578   {   141, 7, 32,              0x07f },
579   {     0, 0, jbig2HuffmanEOT, 0     }
580 };
581
582 JBIG2HuffmanTable huffTableN[] = {
583   {     0, 1,  0,              0x000 },
584   {    -2, 3,  0,              0x004 },
585   {    -1, 3,  0,              0x005 },
586   {     1, 3,  0,              0x006 },
587   {     2, 3,  0,              0x007 },
588   {     0, 0, jbig2HuffmanEOT, 0     }
589 };
590
591 JBIG2HuffmanTable huffTableO[] = {
592   {     0, 1,  0,              0x000 },
593   {    -1, 3,  0,              0x004 },
594   {     1, 3,  0,              0x005 },
595   {    -2, 4,  0,              0x00c },
596   {     2, 4,  0,              0x00d },
597   {    -4, 5,  1,              0x01c },
598   {     3, 5,  1,              0x01d },
599   {    -8, 6,  2,              0x03c },
600   {     5, 6,  2,              0x03d },
601   {   -24, 7,  4,              0x07c },
602   {     9, 7,  4,              0x07d },
603   {   -25, 7, jbig2HuffmanLOW, 0x07e },
604   {    25, 7, 32,              0x07f },
605   {     0, 0, jbig2HuffmanEOT, 0     }
606 };
607
608 //------------------------------------------------------------------------
609 // JBIG2HuffmanDecoder
610 //------------------------------------------------------------------------
611
612 class JBIG2HuffmanDecoder {
613 public:
614
615   JBIG2HuffmanDecoder();
616   ~JBIG2HuffmanDecoder();
617   void setStream(Stream *strA) { str = strA; }
618
619   void reset();
620
621   // Returns false for OOB, otherwise sets *<x> and returns true.
622   GBool decodeInt(int *x, JBIG2HuffmanTable *table);
623
624   Guint readBits(Guint n);
625   Guint readBit();
626
627   // Sort the table by prefix length and assign prefix values.
628   void buildTable(JBIG2HuffmanTable *table, Guint len);
629
630 private:
631
632   Stream *str;
633   Guint buf;
634   Guint bufLen;
635 };
636
637 JBIG2HuffmanDecoder::JBIG2HuffmanDecoder() {
638   str = NULL;
639   reset();
640 }
641
642 JBIG2HuffmanDecoder::~JBIG2HuffmanDecoder() {
643 }
644
645 void JBIG2HuffmanDecoder::reset() {
646   buf = 0;
647   bufLen = 0;
648 }
649
650 //~ optimize this
651 GBool JBIG2HuffmanDecoder::decodeInt(int *x, JBIG2HuffmanTable *table) {
652   Guint i, len, prefix;
653
654   i = 0;
655   len = 0;
656   prefix = 0;
657   while (table[i].rangeLen != jbig2HuffmanEOT) {
658     //~ if buildTable removes the entries with prefixLen=0, this is unneeded
659     if (table[i].prefixLen > 0) {
660       while (len < table[i].prefixLen) {
661         prefix = (prefix << 1) | readBit();
662         ++len;
663       }
664       if (prefix == table[i].prefix) {
665         if (table[i].rangeLen == jbig2HuffmanOOB) {
666           return gFalse;
667         }
668         if (table[i].rangeLen == jbig2HuffmanLOW) {
669           *x = table[i].val - readBits(32);
670         } else if (table[i].rangeLen > 0) {
671           *x = table[i].val + readBits(table[i].rangeLen);
672         } else {
673           *x = table[i].val;
674         }
675         return gTrue;
676       }
677     }
678     ++i;
679   }
680   return gFalse;
681 }
682
683 Guint JBIG2HuffmanDecoder::readBits(Guint n) {
684   Guint x, mask, nLeft;
685
686   mask = (n == 32) ? 0xffffffff : ((1 << n) - 1);
687   if (bufLen >= n) {
688     x = (buf >> (bufLen - n)) & mask;
689     bufLen -= n;
690   } else {
691     x = buf & ((1 << bufLen) - 1);
692     nLeft = n - bufLen;
693     bufLen = 0;
694     while (nLeft >= 8) {
695       x = (x << 8) | (str->getChar() & 0xff);
696       nLeft -= 8;
697     }
698     if (nLeft > 0) {
699       buf = str->getChar();
700       bufLen = 8 - nLeft;
701       x = (x << nLeft) | ((buf >> bufLen) & ((1 << nLeft) - 1));
702     }
703   }
704   return x;
705 }
706
707 Guint JBIG2HuffmanDecoder::readBit() {
708   if (bufLen == 0) {
709     buf = str->getChar();
710     bufLen = 8;
711   }
712   --bufLen;
713   return (buf >> bufLen) & 1;
714 }
715
716 static int cmpHuffmanTabEntries(const void *p1, const void *p2) {
717   return ((JBIG2HuffmanTable *)p1)->prefixLen
718          - ((JBIG2HuffmanTable *)p2)->prefixLen;
719 }
720
721 //~ should remove entries with prefixLen = 0
722 void JBIG2HuffmanDecoder::buildTable(JBIG2HuffmanTable *table, Guint len) {
723   Guint i, prefix;
724
725   qsort(table, len, sizeof(JBIG2HuffmanTable), &cmpHuffmanTabEntries);
726   for (i = 0; i < len && table[i].prefixLen == 0; ++i) {
727     table[i].prefix = 0;
728   }
729   prefix = 0;
730   table[i++].prefix = prefix++;
731   for (; i < len; ++i) {
732     prefix <<= table[i].prefixLen - table[i-1].prefixLen;
733     table[i].prefix = prefix++;
734   }
735 }
736
737 //------------------------------------------------------------------------
738 // JBIG2MMRDecoder
739 //------------------------------------------------------------------------
740
741 class JBIG2MMRDecoder {
742 public:
743
744   JBIG2MMRDecoder();
745   ~JBIG2MMRDecoder();
746   void setStream(Stream *strA) { str = strA; }
747   void reset();
748   int get2DCode();
749   int getBlackCode();
750   int getWhiteCode();
751   Guint get24Bits();
752   void skipTo(Guint length);
753
754 private:
755
756   Stream *str;
757   Guint buf;
758   Guint bufLen;
759   Guint nBytesRead;
760 };
761
762 JBIG2MMRDecoder::JBIG2MMRDecoder() {
763   str = NULL;
764   reset();
765 }
766
767 JBIG2MMRDecoder::~JBIG2MMRDecoder() {
768 }
769
770 void JBIG2MMRDecoder::reset() {
771   buf = 0;
772   bufLen = 0;
773   nBytesRead = 0;
774 }
775
776 int JBIG2MMRDecoder::get2DCode() {
777   CCITTCode *p;
778
779   if (bufLen == 0) {
780     buf = str->getChar() & 0xff;
781     bufLen = 8;
782     ++nBytesRead;
783     p = &twoDimTab1[(buf >> 1) & 0x7f];
784   } else if (bufLen == 8) {
785     p = &twoDimTab1[(buf >> 1) & 0x7f];
786   } else {
787     p = &twoDimTab1[(buf << (7 - bufLen)) & 0x7f];
788     if (p->bits < 0 || p->bits > (int)bufLen) {
789       buf = (buf << 8) | (str->getChar() & 0xff);
790       bufLen += 8;
791       ++nBytesRead;
792       p = &twoDimTab1[(buf >> (bufLen - 7)) & 0x7f];
793     }
794   }
795   if (p->bits < 0) {
796     error(str->getPos(), "Bad two dim code in JBIG2 MMR stream");
797     return 0;
798   }
799   bufLen -= p->bits;
800   return p->n;
801 }
802
803 int JBIG2MMRDecoder::getWhiteCode() {
804   CCITTCode *p;
805   Guint code;
806
807   if (bufLen == 0) {
808     buf = str->getChar() & 0xff;
809     bufLen = 8;
810     ++nBytesRead;
811   }
812   while (1) {
813     if (bufLen > 7 && ((buf >> (bufLen - 7)) & 0x7f) == 0) {
814       if (bufLen <= 12) {
815         code = buf << (12 - bufLen);
816       } else {
817         code = buf >> (bufLen - 12);
818       }
819       p = &whiteTab1[code & 0x1f];
820     } else {
821       if (bufLen <= 9) {
822         code = buf << (9 - bufLen);
823       } else {
824         code = buf >> (bufLen - 9);
825       }
826       p = &whiteTab2[code & 0x1ff];
827     }
828     if (p->bits > 0 && p->bits < (int)bufLen) {
829       bufLen -= p->bits;
830       return p->n;
831     }
832     if (bufLen >= 12) {
833       break;
834     }
835     buf = (buf << 8) | (str->getChar() & 0xff);
836     bufLen += 8;
837     ++nBytesRead;
838   }
839   error(str->getPos(), "Bad white code in JBIG2 MMR stream");
840   // eat a bit and return a positive number so that the caller doesn't
841   // go into an infinite loop
842   --bufLen;
843   return 1;
844 }
845
846 int JBIG2MMRDecoder::getBlackCode() {
847   CCITTCode *p;
848   Guint code;
849
850   if (bufLen == 0) {
851     buf = str->getChar() & 0xff;
852     bufLen = 8;
853     ++nBytesRead;
854   }
855   while (1) {
856     if (bufLen > 6 && ((buf >> (bufLen - 6)) & 0x3f) == 0) {
857       if (bufLen <= 13) {
858         code = buf << (13 - bufLen);
859       } else {
860         code = buf >> (bufLen - 13);
861       }
862       p = &blackTab1[code & 0x7f];
863     } else if (bufLen > 4 && ((buf >> (bufLen - 4)) & 0x0f) == 0) {
864       if (bufLen <= 12) {
865         code = buf << (12 - bufLen);
866       } else {
867         code = buf >> (bufLen - 12);
868       }
869       p = &blackTab2[(code & 0xff) - 64];
870     } else {
871       if (bufLen <= 6) {
872         code = buf << (6 - bufLen);
873       } else {
874         code = buf >> (bufLen - 6);
875       }
876       p = &blackTab3[code & 0x3f];
877     }
878     if (p->bits > 0 && p->bits < (int)bufLen) {
879       bufLen -= p->bits;
880       return p->n;
881     }
882     if (bufLen >= 13) {
883       break;
884     }
885     buf = (buf << 8) | (str->getChar() & 0xff);
886     bufLen += 8;
887     ++nBytesRead;
888   }
889   error(str->getPos(), "Bad black code in JBIG2 MMR stream");
890   // eat a bit and return a positive number so that the caller doesn't
891   // go into an infinite loop
892   --bufLen;
893   return 1;
894 }
895
896 Guint JBIG2MMRDecoder::get24Bits() {
897   while (bufLen < 24) {
898     buf = (buf << 8) | (str->getChar() & 0xff);
899     bufLen += 8;
900     ++nBytesRead;
901   }
902   return (buf >> (bufLen - 24)) & 0xffffff;
903 }
904
905 void JBIG2MMRDecoder::skipTo(Guint length) {
906   while (nBytesRead < length) {
907     str->getChar();
908     ++nBytesRead;
909   }
910 }
911
912 //------------------------------------------------------------------------
913 // JBIG2Segment
914 //------------------------------------------------------------------------
915
916 enum JBIG2SegmentType {
917   jbig2SegBitmap,
918   jbig2SegSymbolDict,
919   jbig2SegPatternDict,
920   jbig2SegCodeTable
921 };
922
923 class JBIG2Segment {
924 public:
925
926   JBIG2Segment(Guint segNumA) { segNum = segNumA; }
927   virtual ~JBIG2Segment() {}
928   void setSegNum(Guint segNumA) { segNum = segNumA; }
929   Guint getSegNum() { return segNum; }
930   virtual JBIG2SegmentType getType() = 0;
931
932 private:
933
934   Guint segNum;
935 };
936
937 //------------------------------------------------------------------------
938 // JBIG2Bitmap
939 //------------------------------------------------------------------------
940
941 class JBIG2Bitmap: public JBIG2Segment {
942 public:
943
944   JBIG2Bitmap(Guint segNumA, int wA, int hA);
945   virtual ~JBIG2Bitmap();
946   virtual JBIG2SegmentType getType() { return jbig2SegBitmap; }
947   JBIG2Bitmap *copy() { return new JBIG2Bitmap(0, this); }
948   JBIG2Bitmap *getSlice(Guint x, Guint y, Guint wA, Guint hA);
949   void expand(int newH, Guint pixel);
950   void clearToZero();
951   void clearToOne();
952   int getWidth() { return w; }
953   int getHeight() { return h; }
954   int getPixel(int x, int y)
955     { return (x < 0 || x >= w || y < 0 || y >= h) ? 0 :
956              (data[y * line + (x >> 3)] >> (7 - (x & 7))) & 1; }
957   void setPixel(int x, int y)
958     { data[y * line + (x >> 3)] |= 1 << (7 - (x & 7)); }
959   void clearPixel(int x, int y)
960     { data[y * line + (x >> 3)] &= 0x7f7f >> (x & 7); }
961   void duplicateRow(int yDest, int ySrc);
962   void combine(JBIG2Bitmap *bitmap, int x, int y, Guint combOp);
963   Guchar *getDataPtr() { return data; }
964   int getDataSize() { return h * line; }
965
966 private:
967
968   JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap);
969
970   int w, h, line;
971   Guchar *data;
972 };
973
974 JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, int wA, int hA):
975   JBIG2Segment(segNumA)
976 {
977   w = wA;
978   h = hA;
979   line = (wA + 7) >> 3;
980   data = (Guchar *)gmalloc(h * line);
981 }
982
983 JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap):
984   JBIG2Segment(segNumA)
985 {
986   w = bitmap->w;
987   h = bitmap->h;
988   line = bitmap->line;
989   data = (Guchar *)gmalloc(h * line);
990   memcpy(data, bitmap->data, h * line);
991 }
992
993 JBIG2Bitmap::~JBIG2Bitmap() {
994   gfree(data);
995 }
996
997 //~ optimize this
998 JBIG2Bitmap *JBIG2Bitmap::getSlice(Guint x, Guint y, Guint wA, Guint hA) {
999   JBIG2Bitmap *slice;
1000   Guint xx, yy;
1001
1002   slice = new JBIG2Bitmap(0, wA, hA);
1003   slice->clearToZero();
1004   for (yy = 0; yy < hA; ++yy) {
1005     for (xx = 0; xx < wA; ++xx) {
1006       if (getPixel(x + xx, y + yy)) {
1007         slice->setPixel(xx, yy);
1008       }
1009     }
1010   }
1011   return slice;
1012 }
1013
1014 void JBIG2Bitmap::expand(int newH, Guint pixel) {
1015   if (newH <= h) {
1016     return;
1017   }
1018   data = (Guchar *)grealloc(data, newH * line);
1019   if (pixel) {
1020     memset(data + h * line, 0xff, (newH - h) * line);
1021   } else {
1022     memset(data + h * line, 0x00, (newH - h) * line);
1023   }
1024   h = newH;
1025 }
1026
1027 void JBIG2Bitmap::clearToZero() {
1028   memset(data, 0, h * line);
1029 }
1030
1031 void JBIG2Bitmap::clearToOne() {
1032   memset(data, 0xff, h * line);
1033 }
1034
1035 void JBIG2Bitmap::duplicateRow(int yDest, int ySrc) {
1036   memcpy(data + yDest * line, data + ySrc * line, line);
1037 }
1038
1039 void JBIG2Bitmap::combine(JBIG2Bitmap *bitmap, int x, int y,
1040                           Guint combOp) {
1041   int x0, x1, y0, y1, xx, yy;
1042   Guchar *srcPtr, *destPtr;
1043   Guint src0, src1, src, dest, s1, s2, m1, m2, m3;
1044   GBool oneByte;
1045
1046   if (y < 0) {
1047     y0 = -y;
1048   } else {
1049     y0 = 0;
1050   }
1051   if (y + bitmap->h > h) {
1052     y1 = h - y;
1053   } else {
1054     y1 = bitmap->h;
1055   }
1056   if (y0 >= y1) {
1057     return;
1058   }
1059
1060   if (x >= 0) {
1061     x0 = x & ~7;
1062   } else {
1063     x0 = 0;
1064   }
1065   x1 = x + bitmap->w;
1066   if (x1 > w) {
1067     x1 = w;
1068   }
1069   if (x0 >= x1) {
1070     return;
1071   }
1072
1073   s1 = x & 7;
1074   s2 = 8 - s1;
1075   m1 = 0xff >> (x1 & 7);
1076   m2 = 0xff << (((x1 & 7) == 0) ? 0 : 8 - (x1 & 7));
1077   m3 = (0xff >> s1) & m2;
1078
1079   oneByte = x0 == ((x1 - 1) & ~7);
1080
1081   for (yy = y0; yy < y1; ++yy) {
1082
1083     // one byte per line -- need to mask both left and right side
1084     if (oneByte) {
1085       if (x >= 0) {
1086         destPtr = data + (y + yy) * line + (x >> 3);
1087         srcPtr = bitmap->data + yy * bitmap->line;
1088         dest = *destPtr;
1089         src1 = *srcPtr;
1090         switch (combOp) {
1091         case 0: // or
1092           dest |= (src1 >> s1) & m2;
1093           break;
1094         case 1: // and
1095           dest &= ((0xff00 | src1) >> s1) | m1;
1096           break;
1097         case 2: // xor
1098           dest ^= (src1 >> s1) & m2;
1099           break;
1100         case 3: // xnor
1101           dest ^= ((src1 ^ 0xff) >> s1) & m2;
1102           break;
1103         case 4: // replace
1104           dest = (dest & ~m3) | ((src1 >> s1) & m3);
1105           break;
1106         }
1107         *destPtr = dest;
1108       } else {
1109         destPtr = data + (y + yy) * line;
1110         srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
1111         dest = *destPtr;
1112         src1 = *srcPtr;
1113         switch (combOp) {
1114         case 0: // or
1115           dest |= src1 & m2;
1116           break;
1117         case 1: // and
1118           dest &= src1 | m1;
1119           break;
1120         case 2: // xor
1121           dest ^= src1 & m2;
1122           break;
1123         case 3: // xnor
1124           dest ^= (src1 ^ 0xff) & m2;
1125           break;
1126         case 4: // replace
1127           dest = (src1 & m2) | (dest & m1);
1128           break;
1129         }
1130         *destPtr = dest;
1131       }
1132
1133     // multiple bytes per line -- need to mask left side of left-most
1134     // byte and right side of right-most byte
1135     } else {
1136
1137       // left-most byte
1138       if (x >= 0) {
1139         destPtr = data + (y + yy) * line + (x >> 3);
1140         srcPtr = bitmap->data + yy * bitmap->line;
1141         src1 = *srcPtr++;
1142         dest = *destPtr;
1143         switch (combOp) {
1144         case 0: // or
1145           dest |= src1 >> s1;
1146           break;
1147         case 1: // and
1148           dest &= (0xff00 | src1) >> s1;
1149           break;
1150         case 2: // xor
1151           dest ^= src1 >> s1;
1152           break;
1153         case 3: // xnor
1154           dest ^= (src1 ^ 0xff) >> s1;
1155           break;
1156         case 4: // replace
1157           dest = (dest & (0xff << s2)) | (src1 >> s1);
1158           break;
1159         }
1160         *destPtr++ = dest;
1161         xx = x0 + 8;
1162       } else {
1163         destPtr = data + (y + yy) * line;
1164         srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
1165         src1 = *srcPtr++;
1166         xx = x0;
1167       }
1168
1169       // middle bytes
1170       for (; xx < x1 - 8; xx += 8) {
1171         dest = *destPtr;
1172         src0 = src1;
1173         src1 = *srcPtr++;
1174         src = (((src0 << 8) | src1) >> s1) & 0xff;
1175         switch (combOp) {
1176         case 0: // or
1177           dest |= src;
1178           break;
1179         case 1: // and
1180           dest &= src;
1181           break;
1182         case 2: // xor
1183           dest ^= src;
1184           break;
1185         case 3: // xnor
1186           dest ^= src ^ 0xff;
1187           break;
1188         case 4: // replace
1189           dest = src;
1190           break;
1191         }
1192         *destPtr++ = dest;
1193       }
1194
1195       // right-most byte
1196       dest = *destPtr;
1197       src0 = src1;
1198       src1 = *srcPtr++;
1199       src = (((src0 << 8) | src1) >> s1) & 0xff;
1200       switch (combOp) {
1201       case 0: // or
1202         dest |= src & m2;
1203         break;
1204       case 1: // and
1205         dest &= src | m1;
1206         break;
1207       case 2: // xor
1208         dest ^= src & m2;
1209         break;
1210       case 3: // xnor
1211         dest ^= (src ^ 0xff) & m2;
1212         break;
1213       case 4: // replace
1214         dest = (src & m2) | (dest & m1);
1215         break;
1216       }
1217       *destPtr = dest;
1218     }
1219   }
1220 }
1221
1222 //------------------------------------------------------------------------
1223 // JBIG2SymbolDict
1224 //------------------------------------------------------------------------
1225
1226 class JBIG2SymbolDict: public JBIG2Segment {
1227 public:
1228
1229   JBIG2SymbolDict(Guint segNumA, Guint sizeA);
1230   virtual ~JBIG2SymbolDict();
1231   virtual JBIG2SegmentType getType() { return jbig2SegSymbolDict; }
1232   Guint getSize() { return size; }
1233   void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
1234   JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
1235   void setGenericRegionStats(JBIG2ArithmeticDecoderStats *stats)
1236     { genericRegionStats = stats; }
1237   void setRefinementRegionStats(JBIG2ArithmeticDecoderStats *stats)
1238     { refinementRegionStats = stats; }
1239   JBIG2ArithmeticDecoderStats *getGenericRegionStats()
1240     { return genericRegionStats; }
1241   JBIG2ArithmeticDecoderStats *getRefinementRegionStats()
1242     { return refinementRegionStats; }
1243
1244 private:
1245
1246   Guint size;
1247   JBIG2Bitmap **bitmaps;
1248   JBIG2ArithmeticDecoderStats *genericRegionStats;
1249   JBIG2ArithmeticDecoderStats *refinementRegionStats;
1250 };
1251
1252 JBIG2SymbolDict::JBIG2SymbolDict(Guint segNumA, Guint sizeA):
1253   JBIG2Segment(segNumA)
1254 {
1255   size = sizeA;
1256   bitmaps = (JBIG2Bitmap **)gmalloc(size * sizeof(JBIG2Bitmap *));
1257   genericRegionStats = NULL;
1258   refinementRegionStats = NULL;
1259 }
1260
1261 JBIG2SymbolDict::~JBIG2SymbolDict() {
1262   Guint i;
1263
1264   for (i = 0; i < size; ++i) {
1265     delete bitmaps[i];
1266   }
1267   gfree(bitmaps);
1268   if (genericRegionStats) {
1269     delete genericRegionStats;
1270   }
1271   if (refinementRegionStats) {
1272     delete refinementRegionStats;
1273   }
1274 }
1275
1276 //------------------------------------------------------------------------
1277 // JBIG2PatternDict
1278 //------------------------------------------------------------------------
1279
1280 class JBIG2PatternDict: public JBIG2Segment {
1281 public:
1282
1283   JBIG2PatternDict(Guint segNumA, Guint sizeA);
1284   virtual ~JBIG2PatternDict();
1285   virtual JBIG2SegmentType getType() { return jbig2SegPatternDict; }
1286   Guint getSize() { return size; }
1287   void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
1288   JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
1289
1290 private:
1291
1292   Guint size;
1293   JBIG2Bitmap **bitmaps;
1294 };
1295
1296 JBIG2PatternDict::JBIG2PatternDict(Guint segNumA, Guint sizeA):
1297   JBIG2Segment(segNumA)
1298 {
1299   size = sizeA;
1300   bitmaps = (JBIG2Bitmap **)gmalloc(size * sizeof(JBIG2Bitmap *));
1301 }
1302
1303 JBIG2PatternDict::~JBIG2PatternDict() {
1304   Guint i;
1305
1306   for (i = 0; i < size; ++i) {
1307     delete bitmaps[i];
1308   }
1309   gfree(bitmaps);
1310 }
1311
1312 //------------------------------------------------------------------------
1313 // JBIG2CodeTable
1314 //------------------------------------------------------------------------
1315
1316 class JBIG2CodeTable: public JBIG2Segment {
1317 public:
1318
1319   JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA);
1320   virtual ~JBIG2CodeTable();
1321   virtual JBIG2SegmentType getType() { return jbig2SegCodeTable; }
1322   JBIG2HuffmanTable *getHuffTable() { return table; }
1323
1324 private:
1325
1326   JBIG2HuffmanTable *table;
1327 };
1328
1329 JBIG2CodeTable::JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA):
1330   JBIG2Segment(segNumA)
1331 {
1332   table = tableA;
1333 }
1334
1335 JBIG2CodeTable::~JBIG2CodeTable() {
1336   gfree(table);
1337 }
1338
1339 //------------------------------------------------------------------------
1340 // JBIG2Stream
1341 //------------------------------------------------------------------------
1342
1343 JBIG2Stream::JBIG2Stream(Stream *strA, Object *globalsStream):
1344   FilterStream(strA)
1345 {
1346   pageBitmap = NULL;
1347
1348   arithDecoder = new JBIG2ArithmeticDecoder();
1349   genericRegionStats = new JBIG2ArithmeticDecoderStats(1);
1350   refinementRegionStats = new JBIG2ArithmeticDecoderStats(1);
1351   iadhStats = new JBIG2ArithmeticDecoderStats(9);
1352   iadwStats = new JBIG2ArithmeticDecoderStats(9);
1353   iaexStats = new JBIG2ArithmeticDecoderStats(9);
1354   iaaiStats = new JBIG2ArithmeticDecoderStats(9);
1355   iadtStats = new JBIG2ArithmeticDecoderStats(9);
1356   iaitStats = new JBIG2ArithmeticDecoderStats(9);
1357   iafsStats = new JBIG2ArithmeticDecoderStats(9);
1358   iadsStats = new JBIG2ArithmeticDecoderStats(9);
1359   iardxStats = new JBIG2ArithmeticDecoderStats(9);
1360   iardyStats = new JBIG2ArithmeticDecoderStats(9);
1361   iardwStats = new JBIG2ArithmeticDecoderStats(9);
1362   iardhStats = new JBIG2ArithmeticDecoderStats(9);
1363   iariStats = new JBIG2ArithmeticDecoderStats(9);
1364   iaidStats = new JBIG2ArithmeticDecoderStats(1);
1365   huffDecoder = new JBIG2HuffmanDecoder();
1366   mmrDecoder = new JBIG2MMRDecoder();
1367
1368   segments = new GList();
1369   if (globalsStream->isStream()) {
1370     curStr = globalsStream->getStream();
1371     curStr->reset();
1372     arithDecoder->setStream(curStr);
1373     huffDecoder->setStream(curStr);
1374     mmrDecoder->setStream(curStr);
1375     readSegments();
1376   }
1377   globalSegments = segments;
1378
1379   segments = NULL;
1380   curStr = NULL;
1381   dataPtr = dataEnd = NULL;
1382 }
1383
1384 JBIG2Stream::~JBIG2Stream() {
1385   delete arithDecoder;
1386   delete genericRegionStats;
1387   delete refinementRegionStats;
1388   delete iadhStats;
1389   delete iadwStats;
1390   delete iaexStats;
1391   delete iaaiStats;
1392   delete iadtStats;
1393   delete iaitStats;
1394   delete iafsStats;
1395   delete iadsStats;
1396   delete iardxStats;
1397   delete iardyStats;
1398   delete iardwStats;
1399   delete iardhStats;
1400   delete iariStats;
1401   delete iaidStats;
1402   delete huffDecoder;
1403   delete mmrDecoder;
1404   if (pageBitmap) {
1405     delete pageBitmap;
1406   }
1407   if (segments) {
1408     deleteGList(segments, JBIG2Segment);
1409   }
1410   if (globalSegments) {
1411     deleteGList(globalSegments, JBIG2Segment);
1412   }
1413   delete str;
1414 }
1415
1416 void JBIG2Stream::reset() {
1417   if (pageBitmap) {
1418     delete pageBitmap;
1419     pageBitmap = NULL;
1420   }
1421   if (segments) {
1422     deleteGList(segments, JBIG2Segment);
1423   }
1424   segments = new GList();
1425
1426   curStr = str;
1427   curStr->reset();
1428   arithDecoder->setStream(curStr);
1429   huffDecoder->setStream(curStr);
1430   mmrDecoder->setStream(curStr);
1431   readSegments();
1432
1433   if (pageBitmap) {
1434     dataPtr = pageBitmap->getDataPtr();
1435     dataEnd = dataPtr + pageBitmap->getDataSize();
1436   } else {
1437     dataPtr = NULL;
1438   }
1439 }
1440
1441 int JBIG2Stream::getChar() {
1442   if (dataPtr && dataPtr < dataEnd) {
1443     return (*dataPtr++ ^ 0xff) & 0xff;
1444   }
1445   return EOF;
1446 }
1447
1448 int JBIG2Stream::lookChar() {
1449   if (dataPtr && dataPtr < dataEnd) {
1450     return (*dataPtr ^ 0xff) & 0xff;
1451   }
1452   return EOF;
1453 }
1454
1455 GString *JBIG2Stream::getPSFilter(char *indent) {
1456   return NULL;
1457 }
1458
1459 GBool JBIG2Stream::isBinary(GBool last) {
1460   return str->isBinary(gTrue);
1461 }
1462
1463 void JBIG2Stream::readSegments() {
1464   Guint segNum, segFlags, segType, page, segLength;
1465   Guint refFlags, nRefSegs;
1466   Guint *refSegs;
1467   int c1, c2, c3;
1468   Guint i;
1469
1470   while (readULong(&segNum)) {
1471
1472     // segment header flags
1473     if (!readUByte(&segFlags)) {
1474       goto eofError1;
1475     }
1476     segType = segFlags & 0x3f;
1477
1478     // referred-to segment count and retention flags
1479     if (!readUByte(&refFlags)) {
1480       goto eofError1;
1481     }
1482     nRefSegs = refFlags >> 5;
1483     if (nRefSegs == 7) {
1484       if ((c1 = curStr->getChar()) == EOF ||
1485           (c2 = curStr->getChar()) == EOF ||
1486           (c3 = curStr->getChar()) == EOF) {
1487         goto eofError1;
1488       }
1489       refFlags = (refFlags << 24) | (c1 << 16) | (c2 << 8) | c3;
1490       nRefSegs = refFlags & 0x1fffffff;
1491       for (i = 0; i < (nRefSegs + 9) >> 3; ++i) {
1492         c1 = curStr->getChar();
1493       }
1494     }
1495
1496     // referred-to segment numbers
1497     refSegs = (Guint *)gmalloc(nRefSegs * sizeof(Guint));
1498     if (segNum <= 256) {
1499       for (i = 0; i < nRefSegs; ++i) {
1500         if (!readUByte(&refSegs[i])) {
1501           goto eofError2;
1502         }
1503       }
1504     } else if (segNum <= 65536) {
1505       for (i = 0; i < nRefSegs; ++i) {
1506         if (!readUWord(&refSegs[i])) {
1507           goto eofError2;
1508         }
1509       }
1510     } else {
1511       for (i = 0; i < nRefSegs; ++i) {
1512         if (!readULong(&refSegs[i])) {
1513           goto eofError2;
1514         }
1515       }
1516     }
1517
1518     // segment page association
1519     if (segFlags & 0x40) {
1520       if (!readULong(&page)) {
1521         goto eofError2;
1522       }
1523     } else {
1524       if (!readUByte(&page)) {
1525         goto eofError2;
1526       }
1527     }
1528
1529     // segment data length
1530     if (!readULong(&segLength)) {
1531       goto eofError2;
1532     }
1533
1534     // read the segment data
1535     switch (segType) {
1536     case 0:
1537       readSymbolDictSeg(segNum, segLength, refSegs, nRefSegs);
1538       break;
1539     case 4:
1540       readTextRegionSeg(segNum, gFalse, gFalse, segLength, refSegs, nRefSegs);
1541       break;
1542     case 6:
1543       readTextRegionSeg(segNum, gTrue, gFalse, segLength, refSegs, nRefSegs);
1544       break;
1545     case 7:
1546       readTextRegionSeg(segNum, gTrue, gTrue, segLength, refSegs, nRefSegs);
1547       break;
1548     case 16:
1549       readPatternDictSeg(segNum, segLength);
1550       break;
1551     case 20:
1552       readHalftoneRegionSeg(segNum, gFalse, gFalse, segLength,
1553                             refSegs, nRefSegs);
1554       break;
1555     case 22:
1556       readHalftoneRegionSeg(segNum, gTrue, gFalse, segLength,
1557                             refSegs, nRefSegs);
1558       break;
1559     case 23:
1560       readHalftoneRegionSeg(segNum, gTrue, gTrue, segLength,
1561                             refSegs, nRefSegs);
1562       break;
1563     case 36:
1564       readGenericRegionSeg(segNum, gFalse, gFalse, segLength);
1565       break;
1566     case 38:
1567       readGenericRegionSeg(segNum, gTrue, gFalse, segLength);
1568       break;
1569     case 39:
1570       readGenericRegionSeg(segNum, gTrue, gTrue, segLength);
1571       break;
1572     case 40:
1573       readGenericRefinementRegionSeg(segNum, gFalse, gFalse, segLength,
1574                                      refSegs, nRefSegs);
1575       break;
1576     case 42:
1577       readGenericRefinementRegionSeg(segNum, gTrue, gFalse, segLength,
1578                                      refSegs, nRefSegs);
1579       break;
1580     case 43:
1581       readGenericRefinementRegionSeg(segNum, gTrue, gTrue, segLength,
1582                                      refSegs, nRefSegs);
1583       break;
1584     case 48:
1585       readPageInfoSeg(segLength);
1586       break;
1587     case 50:
1588       readEndOfStripeSeg(segLength);
1589       break;
1590     case 52:
1591       readProfilesSeg(segLength);
1592       break;
1593     case 53:
1594       readCodeTableSeg(segNum, segLength);
1595       break;
1596     case 62:
1597       readExtensionSeg(segLength);
1598       break;
1599     default:
1600       error(getPos(), "Unknown segment type in JBIG2 stream");
1601       for (i = 0; i < segLength; ++i) {
1602         if ((c1 = curStr->getChar()) == EOF) {
1603           goto eofError2;
1604         }
1605       }
1606       break;
1607     }
1608
1609     gfree(refSegs);
1610   }
1611
1612   return;
1613
1614  eofError2:
1615   gfree(refSegs);
1616  eofError1:
1617   error(getPos(), "Unexpected EOF in JBIG2 stream");
1618 }
1619
1620 void JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
1621                                     Guint *refSegs, Guint nRefSegs) {
1622   JBIG2SymbolDict *symbolDict;
1623   JBIG2HuffmanTable *huffDHTable, *huffDWTable;
1624   JBIG2HuffmanTable *huffBMSizeTable, *huffAggInstTable;
1625   JBIG2Segment *seg;
1626   GList *codeTables;
1627   JBIG2SymbolDict *inputSymbolDict;
1628   Guint flags, sdTemplate, sdrTemplate, huff, refAgg;
1629   Guint huffDH, huffDW, huffBMSize, huffAggInst;
1630   Guint contextUsed, contextRetained;
1631   int sdATX[4], sdATY[4], sdrATX[2], sdrATY[2];
1632   Guint numExSyms, numNewSyms, numInputSyms, symCodeLen;
1633   JBIG2Bitmap **bitmaps;
1634   JBIG2Bitmap *collBitmap, *refBitmap;
1635   Guint *symWidths;
1636   Guint symHeight, symWidth, totalWidth, x, symID;
1637   int dh, dw, refAggNum, refDX, refDY, bmSize;
1638   GBool ex;
1639   int run, cnt;
1640   Guint i, j, k;
1641   Guchar *p;
1642
1643   // symbol dictionary flags
1644   if (!readUWord(&flags)) {
1645     goto eofError;
1646   }
1647   sdTemplate = (flags >> 10) & 3;
1648   sdrTemplate = (flags >> 12) & 1;
1649   huff = flags & 1;
1650   refAgg = (flags >> 1) & 1;
1651   huffDH = (flags >> 2) & 3;
1652   huffDW = (flags >> 4) & 3;
1653   huffBMSize = (flags >> 6) & 1;
1654   huffAggInst = (flags >> 7) & 1;
1655   contextUsed = (flags >> 8) & 1;
1656   contextRetained = (flags >> 9) & 1;
1657
1658   // symbol dictionary AT flags
1659   if (!huff) {
1660     if (sdTemplate == 0) {
1661       if (!readByte(&sdATX[0]) ||
1662           !readByte(&sdATY[0]) ||
1663           !readByte(&sdATX[1]) ||
1664           !readByte(&sdATY[1]) ||
1665           !readByte(&sdATX[2]) ||
1666           !readByte(&sdATY[2]) ||
1667           !readByte(&sdATX[3]) ||
1668           !readByte(&sdATY[3])) {
1669         goto eofError;
1670       }
1671     } else {
1672       if (!readByte(&sdATX[0]) ||
1673           !readByte(&sdATY[0])) {
1674         goto eofError;
1675       }
1676     }
1677   }
1678
1679   // symbol dictionary refinement AT flags
1680   if (refAgg && !sdrTemplate) {
1681     if (!readByte(&sdrATX[0]) ||
1682         !readByte(&sdrATY[0]) ||
1683         !readByte(&sdrATX[1]) ||
1684         !readByte(&sdrATY[1])) {
1685       goto eofError;
1686     }
1687   }
1688
1689   // SDNUMEXSYMS and SDNUMNEWSYMS
1690   if (!readULong(&numExSyms) || !readULong(&numNewSyms)) {
1691     goto eofError;
1692   }
1693
1694   // get referenced segments: input symbol dictionaries and code tables
1695   codeTables = new GList();
1696   numInputSyms = 0;
1697   for (i = 0; i < nRefSegs; ++i) {
1698     seg = findSegment(refSegs[i]);
1699     if (seg->getType() == jbig2SegSymbolDict) {
1700       numInputSyms += ((JBIG2SymbolDict *)seg)->getSize();
1701     } else if (seg->getType() == jbig2SegCodeTable) {
1702       codeTables->append(seg);
1703     }
1704   }
1705
1706   // compute symbol code length
1707   symCodeLen = 0;
1708   i = 1;
1709   while (i < numInputSyms + numNewSyms) {
1710     ++symCodeLen;
1711     i <<= 1;
1712   }
1713
1714   // get the input symbol bitmaps
1715   bitmaps = (JBIG2Bitmap **)gmalloc((numInputSyms + numNewSyms) *
1716                                     sizeof(JBIG2Bitmap *));
1717   k = 0;
1718   inputSymbolDict = NULL;
1719   for (i = 0; i < nRefSegs; ++i) {
1720     seg = findSegment(refSegs[i]);
1721     if (seg->getType() == jbig2SegSymbolDict) {
1722       inputSymbolDict = (JBIG2SymbolDict *)seg;
1723       for (j = 0; j < inputSymbolDict->getSize(); ++j) {
1724         bitmaps[k++] = inputSymbolDict->getBitmap(j);
1725       }
1726     }
1727   }
1728
1729   // get the Huffman tables
1730   huffDHTable = huffDWTable = NULL; // make gcc happy
1731   huffBMSizeTable = huffAggInstTable = NULL; // make gcc happy
1732   i = 0;
1733   if (huff) {
1734     if (huffDH == 0) {
1735       huffDHTable = huffTableD;
1736     } else if (huffDH == 1) {
1737       huffDHTable = huffTableE;
1738     } else {
1739       huffDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1740     }
1741     if (huffDW == 0) {
1742       huffDWTable = huffTableB;
1743     } else if (huffDW == 1) {
1744       huffDWTable = huffTableC;
1745     } else {
1746       huffDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1747     }
1748     if (huffBMSize == 0) {
1749       huffBMSizeTable = huffTableA;
1750     } else {
1751       huffBMSizeTable =
1752           ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1753     }
1754     if (huffAggInst == 0) {
1755       huffAggInstTable = huffTableA;
1756     } else {
1757       huffAggInstTable =
1758           ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1759     }
1760   }
1761   delete codeTables;
1762
1763   // set up the Huffman decoder
1764   if (huff) {
1765     huffDecoder->reset();
1766
1767   // set up the arithmetic decoder
1768   } else {
1769     if (contextUsed && inputSymbolDict) {
1770       resetGenericStats(sdTemplate, inputSymbolDict->getGenericRegionStats());
1771       if (refAgg) {
1772         resetRefinementStats(sdrTemplate,
1773                              inputSymbolDict->getRefinementRegionStats());
1774       }
1775     } else {
1776       resetGenericStats(sdTemplate, NULL);
1777       if (refAgg) {
1778         resetRefinementStats(sdrTemplate, NULL);
1779       }
1780     }
1781     resetIntStats(symCodeLen);
1782     arithDecoder->start();
1783   }
1784
1785   // allocate symbol widths storage
1786   symWidths = NULL;
1787   if (huff && !refAgg) {
1788     symWidths = (Guint *)gmalloc(numNewSyms * sizeof(Guint));
1789   }
1790
1791   symHeight = 0;
1792   i = 0;
1793   while (i < numNewSyms) {
1794
1795     // read the height class delta height
1796     if (huff) {
1797       huffDecoder->decodeInt(&dh, huffDHTable);
1798     } else {
1799       arithDecoder->decodeInt(&dh, iadhStats);
1800     }
1801     symHeight += dh;
1802     symWidth = 0;
1803     totalWidth = 0;
1804     j = i;
1805
1806     // read the symbols in this height class
1807     while (1) {
1808
1809       // read the delta width
1810       if (huff) {
1811         if (!huffDecoder->decodeInt(&dw, huffDWTable)) {
1812           break;
1813         }
1814       } else {
1815         if (!arithDecoder->decodeInt(&dw, iadwStats)) {
1816           break;
1817         }
1818       }
1819       symWidth += dw;
1820
1821       // using a collective bitmap, so don't read a bitmap here
1822       if (huff && !refAgg) {
1823         symWidths[i] = symWidth;
1824         totalWidth += symWidth;
1825
1826       // refinement/aggregate coding
1827       } else if (refAgg) {
1828         if (huff) {
1829           if (!huffDecoder->decodeInt(&refAggNum, huffAggInstTable)) {
1830             break;
1831           }
1832         } else {
1833           if (!arithDecoder->decodeInt(&refAggNum, iaaiStats)) {
1834             break;
1835           }
1836         }
1837         if (refAggNum == 1) {
1838           if (huff) {
1839             symID = huffDecoder->readBits(symCodeLen);
1840             huffDecoder->decodeInt(&refDX, huffTableO);
1841             huffDecoder->decodeInt(&refDY, huffTableO);
1842             huffDecoder->decodeInt(&bmSize, huffTableA);
1843             huffDecoder->reset();
1844             arithDecoder->start();
1845           } else {
1846             symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
1847             arithDecoder->decodeInt(&refDX, iardxStats);
1848             arithDecoder->decodeInt(&refDY, iardyStats);
1849           }
1850           refBitmap = bitmaps[symID];
1851           bitmaps[numInputSyms + i] =
1852               readGenericRefinementRegion(symWidth, symHeight,
1853                                           sdrTemplate, gFalse,
1854                                           refBitmap, refDX, refDY,
1855                                           sdrATX, sdrATY);
1856           //~ do we need to use the bmSize value here (in Huffman mode)?
1857         } else {
1858           bitmaps[numInputSyms + i] =
1859               readTextRegion(huff, gTrue, symWidth, symHeight,
1860                              refAggNum, 0, numInputSyms + i, NULL,
1861                              symCodeLen, bitmaps, 0, 0, 0, 1, 0,
1862                              huffTableF, huffTableH, huffTableK, huffTableO,
1863                              huffTableO, huffTableO, huffTableO, huffTableA,
1864                              sdrTemplate, sdrATX, sdrATY);
1865         }
1866
1867       // non-ref/agg coding
1868       } else {
1869         bitmaps[numInputSyms + i] =
1870             readGenericBitmap(gFalse, symWidth, symHeight,
1871                               sdTemplate, gFalse, gFalse, NULL,
1872                               sdATX, sdATY, 0);
1873       }
1874
1875       ++i;
1876     }
1877
1878     // read the collective bitmap
1879     if (huff && !refAgg) {
1880       huffDecoder->decodeInt(&bmSize, huffBMSizeTable);
1881       if (huff) {
1882         huffDecoder->reset();
1883       }
1884       if (bmSize == 0) {
1885         collBitmap = new JBIG2Bitmap(0, totalWidth, symHeight);
1886         bmSize = symHeight * ((totalWidth + 7) >> 3);
1887         p = collBitmap->getDataPtr();
1888         for (k = 0; k < (Guint)bmSize; ++k) {
1889           *p++ = str->getChar();
1890         }
1891       } else {
1892         collBitmap = readGenericBitmap(gTrue, totalWidth, symHeight,
1893                                        0, gFalse, gFalse, NULL, NULL, NULL,
1894                                        bmSize);
1895       }
1896       x = 0;
1897       for (; j < i; ++j) {
1898         bitmaps[numInputSyms + j] =
1899             collBitmap->getSlice(x, 0, symWidths[j], symHeight);
1900         x += symWidths[j];
1901       }
1902       delete collBitmap;
1903     }
1904   }
1905
1906   // create the symbol dict object
1907   symbolDict = new JBIG2SymbolDict(segNum, numExSyms);
1908
1909   // exported symbol list
1910   i = j = 0;
1911   ex = gFalse;
1912   while (i < numInputSyms + numNewSyms) {
1913     if (huff) {
1914       huffDecoder->decodeInt(&run, huffTableA);
1915     } else {
1916       arithDecoder->decodeInt(&run, iaexStats);
1917     }
1918     if (ex) {
1919       for (cnt = 0; cnt < run; ++cnt) {
1920         symbolDict->setBitmap(j++, bitmaps[i++]->copy());
1921       }
1922     } else {
1923       i += run;
1924     }
1925     ex = !ex;
1926   }
1927   
1928   for (i = 0; i < numNewSyms; ++i) {
1929     delete bitmaps[numInputSyms + i];
1930   }
1931   gfree(bitmaps);
1932   if (symWidths) {
1933     gfree(symWidths);
1934   }
1935
1936   // save the arithmetic decoder stats
1937   if (!huff && contextRetained) {
1938     symbolDict->setGenericRegionStats(genericRegionStats->copy());
1939     if (refAgg) {
1940       symbolDict->setRefinementRegionStats(refinementRegionStats->copy());
1941     }
1942   }
1943
1944   // store the new symbol dict
1945   segments->append(symbolDict);
1946
1947   return;
1948
1949  eofError:
1950   error(getPos(), "Unexpected EOF in JBIG2 stream");
1951 }
1952
1953 void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
1954                                     GBool lossless, Guint length,
1955                                     Guint *refSegs, Guint nRefSegs) {
1956   JBIG2Bitmap *bitmap;
1957   JBIG2HuffmanTable runLengthTab[36];
1958   JBIG2HuffmanTable *symCodeTab;
1959   JBIG2HuffmanTable *huffFSTable, *huffDSTable, *huffDTTable;
1960   JBIG2HuffmanTable *huffRDWTable, *huffRDHTable;
1961   JBIG2HuffmanTable *huffRDXTable, *huffRDYTable, *huffRSizeTable;
1962   JBIG2Segment *seg;
1963   GList *codeTables;
1964   JBIG2SymbolDict *symbolDict;
1965   JBIG2Bitmap **syms;
1966   Guint w, h, x, y, segInfoFlags, extCombOp;
1967   Guint flags, huff, refine, logStrips, refCorner, transposed;
1968   Guint combOp, defPixel, sOffset, templ;
1969   Guint huffFlags, huffFS, huffDS, huffDT;
1970   Guint huffRDW, huffRDH, huffRDX, huffRDY, huffRSize;
1971   Guint numInstances, numSyms, symCodeLen;
1972   int atx[2], aty[2];
1973   Guint i, k, kk;
1974   int j;
1975
1976   // region segment info field
1977   if (!readULong(&w) || !readULong(&h) ||
1978       !readULong(&x) || !readULong(&y) ||
1979       !readUByte(&segInfoFlags)) {
1980     goto eofError;
1981   }
1982   extCombOp = segInfoFlags & 7;
1983
1984   // rest of the text region header
1985   if (!readUWord(&flags)) {
1986     goto eofError;
1987   }
1988   huff = flags & 1;
1989   refine = (flags >> 1) & 1;
1990   logStrips = (flags >> 2) & 3;
1991   refCorner = (flags >> 4) & 3;
1992   transposed = (flags >> 6) & 1;
1993   combOp = (flags >> 7) & 3;
1994   defPixel = (flags >> 9) & 1;
1995   sOffset = (flags >> 10) & 0x1f;
1996   templ = (flags >> 15) & 1;
1997   huffFS = huffDS = huffDT = 0; // make gcc happy
1998   huffRDW = huffRDH = huffRDX = huffRDY = huffRSize = 0; // make gcc happy
1999   if (huff) {
2000     if (!readUWord(&huffFlags)) {
2001       goto eofError;
2002     }
2003     huffFS = huffFlags & 3;
2004     huffDS = (huffFlags >> 2) & 3;
2005     huffDT = (huffFlags >> 4) & 3;
2006     huffRDW = (huffFlags >> 6) & 3;
2007     huffRDH = (huffFlags >> 8) & 3;
2008     huffRDX = (huffFlags >> 10) & 3;
2009     huffRDY = (huffFlags >> 12) & 3;
2010     huffRSize = (huffFlags >> 14) & 1;
2011   }
2012   if (refine && templ == 0) {
2013     if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
2014         !readByte(&atx[1]) || !readByte(&aty[1])) {
2015       goto eofError;
2016     }
2017   }
2018   if (!readULong(&numInstances)) {
2019     goto eofError;
2020   }
2021
2022   // get symbol dictionaries and tables
2023   codeTables = new GList();
2024   numSyms = 0;
2025   for (i = 0; i < nRefSegs; ++i) {
2026     seg = findSegment(refSegs[i]);
2027     if (seg->getType() == jbig2SegSymbolDict) {
2028       numSyms += ((JBIG2SymbolDict *)seg)->getSize();
2029     } else if (seg->getType() == jbig2SegCodeTable) {
2030       codeTables->append(seg);
2031     }
2032   }
2033   symCodeLen = 0;
2034   i = 1;
2035   while (i < numSyms) {
2036     ++symCodeLen;
2037     i <<= 1;
2038   }
2039
2040   // get the symbol bitmaps
2041   syms = (JBIG2Bitmap **)gmalloc(numSyms * sizeof(JBIG2Bitmap *));
2042   kk = 0;
2043   for (i = 0; i < nRefSegs; ++i) {
2044     seg = findSegment(refSegs[i]);
2045     if (seg->getType() == jbig2SegSymbolDict) {
2046       symbolDict = (JBIG2SymbolDict *)seg;
2047       for (k = 0; k < symbolDict->getSize(); ++k) {
2048         syms[kk++] = symbolDict->getBitmap(k);
2049       }
2050     }
2051   }
2052
2053   // get the Huffman tables
2054   huffFSTable = huffDSTable = huffDTTable = NULL; // make gcc happy
2055   huffRDWTable = huffRDHTable = NULL; // make gcc happy
2056   huffRDXTable = huffRDYTable = huffRSizeTable = NULL; // make gcc happy
2057   i = 0;
2058   if (huff) {
2059     if (huffFS == 0) {
2060       huffFSTable = huffTableF;
2061     } else if (huffFS == 1) {
2062       huffFSTable = huffTableG;
2063     } else {
2064       huffFSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2065     }
2066     if (huffDS == 0) {
2067       huffDSTable = huffTableH;
2068     } else if (huffDS == 1) {
2069       huffDSTable = huffTableI;
2070     } else if (huffDS == 2) {
2071       huffDSTable = huffTableJ;
2072     } else {
2073       huffDSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2074     }
2075     if (huffDT == 0) {
2076       huffDTTable = huffTableK;
2077     } else if (huffDT == 1) {
2078       huffDTTable = huffTableL;
2079     } else if (huffDT == 2) {
2080       huffDTTable = huffTableM;
2081     } else {
2082       huffDTTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2083     }
2084     if (huffRDW == 0) {
2085       huffRDWTable = huffTableN;
2086     } else if (huffRDW == 1) {
2087       huffRDWTable = huffTableO;
2088     } else {
2089       huffRDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2090     }
2091     if (huffRDH == 0) {
2092       huffRDHTable = huffTableN;
2093     } else if (huffRDH == 1) {
2094       huffRDHTable = huffTableO;
2095     } else {
2096       huffRDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2097     }
2098     if (huffRDX == 0) {
2099       huffRDXTable = huffTableN;
2100     } else if (huffRDX == 1) {
2101       huffRDXTable = huffTableO;
2102     } else {
2103       huffRDXTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2104     }
2105     if (huffRDY == 0) {
2106       huffRDYTable = huffTableN;
2107     } else if (huffRDY == 1) {
2108       huffRDYTable = huffTableO;
2109     } else {
2110       huffRDYTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2111     }
2112     if (huffRSize == 0) {
2113       huffRSizeTable = huffTableA;
2114     } else {
2115       huffRSizeTable =
2116           ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2117     }
2118   }
2119   delete codeTables;
2120
2121   // symbol ID Huffman decoding table
2122   if (huff) {
2123     huffDecoder->reset();
2124     for (i = 0; i < 32; ++i) {
2125       runLengthTab[i].val = i;
2126       runLengthTab[i].prefixLen = huffDecoder->readBits(4);
2127       runLengthTab[i].rangeLen = 0;
2128     }
2129     runLengthTab[32].val = 0x103;
2130     runLengthTab[32].prefixLen = huffDecoder->readBits(4);
2131     runLengthTab[32].rangeLen = 2;
2132     runLengthTab[33].val = 0x203;
2133     runLengthTab[33].prefixLen = huffDecoder->readBits(4);
2134     runLengthTab[33].rangeLen = 3;
2135     runLengthTab[34].val = 0x20b;
2136     runLengthTab[34].prefixLen = huffDecoder->readBits(4);
2137     runLengthTab[34].rangeLen = 7;
2138     runLengthTab[35].rangeLen = jbig2HuffmanEOT;
2139     huffDecoder->buildTable(runLengthTab, 35);
2140     symCodeTab = (JBIG2HuffmanTable *)gmalloc((numSyms + 1) *
2141                                               sizeof(JBIG2HuffmanTable));
2142     for (i = 0; i < numSyms; ++i) {
2143       symCodeTab[i].val = i;
2144       symCodeTab[i].rangeLen = 0;
2145     }
2146     i = 0;
2147     while (i < numSyms) {
2148       huffDecoder->decodeInt(&j, runLengthTab);
2149       if (j > 0x200) {
2150         for (j -= 0x200; j && i < numSyms; --j) {
2151           symCodeTab[i++].prefixLen = 0;
2152         }
2153       } else if (j > 0x100) {
2154         for (j -= 0x100; j && i < numSyms; --j) {
2155           symCodeTab[i].prefixLen = symCodeTab[i-1].prefixLen;
2156           ++i;
2157         }
2158       } else {
2159         symCodeTab[i++].prefixLen = j;
2160       }
2161
2162     }
2163     symCodeTab[numSyms].rangeLen = jbig2HuffmanEOT;
2164     huffDecoder->buildTable(symCodeTab, numSyms);
2165     huffDecoder->reset();
2166
2167   // set up the arithmetic decoder
2168   } else {
2169     symCodeTab = NULL;
2170     resetIntStats(symCodeLen);
2171     if (refine) {
2172       resetRefinementStats(templ, NULL);
2173     }
2174     arithDecoder->start();
2175   }
2176
2177   bitmap = readTextRegion(huff, refine, w, h, numInstances,
2178                           logStrips, numSyms, symCodeTab, symCodeLen, syms,
2179                           defPixel, combOp, transposed, refCorner, sOffset,
2180                           huffFSTable, huffDSTable, huffDTTable,
2181                           huffRDWTable, huffRDHTable,
2182                           huffRDXTable, huffRDYTable, huffRSizeTable,
2183                           templ, atx, aty);
2184
2185   gfree(syms);
2186
2187   // combine the region bitmap into the page bitmap
2188   if (imm) {
2189     if (pageH == 0xffffffff && y + h > curPageH) {
2190       pageBitmap->expand(y + h, pageDefPixel);
2191     }
2192     pageBitmap->combine(bitmap, x, y, extCombOp);
2193     delete bitmap;
2194
2195   // store the region bitmap
2196   } else {
2197     bitmap->setSegNum(segNum);
2198     segments->append(bitmap);
2199   }
2200
2201   // clean up the Huffman decoder
2202   if (huff) {
2203     gfree(symCodeTab);
2204   }
2205
2206   return;
2207
2208  eofError:
2209   error(getPos(), "Unexpected EOF in JBIG2 stream");
2210 }
2211
2212 JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
2213                                          int w, int h,
2214                                          Guint numInstances,
2215                                          Guint logStrips,
2216                                          int numSyms,
2217                                          JBIG2HuffmanTable *symCodeTab,
2218                                          Guint symCodeLen,
2219                                          JBIG2Bitmap **syms,
2220                                          Guint defPixel, Guint combOp,
2221                                          Guint transposed, Guint refCorner,
2222                                          Guint sOffset,
2223                                          JBIG2HuffmanTable *huffFSTable,
2224                                          JBIG2HuffmanTable *huffDSTable,
2225                                          JBIG2HuffmanTable *huffDTTable,
2226                                          JBIG2HuffmanTable *huffRDWTable,
2227                                          JBIG2HuffmanTable *huffRDHTable,
2228                                          JBIG2HuffmanTable *huffRDXTable,
2229                                          JBIG2HuffmanTable *huffRDYTable,
2230                                          JBIG2HuffmanTable *huffRSizeTable,
2231                                          Guint templ,
2232                                          int *atx, int *aty) {
2233   JBIG2Bitmap *bitmap;
2234   JBIG2Bitmap *symbolBitmap;
2235   Guint strips;
2236   int t, dt, tt, s, ds, sFirst, j;
2237   int rdw, rdh, rdx, rdy, ri, refDX, refDY, bmSize;
2238   Guint symID, inst, bw, bh;
2239
2240   strips = 1 << logStrips;
2241
2242   // allocate the bitmap
2243   bitmap = new JBIG2Bitmap(0, w, h);
2244   if (defPixel) {
2245     bitmap->clearToOne();
2246   } else {
2247     bitmap->clearToZero();
2248   }
2249
2250   // decode initial T value
2251   if (huff) {
2252     huffDecoder->decodeInt(&t, huffDTTable);
2253   } else {
2254     arithDecoder->decodeInt(&t, iadtStats);
2255   }
2256   t *= -strips;
2257
2258   inst = 0;
2259   sFirst = 0;
2260   while (inst < numInstances) {
2261
2262     // decode delta-T
2263     if (huff) {
2264       huffDecoder->decodeInt(&dt, huffDTTable);
2265     } else {
2266       arithDecoder->decodeInt(&dt, iadtStats);
2267     }
2268     t += dt * strips;
2269
2270     // first S value
2271     if (huff) {
2272       huffDecoder->decodeInt(&ds, huffFSTable);
2273     } else {
2274       arithDecoder->decodeInt(&ds, iafsStats);
2275     }
2276     sFirst += ds;
2277     s = sFirst;
2278
2279     // read the instances
2280     while (1) {
2281
2282       // T value
2283       if (strips == 1) {
2284         dt = 0;
2285       } else if (huff) {
2286         dt = huffDecoder->readBits(logStrips);
2287       } else {
2288         arithDecoder->decodeInt(&dt, iaitStats);
2289       }
2290       tt = t + dt;
2291
2292       // symbol ID
2293       if (huff) {
2294         if (symCodeTab) {
2295           huffDecoder->decodeInt(&j, symCodeTab);
2296           symID = (Guint)j;
2297         } else {
2298           symID = huffDecoder->readBits(symCodeLen);
2299         }
2300       } else {
2301         symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
2302       }
2303
2304       // get the symbol bitmap
2305       symbolBitmap = NULL;
2306       if (refine) {
2307         if (huff) {
2308           ri = (int)huffDecoder->readBit();
2309         } else {
2310           arithDecoder->decodeInt(&ri, iariStats);
2311         }
2312       } else {
2313         ri = 0;
2314       }
2315       if (ri) {
2316         if (huff) {
2317           huffDecoder->decodeInt(&rdw, huffRDWTable);
2318           huffDecoder->decodeInt(&rdh, huffRDHTable);
2319           huffDecoder->decodeInt(&rdx, huffRDXTable);
2320           huffDecoder->decodeInt(&rdy, huffRDYTable);
2321           huffDecoder->decodeInt(&bmSize, huffRSizeTable);
2322           huffDecoder->reset();
2323           arithDecoder->start();
2324         } else {
2325           arithDecoder->decodeInt(&rdw, iardwStats);
2326           arithDecoder->decodeInt(&rdh, iardhStats);
2327           arithDecoder->decodeInt(&rdx, iardxStats);
2328           arithDecoder->decodeInt(&rdy, iardyStats);
2329         }
2330         refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
2331         refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
2332
2333         symbolBitmap =
2334           readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
2335                                       rdh + syms[symID]->getHeight(),
2336                                       templ, gFalse, syms[symID],
2337                                       refDX, refDY, atx, aty);
2338         //~ do we need to use the bmSize value here (in Huffman mode)?
2339       } else {
2340         symbolBitmap = syms[symID];
2341       }
2342
2343       // combine the symbol bitmap into the region bitmap
2344       //~ something is wrong here - refCorner shouldn't degenerate into
2345       //~   two cases
2346       bw = symbolBitmap->getWidth() - 1;
2347       bh = symbolBitmap->getHeight() - 1;
2348       if (transposed) {
2349         switch (refCorner) {
2350         case 0: // bottom left
2351           bitmap->combine(symbolBitmap, tt, s, combOp);
2352           break;
2353         case 1: // top left
2354           bitmap->combine(symbolBitmap, tt, s, combOp);
2355           break;
2356         case 2: // bottom right
2357           bitmap->combine(symbolBitmap, tt - bw, s, combOp);
2358           break;
2359         case 3: // top right
2360           bitmap->combine(symbolBitmap, tt - bw, s, combOp);
2361           break;
2362         }
2363         s += bh;
2364       } else {
2365         switch (refCorner) {
2366         case 0: // bottom left
2367           bitmap->combine(symbolBitmap, s, tt - bh, combOp);
2368           break;
2369         case 1: // top left
2370           bitmap->combine(symbolBitmap, s, tt, combOp);
2371           break;
2372         case 2: // bottom right
2373           bitmap->combine(symbolBitmap, s, tt - bh, combOp);
2374           break;
2375         case 3: // top right
2376           bitmap->combine(symbolBitmap, s, tt, combOp);
2377           break;
2378         }
2379         s += bw;
2380       }
2381       if (ri) {
2382         delete symbolBitmap;
2383       }
2384
2385       // next instance
2386       ++inst;
2387
2388       // next S value
2389       if (huff) {
2390         if (!huffDecoder->decodeInt(&ds, huffDSTable)) {
2391           break;
2392         }
2393       } else {
2394         if (!arithDecoder->decodeInt(&ds, iadsStats)) {
2395           break;
2396         }
2397       }
2398       s += sOffset + ds;
2399     }
2400   }
2401
2402   return bitmap;
2403 }
2404
2405 void JBIG2Stream::readPatternDictSeg(Guint segNum, Guint length) {
2406   JBIG2PatternDict *patternDict;
2407   JBIG2Bitmap *bitmap;
2408   Guint flags, patternW, patternH, grayMax, templ, mmr;
2409   int atx[4], aty[4];
2410   Guint i, x;
2411
2412   // halftone dictionary flags, pattern width and height, max gray value
2413   if (!readUByte(&flags) ||
2414       !readUByte(&patternW) ||
2415       !readUByte(&patternH) ||
2416       !readULong(&grayMax)) {
2417     goto eofError;
2418   }
2419   templ = (flags >> 1) & 3;
2420   mmr = flags & 1;
2421
2422   // set up the arithmetic decoder
2423   if (!mmr) {
2424     resetGenericStats(templ, NULL);
2425     arithDecoder->start();
2426   }
2427
2428   // read the bitmap
2429   atx[0] = -patternW; aty[0] =  0;
2430   atx[1] = -3;        aty[1] = -1;
2431   atx[2] =  2;        aty[2] = -2;
2432   atx[3] = -2;        aty[3] = -2;
2433   bitmap = readGenericBitmap(mmr, (grayMax + 1) * patternW, patternH,
2434                              templ, gFalse, gFalse, NULL,
2435                              atx, aty, length - 7);
2436
2437   // create the pattern dict object
2438   patternDict = new JBIG2PatternDict(segNum, grayMax + 1);
2439
2440   // split up the bitmap
2441   x = 0;
2442   for (i = 0; i <= grayMax; ++i) {
2443     patternDict->setBitmap(i, bitmap->getSlice(x, 0, patternW, patternH));
2444     x += patternW;
2445   }
2446
2447   // free memory
2448   delete bitmap;
2449
2450   // store the new pattern dict
2451   segments->append(patternDict);
2452
2453   return;
2454
2455  eofError:
2456   error(getPos(), "Unexpected EOF in JBIG2 stream");
2457 }
2458
2459 void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm,
2460                                         GBool lossless, Guint length,
2461                                         Guint *refSegs, Guint nRefSegs) {
2462   JBIG2Bitmap *bitmap;
2463   JBIG2Segment *seg;
2464   JBIG2PatternDict *patternDict;
2465   JBIG2Bitmap *skipBitmap;
2466   Guint *grayImg;
2467   JBIG2Bitmap *grayBitmap;
2468   JBIG2Bitmap *patternBitmap;
2469   Guint w, h, x, y, segInfoFlags, extCombOp;
2470   Guint flags, mmr, templ, enableSkip, combOp;
2471   Guint gridW, gridH, stepX, stepY, patW, patH;
2472   int atx[4], aty[4];
2473   int gridX, gridY, xx, yy, bit, j;
2474   Guint bpp, m, n, i;
2475
2476   // region segment info field
2477   if (!readULong(&w) || !readULong(&h) ||
2478       !readULong(&x) || !readULong(&y) ||
2479       !readUByte(&segInfoFlags)) {
2480     goto eofError;
2481   }
2482   extCombOp = segInfoFlags & 7;
2483
2484   // rest of the halftone region header
2485   if (!readUByte(&flags)) {
2486     goto eofError;
2487   }
2488   mmr = flags & 1;
2489   templ = (flags >> 1) & 3;
2490   enableSkip = (flags >> 3) & 1;
2491   combOp = (flags >> 4) & 7;
2492   if (!readULong(&gridW) || !readULong(&gridH) ||
2493       !readLong(&gridX) || !readLong(&gridY) ||
2494       !readUWord(&stepX) || !readUWord(&stepY)) {
2495     goto eofError;
2496   }
2497
2498   // get pattern dictionary
2499   if (nRefSegs != 1) {
2500     error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
2501     return;
2502   }
2503   seg = findSegment(refSegs[0]);
2504   if (seg->getType() != jbig2SegPatternDict) {
2505     error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
2506     return;
2507   }
2508   patternDict = (JBIG2PatternDict *)seg;
2509   bpp = 0;
2510   i = 1;
2511   while (i < patternDict->getSize()) {
2512     ++bpp;
2513     i <<= 1;
2514   }
2515   patW = patternDict->getBitmap(0)->getWidth();
2516   patH = patternDict->getBitmap(0)->getHeight();
2517
2518   // set up the arithmetic decoder
2519   if (!mmr) {
2520     resetGenericStats(templ, NULL);
2521     arithDecoder->start();
2522   }
2523
2524   // allocate the bitmap
2525   bitmap = new JBIG2Bitmap(segNum, w, h);
2526   if (flags & 0x80) { // HDEFPIXEL
2527     bitmap->clearToOne();
2528   } else {
2529     bitmap->clearToZero();
2530   }
2531
2532   // compute the skip bitmap
2533   skipBitmap = NULL;
2534   if (enableSkip) {
2535     skipBitmap = new JBIG2Bitmap(0, gridW, gridH);
2536     skipBitmap->clearToZero();
2537     for (m = 0; m < gridH; ++m) {
2538       xx = gridX + m * stepY;
2539       yy = gridY + m * stepX;
2540       for (n = 0; n < gridW; ++n) {
2541         if (((xx + (int)patW) >> 8) <= 0 || (xx >> 8) >= (int)w ||
2542             ((yy + (int)patH) >> 8) <= 0 || (yy >> 8) >= (int)h) {
2543           skipBitmap->setPixel(n, m);
2544         }
2545       }
2546     }
2547   }
2548
2549   // read the gray-scale image
2550   grayImg = (Guint *)gmalloc(gridW * gridH * sizeof(Guint));
2551   memset(grayImg, 0, gridW * gridH * sizeof(Guint));
2552   atx[0] = templ <= 1 ? 3 : 2;  aty[0] = -1;
2553   atx[1] = -3;                  aty[1] = -1;
2554   atx[2] =  2;                  aty[2] = -2;
2555   atx[3] = -2;                  aty[3] = -2;
2556   for (j = bpp - 1; j >= 0; --j) {
2557     grayBitmap = readGenericBitmap(mmr, gridW, gridH, templ, gFalse,
2558                                    enableSkip, skipBitmap, atx, aty, -1);
2559     i = 0;
2560     for (m = 0; m < gridH; ++m) {
2561       for (n = 0; n < gridW; ++n) {
2562         bit = grayBitmap->getPixel(n, m) ^ (grayImg[i] & 1);
2563         grayImg[i] = (grayImg[i] << 1) | bit;
2564         ++i;
2565       }
2566     }
2567     delete grayBitmap;
2568   }
2569
2570   // decode the image
2571   i = 0;
2572   for (m = 0; m < gridH; ++m) {
2573     xx = gridX + m * stepY;
2574     yy = gridY + m * stepX;
2575     for (n = 0; n < gridW; ++n) {
2576       if (!(enableSkip && skipBitmap->getPixel(n, m))) {
2577         patternBitmap = patternDict->getBitmap(grayImg[i]);
2578         bitmap->combine(patternBitmap, xx >> 8, yy >> 8, combOp);
2579       }
2580       xx += stepX;
2581       yy -= stepY;
2582       ++i;
2583     }
2584   }
2585
2586   gfree(grayImg);
2587
2588   // combine the region bitmap into the page bitmap
2589   if (imm) {
2590     if (pageH == 0xffffffff && y + h > curPageH) {
2591       pageBitmap->expand(y + h, pageDefPixel);
2592     }
2593     pageBitmap->combine(bitmap, x, y, extCombOp);
2594     delete bitmap;
2595
2596   // store the region bitmap
2597   } else {
2598     segments->append(bitmap);
2599   }
2600
2601   return;
2602
2603  eofError:
2604   error(getPos(), "Unexpected EOF in JBIG2 stream");
2605 }
2606
2607 void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm,
2608                                        GBool lossless, Guint length) {
2609   JBIG2Bitmap *bitmap;
2610   Guint w, h, x, y, segInfoFlags, extCombOp;
2611   Guint flags, mmr, templ, tpgdOn;
2612   int atx[4], aty[4];
2613
2614   // region segment info field
2615   if (!readULong(&w) || !readULong(&h) ||
2616       !readULong(&x) || !readULong(&y) ||
2617       !readUByte(&segInfoFlags)) {
2618     goto eofError;
2619   }
2620   extCombOp = segInfoFlags & 7;
2621
2622   // rest of the generic region segment header
2623   if (!readUByte(&flags)) {
2624     goto eofError;
2625   }
2626   mmr = flags & 1;
2627   templ = (flags >> 1) & 3;
2628   tpgdOn = (flags >> 3) & 1;
2629
2630   // AT flags
2631   if (!mmr) {
2632     if (templ == 0) {
2633       if (!readByte(&atx[0]) ||
2634           !readByte(&aty[0]) ||
2635           !readByte(&atx[1]) ||
2636           !readByte(&aty[1]) ||
2637           !readByte(&atx[2]) ||
2638           !readByte(&aty[2]) ||
2639           !readByte(&atx[3]) ||
2640           !readByte(&aty[3])) {
2641         goto eofError;
2642       }
2643     } else {
2644       if (!readByte(&atx[0]) ||
2645           !readByte(&aty[0])) {
2646         goto eofError;
2647       }
2648     }
2649   }
2650
2651   // set up the arithmetic decoder
2652   if (!mmr) {
2653     resetGenericStats(templ, NULL);
2654     arithDecoder->start();
2655   }
2656
2657   // read the bitmap
2658   bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse,
2659                              NULL, atx, aty, mmr ? 0 : length - 18);
2660
2661   // combine the region bitmap into the page bitmap
2662   if (imm) {
2663     if (pageH == 0xffffffff && y + h > curPageH) {
2664       pageBitmap->expand(y + h, pageDefPixel);
2665     }
2666     pageBitmap->combine(bitmap, x, y, extCombOp);
2667     delete bitmap;
2668
2669   // store the region bitmap
2670   } else {
2671     bitmap->setSegNum(segNum);
2672     segments->append(bitmap);
2673   }
2674
2675   return;
2676
2677  eofError:
2678   error(getPos(), "Unexpected EOF in JBIG2 stream");
2679 }
2680
2681 JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
2682                                             int templ, GBool tpgdOn,
2683                                             GBool useSkip, JBIG2Bitmap *skip,
2684                                             int *atx, int *aty,
2685                                             int mmrDataLength) {
2686   JBIG2Bitmap *bitmap;
2687   GBool ltp;
2688   Guint ltpCX, cx, cx0, cx1, cx2;
2689   int *refLine, *codingLine;
2690   int code1, code2, code3;
2691   int x, y, a0, pix, i, refI, codingI;
2692
2693   bitmap = new JBIG2Bitmap(0, w, h);
2694   bitmap->clearToZero();
2695
2696   //----- MMR decode
2697
2698   if (mmr) {
2699
2700     mmrDecoder->reset();
2701     refLine = (int *)gmalloc((w + 2) * sizeof(int));
2702     codingLine = (int *)gmalloc((w + 2) * sizeof(int));
2703     codingLine[0] = codingLine[1] = w;
2704
2705     for (y = 0; y < h; ++y) {
2706
2707       // copy coding line to ref line
2708       for (i = 0; codingLine[i] < w; ++i) {
2709         refLine[i] = codingLine[i];
2710       }
2711       refLine[i] = refLine[i + 1] = w;
2712
2713       // decode a line
2714       refI = 0;     // b1 = refLine[refI]
2715       codingI = 0;  // a1 = codingLine[codingI]
2716       a0 = 0;
2717       do {
2718         code1 = mmrDecoder->get2DCode();
2719         switch (code1) {
2720         case twoDimPass:
2721           if (refLine[refI] < w) {
2722             a0 = refLine[refI + 1];
2723             refI += 2;
2724           }
2725           break;
2726         case twoDimHoriz:
2727           if (codingI & 1) {
2728             code1 = 0;
2729             do {
2730               code1 += code3 = mmrDecoder->getBlackCode();
2731             } while (code3 >= 64);
2732             code2 = 0;
2733             do {
2734               code2 += code3 = mmrDecoder->getWhiteCode();
2735             } while (code3 >= 64);
2736           } else {
2737             code1 = 0;
2738             do {
2739               code1 += code3 = mmrDecoder->getWhiteCode();
2740             } while (code3 >= 64);
2741             code2 = 0;
2742             do {
2743               code2 += code3 = mmrDecoder->getBlackCode();
2744             } while (code3 >= 64);
2745           }
2746           a0 = codingLine[codingI++] = a0 + code1;
2747           a0 = codingLine[codingI++] = a0 + code2;
2748           while (refLine[refI] <= a0 && refLine[refI] < w) {
2749             refI += 2;
2750           }
2751           break;
2752         case twoDimVert0:
2753           a0 = codingLine[codingI++] = refLine[refI];
2754           if (refLine[refI] < w) {
2755             ++refI;
2756           }
2757           break;
2758         case twoDimVertR1:
2759           a0 = codingLine[codingI++] = refLine[refI] + 1;
2760           if (refLine[refI] < w) {
2761             ++refI;
2762             while (refLine[refI] <= a0 && refLine[refI] < w) {
2763               refI += 2;
2764             }
2765           }
2766           break;
2767         case twoDimVertR2:
2768           a0 = codingLine[codingI++] = refLine[refI] + 2;
2769           if (refLine[refI] < w) {
2770             ++refI;
2771             while (refLine[refI] <= a0 && refLine[refI] < w) {
2772               refI += 2;
2773             }
2774           }
2775           break;
2776         case twoDimVertR3:
2777           a0 = codingLine[codingI++] = refLine[refI] + 3;
2778           if (refLine[refI] < w) {
2779             ++refI;
2780             while (refLine[refI] <= a0 && refLine[refI] < w) {
2781               refI += 2;
2782             }
2783           }
2784           break;
2785         case twoDimVertL1:
2786           a0 = codingLine[codingI++] = refLine[refI] - 1;
2787           if (refI > 0) {
2788             --refI;
2789           } else {
2790             ++refI;
2791           }
2792           while (refLine[refI] <= a0 && refLine[refI] < w) {
2793             refI += 2;
2794           }
2795           break;
2796         case twoDimVertL2:
2797           a0 = codingLine[codingI++] = refLine[refI] - 2;
2798           if (refI > 0) {
2799             --refI;
2800           } else {
2801             ++refI;
2802           }
2803           while (refLine[refI] <= a0 && refLine[refI] < w) {
2804             refI += 2;
2805           }
2806           break;
2807         case twoDimVertL3:
2808           a0 = codingLine[codingI++] = refLine[refI] - 3;
2809           if (refI > 0) {
2810             --refI;
2811           } else {
2812             ++refI;
2813           }
2814           while (refLine[refI] <= a0 && refLine[refI] < w) {
2815             refI += 2;
2816           }
2817           break;
2818         default:
2819           error(getPos(), "Illegal code in JBIG2 MMR bitmap data");
2820           break;
2821         }
2822       } while (a0 < w);
2823       codingLine[codingI++] = w;
2824
2825       // convert the run lengths to a bitmap line
2826       i = 0;
2827       while (codingLine[i] < w) {
2828         for (x = codingLine[i]; x < codingLine[i+1]; ++x) {
2829           bitmap->setPixel(x, y);
2830         }
2831         i += 2;
2832       }
2833     }
2834
2835     if (mmrDataLength >= 0) {
2836       mmrDecoder->skipTo(mmrDataLength);
2837     } else {
2838       if (mmrDecoder->get24Bits() != 0x001001) {
2839         error(getPos(), "Missing EOFB in JBIG2 MMR bitmap data");
2840       }
2841     }
2842
2843     gfree(refLine);
2844     gfree(codingLine);
2845
2846   //----- arithmetic decode
2847
2848   } else {
2849     // set up the typical row context
2850     ltpCX = 0; // make gcc happy
2851     if (tpgdOn) {
2852       switch (templ) {
2853       case 0:
2854         ltpCX = 0x3953; // 001 11001 0101 0011
2855         break;
2856       case 1:
2857         ltpCX = 0x079a; // 0011 11001 101 0
2858         break;
2859       case 2:
2860         ltpCX = 0x0e3; // 001 1100 01 1
2861         break;
2862       case 3:
2863         ltpCX = 0x18a; // 01100 0101 1
2864         break;
2865       }
2866     }
2867
2868     ltp = 0;
2869     cx = cx0 = cx1 = cx2 = 0; // make gcc happy
2870     for (y = 0; y < h; ++y) {
2871
2872       // check for a "typical" (duplicate) row
2873       if (tpgdOn) {
2874         if (arithDecoder->decodeBit(ltpCX, genericRegionStats)) {
2875           ltp = !ltp;
2876         }
2877         if (ltp) {
2878           bitmap->duplicateRow(y, y-1);
2879           continue;
2880         }
2881       }
2882
2883       // set up the context
2884       switch (templ) {
2885       case 0:
2886         cx0 = (bitmap->getPixel(0, y-2) << 1) |
2887               bitmap->getPixel(1, y-2);
2888         cx1 = (bitmap->getPixel(0, y-1) << 2) |
2889               (bitmap->getPixel(1, y-1) << 1) |
2890               bitmap->getPixel(2, y-1);
2891         cx2 = 0;
2892         break;
2893       case 1:
2894         cx0 = (bitmap->getPixel(0, y-2) << 2) |
2895               (bitmap->getPixel(1, y-2) << 1) |
2896               bitmap->getPixel(2, y-2);
2897         cx1 = (bitmap->getPixel(0, y-1) << 2) |
2898               (bitmap->getPixel(1, y-1) << 1) |
2899               bitmap->getPixel(2, y-1);
2900         cx2 = 0;
2901         break;
2902       case 2:
2903         cx0 = (bitmap->getPixel(0, y-2) << 1) |
2904               bitmap->getPixel(1, y-2);
2905         cx1 = (bitmap->getPixel(0, y-1) << 1) |
2906               bitmap->getPixel(1, y-1);
2907         cx2 = 0;
2908         break;
2909       case 3:
2910         cx1 = (bitmap->getPixel(0, y-1) << 1) |
2911               bitmap->getPixel(1, y-1);
2912         cx2 = 0;
2913         break;
2914       }
2915
2916       // decode the row
2917       for (x = 0; x < w; ++x) {
2918
2919         // check for a skipped pixel
2920         if (useSkip && skip->getPixel(x, y)) {
2921           pix = 0;
2922
2923         } else {
2924
2925           // build the context
2926           switch (templ) {
2927           case 0:
2928             cx = (cx0 << 13) | (cx1 << 8) | (cx2 << 4) |
2929                  (bitmap->getPixel(x + atx[0], y + aty[0]) << 3) |
2930                  (bitmap->getPixel(x + atx[1], y + aty[1]) << 2) |
2931                  (bitmap->getPixel(x + atx[2], y + aty[2]) << 1) |
2932                  bitmap->getPixel(x + atx[3], y + aty[3]);
2933             break;
2934           case 1:
2935             cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
2936                  bitmap->getPixel(x + atx[0], y + aty[0]);
2937             break;
2938           case 2:
2939             cx = (cx0 << 7) | (cx1 << 3) | (cx2 << 1) |
2940                  bitmap->getPixel(x + atx[0], y + aty[0]);
2941             break;
2942           case 3:
2943             cx = (cx1 << 5) | (cx2 << 1) |
2944                  bitmap->getPixel(x + atx[0], y + aty[0]);
2945             break;
2946           }
2947
2948           // decode the pixel
2949           if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
2950             bitmap->setPixel(x, y);
2951           }
2952         }
2953
2954         // update the context
2955         switch (templ) {
2956           case 0:
2957             cx0 = ((cx0 << 1) | bitmap->getPixel(x+2, y-2)) & 0x07;
2958             cx1 = ((cx1 << 1) | bitmap->getPixel(x+3, y-1)) & 0x1f;
2959             cx2 = ((cx2 << 1) | pix) & 0x0f;
2960             break;
2961           case 1:
2962             cx0 = ((cx0 << 1) | bitmap->getPixel(x+3, y-2)) & 0x0f;
2963             cx1 = ((cx1 << 1) | bitmap->getPixel(x+3, y-1)) & 0x1f;
2964             cx2 = ((cx2 << 1) | pix) & 0x07;
2965             break;
2966           case 2:
2967             cx0 = ((cx0 << 1) | bitmap->getPixel(x+2, y-2)) & 0x07;
2968             cx1 = ((cx1 << 1) | bitmap->getPixel(x+2, y-1)) & 0x0f;
2969             cx2 = ((cx2 << 1) | pix) & 0x03;
2970             break;
2971           case 3:
2972             cx1 = ((cx1 << 1) | bitmap->getPixel(x+2, y-1)) & 0x1f;
2973             cx2 = ((cx2 << 1) | pix) & 0x0f;
2974             break;
2975         }
2976       }
2977     }
2978   }
2979
2980   return bitmap;
2981 }
2982
2983 void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum, GBool imm,
2984                                                  GBool lossless, Guint length,
2985                                                  Guint *refSegs,
2986                                                  Guint nRefSegs) {
2987   JBIG2Bitmap *bitmap, *refBitmap;
2988   Guint w, h, x, y, segInfoFlags, extCombOp;
2989   Guint flags, templ, tpgrOn;
2990   int atx[2], aty[2];
2991   JBIG2Segment *seg;
2992
2993   // region segment info field
2994   if (!readULong(&w) || !readULong(&h) ||
2995       !readULong(&x) || !readULong(&y) ||
2996       !readUByte(&segInfoFlags)) {
2997     goto eofError;
2998   }
2999   extCombOp = segInfoFlags & 7;
3000
3001   // rest of the generic refinement region segment header
3002   if (!readUByte(&flags)) {
3003     goto eofError;
3004   }
3005   templ = flags & 1;
3006   tpgrOn = (flags >> 1) & 1;
3007
3008   // AT flags
3009   if (!templ) {
3010     if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
3011         !readByte(&atx[1]) || !readByte(&aty[1])) {
3012       goto eofError;
3013     }
3014   }
3015
3016   // resize the page bitmap if needed
3017   if (nRefSegs == 0 || imm) {
3018     if (pageH == 0xffffffff && y + h > curPageH) {
3019       pageBitmap->expand(y + h, pageDefPixel);
3020     }
3021   }
3022
3023   // get referenced bitmap
3024   if (nRefSegs > 1) {
3025     error(getPos(), "Bad reference in JBIG2 generic refinement segment");
3026     return;
3027   }
3028   if (nRefSegs == 1) {
3029     seg = findSegment(refSegs[0]);
3030     if (seg->getType() != jbig2SegBitmap) {
3031       error(getPos(), "Bad bitmap reference in JBIG2 generic refinement segment");
3032       return;
3033     }
3034     refBitmap = (JBIG2Bitmap *)seg;
3035   } else {
3036     refBitmap = pageBitmap->getSlice(x, y, w, h);
3037   }
3038
3039   // set up the arithmetic decoder
3040   resetRefinementStats(templ, NULL);
3041   arithDecoder->start();
3042
3043   // read
3044   bitmap = readGenericRefinementRegion(w, h, templ, tpgrOn,
3045                                        refBitmap, 0, 0, atx, aty);
3046
3047   // combine the region bitmap into the page bitmap
3048   if (imm) {
3049     pageBitmap->combine(bitmap, x, y, extCombOp);
3050     delete bitmap;
3051
3052   // store the region bitmap
3053   } else {
3054     bitmap->setSegNum(segNum);
3055     segments->append(bitmap);
3056   }
3057
3058   // delete the referenced bitmap
3059   if (nRefSegs == 1) {
3060     discardSegment(refSegs[0]);
3061   } else {
3062     delete refBitmap;
3063   }
3064
3065   return;
3066
3067  eofError:
3068   error(getPos(), "Unexpected EOF in JBIG2 stream");
3069 }
3070
3071 JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion(int w, int h,
3072                                                       int templ, GBool tpgrOn,
3073                                                       JBIG2Bitmap *refBitmap,
3074                                                       int refDX, int refDY,
3075                                                       int *atx, int *aty) {
3076   JBIG2Bitmap *bitmap;
3077   GBool ltp;
3078   Guint ltpCX, cx, cx0, cx2, cx3, cx4, tpgrCX0, tpgrCX1, tpgrCX2;
3079   int x, y, pix;
3080
3081   bitmap = new JBIG2Bitmap(0, w, h);
3082   bitmap->clearToZero();
3083
3084   // set up the typical row context
3085   if (templ) {
3086     ltpCX = 0x008;
3087   } else {
3088     ltpCX = 0x0010;
3089   }
3090
3091   ltp = 0;
3092   for (y = 0; y < h; ++y) {
3093
3094     // set up the context
3095     if (templ) {
3096       cx0 = bitmap->getPixel(0, y-1);
3097       cx2 = 0; // unused
3098       cx3 = (refBitmap->getPixel(-1-refDX, y-refDY) << 1) |
3099             refBitmap->getPixel(-refDX, y-refDY);
3100       cx4 = refBitmap->getPixel(-refDX, y+1-refDY);
3101     } else {
3102       cx0 = bitmap->getPixel(0, y-1);
3103       cx2 = refBitmap->getPixel(-refDX, y-1-refDY);
3104       cx3 = (refBitmap->getPixel(-1-refDX, y-refDY) << 1) |
3105             refBitmap->getPixel(-refDX, y-refDY);
3106       cx4 = (refBitmap->getPixel(-1-refDX, y+1-refDY) << 1) |
3107             refBitmap->getPixel(-refDX, y+1-refDY);
3108     }
3109
3110     // set up the typical prediction context
3111     tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy
3112     if (tpgrOn) {
3113       tpgrCX0 = (refBitmap->getPixel(-1-refDX, y-1-refDY) << 2) |
3114                 (refBitmap->getPixel(-refDX, y-1-refDY) << 1) |
3115                 refBitmap->getPixel(1-refDX, y-1-refDY);
3116       tpgrCX1 = (refBitmap->getPixel(-1-refDX, y-refDY) << 2) |
3117                 (refBitmap->getPixel(-refDX, y-refDY) << 1) |
3118                 refBitmap->getPixel(1-refDX, y-refDY);
3119       tpgrCX2 = (refBitmap->getPixel(-1-refDX, y+1-refDY) << 2) |
3120                 (refBitmap->getPixel(-refDX, y+1-refDY) << 1) |
3121                 refBitmap->getPixel(1-refDX, y+1-refDY);
3122     }
3123
3124     for (x = 0; x < w; ++x) {
3125
3126       // update the context
3127       if (templ) {
3128         cx0 = ((cx0 << 1) | bitmap->getPixel(x+1, y-1)) & 7;
3129         cx3 = ((cx3 << 1) | refBitmap->getPixel(x+1-refDX, y-refDY)) & 7;
3130         cx4 = ((cx4 << 1) | refBitmap->getPixel(x+1-refDX, y+1-refDY)) & 3;
3131       } else {
3132         cx0 = ((cx0 << 1) | bitmap->getPixel(x+1, y-1)) & 3;
3133         cx2 = ((cx2 << 1) | refBitmap->getPixel(x+1-refDX, y-1-refDY)) & 3;
3134         cx3 = ((cx3 << 1) | refBitmap->getPixel(x+1-refDX, y-refDY)) & 7;
3135         cx4 = ((cx4 << 1) | refBitmap->getPixel(x+1-refDX, y+1-refDY)) & 7;
3136       }
3137
3138       if (tpgrOn) {
3139         // update the typical predictor context
3140         tpgrCX0 = ((tpgrCX0 << 1) |
3141                    refBitmap->getPixel(x+1-refDX, y-1-refDY)) & 7;
3142         tpgrCX1 = ((tpgrCX1 << 1) |
3143                    refBitmap->getPixel(x+1-refDX, y-refDY)) & 7;
3144         tpgrCX2 = ((tpgrCX2 << 1) |
3145                    refBitmap->getPixel(x+1-refDX, y+1-refDY)) & 7;
3146
3147         // check for a "typical" pixel
3148         if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
3149           ltp = !ltp;
3150         }
3151         if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
3152           bitmap->clearPixel(x, y);
3153           continue;
3154         } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
3155           bitmap->setPixel(x, y);
3156           continue;
3157         }
3158       }
3159
3160       // build the context
3161       if (templ) {
3162         cx = (cx0 << 7) | (bitmap->getPixel(x-1, y) << 6) |
3163              (refBitmap->getPixel(x-refDX, y-1-refDY) << 5) |
3164              (cx3 << 2) | cx4;
3165       } else {
3166         cx = (cx0 << 11) | (bitmap->getPixel(x-1, y) << 10) |
3167              (cx2 << 8) | (cx3 << 5) | (cx4 << 2) |
3168              (bitmap->getPixel(x+atx[0], y+aty[0]) << 1) |
3169              refBitmap->getPixel(x+atx[1]-refDX, y+aty[1]-refDY);
3170       }
3171
3172       // decode the pixel
3173       if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
3174         bitmap->setPixel(x, y);
3175       }
3176     }
3177   }
3178
3179   return bitmap;
3180 }
3181
3182 void JBIG2Stream::readPageInfoSeg(Guint length) {
3183   Guint xRes, yRes, flags, striping;
3184
3185   if (!readULong(&pageW) || !readULong(&pageH) ||
3186       !readULong(&xRes) || !readULong(&yRes) ||
3187       !readUByte(&flags) || !readUWord(&striping)) {
3188     goto eofError;
3189   }
3190   pageDefPixel = (flags >> 2) & 1;
3191   defCombOp = (flags >> 3) & 3;
3192
3193   // allocate the page bitmap
3194   if (pageH == 0xffffffff) {
3195     curPageH = striping & 0x7fff;
3196   } else {
3197     curPageH = pageH;
3198   }
3199   pageBitmap = new JBIG2Bitmap(0, pageW, curPageH);
3200
3201   // default pixel value
3202   if (pageDefPixel) {
3203     pageBitmap->clearToOne();
3204   } else {
3205     pageBitmap->clearToZero();
3206   }
3207
3208   return;
3209
3210  eofError:
3211   error(getPos(), "Unexpected EOF in JBIG2 stream");
3212 }
3213
3214 void JBIG2Stream::readEndOfStripeSeg(Guint length) {
3215   Guint i;
3216
3217   // skip the segment
3218   for (i = 0; i < length; ++i) {
3219     curStr->getChar();
3220   }
3221 }
3222
3223 void JBIG2Stream::readProfilesSeg(Guint length) {
3224   Guint i;
3225
3226   // skip the segment
3227   for (i = 0; i < length; ++i) {
3228     curStr->getChar();
3229   }
3230 }
3231
3232 void JBIG2Stream::readCodeTableSeg(Guint segNum, Guint length) {
3233   JBIG2HuffmanTable *huffTab;
3234   Guint flags, oob, prefixBits, rangeBits;
3235   int lowVal, highVal, val;
3236   Guint huffTabSize, i;
3237
3238   if (!readUByte(&flags) || !readLong(&lowVal) || !readLong(&highVal)) {
3239     goto eofError;
3240   }
3241   oob = flags & 1;
3242   prefixBits = (flags >> 1) & 7;
3243   rangeBits = (flags >> 4) & 7;
3244
3245   huffDecoder->reset();
3246   huffTabSize = 8;
3247   huffTab = (JBIG2HuffmanTable *)
3248                 gmalloc(huffTabSize * sizeof(JBIG2HuffmanTable));
3249   i = 0;
3250   val = lowVal;
3251   while (val < highVal) {
3252     if (i == huffTabSize) {
3253       huffTabSize *= 2;
3254       huffTab = (JBIG2HuffmanTable *)
3255                     grealloc(huffTab, huffTabSize * sizeof(JBIG2HuffmanTable));
3256     }
3257     huffTab[i].val = val;
3258     huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3259     huffTab[i].rangeLen = huffDecoder->readBits(rangeBits);
3260     val += 1 << huffTab[i].rangeLen;
3261     ++i;
3262   }
3263   if (i + oob + 3 > huffTabSize) {
3264     huffTabSize = i + oob + 3;
3265     huffTab = (JBIG2HuffmanTable *)
3266                   grealloc(huffTab, huffTabSize * sizeof(JBIG2HuffmanTable));
3267   }
3268   huffTab[i].val = lowVal - 1;
3269   huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3270   huffTab[i].rangeLen = jbig2HuffmanLOW;
3271   ++i;
3272   huffTab[i].val = highVal;
3273   huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3274   huffTab[i].rangeLen = 32;
3275   ++i;
3276   if (oob) {
3277     huffTab[i].val = 0;
3278     huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3279     huffTab[i].rangeLen = jbig2HuffmanOOB;
3280     ++i;
3281   }
3282   huffTab[i].val = 0;
3283   huffTab[i].prefixLen = 0;
3284   huffTab[i].rangeLen = jbig2HuffmanEOT;
3285   ++i;
3286   huffDecoder->buildTable(huffTab, i);
3287
3288   // create and store the new table segment
3289   segments->append(new JBIG2CodeTable(segNum, huffTab));
3290
3291   return;
3292
3293  eofError:
3294   error(getPos(), "Unexpected EOF in JBIG2 stream");
3295 }
3296
3297 void JBIG2Stream::readExtensionSeg(Guint length) {
3298   Guint i;
3299
3300   // skip the segment
3301   for (i = 0; i < length; ++i) {
3302     curStr->getChar();
3303   }
3304 }
3305
3306 JBIG2Segment *JBIG2Stream::findSegment(Guint segNum) {
3307   JBIG2Segment *seg;
3308   int i;
3309
3310   for (i = 0; i < globalSegments->getLength(); ++i) {
3311     seg = (JBIG2Segment *)globalSegments->get(i);
3312     if (seg->getSegNum() == segNum) {
3313       return seg;
3314     }
3315   }
3316   for (i = 0; i < segments->getLength(); ++i) {
3317     seg = (JBIG2Segment *)segments->get(i);
3318     if (seg->getSegNum() == segNum) {
3319       return seg;
3320     }
3321   }
3322   return NULL;
3323 }
3324
3325 void JBIG2Stream::discardSegment(Guint segNum) {
3326   JBIG2Segment *seg;
3327   int i;
3328
3329   for (i = 0; i < globalSegments->getLength(); ++i) {
3330     seg = (JBIG2Segment *)globalSegments->get(i);
3331     if (seg->getSegNum() == segNum) {
3332       globalSegments->del(i);
3333       return;
3334     }
3335   }
3336   for (i = 0; i < segments->getLength(); ++i) {
3337     seg = (JBIG2Segment *)segments->get(i);
3338     if (seg->getSegNum() == segNum) {
3339       globalSegments->del(i);
3340       return;
3341     }
3342   }
3343 }
3344
3345 void JBIG2Stream::resetGenericStats(Guint templ,
3346                                     JBIG2ArithmeticDecoderStats *prevStats) {
3347   int size;
3348
3349   size = contextSize[templ];
3350   if (prevStats && prevStats->getContextSize() == size) {
3351     if (genericRegionStats->getContextSize() == size) {
3352       genericRegionStats->copyFrom(prevStats);
3353     } else {
3354       delete genericRegionStats;
3355       genericRegionStats = prevStats->copy();
3356     }
3357   } else {
3358     if (genericRegionStats->getContextSize() == size) {
3359       genericRegionStats->reset();
3360     } else {
3361       delete genericRegionStats;
3362       genericRegionStats = new JBIG2ArithmeticDecoderStats(size);
3363     }
3364   }
3365 }
3366
3367 void JBIG2Stream::resetRefinementStats(
3368                       Guint templ,
3369                       JBIG2ArithmeticDecoderStats *prevStats) {
3370   int size;
3371
3372   size = refContextSize[templ];
3373   if (prevStats && prevStats->getContextSize() == size) {
3374     if (refinementRegionStats->getContextSize() == size) {
3375       refinementRegionStats->copyFrom(prevStats);
3376     } else {
3377       delete refinementRegionStats;
3378       refinementRegionStats = prevStats->copy();
3379     }
3380   } else {
3381     if (refinementRegionStats->getContextSize() == size) {
3382       refinementRegionStats->reset();
3383     } else {
3384       delete refinementRegionStats;
3385       refinementRegionStats = new JBIG2ArithmeticDecoderStats(size);
3386     }
3387   }
3388 }
3389
3390 void JBIG2Stream::resetIntStats(int symCodeLen) {
3391   iadhStats->reset();
3392   iadwStats->reset();
3393   iaexStats->reset();
3394   iaaiStats->reset();
3395   iadtStats->reset();
3396   iaitStats->reset();
3397   iafsStats->reset();
3398   iadsStats->reset();
3399   iardxStats->reset();
3400   iardyStats->reset();
3401   iardwStats->reset();
3402   iardhStats->reset();
3403   iariStats->reset();
3404   if (iaidStats->getContextSize() == symCodeLen + 1) {
3405     iaidStats->reset();
3406   } else {
3407     delete iaidStats;
3408     iaidStats = new JBIG2ArithmeticDecoderStats(symCodeLen + 1);
3409   }
3410 }
3411
3412 GBool JBIG2Stream::readUByte(Guint *x) {
3413   int c0;
3414
3415   if ((c0 = curStr->getChar()) == EOF) {
3416     return gFalse;
3417   }
3418   *x = (Guint)c0;
3419   return gTrue;
3420 }
3421
3422 GBool JBIG2Stream::readByte(int *x) {
3423  int c0;
3424
3425   if ((c0 = curStr->getChar()) == EOF) {
3426     return gFalse;
3427   }
3428   *x = c0;
3429   if (c0 & 0x80) {
3430     *x |= -1 - 0xff;
3431   }
3432   return gTrue;
3433 }
3434
3435 GBool JBIG2Stream::readUWord(Guint *x) {
3436   int c0, c1;
3437
3438   if ((c0 = curStr->getChar()) == EOF ||
3439       (c1 = curStr->getChar()) == EOF) {
3440     return gFalse;
3441   }
3442   *x = (Guint)((c0 << 8) | c1);
3443   return gTrue;
3444 }
3445
3446 GBool JBIG2Stream::readULong(Guint *x) {
3447   int c0, c1, c2, c3;
3448
3449   if ((c0 = curStr->getChar()) == EOF ||
3450       (c1 = curStr->getChar()) == EOF ||
3451       (c2 = curStr->getChar()) == EOF ||
3452       (c3 = curStr->getChar()) == EOF) {
3453     return gFalse;
3454   }
3455   *x = (Guint)((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
3456   return gTrue;
3457 }
3458
3459 GBool JBIG2Stream::readLong(int *x) {
3460   int c0, c1, c2, c3;
3461
3462   if ((c0 = curStr->getChar()) == EOF ||
3463       (c1 = curStr->getChar()) == EOF ||
3464       (c2 = curStr->getChar()) == EOF ||
3465       (c3 = curStr->getChar()) == EOF) {
3466     return gFalse;
3467   }
3468   *x = ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
3469   if (c0 & 0x80) {
3470     *x |= -1 - 0xffffffff;
3471   }
3472   return gTrue;
3473 }