]> www.fi.muni.cz Git - evince.git/blob - pdf/xpdf/JBIG2Stream.cc
Import of Xpdf 2.02 for merge
[evince.git] / pdf / xpdf / JBIG2Stream.cc
1 //========================================================================
2 //
3 // JBIG2Stream.cc
4 //
5 // Copyright 2002-2003 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     while (len < table[i].prefixLen) {
659       prefix = (prefix << 1) | readBit();
660       ++len;
661     }
662     if (prefix == table[i].prefix) {
663       if (table[i].rangeLen == jbig2HuffmanOOB) {
664         return gFalse;
665       }
666       if (table[i].rangeLen == jbig2HuffmanLOW) {
667         *x = table[i].val - readBits(32);
668       } else if (table[i].rangeLen > 0) {
669         *x = table[i].val + readBits(table[i].rangeLen);
670       } else {
671         *x = table[i].val;
672       }
673       return gTrue;
674     }
675     ++i;
676   }
677   return gFalse;
678 }
679
680 Guint JBIG2HuffmanDecoder::readBits(Guint n) {
681   Guint x, mask, nLeft;
682
683   mask = (n == 32) ? 0xffffffff : ((1 << n) - 1);
684   if (bufLen >= n) {
685     x = (buf >> (bufLen - n)) & mask;
686     bufLen -= n;
687   } else {
688     x = buf & ((1 << bufLen) - 1);
689     nLeft = n - bufLen;
690     bufLen = 0;
691     while (nLeft >= 8) {
692       x = (x << 8) | (str->getChar() & 0xff);
693       nLeft -= 8;
694     }
695     if (nLeft > 0) {
696       buf = str->getChar();
697       bufLen = 8 - nLeft;
698       x = (x << nLeft) | ((buf >> bufLen) & ((1 << nLeft) - 1));
699     }
700   }
701   return x;
702 }
703
704 Guint JBIG2HuffmanDecoder::readBit() {
705   if (bufLen == 0) {
706     buf = str->getChar();
707     bufLen = 8;
708   }
709   --bufLen;
710   return (buf >> bufLen) & 1;
711 }
712
713 void JBIG2HuffmanDecoder::buildTable(JBIG2HuffmanTable *table, Guint len) {
714   Guint i, j, k, prefix;
715   JBIG2HuffmanTable tab;
716
717   // stable selection sort:
718   // - entries with prefixLen > 0, in ascending prefixLen order
719   // - entry with prefixLen = 0, rangeLen = EOT
720   // - all other entries with prefixLen = 0
721   // (on entry, table[len] has prefixLen = 0, rangeLen = EOT)
722   for (i = 0; i < len; ++i) {
723     for (j = i; j < len && table[j].prefixLen == 0; ++j) ;
724     if (j == len) {
725       break;
726     }
727     for (k = j + 1; k < len; ++k) {
728       if (table[k].prefixLen > 0 &&
729           table[k].prefixLen < table[j].prefixLen) {
730         j = k;
731       }
732     }
733     if (j != i) {
734       tab = table[j];
735       for (k = j; k > i; --k) {
736         table[k] = table[k - 1];
737       }
738       table[i] = tab;
739     }
740   }
741   table[i] = table[len];
742
743   // assign prefixes
744   i = 0;
745   prefix = 0;
746   table[i++].prefix = prefix++;
747   for (; table[i].rangeLen != jbig2HuffmanEOT; ++i) {
748     prefix <<= table[i].prefixLen - table[i-1].prefixLen;
749     table[i].prefix = prefix++;
750   }
751 }
752
753 //------------------------------------------------------------------------
754 // JBIG2MMRDecoder
755 //------------------------------------------------------------------------
756
757 class JBIG2MMRDecoder {
758 public:
759
760   JBIG2MMRDecoder();
761   ~JBIG2MMRDecoder();
762   void setStream(Stream *strA) { str = strA; }
763   void reset();
764   int get2DCode();
765   int getBlackCode();
766   int getWhiteCode();
767   Guint get24Bits();
768   void skipTo(Guint length);
769
770 private:
771
772   Stream *str;
773   Guint buf;
774   Guint bufLen;
775   Guint nBytesRead;
776 };
777
778 JBIG2MMRDecoder::JBIG2MMRDecoder() {
779   str = NULL;
780   reset();
781 }
782
783 JBIG2MMRDecoder::~JBIG2MMRDecoder() {
784 }
785
786 void JBIG2MMRDecoder::reset() {
787   buf = 0;
788   bufLen = 0;
789   nBytesRead = 0;
790 }
791
792 int JBIG2MMRDecoder::get2DCode() {
793   CCITTCode *p;
794
795   if (bufLen == 0) {
796     buf = str->getChar() & 0xff;
797     bufLen = 8;
798     ++nBytesRead;
799     p = &twoDimTab1[(buf >> 1) & 0x7f];
800   } else if (bufLen == 8) {
801     p = &twoDimTab1[(buf >> 1) & 0x7f];
802   } else {
803     p = &twoDimTab1[(buf << (7 - bufLen)) & 0x7f];
804     if (p->bits < 0 || p->bits > (int)bufLen) {
805       buf = (buf << 8) | (str->getChar() & 0xff);
806       bufLen += 8;
807       ++nBytesRead;
808       p = &twoDimTab1[(buf >> (bufLen - 7)) & 0x7f];
809     }
810   }
811   if (p->bits < 0) {
812     error(str->getPos(), "Bad two dim code in JBIG2 MMR stream");
813     return 0;
814   }
815   bufLen -= p->bits;
816   return p->n;
817 }
818
819 int JBIG2MMRDecoder::getWhiteCode() {
820   CCITTCode *p;
821   Guint code;
822
823   if (bufLen == 0) {
824     buf = str->getChar() & 0xff;
825     bufLen = 8;
826     ++nBytesRead;
827   }
828   while (1) {
829     if (bufLen >= 7 && ((buf >> (bufLen - 7)) & 0x7f) == 0) {
830       if (bufLen <= 12) {
831         code = buf << (12 - bufLen);
832       } else {
833         code = buf >> (bufLen - 12);
834       }
835       p = &whiteTab1[code & 0x1f];
836     } else {
837       if (bufLen <= 9) {
838         code = buf << (9 - bufLen);
839       } else {
840         code = buf >> (bufLen - 9);
841       }
842       p = &whiteTab2[code & 0x1ff];
843     }
844     if (p->bits > 0 && p->bits <= (int)bufLen) {
845       bufLen -= p->bits;
846       return p->n;
847     }
848     if (bufLen >= 12) {
849       break;
850     }
851     buf = (buf << 8) | (str->getChar() & 0xff);
852     bufLen += 8;
853     ++nBytesRead;
854   }
855   error(str->getPos(), "Bad white code in JBIG2 MMR stream");
856   // eat a bit and return a positive number so that the caller doesn't
857   // go into an infinite loop
858   --bufLen;
859   return 1;
860 }
861
862 int JBIG2MMRDecoder::getBlackCode() {
863   CCITTCode *p;
864   Guint code;
865
866   if (bufLen == 0) {
867     buf = str->getChar() & 0xff;
868     bufLen = 8;
869     ++nBytesRead;
870   }
871   while (1) {
872     if (bufLen >= 6 && ((buf >> (bufLen - 6)) & 0x3f) == 0) {
873       if (bufLen <= 13) {
874         code = buf << (13 - bufLen);
875       } else {
876         code = buf >> (bufLen - 13);
877       }
878       p = &blackTab1[code & 0x7f];
879     } else if (bufLen >= 4 && ((buf >> (bufLen - 4)) & 0x0f) == 0) {
880       if (bufLen <= 12) {
881         code = buf << (12 - bufLen);
882       } else {
883         code = buf >> (bufLen - 12);
884       }
885       p = &blackTab2[(code & 0xff) - 64];
886     } else {
887       if (bufLen <= 6) {
888         code = buf << (6 - bufLen);
889       } else {
890         code = buf >> (bufLen - 6);
891       }
892       p = &blackTab3[code & 0x3f];
893     }
894     if (p->bits > 0 && p->bits <= (int)bufLen) {
895       bufLen -= p->bits;
896       return p->n;
897     }
898     if (bufLen >= 13) {
899       break;
900     }
901     buf = (buf << 8) | (str->getChar() & 0xff);
902     bufLen += 8;
903     ++nBytesRead;
904   }
905   error(str->getPos(), "Bad black code in JBIG2 MMR stream");
906   // eat a bit and return a positive number so that the caller doesn't
907   // go into an infinite loop
908   --bufLen;
909   return 1;
910 }
911
912 Guint JBIG2MMRDecoder::get24Bits() {
913   while (bufLen < 24) {
914     buf = (buf << 8) | (str->getChar() & 0xff);
915     bufLen += 8;
916     ++nBytesRead;
917   }
918   return (buf >> (bufLen - 24)) & 0xffffff;
919 }
920
921 void JBIG2MMRDecoder::skipTo(Guint length) {
922   while (nBytesRead < length) {
923     str->getChar();
924     ++nBytesRead;
925   }
926 }
927
928 //------------------------------------------------------------------------
929 // JBIG2Segment
930 //------------------------------------------------------------------------
931
932 enum JBIG2SegmentType {
933   jbig2SegBitmap,
934   jbig2SegSymbolDict,
935   jbig2SegPatternDict,
936   jbig2SegCodeTable
937 };
938
939 class JBIG2Segment {
940 public:
941
942   JBIG2Segment(Guint segNumA) { segNum = segNumA; }
943   virtual ~JBIG2Segment() {}
944   void setSegNum(Guint segNumA) { segNum = segNumA; }
945   Guint getSegNum() { return segNum; }
946   virtual JBIG2SegmentType getType() = 0;
947
948 private:
949
950   Guint segNum;
951 };
952
953 //------------------------------------------------------------------------
954 // JBIG2Bitmap
955 //------------------------------------------------------------------------
956
957 struct JBIG2BitmapPtr {
958   Guchar *p;
959   int shift;
960   int x;
961 };
962
963 class JBIG2Bitmap: public JBIG2Segment {
964 public:
965
966   JBIG2Bitmap(Guint segNumA, int wA, int hA);
967   virtual ~JBIG2Bitmap();
968   virtual JBIG2SegmentType getType() { return jbig2SegBitmap; }
969   JBIG2Bitmap *copy() { return new JBIG2Bitmap(0, this); }
970   JBIG2Bitmap *getSlice(Guint x, Guint y, Guint wA, Guint hA);
971   void expand(int newH, Guint pixel);
972   void clearToZero();
973   void clearToOne();
974   int getWidth() { return w; }
975   int getHeight() { return h; }
976   int getPixel(int x, int y)
977     { return (x < 0 || x >= w || y < 0 || y >= h) ? 0 :
978              (data[y * line + (x >> 3)] >> (7 - (x & 7))) & 1; }
979   void setPixel(int x, int y)
980     { data[y * line + (x >> 3)] |= 1 << (7 - (x & 7)); }
981   void clearPixel(int x, int y)
982     { data[y * line + (x >> 3)] &= 0x7f7f >> (x & 7); }
983   void getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr);
984   int nextPixel(JBIG2BitmapPtr *ptr);
985   void duplicateRow(int yDest, int ySrc);
986   void combine(JBIG2Bitmap *bitmap, int x, int y, Guint combOp);
987   Guchar *getDataPtr() { return data; }
988   int getDataSize() { return h * line; }
989
990 private:
991
992   JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap);
993
994   int w, h, line;
995   Guchar *data;
996 };
997
998 JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, int wA, int hA):
999   JBIG2Segment(segNumA)
1000 {
1001   w = wA;
1002   h = hA;
1003   line = (wA + 7) >> 3;
1004   data = (Guchar *)gmalloc(h * line);
1005 }
1006
1007 JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap):
1008   JBIG2Segment(segNumA)
1009 {
1010   w = bitmap->w;
1011   h = bitmap->h;
1012   line = bitmap->line;
1013   data = (Guchar *)gmalloc(h * line);
1014   memcpy(data, bitmap->data, h * line);
1015 }
1016
1017 JBIG2Bitmap::~JBIG2Bitmap() {
1018   gfree(data);
1019 }
1020
1021 //~ optimize this
1022 JBIG2Bitmap *JBIG2Bitmap::getSlice(Guint x, Guint y, Guint wA, Guint hA) {
1023   JBIG2Bitmap *slice;
1024   Guint xx, yy;
1025
1026   slice = new JBIG2Bitmap(0, wA, hA);
1027   slice->clearToZero();
1028   for (yy = 0; yy < hA; ++yy) {
1029     for (xx = 0; xx < wA; ++xx) {
1030       if (getPixel(x + xx, y + yy)) {
1031         slice->setPixel(xx, yy);
1032       }
1033     }
1034   }
1035   return slice;
1036 }
1037
1038 void JBIG2Bitmap::expand(int newH, Guint pixel) {
1039   if (newH <= h) {
1040     return;
1041   }
1042   data = (Guchar *)grealloc(data, newH * line);
1043   if (pixel) {
1044     memset(data + h * line, 0xff, (newH - h) * line);
1045   } else {
1046     memset(data + h * line, 0x00, (newH - h) * line);
1047   }
1048   h = newH;
1049 }
1050
1051 void JBIG2Bitmap::clearToZero() {
1052   memset(data, 0, h * line);
1053 }
1054
1055 void JBIG2Bitmap::clearToOne() {
1056   memset(data, 0xff, h * line);
1057 }
1058
1059 inline void JBIG2Bitmap::getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr) {
1060   if (y < 0 || y >= h || x >= w) {
1061     ptr->p = NULL;
1062   } else if (x < 0) {
1063     ptr->p = &data[y * line];
1064     ptr->shift = 7;
1065     ptr->x = x;
1066   } else {
1067     ptr->p = &data[y * line + (x >> 3)];
1068     ptr->shift = 7 - (x & 7);
1069     ptr->x = x;
1070   }
1071 }
1072
1073 inline int JBIG2Bitmap::nextPixel(JBIG2BitmapPtr *ptr) {
1074   int pix;
1075
1076   if (!ptr->p) {
1077     pix = 0;
1078   } else if (ptr->x < 0) {
1079     ++ptr->x;
1080     pix = 0;
1081   } else {
1082     pix = (*ptr->p >> ptr->shift) & 1;
1083     if (++ptr->x == w) {
1084       ptr->p = NULL;
1085     } else if (ptr->shift == 0) {
1086       ++ptr->p;
1087       ptr->shift = 7;
1088     } else {
1089       --ptr->shift;
1090     }
1091   }
1092   return pix;
1093 }
1094
1095 void JBIG2Bitmap::duplicateRow(int yDest, int ySrc) {
1096   memcpy(data + yDest * line, data + ySrc * line, line);
1097 }
1098
1099 void JBIG2Bitmap::combine(JBIG2Bitmap *bitmap, int x, int y,
1100                           Guint combOp) {
1101   int x0, x1, y0, y1, xx, yy;
1102   Guchar *srcPtr, *destPtr;
1103   Guint src0, src1, src, dest, s1, s2, m1, m2, m3;
1104   GBool oneByte;
1105
1106   if (y < 0) {
1107     y0 = -y;
1108   } else {
1109     y0 = 0;
1110   }
1111   if (y + bitmap->h > h) {
1112     y1 = h - y;
1113   } else {
1114     y1 = bitmap->h;
1115   }
1116   if (y0 >= y1) {
1117     return;
1118   }
1119
1120   if (x >= 0) {
1121     x0 = x & ~7;
1122   } else {
1123     x0 = 0;
1124   }
1125   x1 = x + bitmap->w;
1126   if (x1 > w) {
1127     x1 = w;
1128   }
1129   if (x0 >= x1) {
1130     return;
1131   }
1132
1133   s1 = x & 7;
1134   s2 = 8 - s1;
1135   m1 = 0xff >> (x1 & 7);
1136   m2 = 0xff << (((x1 & 7) == 0) ? 0 : 8 - (x1 & 7));
1137   m3 = (0xff >> s1) & m2;
1138
1139   oneByte = x0 == ((x1 - 1) & ~7);
1140
1141   for (yy = y0; yy < y1; ++yy) {
1142
1143     // one byte per line -- need to mask both left and right side
1144     if (oneByte) {
1145       if (x >= 0) {
1146         destPtr = data + (y + yy) * line + (x >> 3);
1147         srcPtr = bitmap->data + yy * bitmap->line;
1148         dest = *destPtr;
1149         src1 = *srcPtr;
1150         switch (combOp) {
1151         case 0: // or
1152           dest |= (src1 >> s1) & m2;
1153           break;
1154         case 1: // and
1155           dest &= ((0xff00 | src1) >> s1) | m1;
1156           break;
1157         case 2: // xor
1158           dest ^= (src1 >> s1) & m2;
1159           break;
1160         case 3: // xnor
1161           dest ^= ((src1 ^ 0xff) >> s1) & m2;
1162           break;
1163         case 4: // replace
1164           dest = (dest & ~m3) | ((src1 >> s1) & m3);
1165           break;
1166         }
1167         *destPtr = dest;
1168       } else {
1169         destPtr = data + (y + yy) * line;
1170         srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
1171         dest = *destPtr;
1172         src1 = *srcPtr;
1173         switch (combOp) {
1174         case 0: // or
1175           dest |= src1 & m2;
1176           break;
1177         case 1: // and
1178           dest &= src1 | m1;
1179           break;
1180         case 2: // xor
1181           dest ^= src1 & m2;
1182           break;
1183         case 3: // xnor
1184           dest ^= (src1 ^ 0xff) & m2;
1185           break;
1186         case 4: // replace
1187           dest = (src1 & m2) | (dest & m1);
1188           break;
1189         }
1190         *destPtr = dest;
1191       }
1192
1193     // multiple bytes per line -- need to mask left side of left-most
1194     // byte and right side of right-most byte
1195     } else {
1196
1197       // left-most byte
1198       if (x >= 0) {
1199         destPtr = data + (y + yy) * line + (x >> 3);
1200         srcPtr = bitmap->data + yy * bitmap->line;
1201         src1 = *srcPtr++;
1202         dest = *destPtr;
1203         switch (combOp) {
1204         case 0: // or
1205           dest |= src1 >> s1;
1206           break;
1207         case 1: // and
1208           dest &= (0xff00 | src1) >> s1;
1209           break;
1210         case 2: // xor
1211           dest ^= src1 >> s1;
1212           break;
1213         case 3: // xnor
1214           dest ^= (src1 ^ 0xff) >> s1;
1215           break;
1216         case 4: // replace
1217           dest = (dest & (0xff << s2)) | (src1 >> s1);
1218           break;
1219         }
1220         *destPtr++ = dest;
1221         xx = x0 + 8;
1222       } else {
1223         destPtr = data + (y + yy) * line;
1224         srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
1225         src1 = *srcPtr++;
1226         xx = x0;
1227       }
1228
1229       // middle bytes
1230       for (; xx < x1 - 8; xx += 8) {
1231         dest = *destPtr;
1232         src0 = src1;
1233         src1 = *srcPtr++;
1234         src = (((src0 << 8) | src1) >> s1) & 0xff;
1235         switch (combOp) {
1236         case 0: // or
1237           dest |= src;
1238           break;
1239         case 1: // and
1240           dest &= src;
1241           break;
1242         case 2: // xor
1243           dest ^= src;
1244           break;
1245         case 3: // xnor
1246           dest ^= src ^ 0xff;
1247           break;
1248         case 4: // replace
1249           dest = src;
1250           break;
1251         }
1252         *destPtr++ = dest;
1253       }
1254
1255       // right-most byte
1256       dest = *destPtr;
1257       src0 = src1;
1258       src1 = *srcPtr++;
1259       src = (((src0 << 8) | src1) >> s1) & 0xff;
1260       switch (combOp) {
1261       case 0: // or
1262         dest |= src & m2;
1263         break;
1264       case 1: // and
1265         dest &= src | m1;
1266         break;
1267       case 2: // xor
1268         dest ^= src & m2;
1269         break;
1270       case 3: // xnor
1271         dest ^= (src ^ 0xff) & m2;
1272         break;
1273       case 4: // replace
1274         dest = (src & m2) | (dest & m1);
1275         break;
1276       }
1277       *destPtr = dest;
1278     }
1279   }
1280 }
1281
1282 //------------------------------------------------------------------------
1283 // JBIG2SymbolDict
1284 //------------------------------------------------------------------------
1285
1286 class JBIG2SymbolDict: public JBIG2Segment {
1287 public:
1288
1289   JBIG2SymbolDict(Guint segNumA, Guint sizeA);
1290   virtual ~JBIG2SymbolDict();
1291   virtual JBIG2SegmentType getType() { return jbig2SegSymbolDict; }
1292   Guint getSize() { return size; }
1293   void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
1294   JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
1295   void setGenericRegionStats(JBIG2ArithmeticDecoderStats *stats)
1296     { genericRegionStats = stats; }
1297   void setRefinementRegionStats(JBIG2ArithmeticDecoderStats *stats)
1298     { refinementRegionStats = stats; }
1299   JBIG2ArithmeticDecoderStats *getGenericRegionStats()
1300     { return genericRegionStats; }
1301   JBIG2ArithmeticDecoderStats *getRefinementRegionStats()
1302     { return refinementRegionStats; }
1303
1304 private:
1305
1306   Guint size;
1307   JBIG2Bitmap **bitmaps;
1308   JBIG2ArithmeticDecoderStats *genericRegionStats;
1309   JBIG2ArithmeticDecoderStats *refinementRegionStats;
1310 };
1311
1312 JBIG2SymbolDict::JBIG2SymbolDict(Guint segNumA, Guint sizeA):
1313   JBIG2Segment(segNumA)
1314 {
1315   size = sizeA;
1316   bitmaps = (JBIG2Bitmap **)gmalloc(size * sizeof(JBIG2Bitmap *));
1317   genericRegionStats = NULL;
1318   refinementRegionStats = NULL;
1319 }
1320
1321 JBIG2SymbolDict::~JBIG2SymbolDict() {
1322   Guint i;
1323
1324   for (i = 0; i < size; ++i) {
1325     delete bitmaps[i];
1326   }
1327   gfree(bitmaps);
1328   if (genericRegionStats) {
1329     delete genericRegionStats;
1330   }
1331   if (refinementRegionStats) {
1332     delete refinementRegionStats;
1333   }
1334 }
1335
1336 //------------------------------------------------------------------------
1337 // JBIG2PatternDict
1338 //------------------------------------------------------------------------
1339
1340 class JBIG2PatternDict: public JBIG2Segment {
1341 public:
1342
1343   JBIG2PatternDict(Guint segNumA, Guint sizeA);
1344   virtual ~JBIG2PatternDict();
1345   virtual JBIG2SegmentType getType() { return jbig2SegPatternDict; }
1346   Guint getSize() { return size; }
1347   void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
1348   JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
1349
1350 private:
1351
1352   Guint size;
1353   JBIG2Bitmap **bitmaps;
1354 };
1355
1356 JBIG2PatternDict::JBIG2PatternDict(Guint segNumA, Guint sizeA):
1357   JBIG2Segment(segNumA)
1358 {
1359   size = sizeA;
1360   bitmaps = (JBIG2Bitmap **)gmalloc(size * sizeof(JBIG2Bitmap *));
1361 }
1362
1363 JBIG2PatternDict::~JBIG2PatternDict() {
1364   Guint i;
1365
1366   for (i = 0; i < size; ++i) {
1367     delete bitmaps[i];
1368   }
1369   gfree(bitmaps);
1370 }
1371
1372 //------------------------------------------------------------------------
1373 // JBIG2CodeTable
1374 //------------------------------------------------------------------------
1375
1376 class JBIG2CodeTable: public JBIG2Segment {
1377 public:
1378
1379   JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA);
1380   virtual ~JBIG2CodeTable();
1381   virtual JBIG2SegmentType getType() { return jbig2SegCodeTable; }
1382   JBIG2HuffmanTable *getHuffTable() { return table; }
1383
1384 private:
1385
1386   JBIG2HuffmanTable *table;
1387 };
1388
1389 JBIG2CodeTable::JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA):
1390   JBIG2Segment(segNumA)
1391 {
1392   table = tableA;
1393 }
1394
1395 JBIG2CodeTable::~JBIG2CodeTable() {
1396   gfree(table);
1397 }
1398
1399 //------------------------------------------------------------------------
1400 // JBIG2Stream
1401 //------------------------------------------------------------------------
1402
1403 JBIG2Stream::JBIG2Stream(Stream *strA, Object *globalsStream):
1404   FilterStream(strA)
1405 {
1406   pageBitmap = NULL;
1407
1408   arithDecoder = new JBIG2ArithmeticDecoder();
1409   genericRegionStats = new JBIG2ArithmeticDecoderStats(1);
1410   refinementRegionStats = new JBIG2ArithmeticDecoderStats(1);
1411   iadhStats = new JBIG2ArithmeticDecoderStats(9);
1412   iadwStats = new JBIG2ArithmeticDecoderStats(9);
1413   iaexStats = new JBIG2ArithmeticDecoderStats(9);
1414   iaaiStats = new JBIG2ArithmeticDecoderStats(9);
1415   iadtStats = new JBIG2ArithmeticDecoderStats(9);
1416   iaitStats = new JBIG2ArithmeticDecoderStats(9);
1417   iafsStats = new JBIG2ArithmeticDecoderStats(9);
1418   iadsStats = new JBIG2ArithmeticDecoderStats(9);
1419   iardxStats = new JBIG2ArithmeticDecoderStats(9);
1420   iardyStats = new JBIG2ArithmeticDecoderStats(9);
1421   iardwStats = new JBIG2ArithmeticDecoderStats(9);
1422   iardhStats = new JBIG2ArithmeticDecoderStats(9);
1423   iariStats = new JBIG2ArithmeticDecoderStats(9);
1424   iaidStats = new JBIG2ArithmeticDecoderStats(1);
1425   huffDecoder = new JBIG2HuffmanDecoder();
1426   mmrDecoder = new JBIG2MMRDecoder();
1427
1428   segments = globalSegments = new GList();
1429   if (globalsStream->isStream()) {
1430     curStr = globalsStream->getStream();
1431     curStr->reset();
1432     arithDecoder->setStream(curStr);
1433     huffDecoder->setStream(curStr);
1434     mmrDecoder->setStream(curStr);
1435     readSegments();
1436   }
1437
1438   segments = NULL;
1439   curStr = NULL;
1440   dataPtr = dataEnd = NULL;
1441 }
1442
1443 JBIG2Stream::~JBIG2Stream() {
1444   delete arithDecoder;
1445   delete genericRegionStats;
1446   delete refinementRegionStats;
1447   delete iadhStats;
1448   delete iadwStats;
1449   delete iaexStats;
1450   delete iaaiStats;
1451   delete iadtStats;
1452   delete iaitStats;
1453   delete iafsStats;
1454   delete iadsStats;
1455   delete iardxStats;
1456   delete iardyStats;
1457   delete iardwStats;
1458   delete iardhStats;
1459   delete iariStats;
1460   delete iaidStats;
1461   delete huffDecoder;
1462   delete mmrDecoder;
1463   if (pageBitmap) {
1464     delete pageBitmap;
1465   }
1466   if (segments) {
1467     deleteGList(segments, JBIG2Segment);
1468   }
1469   if (globalSegments) {
1470     deleteGList(globalSegments, JBIG2Segment);
1471   }
1472   delete str;
1473 }
1474
1475 void JBIG2Stream::reset() {
1476   if (pageBitmap) {
1477     delete pageBitmap;
1478     pageBitmap = NULL;
1479   }
1480   if (segments) {
1481     deleteGList(segments, JBIG2Segment);
1482   }
1483   segments = new GList();
1484
1485   curStr = str;
1486   curStr->reset();
1487   arithDecoder->setStream(curStr);
1488   huffDecoder->setStream(curStr);
1489   mmrDecoder->setStream(curStr);
1490   readSegments();
1491
1492   if (pageBitmap) {
1493     dataPtr = pageBitmap->getDataPtr();
1494     dataEnd = dataPtr + pageBitmap->getDataSize();
1495   } else {
1496     dataPtr = NULL;
1497   }
1498 }
1499
1500 int JBIG2Stream::getChar() {
1501   if (dataPtr && dataPtr < dataEnd) {
1502     return (*dataPtr++ ^ 0xff) & 0xff;
1503   }
1504   return EOF;
1505 }
1506
1507 int JBIG2Stream::lookChar() {
1508   if (dataPtr && dataPtr < dataEnd) {
1509     return (*dataPtr ^ 0xff) & 0xff;
1510   }
1511   return EOF;
1512 }
1513
1514 GString *JBIG2Stream::getPSFilter(char *indent) {
1515   return NULL;
1516 }
1517
1518 GBool JBIG2Stream::isBinary(GBool last) {
1519   return str->isBinary(gTrue);
1520 }
1521
1522 void JBIG2Stream::readSegments() {
1523   Guint segNum, segFlags, segType, page, segLength;
1524   Guint refFlags, nRefSegs;
1525   Guint *refSegs;
1526   int c1, c2, c3;
1527   Guint i;
1528
1529   while (readULong(&segNum)) {
1530
1531     // segment header flags
1532     if (!readUByte(&segFlags)) {
1533       goto eofError1;
1534     }
1535     segType = segFlags & 0x3f;
1536
1537     // referred-to segment count and retention flags
1538     if (!readUByte(&refFlags)) {
1539       goto eofError1;
1540     }
1541     nRefSegs = refFlags >> 5;
1542     if (nRefSegs == 7) {
1543       if ((c1 = curStr->getChar()) == EOF ||
1544           (c2 = curStr->getChar()) == EOF ||
1545           (c3 = curStr->getChar()) == EOF) {
1546         goto eofError1;
1547       }
1548       refFlags = (refFlags << 24) | (c1 << 16) | (c2 << 8) | c3;
1549       nRefSegs = refFlags & 0x1fffffff;
1550       for (i = 0; i < (nRefSegs + 9) >> 3; ++i) {
1551         c1 = curStr->getChar();
1552       }
1553     }
1554
1555     // referred-to segment numbers
1556     refSegs = (Guint *)gmalloc(nRefSegs * sizeof(Guint));
1557     if (segNum <= 256) {
1558       for (i = 0; i < nRefSegs; ++i) {
1559         if (!readUByte(&refSegs[i])) {
1560           goto eofError2;
1561         }
1562       }
1563     } else if (segNum <= 65536) {
1564       for (i = 0; i < nRefSegs; ++i) {
1565         if (!readUWord(&refSegs[i])) {
1566           goto eofError2;
1567         }
1568       }
1569     } else {
1570       for (i = 0; i < nRefSegs; ++i) {
1571         if (!readULong(&refSegs[i])) {
1572           goto eofError2;
1573         }
1574       }
1575     }
1576
1577     // segment page association
1578     if (segFlags & 0x40) {
1579       if (!readULong(&page)) {
1580         goto eofError2;
1581       }
1582     } else {
1583       if (!readUByte(&page)) {
1584         goto eofError2;
1585       }
1586     }
1587
1588     // segment data length
1589     if (!readULong(&segLength)) {
1590       goto eofError2;
1591     }
1592
1593     // read the segment data
1594     switch (segType) {
1595     case 0:
1596       readSymbolDictSeg(segNum, segLength, refSegs, nRefSegs);
1597       break;
1598     case 4:
1599       readTextRegionSeg(segNum, gFalse, gFalse, segLength, refSegs, nRefSegs);
1600       break;
1601     case 6:
1602       readTextRegionSeg(segNum, gTrue, gFalse, segLength, refSegs, nRefSegs);
1603       break;
1604     case 7:
1605       readTextRegionSeg(segNum, gTrue, gTrue, segLength, refSegs, nRefSegs);
1606       break;
1607     case 16:
1608       readPatternDictSeg(segNum, segLength);
1609       break;
1610     case 20:
1611       readHalftoneRegionSeg(segNum, gFalse, gFalse, segLength,
1612                             refSegs, nRefSegs);
1613       break;
1614     case 22:
1615       readHalftoneRegionSeg(segNum, gTrue, gFalse, segLength,
1616                             refSegs, nRefSegs);
1617       break;
1618     case 23:
1619       readHalftoneRegionSeg(segNum, gTrue, gTrue, segLength,
1620                             refSegs, nRefSegs);
1621       break;
1622     case 36:
1623       readGenericRegionSeg(segNum, gFalse, gFalse, segLength);
1624       break;
1625     case 38:
1626       readGenericRegionSeg(segNum, gTrue, gFalse, segLength);
1627       break;
1628     case 39:
1629       readGenericRegionSeg(segNum, gTrue, gTrue, segLength);
1630       break;
1631     case 40:
1632       readGenericRefinementRegionSeg(segNum, gFalse, gFalse, segLength,
1633                                      refSegs, nRefSegs);
1634       break;
1635     case 42:
1636       readGenericRefinementRegionSeg(segNum, gTrue, gFalse, segLength,
1637                                      refSegs, nRefSegs);
1638       break;
1639     case 43:
1640       readGenericRefinementRegionSeg(segNum, gTrue, gTrue, segLength,
1641                                      refSegs, nRefSegs);
1642       break;
1643     case 48:
1644       readPageInfoSeg(segLength);
1645       break;
1646     case 50:
1647       readEndOfStripeSeg(segLength);
1648       break;
1649     case 52:
1650       readProfilesSeg(segLength);
1651       break;
1652     case 53:
1653       readCodeTableSeg(segNum, segLength);
1654       break;
1655     case 62:
1656       readExtensionSeg(segLength);
1657       break;
1658     default:
1659       error(getPos(), "Unknown segment type in JBIG2 stream");
1660       for (i = 0; i < segLength; ++i) {
1661         if ((c1 = curStr->getChar()) == EOF) {
1662           goto eofError2;
1663         }
1664       }
1665       break;
1666     }
1667
1668     gfree(refSegs);
1669   }
1670
1671   return;
1672
1673  eofError2:
1674   gfree(refSegs);
1675  eofError1:
1676   error(getPos(), "Unexpected EOF in JBIG2 stream");
1677 }
1678
1679 void JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
1680                                     Guint *refSegs, Guint nRefSegs) {
1681   JBIG2SymbolDict *symbolDict;
1682   JBIG2HuffmanTable *huffDHTable, *huffDWTable;
1683   JBIG2HuffmanTable *huffBMSizeTable, *huffAggInstTable;
1684   JBIG2Segment *seg;
1685   GList *codeTables;
1686   JBIG2SymbolDict *inputSymbolDict;
1687   Guint flags, sdTemplate, sdrTemplate, huff, refAgg;
1688   Guint huffDH, huffDW, huffBMSize, huffAggInst;
1689   Guint contextUsed, contextRetained;
1690   int sdATX[4], sdATY[4], sdrATX[2], sdrATY[2];
1691   Guint numExSyms, numNewSyms, numInputSyms, symCodeLen;
1692   JBIG2Bitmap **bitmaps;
1693   JBIG2Bitmap *collBitmap, *refBitmap;
1694   Guint *symWidths;
1695   Guint symHeight, symWidth, totalWidth, x, symID;
1696   int dh, dw, refAggNum, refDX, refDY, bmSize;
1697   GBool ex;
1698   int run, cnt;
1699   Guint i, j, k;
1700   Guchar *p;
1701
1702   // symbol dictionary flags
1703   if (!readUWord(&flags)) {
1704     goto eofError;
1705   }
1706   sdTemplate = (flags >> 10) & 3;
1707   sdrTemplate = (flags >> 12) & 1;
1708   huff = flags & 1;
1709   refAgg = (flags >> 1) & 1;
1710   huffDH = (flags >> 2) & 3;
1711   huffDW = (flags >> 4) & 3;
1712   huffBMSize = (flags >> 6) & 1;
1713   huffAggInst = (flags >> 7) & 1;
1714   contextUsed = (flags >> 8) & 1;
1715   contextRetained = (flags >> 9) & 1;
1716
1717   // symbol dictionary AT flags
1718   if (!huff) {
1719     if (sdTemplate == 0) {
1720       if (!readByte(&sdATX[0]) ||
1721           !readByte(&sdATY[0]) ||
1722           !readByte(&sdATX[1]) ||
1723           !readByte(&sdATY[1]) ||
1724           !readByte(&sdATX[2]) ||
1725           !readByte(&sdATY[2]) ||
1726           !readByte(&sdATX[3]) ||
1727           !readByte(&sdATY[3])) {
1728         goto eofError;
1729       }
1730     } else {
1731       if (!readByte(&sdATX[0]) ||
1732           !readByte(&sdATY[0])) {
1733         goto eofError;
1734       }
1735     }
1736   }
1737
1738   // symbol dictionary refinement AT flags
1739   if (refAgg && !sdrTemplate) {
1740     if (!readByte(&sdrATX[0]) ||
1741         !readByte(&sdrATY[0]) ||
1742         !readByte(&sdrATX[1]) ||
1743         !readByte(&sdrATY[1])) {
1744       goto eofError;
1745     }
1746   }
1747
1748   // SDNUMEXSYMS and SDNUMNEWSYMS
1749   if (!readULong(&numExSyms) || !readULong(&numNewSyms)) {
1750     goto eofError;
1751   }
1752
1753   // get referenced segments: input symbol dictionaries and code tables
1754   codeTables = new GList();
1755   numInputSyms = 0;
1756   for (i = 0; i < nRefSegs; ++i) {
1757     seg = findSegment(refSegs[i]);
1758     if (seg->getType() == jbig2SegSymbolDict) {
1759       numInputSyms += ((JBIG2SymbolDict *)seg)->getSize();
1760     } else if (seg->getType() == jbig2SegCodeTable) {
1761       codeTables->append(seg);
1762     }
1763   }
1764
1765   // compute symbol code length
1766   symCodeLen = 0;
1767   i = 1;
1768   while (i < numInputSyms + numNewSyms) {
1769     ++symCodeLen;
1770     i <<= 1;
1771   }
1772
1773   // get the input symbol bitmaps
1774   bitmaps = (JBIG2Bitmap **)gmalloc((numInputSyms + numNewSyms) *
1775                                     sizeof(JBIG2Bitmap *));
1776   k = 0;
1777   inputSymbolDict = NULL;
1778   for (i = 0; i < nRefSegs; ++i) {
1779     seg = findSegment(refSegs[i]);
1780     if (seg->getType() == jbig2SegSymbolDict) {
1781       inputSymbolDict = (JBIG2SymbolDict *)seg;
1782       for (j = 0; j < inputSymbolDict->getSize(); ++j) {
1783         bitmaps[k++] = inputSymbolDict->getBitmap(j);
1784       }
1785     }
1786   }
1787
1788   // get the Huffman tables
1789   huffDHTable = huffDWTable = NULL; // make gcc happy
1790   huffBMSizeTable = huffAggInstTable = NULL; // make gcc happy
1791   i = 0;
1792   if (huff) {
1793     if (huffDH == 0) {
1794       huffDHTable = huffTableD;
1795     } else if (huffDH == 1) {
1796       huffDHTable = huffTableE;
1797     } else {
1798       huffDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1799     }
1800     if (huffDW == 0) {
1801       huffDWTable = huffTableB;
1802     } else if (huffDW == 1) {
1803       huffDWTable = huffTableC;
1804     } else {
1805       huffDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1806     }
1807     if (huffBMSize == 0) {
1808       huffBMSizeTable = huffTableA;
1809     } else {
1810       huffBMSizeTable =
1811           ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1812     }
1813     if (huffAggInst == 0) {
1814       huffAggInstTable = huffTableA;
1815     } else {
1816       huffAggInstTable =
1817           ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1818     }
1819   }
1820   delete codeTables;
1821
1822   // set up the Huffman decoder
1823   if (huff) {
1824     huffDecoder->reset();
1825
1826   // set up the arithmetic decoder
1827   } else {
1828     if (contextUsed && inputSymbolDict) {
1829       resetGenericStats(sdTemplate, inputSymbolDict->getGenericRegionStats());
1830     } else {
1831       resetGenericStats(sdTemplate, NULL);
1832     }
1833     resetIntStats(symCodeLen);
1834     arithDecoder->start();
1835   }
1836
1837   // set up the arithmetic decoder for refinement/aggregation
1838   if (refAgg) {
1839     if (contextUsed && inputSymbolDict) {
1840       resetRefinementStats(sdrTemplate,
1841                            inputSymbolDict->getRefinementRegionStats());
1842     } else {
1843       resetRefinementStats(sdrTemplate, NULL);
1844     }
1845   }
1846
1847   // allocate symbol widths storage
1848   symWidths = NULL;
1849   if (huff && !refAgg) {
1850     symWidths = (Guint *)gmalloc(numNewSyms * sizeof(Guint));
1851   }
1852
1853   symHeight = 0;
1854   i = 0;
1855   while (i < numNewSyms) {
1856
1857     // read the height class delta height
1858     if (huff) {
1859       huffDecoder->decodeInt(&dh, huffDHTable);
1860     } else {
1861       arithDecoder->decodeInt(&dh, iadhStats);
1862     }
1863     symHeight += dh;
1864     symWidth = 0;
1865     totalWidth = 0;
1866     j = i;
1867
1868     // read the symbols in this height class
1869     while (1) {
1870
1871       // read the delta width
1872       if (huff) {
1873         if (!huffDecoder->decodeInt(&dw, huffDWTable)) {
1874           break;
1875         }
1876       } else {
1877         if (!arithDecoder->decodeInt(&dw, iadwStats)) {
1878           break;
1879         }
1880       }
1881       symWidth += dw;
1882
1883       // using a collective bitmap, so don't read a bitmap here
1884       if (huff && !refAgg) {
1885         symWidths[i] = symWidth;
1886         totalWidth += symWidth;
1887
1888       // refinement/aggregate coding
1889       } else if (refAgg) {
1890         if (huff) {
1891           if (!huffDecoder->decodeInt(&refAggNum, huffAggInstTable)) {
1892             break;
1893           }
1894         } else {
1895           if (!arithDecoder->decodeInt(&refAggNum, iaaiStats)) {
1896             break;
1897           }
1898         }
1899 #if 0 //~ This special case was added about a year before the final draft
1900       //~ of the JBIG2 spec was released.  I have encountered some old
1901       //~ JBIG2 images that predate it.
1902         if (0) {
1903 #else
1904         if (refAggNum == 1) {
1905 #endif
1906           if (huff) {
1907             symID = huffDecoder->readBits(symCodeLen);
1908             huffDecoder->decodeInt(&refDX, huffTableO);
1909             huffDecoder->decodeInt(&refDY, huffTableO);
1910             huffDecoder->decodeInt(&bmSize, huffTableA);
1911             huffDecoder->reset();
1912             arithDecoder->start();
1913           } else {
1914             symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
1915             arithDecoder->decodeInt(&refDX, iardxStats);
1916             arithDecoder->decodeInt(&refDY, iardyStats);
1917           }
1918           refBitmap = bitmaps[symID];
1919           bitmaps[numInputSyms + i] =
1920               readGenericRefinementRegion(symWidth, symHeight,
1921                                           sdrTemplate, gFalse,
1922                                           refBitmap, refDX, refDY,
1923                                           sdrATX, sdrATY);
1924           //~ do we need to use the bmSize value here (in Huffman mode)?
1925         } else {
1926           bitmaps[numInputSyms + i] =
1927               readTextRegion(huff, gTrue, symWidth, symHeight,
1928                              refAggNum, 0, numInputSyms + i, NULL,
1929                              symCodeLen, bitmaps, 0, 0, 0, 1, 0,
1930                              huffTableF, huffTableH, huffTableK, huffTableO,
1931                              huffTableO, huffTableO, huffTableO, huffTableA,
1932                              sdrTemplate, sdrATX, sdrATY);
1933         }
1934
1935       // non-ref/agg coding
1936       } else {
1937         bitmaps[numInputSyms + i] =
1938             readGenericBitmap(gFalse, symWidth, symHeight,
1939                               sdTemplate, gFalse, gFalse, NULL,
1940                               sdATX, sdATY, 0);
1941       }
1942
1943       ++i;
1944     }
1945
1946     // read the collective bitmap
1947     if (huff && !refAgg) {
1948       huffDecoder->decodeInt(&bmSize, huffBMSizeTable);
1949       huffDecoder->reset();
1950       if (bmSize == 0) {
1951         collBitmap = new JBIG2Bitmap(0, totalWidth, symHeight);
1952         bmSize = symHeight * ((totalWidth + 7) >> 3);
1953         p = collBitmap->getDataPtr();
1954         for (k = 0; k < (Guint)bmSize; ++k) {
1955           *p++ = curStr->getChar();
1956         }
1957       } else {
1958         collBitmap = readGenericBitmap(gTrue, totalWidth, symHeight,
1959                                        0, gFalse, gFalse, NULL, NULL, NULL,
1960                                        bmSize);
1961       }
1962       x = 0;
1963       for (; j < i; ++j) {
1964         bitmaps[numInputSyms + j] =
1965             collBitmap->getSlice(x, 0, symWidths[j], symHeight);
1966         x += symWidths[j];
1967       }
1968       delete collBitmap;
1969     }
1970   }
1971
1972   // create the symbol dict object
1973   symbolDict = new JBIG2SymbolDict(segNum, numExSyms);
1974
1975   // exported symbol list
1976   i = j = 0;
1977   ex = gFalse;
1978   while (i < numInputSyms + numNewSyms) {
1979     if (huff) {
1980       huffDecoder->decodeInt(&run, huffTableA);
1981     } else {
1982       arithDecoder->decodeInt(&run, iaexStats);
1983     }
1984     if (ex) {
1985       for (cnt = 0; cnt < run; ++cnt) {
1986         symbolDict->setBitmap(j++, bitmaps[i++]->copy());
1987       }
1988     } else {
1989       i += run;
1990     }
1991     ex = !ex;
1992   }
1993
1994   for (i = 0; i < numNewSyms; ++i) {
1995     delete bitmaps[numInputSyms + i];
1996   }
1997   gfree(bitmaps);
1998   if (symWidths) {
1999     gfree(symWidths);
2000   }
2001
2002   // save the arithmetic decoder stats
2003   if (!huff && contextRetained) {
2004     symbolDict->setGenericRegionStats(genericRegionStats->copy());
2005     if (refAgg) {
2006       symbolDict->setRefinementRegionStats(refinementRegionStats->copy());
2007     }
2008   }
2009
2010   // store the new symbol dict
2011   segments->append(symbolDict);
2012
2013   return;
2014
2015  eofError:
2016   error(getPos(), "Unexpected EOF in JBIG2 stream");
2017 }
2018
2019 void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
2020                                     GBool lossless, Guint length,
2021                                     Guint *refSegs, Guint nRefSegs) {
2022   JBIG2Bitmap *bitmap;
2023   JBIG2HuffmanTable runLengthTab[36];
2024   JBIG2HuffmanTable *symCodeTab;
2025   JBIG2HuffmanTable *huffFSTable, *huffDSTable, *huffDTTable;
2026   JBIG2HuffmanTable *huffRDWTable, *huffRDHTable;
2027   JBIG2HuffmanTable *huffRDXTable, *huffRDYTable, *huffRSizeTable;
2028   JBIG2Segment *seg;
2029   GList *codeTables;
2030   JBIG2SymbolDict *symbolDict;
2031   JBIG2Bitmap **syms;
2032   Guint w, h, x, y, segInfoFlags, extCombOp;
2033   Guint flags, huff, refine, logStrips, refCorner, transposed;
2034   Guint combOp, defPixel, templ;
2035   int sOffset;
2036   Guint huffFlags, huffFS, huffDS, huffDT;
2037   Guint huffRDW, huffRDH, huffRDX, huffRDY, huffRSize;
2038   Guint numInstances, numSyms, symCodeLen;
2039   int atx[2], aty[2];
2040   Guint i, k, kk;
2041   int j;
2042
2043   // region segment info field
2044   if (!readULong(&w) || !readULong(&h) ||
2045       !readULong(&x) || !readULong(&y) ||
2046       !readUByte(&segInfoFlags)) {
2047     goto eofError;
2048   }
2049   extCombOp = segInfoFlags & 7;
2050
2051   // rest of the text region header
2052   if (!readUWord(&flags)) {
2053     goto eofError;
2054   }
2055   huff = flags & 1;
2056   refine = (flags >> 1) & 1;
2057   logStrips = (flags >> 2) & 3;
2058   refCorner = (flags >> 4) & 3;
2059   transposed = (flags >> 6) & 1;
2060   combOp = (flags >> 7) & 3;
2061   defPixel = (flags >> 9) & 1;
2062   sOffset = (flags >> 10) & 0x1f;
2063   if (sOffset & 0x10) {
2064     sOffset |= -1 - 0x0f;
2065   }
2066   templ = (flags >> 15) & 1;
2067   huffFS = huffDS = huffDT = 0; // make gcc happy
2068   huffRDW = huffRDH = huffRDX = huffRDY = huffRSize = 0; // make gcc happy
2069   if (huff) {
2070     if (!readUWord(&huffFlags)) {
2071       goto eofError;
2072     }
2073     huffFS = huffFlags & 3;
2074     huffDS = (huffFlags >> 2) & 3;
2075     huffDT = (huffFlags >> 4) & 3;
2076     huffRDW = (huffFlags >> 6) & 3;
2077     huffRDH = (huffFlags >> 8) & 3;
2078     huffRDX = (huffFlags >> 10) & 3;
2079     huffRDY = (huffFlags >> 12) & 3;
2080     huffRSize = (huffFlags >> 14) & 1;
2081   }
2082   if (refine && templ == 0) {
2083     if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
2084         !readByte(&atx[1]) || !readByte(&aty[1])) {
2085       goto eofError;
2086     }
2087   }
2088   if (!readULong(&numInstances)) {
2089     goto eofError;
2090   }
2091
2092   // get symbol dictionaries and tables
2093   codeTables = new GList();
2094   numSyms = 0;
2095   for (i = 0; i < nRefSegs; ++i) {
2096     seg = findSegment(refSegs[i]);
2097     if (seg->getType() == jbig2SegSymbolDict) {
2098       numSyms += ((JBIG2SymbolDict *)seg)->getSize();
2099     } else if (seg->getType() == jbig2SegCodeTable) {
2100       codeTables->append(seg);
2101     }
2102   }
2103   symCodeLen = 0;
2104   i = 1;
2105   while (i < numSyms) {
2106     ++symCodeLen;
2107     i <<= 1;
2108   }
2109
2110   // get the symbol bitmaps
2111   syms = (JBIG2Bitmap **)gmalloc(numSyms * sizeof(JBIG2Bitmap *));
2112   kk = 0;
2113   for (i = 0; i < nRefSegs; ++i) {
2114     seg = findSegment(refSegs[i]);
2115     if (seg->getType() == jbig2SegSymbolDict) {
2116       symbolDict = (JBIG2SymbolDict *)seg;
2117       for (k = 0; k < symbolDict->getSize(); ++k) {
2118         syms[kk++] = symbolDict->getBitmap(k);
2119       }
2120     }
2121   }
2122
2123   // get the Huffman tables
2124   huffFSTable = huffDSTable = huffDTTable = NULL; // make gcc happy
2125   huffRDWTable = huffRDHTable = NULL; // make gcc happy
2126   huffRDXTable = huffRDYTable = huffRSizeTable = NULL; // make gcc happy
2127   i = 0;
2128   if (huff) {
2129     if (huffFS == 0) {
2130       huffFSTable = huffTableF;
2131     } else if (huffFS == 1) {
2132       huffFSTable = huffTableG;
2133     } else {
2134       huffFSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2135     }
2136     if (huffDS == 0) {
2137       huffDSTable = huffTableH;
2138     } else if (huffDS == 1) {
2139       huffDSTable = huffTableI;
2140     } else if (huffDS == 2) {
2141       huffDSTable = huffTableJ;
2142     } else {
2143       huffDSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2144     }
2145     if (huffDT == 0) {
2146       huffDTTable = huffTableK;
2147     } else if (huffDT == 1) {
2148       huffDTTable = huffTableL;
2149     } else if (huffDT == 2) {
2150       huffDTTable = huffTableM;
2151     } else {
2152       huffDTTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2153     }
2154     if (huffRDW == 0) {
2155       huffRDWTable = huffTableN;
2156     } else if (huffRDW == 1) {
2157       huffRDWTable = huffTableO;
2158     } else {
2159       huffRDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2160     }
2161     if (huffRDH == 0) {
2162       huffRDHTable = huffTableN;
2163     } else if (huffRDH == 1) {
2164       huffRDHTable = huffTableO;
2165     } else {
2166       huffRDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2167     }
2168     if (huffRDX == 0) {
2169       huffRDXTable = huffTableN;
2170     } else if (huffRDX == 1) {
2171       huffRDXTable = huffTableO;
2172     } else {
2173       huffRDXTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2174     }
2175     if (huffRDY == 0) {
2176       huffRDYTable = huffTableN;
2177     } else if (huffRDY == 1) {
2178       huffRDYTable = huffTableO;
2179     } else {
2180       huffRDYTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2181     }
2182     if (huffRSize == 0) {
2183       huffRSizeTable = huffTableA;
2184     } else {
2185       huffRSizeTable =
2186           ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2187     }
2188   }
2189   delete codeTables;
2190
2191   // symbol ID Huffman decoding table
2192   if (huff) {
2193     huffDecoder->reset();
2194     for (i = 0; i < 32; ++i) {
2195       runLengthTab[i].val = i;
2196       runLengthTab[i].prefixLen = huffDecoder->readBits(4);
2197       runLengthTab[i].rangeLen = 0;
2198     }
2199     runLengthTab[32].val = 0x103;
2200     runLengthTab[32].prefixLen = huffDecoder->readBits(4);
2201     runLengthTab[32].rangeLen = 2;
2202     runLengthTab[33].val = 0x203;
2203     runLengthTab[33].prefixLen = huffDecoder->readBits(4);
2204     runLengthTab[33].rangeLen = 3;
2205     runLengthTab[34].val = 0x20b;
2206     runLengthTab[34].prefixLen = huffDecoder->readBits(4);
2207     runLengthTab[34].rangeLen = 7;
2208     runLengthTab[35].prefixLen = 0;
2209     runLengthTab[35].rangeLen = jbig2HuffmanEOT;
2210     huffDecoder->buildTable(runLengthTab, 35);
2211     symCodeTab = (JBIG2HuffmanTable *)gmalloc((numSyms + 1) *
2212                                               sizeof(JBIG2HuffmanTable));
2213     for (i = 0; i < numSyms; ++i) {
2214       symCodeTab[i].val = i;
2215       symCodeTab[i].rangeLen = 0;
2216     }
2217     i = 0;
2218     while (i < numSyms) {
2219       huffDecoder->decodeInt(&j, runLengthTab);
2220       if (j > 0x200) {
2221         for (j -= 0x200; j && i < numSyms; --j) {
2222           symCodeTab[i++].prefixLen = 0;
2223         }
2224       } else if (j > 0x100) {
2225         for (j -= 0x100; j && i < numSyms; --j) {
2226           symCodeTab[i].prefixLen = symCodeTab[i-1].prefixLen;
2227           ++i;
2228         }
2229       } else {
2230         symCodeTab[i++].prefixLen = j;
2231       }
2232     }
2233     symCodeTab[numSyms].prefixLen = 0;
2234     symCodeTab[numSyms].rangeLen = jbig2HuffmanEOT;
2235     huffDecoder->buildTable(symCodeTab, numSyms);
2236     huffDecoder->reset();
2237
2238   // set up the arithmetic decoder
2239   } else {
2240     symCodeTab = NULL;
2241     resetIntStats(symCodeLen);
2242     arithDecoder->start();
2243   }
2244   if (refine) {
2245     resetRefinementStats(templ, NULL);
2246   }
2247
2248   bitmap = readTextRegion(huff, refine, w, h, numInstances,
2249                           logStrips, numSyms, symCodeTab, symCodeLen, syms,
2250                           defPixel, combOp, transposed, refCorner, sOffset,
2251                           huffFSTable, huffDSTable, huffDTTable,
2252                           huffRDWTable, huffRDHTable,
2253                           huffRDXTable, huffRDYTable, huffRSizeTable,
2254                           templ, atx, aty);
2255
2256   gfree(syms);
2257
2258   // combine the region bitmap into the page bitmap
2259   if (imm) {
2260     if (pageH == 0xffffffff && y + h > curPageH) {
2261       pageBitmap->expand(y + h, pageDefPixel);
2262     }
2263     pageBitmap->combine(bitmap, x, y, extCombOp);
2264     delete bitmap;
2265
2266   // store the region bitmap
2267   } else {
2268     bitmap->setSegNum(segNum);
2269     segments->append(bitmap);
2270   }
2271
2272   // clean up the Huffman decoder
2273   if (huff) {
2274     gfree(symCodeTab);
2275   }
2276
2277   return;
2278
2279  eofError:
2280   error(getPos(), "Unexpected EOF in JBIG2 stream");
2281 }
2282
2283 JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
2284                                          int w, int h,
2285                                          Guint numInstances,
2286                                          Guint logStrips,
2287                                          int numSyms,
2288                                          JBIG2HuffmanTable *symCodeTab,
2289                                          Guint symCodeLen,
2290                                          JBIG2Bitmap **syms,
2291                                          Guint defPixel, Guint combOp,
2292                                          Guint transposed, Guint refCorner,
2293                                          int sOffset,
2294                                          JBIG2HuffmanTable *huffFSTable,
2295                                          JBIG2HuffmanTable *huffDSTable,
2296                                          JBIG2HuffmanTable *huffDTTable,
2297                                          JBIG2HuffmanTable *huffRDWTable,
2298                                          JBIG2HuffmanTable *huffRDHTable,
2299                                          JBIG2HuffmanTable *huffRDXTable,
2300                                          JBIG2HuffmanTable *huffRDYTable,
2301                                          JBIG2HuffmanTable *huffRSizeTable,
2302                                          Guint templ,
2303                                          int *atx, int *aty) {
2304   JBIG2Bitmap *bitmap;
2305   JBIG2Bitmap *symbolBitmap;
2306   Guint strips;
2307   int t, dt, tt, s, ds, sFirst, j;
2308   int rdw, rdh, rdx, rdy, ri, refDX, refDY, bmSize;
2309   Guint symID, inst, bw, bh;
2310
2311   strips = 1 << logStrips;
2312
2313   // allocate the bitmap
2314   bitmap = new JBIG2Bitmap(0, w, h);
2315   if (defPixel) {
2316     bitmap->clearToOne();
2317   } else {
2318     bitmap->clearToZero();
2319   }
2320
2321   // decode initial T value
2322   if (huff) {
2323     huffDecoder->decodeInt(&t, huffDTTable);
2324   } else {
2325     arithDecoder->decodeInt(&t, iadtStats);
2326   }
2327   t *= -strips;
2328
2329   inst = 0;
2330   sFirst = 0;
2331   while (inst < numInstances) {
2332
2333     // decode delta-T
2334     if (huff) {
2335       huffDecoder->decodeInt(&dt, huffDTTable);
2336     } else {
2337       arithDecoder->decodeInt(&dt, iadtStats);
2338     }
2339     t += dt * strips;
2340
2341     // first S value
2342     if (huff) {
2343       huffDecoder->decodeInt(&ds, huffFSTable);
2344     } else {
2345       arithDecoder->decodeInt(&ds, iafsStats);
2346     }
2347     sFirst += ds;
2348     s = sFirst;
2349
2350     // read the instances
2351     while (1) {
2352
2353       // T value
2354       if (strips == 1) {
2355         dt = 0;
2356       } else if (huff) {
2357         dt = huffDecoder->readBits(logStrips);
2358       } else {
2359         arithDecoder->decodeInt(&dt, iaitStats);
2360       }
2361       tt = t + dt;
2362
2363       // symbol ID
2364       if (huff) {
2365         if (symCodeTab) {
2366           huffDecoder->decodeInt(&j, symCodeTab);
2367           symID = (Guint)j;
2368         } else {
2369           symID = huffDecoder->readBits(symCodeLen);
2370         }
2371       } else {
2372         symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
2373       }
2374
2375       // get the symbol bitmap
2376       symbolBitmap = NULL;
2377       if (refine) {
2378         if (huff) {
2379           ri = (int)huffDecoder->readBit();
2380         } else {
2381           arithDecoder->decodeInt(&ri, iariStats);
2382         }
2383       } else {
2384         ri = 0;
2385       }
2386       if (ri) {
2387         if (huff) {
2388           huffDecoder->decodeInt(&rdw, huffRDWTable);
2389           huffDecoder->decodeInt(&rdh, huffRDHTable);
2390           huffDecoder->decodeInt(&rdx, huffRDXTable);
2391           huffDecoder->decodeInt(&rdy, huffRDYTable);
2392           huffDecoder->decodeInt(&bmSize, huffRSizeTable);
2393           huffDecoder->reset();
2394           arithDecoder->start();
2395         } else {
2396           arithDecoder->decodeInt(&rdw, iardwStats);
2397           arithDecoder->decodeInt(&rdh, iardhStats);
2398           arithDecoder->decodeInt(&rdx, iardxStats);
2399           arithDecoder->decodeInt(&rdy, iardyStats);
2400         }
2401         refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
2402         refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
2403
2404         symbolBitmap =
2405           readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
2406                                       rdh + syms[symID]->getHeight(),
2407                                       templ, gFalse, syms[symID],
2408                                       refDX, refDY, atx, aty);
2409         //~ do we need to use the bmSize value here (in Huffman mode)?
2410       } else {
2411         symbolBitmap = syms[symID];
2412       }
2413
2414       // combine the symbol bitmap into the region bitmap
2415       //~ something is wrong here - refCorner shouldn't degenerate into
2416       //~   two cases
2417       bw = symbolBitmap->getWidth() - 1;
2418       bh = symbolBitmap->getHeight() - 1;
2419       if (transposed) {
2420         switch (refCorner) {
2421         case 0: // bottom left
2422           bitmap->combine(symbolBitmap, tt, s, combOp);
2423           break;
2424         case 1: // top left
2425           bitmap->combine(symbolBitmap, tt, s, combOp);
2426           break;
2427         case 2: // bottom right
2428           bitmap->combine(symbolBitmap, tt - bw, s, combOp);
2429           break;
2430         case 3: // top right
2431           bitmap->combine(symbolBitmap, tt - bw, s, combOp);
2432           break;
2433         }
2434         s += bh;
2435       } else {
2436         switch (refCorner) {
2437         case 0: // bottom left
2438           bitmap->combine(symbolBitmap, s, tt - bh, combOp);
2439           break;
2440         case 1: // top left
2441           bitmap->combine(symbolBitmap, s, tt, combOp);
2442           break;
2443         case 2: // bottom right
2444           bitmap->combine(symbolBitmap, s, tt - bh, combOp);
2445           break;
2446         case 3: // top right
2447           bitmap->combine(symbolBitmap, s, tt, combOp);
2448           break;
2449         }
2450         s += bw;
2451       }
2452       if (ri) {
2453         delete symbolBitmap;
2454       }
2455
2456       // next instance
2457       ++inst;
2458
2459       // next S value
2460       if (huff) {
2461         if (!huffDecoder->decodeInt(&ds, huffDSTable)) {
2462           break;
2463         }
2464       } else {
2465         if (!arithDecoder->decodeInt(&ds, iadsStats)) {
2466           break;
2467         }
2468       }
2469       s += sOffset + ds;
2470     }
2471   }
2472
2473   return bitmap;
2474 }
2475
2476 void JBIG2Stream::readPatternDictSeg(Guint segNum, Guint length) {
2477   JBIG2PatternDict *patternDict;
2478   JBIG2Bitmap *bitmap;
2479   Guint flags, patternW, patternH, grayMax, templ, mmr;
2480   int atx[4], aty[4];
2481   Guint i, x;
2482
2483   // halftone dictionary flags, pattern width and height, max gray value
2484   if (!readUByte(&flags) ||
2485       !readUByte(&patternW) ||
2486       !readUByte(&patternH) ||
2487       !readULong(&grayMax)) {
2488     goto eofError;
2489   }
2490   templ = (flags >> 1) & 3;
2491   mmr = flags & 1;
2492
2493   // set up the arithmetic decoder
2494   if (!mmr) {
2495     resetGenericStats(templ, NULL);
2496     arithDecoder->start();
2497   }
2498
2499   // read the bitmap
2500   atx[0] = -patternW; aty[0] =  0;
2501   atx[1] = -3;        aty[1] = -1;
2502   atx[2] =  2;        aty[2] = -2;
2503   atx[3] = -2;        aty[3] = -2;
2504   bitmap = readGenericBitmap(mmr, (grayMax + 1) * patternW, patternH,
2505                              templ, gFalse, gFalse, NULL,
2506                              atx, aty, length - 7);
2507
2508   // create the pattern dict object
2509   patternDict = new JBIG2PatternDict(segNum, grayMax + 1);
2510
2511   // split up the bitmap
2512   x = 0;
2513   for (i = 0; i <= grayMax; ++i) {
2514     patternDict->setBitmap(i, bitmap->getSlice(x, 0, patternW, patternH));
2515     x += patternW;
2516   }
2517
2518   // free memory
2519   delete bitmap;
2520
2521   // store the new pattern dict
2522   segments->append(patternDict);
2523
2524   return;
2525
2526  eofError:
2527   error(getPos(), "Unexpected EOF in JBIG2 stream");
2528 }
2529
2530 void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm,
2531                                         GBool lossless, Guint length,
2532                                         Guint *refSegs, Guint nRefSegs) {
2533   JBIG2Bitmap *bitmap;
2534   JBIG2Segment *seg;
2535   JBIG2PatternDict *patternDict;
2536   JBIG2Bitmap *skipBitmap;
2537   Guint *grayImg;
2538   JBIG2Bitmap *grayBitmap;
2539   JBIG2Bitmap *patternBitmap;
2540   Guint w, h, x, y, segInfoFlags, extCombOp;
2541   Guint flags, mmr, templ, enableSkip, combOp;
2542   Guint gridW, gridH, stepX, stepY, patW, patH;
2543   int atx[4], aty[4];
2544   int gridX, gridY, xx, yy, bit, j;
2545   Guint bpp, m, n, i;
2546
2547   // region segment info field
2548   if (!readULong(&w) || !readULong(&h) ||
2549       !readULong(&x) || !readULong(&y) ||
2550       !readUByte(&segInfoFlags)) {
2551     goto eofError;
2552   }
2553   extCombOp = segInfoFlags & 7;
2554
2555   // rest of the halftone region header
2556   if (!readUByte(&flags)) {
2557     goto eofError;
2558   }
2559   mmr = flags & 1;
2560   templ = (flags >> 1) & 3;
2561   enableSkip = (flags >> 3) & 1;
2562   combOp = (flags >> 4) & 7;
2563   if (!readULong(&gridW) || !readULong(&gridH) ||
2564       !readLong(&gridX) || !readLong(&gridY) ||
2565       !readUWord(&stepX) || !readUWord(&stepY)) {
2566     goto eofError;
2567   }
2568
2569   // get pattern dictionary
2570   if (nRefSegs != 1) {
2571     error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
2572     return;
2573   }
2574   seg = findSegment(refSegs[0]);
2575   if (seg->getType() != jbig2SegPatternDict) {
2576     error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
2577     return;
2578   }
2579   patternDict = (JBIG2PatternDict *)seg;
2580   bpp = 0;
2581   i = 1;
2582   while (i < patternDict->getSize()) {
2583     ++bpp;
2584     i <<= 1;
2585   }
2586   patW = patternDict->getBitmap(0)->getWidth();
2587   patH = patternDict->getBitmap(0)->getHeight();
2588
2589   // set up the arithmetic decoder
2590   if (!mmr) {
2591     resetGenericStats(templ, NULL);
2592     arithDecoder->start();
2593   }
2594
2595   // allocate the bitmap
2596   bitmap = new JBIG2Bitmap(segNum, w, h);
2597   if (flags & 0x80) { // HDEFPIXEL
2598     bitmap->clearToOne();
2599   } else {
2600     bitmap->clearToZero();
2601   }
2602
2603   // compute the skip bitmap
2604   skipBitmap = NULL;
2605   if (enableSkip) {
2606     skipBitmap = new JBIG2Bitmap(0, gridW, gridH);
2607     skipBitmap->clearToZero();
2608     for (m = 0; m < gridH; ++m) {
2609       xx = gridX + m * stepY;
2610       yy = gridY + m * stepX;
2611       for (n = 0; n < gridW; ++n) {
2612         if (((xx + (int)patW) >> 8) <= 0 || (xx >> 8) >= (int)w ||
2613             ((yy + (int)patH) >> 8) <= 0 || (yy >> 8) >= (int)h) {
2614           skipBitmap->setPixel(n, m);
2615         }
2616       }
2617     }
2618   }
2619
2620   // read the gray-scale image
2621   grayImg = (Guint *)gmalloc(gridW * gridH * sizeof(Guint));
2622   memset(grayImg, 0, gridW * gridH * sizeof(Guint));
2623   atx[0] = templ <= 1 ? 3 : 2;  aty[0] = -1;
2624   atx[1] = -3;                  aty[1] = -1;
2625   atx[2] =  2;                  aty[2] = -2;
2626   atx[3] = -2;                  aty[3] = -2;
2627   for (j = bpp - 1; j >= 0; --j) {
2628     grayBitmap = readGenericBitmap(mmr, gridW, gridH, templ, gFalse,
2629                                    enableSkip, skipBitmap, atx, aty, -1);
2630     i = 0;
2631     for (m = 0; m < gridH; ++m) {
2632       for (n = 0; n < gridW; ++n) {
2633         bit = grayBitmap->getPixel(n, m) ^ (grayImg[i] & 1);
2634         grayImg[i] = (grayImg[i] << 1) | bit;
2635         ++i;
2636       }
2637     }
2638     delete grayBitmap;
2639   }
2640
2641   // decode the image
2642   i = 0;
2643   for (m = 0; m < gridH; ++m) {
2644     xx = gridX + m * stepY;
2645     yy = gridY + m * stepX;
2646     for (n = 0; n < gridW; ++n) {
2647       if (!(enableSkip && skipBitmap->getPixel(n, m))) {
2648         patternBitmap = patternDict->getBitmap(grayImg[i]);
2649         bitmap->combine(patternBitmap, xx >> 8, yy >> 8, combOp);
2650       }
2651       xx += stepX;
2652       yy -= stepY;
2653       ++i;
2654     }
2655   }
2656
2657   gfree(grayImg);
2658
2659   // combine the region bitmap into the page bitmap
2660   if (imm) {
2661     if (pageH == 0xffffffff && y + h > curPageH) {
2662       pageBitmap->expand(y + h, pageDefPixel);
2663     }
2664     pageBitmap->combine(bitmap, x, y, extCombOp);
2665     delete bitmap;
2666
2667   // store the region bitmap
2668   } else {
2669     segments->append(bitmap);
2670   }
2671
2672   return;
2673
2674  eofError:
2675   error(getPos(), "Unexpected EOF in JBIG2 stream");
2676 }
2677
2678 void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm,
2679                                        GBool lossless, Guint length) {
2680   JBIG2Bitmap *bitmap;
2681   Guint w, h, x, y, segInfoFlags, extCombOp;
2682   Guint flags, mmr, templ, tpgdOn;
2683   int atx[4], aty[4];
2684
2685   // region segment info field
2686   if (!readULong(&w) || !readULong(&h) ||
2687       !readULong(&x) || !readULong(&y) ||
2688       !readUByte(&segInfoFlags)) {
2689     goto eofError;
2690   }
2691   extCombOp = segInfoFlags & 7;
2692
2693   // rest of the generic region segment header
2694   if (!readUByte(&flags)) {
2695     goto eofError;
2696   }
2697   mmr = flags & 1;
2698   templ = (flags >> 1) & 3;
2699   tpgdOn = (flags >> 3) & 1;
2700
2701   // AT flags
2702   if (!mmr) {
2703     if (templ == 0) {
2704       if (!readByte(&atx[0]) ||
2705           !readByte(&aty[0]) ||
2706           !readByte(&atx[1]) ||
2707           !readByte(&aty[1]) ||
2708           !readByte(&atx[2]) ||
2709           !readByte(&aty[2]) ||
2710           !readByte(&atx[3]) ||
2711           !readByte(&aty[3])) {
2712         goto eofError;
2713       }
2714     } else {
2715       if (!readByte(&atx[0]) ||
2716           !readByte(&aty[0])) {
2717         goto eofError;
2718       }
2719     }
2720   }
2721
2722   // set up the arithmetic decoder
2723   if (!mmr) {
2724     resetGenericStats(templ, NULL);
2725     arithDecoder->start();
2726   }
2727
2728   // read the bitmap
2729   bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse,
2730                              NULL, atx, aty, mmr ? 0 : length - 18);
2731
2732   // combine the region bitmap into the page bitmap
2733   if (imm) {
2734     if (pageH == 0xffffffff && y + h > curPageH) {
2735       pageBitmap->expand(y + h, pageDefPixel);
2736     }
2737     pageBitmap->combine(bitmap, x, y, extCombOp);
2738     delete bitmap;
2739
2740   // store the region bitmap
2741   } else {
2742     bitmap->setSegNum(segNum);
2743     segments->append(bitmap);
2744   }
2745
2746   return;
2747
2748  eofError:
2749   error(getPos(), "Unexpected EOF in JBIG2 stream");
2750 }
2751
2752 JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
2753                                             int templ, GBool tpgdOn,
2754                                             GBool useSkip, JBIG2Bitmap *skip,
2755                                             int *atx, int *aty,
2756                                             int mmrDataLength) {
2757   JBIG2Bitmap *bitmap;
2758   GBool ltp;
2759   Guint ltpCX, cx, cx0, cx1, cx2;
2760   JBIG2BitmapPtr cxPtr0, cxPtr1;
2761   JBIG2BitmapPtr atPtr0, atPtr1, atPtr2, atPtr3;
2762   int *refLine, *codingLine;
2763   int code1, code2, code3;
2764   int x, y, a0, pix, i, refI, codingI;
2765
2766   bitmap = new JBIG2Bitmap(0, w, h);
2767   bitmap->clearToZero();
2768
2769   //----- MMR decode
2770
2771   if (mmr) {
2772
2773     mmrDecoder->reset();
2774     refLine = (int *)gmalloc((w + 2) * sizeof(int));
2775     codingLine = (int *)gmalloc((w + 2) * sizeof(int));
2776     codingLine[0] = codingLine[1] = w;
2777
2778     for (y = 0; y < h; ++y) {
2779
2780       // copy coding line to ref line
2781       for (i = 0; codingLine[i] < w; ++i) {
2782         refLine[i] = codingLine[i];
2783       }
2784       refLine[i] = refLine[i + 1] = w;
2785
2786       // decode a line
2787       refI = 0;     // b1 = refLine[refI]
2788       codingI = 0;  // a1 = codingLine[codingI]
2789       a0 = 0;
2790       do {
2791         code1 = mmrDecoder->get2DCode();
2792         switch (code1) {
2793         case twoDimPass:
2794           if (refLine[refI] < w) {
2795             a0 = refLine[refI + 1];
2796             refI += 2;
2797           }
2798           break;
2799         case twoDimHoriz:
2800           if (codingI & 1) {
2801             code1 = 0;
2802             do {
2803               code1 += code3 = mmrDecoder->getBlackCode();
2804             } while (code3 >= 64);
2805             code2 = 0;
2806             do {
2807               code2 += code3 = mmrDecoder->getWhiteCode();
2808             } while (code3 >= 64);
2809           } else {
2810             code1 = 0;
2811             do {
2812               code1 += code3 = mmrDecoder->getWhiteCode();
2813             } while (code3 >= 64);
2814             code2 = 0;
2815             do {
2816               code2 += code3 = mmrDecoder->getBlackCode();
2817             } while (code3 >= 64);
2818           }
2819           a0 = codingLine[codingI++] = a0 + code1;
2820           a0 = codingLine[codingI++] = a0 + code2;
2821           while (refLine[refI] <= a0 && refLine[refI] < w) {
2822             refI += 2;
2823           }
2824           break;
2825         case twoDimVert0:
2826           a0 = codingLine[codingI++] = refLine[refI];
2827           if (refLine[refI] < w) {
2828             ++refI;
2829           }
2830           break;
2831         case twoDimVertR1:
2832           a0 = codingLine[codingI++] = refLine[refI] + 1;
2833           if (refLine[refI] < w) {
2834             ++refI;
2835             while (refLine[refI] <= a0 && refLine[refI] < w) {
2836               refI += 2;
2837             }
2838           }
2839           break;
2840         case twoDimVertR2:
2841           a0 = codingLine[codingI++] = refLine[refI] + 2;
2842           if (refLine[refI] < w) {
2843             ++refI;
2844             while (refLine[refI] <= a0 && refLine[refI] < w) {
2845               refI += 2;
2846             }
2847           }
2848           break;
2849         case twoDimVertR3:
2850           a0 = codingLine[codingI++] = refLine[refI] + 3;
2851           if (refLine[refI] < w) {
2852             ++refI;
2853             while (refLine[refI] <= a0 && refLine[refI] < w) {
2854               refI += 2;
2855             }
2856           }
2857           break;
2858         case twoDimVertL1:
2859           a0 = codingLine[codingI++] = refLine[refI] - 1;
2860           if (refI > 0) {
2861             --refI;
2862           } else {
2863             ++refI;
2864           }
2865           while (refLine[refI] <= a0 && refLine[refI] < w) {
2866             refI += 2;
2867           }
2868           break;
2869         case twoDimVertL2:
2870           a0 = codingLine[codingI++] = refLine[refI] - 2;
2871           if (refI > 0) {
2872             --refI;
2873           } else {
2874             ++refI;
2875           }
2876           while (refLine[refI] <= a0 && refLine[refI] < w) {
2877             refI += 2;
2878           }
2879           break;
2880         case twoDimVertL3:
2881           a0 = codingLine[codingI++] = refLine[refI] - 3;
2882           if (refI > 0) {
2883             --refI;
2884           } else {
2885             ++refI;
2886           }
2887           while (refLine[refI] <= a0 && refLine[refI] < w) {
2888             refI += 2;
2889           }
2890           break;
2891         default:
2892           error(getPos(), "Illegal code in JBIG2 MMR bitmap data");
2893           break;
2894         }
2895       } while (a0 < w);
2896       codingLine[codingI++] = w;
2897
2898       // convert the run lengths to a bitmap line
2899       i = 0;
2900       while (codingLine[i] < w) {
2901         for (x = codingLine[i]; x < codingLine[i+1]; ++x) {
2902           bitmap->setPixel(x, y);
2903         }
2904         i += 2;
2905       }
2906     }
2907
2908     if (mmrDataLength >= 0) {
2909       mmrDecoder->skipTo(mmrDataLength);
2910     } else {
2911       if (mmrDecoder->get24Bits() != 0x001001) {
2912         error(getPos(), "Missing EOFB in JBIG2 MMR bitmap data");
2913       }
2914     }
2915
2916     gfree(refLine);
2917     gfree(codingLine);
2918
2919   //----- arithmetic decode
2920
2921   } else {
2922     // set up the typical row context
2923     ltpCX = 0; // make gcc happy
2924     if (tpgdOn) {
2925       switch (templ) {
2926       case 0:
2927         ltpCX = 0x3953; // 001 11001 0101 0011
2928         break;
2929       case 1:
2930         ltpCX = 0x079a; // 0011 11001 101 0
2931         break;
2932       case 2:
2933         ltpCX = 0x0e3; // 001 1100 01 1
2934         break;
2935       case 3:
2936         ltpCX = 0x18a; // 01100 0101 1
2937         break;
2938       }
2939     }
2940
2941     ltp = 0;
2942     cx = cx0 = cx1 = cx2 = 0; // make gcc happy
2943     for (y = 0; y < h; ++y) {
2944
2945       // check for a "typical" (duplicate) row
2946       if (tpgdOn) {
2947         if (arithDecoder->decodeBit(ltpCX, genericRegionStats)) {
2948           ltp = !ltp;
2949         }
2950         if (ltp) {
2951           bitmap->duplicateRow(y, y-1);
2952           continue;
2953         }
2954       }
2955
2956       switch (templ) {
2957       case 0:
2958
2959         // set up the context
2960         bitmap->getPixelPtr(0, y-2, &cxPtr0);
2961         cx0 = bitmap->nextPixel(&cxPtr0);
2962         cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
2963         bitmap->getPixelPtr(0, y-1, &cxPtr1);
2964         cx1 = bitmap->nextPixel(&cxPtr1);
2965         cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
2966         cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
2967         cx2 = 0;
2968         bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
2969         bitmap->getPixelPtr(atx[1], y + aty[1], &atPtr1);
2970         bitmap->getPixelPtr(atx[2], y + aty[2], &atPtr2);
2971         bitmap->getPixelPtr(atx[3], y + aty[3], &atPtr3);
2972
2973         // decode the row
2974         for (x = 0; x < w; ++x) {
2975
2976           // build the context
2977           cx = (cx0 << 13) | (cx1 << 8) | (cx2 << 4) |
2978                (bitmap->nextPixel(&atPtr0) << 3) |
2979                (bitmap->nextPixel(&atPtr1) << 2) |
2980                (bitmap->nextPixel(&atPtr2) << 1) |
2981                bitmap->nextPixel(&atPtr3);
2982
2983           // check for a skipped pixel
2984           if (useSkip && skip->getPixel(x, y)) {
2985             pix = 0;
2986
2987           // decode the pixel
2988           } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
2989             bitmap->setPixel(x, y);
2990           }
2991
2992           // update the context
2993           cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07;
2994           cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
2995           cx2 = ((cx2 << 1) | pix) & 0x0f;
2996         }
2997         break;
2998
2999       case 1:
3000
3001         // set up the context
3002         bitmap->getPixelPtr(0, y-2, &cxPtr0);
3003         cx0 = bitmap->nextPixel(&cxPtr0);
3004         cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
3005         cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
3006         bitmap->getPixelPtr(0, y-1, &cxPtr1);
3007         cx1 = bitmap->nextPixel(&cxPtr1);
3008         cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
3009         cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
3010         cx2 = 0;
3011         bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
3012
3013         // decode the row
3014         for (x = 0; x < w; ++x) {
3015
3016           // build the context
3017           cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
3018                bitmap->nextPixel(&atPtr0);
3019
3020           // check for a skipped pixel
3021           if (useSkip && skip->getPixel(x, y)) {
3022             pix = 0;
3023
3024           // decode the pixel
3025           } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3026             bitmap->setPixel(x, y);
3027           }
3028
3029           // update the context
3030           cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07;
3031           cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
3032           cx2 = ((cx2 << 1) | pix) & 0x0f;
3033         }
3034         break;
3035
3036       case 2:
3037
3038         // set up the context
3039         bitmap->getPixelPtr(0, y-2, &cxPtr0);
3040         cx0 = bitmap->nextPixel(&cxPtr0);
3041         cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
3042         bitmap->getPixelPtr(0, y-1, &cxPtr1);
3043         cx1 = bitmap->nextPixel(&cxPtr1);
3044         cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
3045         cx2 = 0;
3046         bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
3047
3048         // decode the row
3049         for (x = 0; x < w; ++x) {
3050
3051           // build the context
3052           cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
3053                bitmap->nextPixel(&atPtr0);
3054
3055           // check for a skipped pixel
3056           if (useSkip && skip->getPixel(x, y)) {
3057             pix = 0;
3058
3059           // decode the pixel
3060           } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3061             bitmap->setPixel(x, y);
3062           }
3063
3064           // update the context
3065           cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x0f;
3066           cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
3067           cx2 = ((cx2 << 1) | pix) & 0x07;
3068         }
3069         break;
3070
3071       case 3:
3072
3073         // set up the context
3074         bitmap->getPixelPtr(0, y-1, &cxPtr1);
3075         cx1 = bitmap->nextPixel(&cxPtr1);
3076         cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
3077         cx2 = 0;
3078         bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
3079
3080         // decode the row
3081         for (x = 0; x < w; ++x) {
3082
3083           // build the context
3084           cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
3085                bitmap->nextPixel(&atPtr0);
3086
3087           // check for a skipped pixel
3088           if (useSkip && skip->getPixel(x, y)) {
3089             pix = 0;
3090
3091           // decode the pixel
3092           } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3093             bitmap->setPixel(x, y);
3094           }
3095
3096           // update the context
3097           cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
3098           cx2 = ((cx2 << 1) | pix) & 0x0f;
3099         }
3100         break;
3101       }
3102     }
3103   }
3104
3105   return bitmap;
3106 }
3107
3108 void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum, GBool imm,
3109                                                  GBool lossless, Guint length,
3110                                                  Guint *refSegs,
3111                                                  Guint nRefSegs) {
3112   JBIG2Bitmap *bitmap, *refBitmap;
3113   Guint w, h, x, y, segInfoFlags, extCombOp;
3114   Guint flags, templ, tpgrOn;
3115   int atx[2], aty[2];
3116   JBIG2Segment *seg;
3117
3118   // region segment info field
3119   if (!readULong(&w) || !readULong(&h) ||
3120       !readULong(&x) || !readULong(&y) ||
3121       !readUByte(&segInfoFlags)) {
3122     goto eofError;
3123   }
3124   extCombOp = segInfoFlags & 7;
3125
3126   // rest of the generic refinement region segment header
3127   if (!readUByte(&flags)) {
3128     goto eofError;
3129   }
3130   templ = flags & 1;
3131   tpgrOn = (flags >> 1) & 1;
3132
3133   // AT flags
3134   if (!templ) {
3135     if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
3136         !readByte(&atx[1]) || !readByte(&aty[1])) {
3137       goto eofError;
3138     }
3139   }
3140
3141   // resize the page bitmap if needed
3142   if (nRefSegs == 0 || imm) {
3143     if (pageH == 0xffffffff && y + h > curPageH) {
3144       pageBitmap->expand(y + h, pageDefPixel);
3145     }
3146   }
3147
3148   // get referenced bitmap
3149   if (nRefSegs > 1) {
3150     error(getPos(), "Bad reference in JBIG2 generic refinement segment");
3151     return;
3152   }
3153   if (nRefSegs == 1) {
3154     seg = findSegment(refSegs[0]);
3155     if (seg->getType() != jbig2SegBitmap) {
3156       error(getPos(), "Bad bitmap reference in JBIG2 generic refinement segment");
3157       return;
3158     }
3159     refBitmap = (JBIG2Bitmap *)seg;
3160   } else {
3161     refBitmap = pageBitmap->getSlice(x, y, w, h);
3162   }
3163
3164   // set up the arithmetic decoder
3165   resetRefinementStats(templ, NULL);
3166   arithDecoder->start();
3167
3168   // read
3169   bitmap = readGenericRefinementRegion(w, h, templ, tpgrOn,
3170                                        refBitmap, 0, 0, atx, aty);
3171
3172   // combine the region bitmap into the page bitmap
3173   if (imm) {
3174     pageBitmap->combine(bitmap, x, y, extCombOp);
3175     delete bitmap;
3176
3177   // store the region bitmap
3178   } else {
3179     bitmap->setSegNum(segNum);
3180     segments->append(bitmap);
3181   }
3182
3183   // delete the referenced bitmap
3184   if (nRefSegs == 1) {
3185     discardSegment(refSegs[0]);
3186   } else {
3187     delete refBitmap;
3188   }
3189
3190   return;
3191
3192  eofError:
3193   error(getPos(), "Unexpected EOF in JBIG2 stream");
3194 }
3195
3196 JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion(int w, int h,
3197                                                       int templ, GBool tpgrOn,
3198                                                       JBIG2Bitmap *refBitmap,
3199                                                       int refDX, int refDY,
3200                                                       int *atx, int *aty) {
3201   JBIG2Bitmap *bitmap;
3202   GBool ltp;
3203   Guint ltpCX, cx, cx0, cx2, cx3, cx4, tpgrCX0, tpgrCX1, tpgrCX2;
3204   JBIG2BitmapPtr cxPtr0, cxPtr1, cxPtr2, cxPtr3, cxPtr4, cxPtr5, cxPtr6;
3205   JBIG2BitmapPtr tpgrCXPtr0, tpgrCXPtr1, tpgrCXPtr2;
3206   int x, y, pix;
3207
3208   bitmap = new JBIG2Bitmap(0, w, h);
3209   bitmap->clearToZero();
3210
3211   // set up the typical row context
3212   if (templ) {
3213     ltpCX = 0x008;
3214   } else {
3215     ltpCX = 0x0010;
3216   }
3217
3218   ltp = 0;
3219   for (y = 0; y < h; ++y) {
3220
3221     if (templ) {
3222
3223       // set up the context
3224       bitmap->getPixelPtr(0, y-1, &cxPtr0);
3225       cx0 = bitmap->nextPixel(&cxPtr0);
3226       bitmap->getPixelPtr(-1, y, &cxPtr1);
3227       refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2);
3228       refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3);
3229       cx3 = refBitmap->nextPixel(&cxPtr3);
3230       cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3);
3231       refBitmap->getPixelPtr(-refDX, y+1-refDY, &cxPtr4);
3232       cx4 = refBitmap->nextPixel(&cxPtr4);
3233
3234       // set up the typical prediction context
3235       tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy
3236       if (tpgrOn) {
3237         refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0);
3238         tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0);
3239         tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3240         tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3241         refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1);
3242         tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1);
3243         tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3244         tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3245         refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2);
3246         tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
3247         tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3248         tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3249       }
3250
3251       for (x = 0; x < w; ++x) {
3252
3253         // update the context
3254         cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 7;
3255         cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7;
3256         cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 3;
3257
3258         if (tpgrOn) {
3259           // update the typical predictor context
3260           tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7;
3261           tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7;
3262           tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7;
3263
3264           // check for a "typical" pixel
3265           if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
3266             ltp = !ltp;
3267           }
3268           if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
3269             bitmap->clearPixel(x, y);
3270             continue;
3271           } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
3272             bitmap->setPixel(x, y);
3273             continue;
3274           }
3275         }
3276
3277         // build the context
3278         cx = (cx0 << 7) | (bitmap->nextPixel(&cxPtr1) << 6) |
3279              (refBitmap->nextPixel(&cxPtr2) << 5) |
3280              (cx3 << 2) | cx4;
3281
3282         // decode the pixel
3283         if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
3284           bitmap->setPixel(x, y);
3285         }
3286       }
3287
3288     } else {
3289
3290       // set up the context
3291       bitmap->getPixelPtr(0, y-1, &cxPtr0);
3292       cx0 = bitmap->nextPixel(&cxPtr0);
3293       bitmap->getPixelPtr(-1, y, &cxPtr1);
3294       refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2);
3295       cx2 = refBitmap->nextPixel(&cxPtr2);
3296       refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3);
3297       cx3 = refBitmap->nextPixel(&cxPtr3);
3298       cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3);
3299       refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &cxPtr4);
3300       cx4 = refBitmap->nextPixel(&cxPtr4);
3301       cx4 = (cx4 << 1) | refBitmap->nextPixel(&cxPtr4);
3302       bitmap->getPixelPtr(atx[0], y+aty[0], &cxPtr5);
3303       refBitmap->getPixelPtr(atx[1]-refDX, y+aty[1]-refDY, &cxPtr6);
3304
3305       // set up the typical prediction context
3306       tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy
3307       if (tpgrOn) {
3308         refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0);
3309         tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0);
3310         tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3311         tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3312         refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1);
3313         tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1);
3314         tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3315         tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3316         refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2);
3317         tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
3318         tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3319         tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3320       }
3321
3322       for (x = 0; x < w; ++x) {
3323
3324         // update the context
3325         cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 3;
3326         cx2 = ((cx2 << 1) | refBitmap->nextPixel(&cxPtr2)) & 3;
3327         cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7;
3328         cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 7;
3329
3330         if (tpgrOn) {
3331           // update the typical predictor context
3332           tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7;
3333           tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7;
3334           tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7;
3335
3336           // check for a "typical" pixel
3337           if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
3338             ltp = !ltp;
3339           }
3340           if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
3341             bitmap->clearPixel(x, y);
3342             continue;
3343           } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
3344             bitmap->setPixel(x, y);
3345             continue;
3346           }
3347         }
3348
3349         // build the context
3350         cx = (cx0 << 11) | (bitmap->nextPixel(&cxPtr1) << 10) |
3351              (cx2 << 8) | (cx3 << 5) | (cx4 << 2) |
3352              (bitmap->nextPixel(&cxPtr5) << 1) |
3353              refBitmap->nextPixel(&cxPtr6);
3354
3355         // decode the pixel
3356         if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
3357           bitmap->setPixel(x, y);
3358         }
3359       }
3360     }
3361   }
3362
3363   return bitmap;
3364 }
3365
3366 void JBIG2Stream::readPageInfoSeg(Guint length) {
3367   Guint xRes, yRes, flags, striping;
3368
3369   if (!readULong(&pageW) || !readULong(&pageH) ||
3370       !readULong(&xRes) || !readULong(&yRes) ||
3371       !readUByte(&flags) || !readUWord(&striping)) {
3372     goto eofError;
3373   }
3374   pageDefPixel = (flags >> 2) & 1;
3375   defCombOp = (flags >> 3) & 3;
3376
3377   // allocate the page bitmap
3378   if (pageH == 0xffffffff) {
3379     curPageH = striping & 0x7fff;
3380   } else {
3381     curPageH = pageH;
3382   }
3383   pageBitmap = new JBIG2Bitmap(0, pageW, curPageH);
3384
3385   // default pixel value
3386   if (pageDefPixel) {
3387     pageBitmap->clearToOne();
3388   } else {
3389     pageBitmap->clearToZero();
3390   }
3391
3392   return;
3393
3394  eofError:
3395   error(getPos(), "Unexpected EOF in JBIG2 stream");
3396 }
3397
3398 void JBIG2Stream::readEndOfStripeSeg(Guint length) {
3399   Guint i;
3400
3401   // skip the segment
3402   for (i = 0; i < length; ++i) {
3403     curStr->getChar();
3404   }
3405 }
3406
3407 void JBIG2Stream::readProfilesSeg(Guint length) {
3408   Guint i;
3409
3410   // skip the segment
3411   for (i = 0; i < length; ++i) {
3412     curStr->getChar();
3413   }
3414 }
3415
3416 void JBIG2Stream::readCodeTableSeg(Guint segNum, Guint length) {
3417   JBIG2HuffmanTable *huffTab;
3418   Guint flags, oob, prefixBits, rangeBits;
3419   int lowVal, highVal, val;
3420   Guint huffTabSize, i;
3421
3422   if (!readUByte(&flags) || !readLong(&lowVal) || !readLong(&highVal)) {
3423     goto eofError;
3424   }
3425   oob = flags & 1;
3426   prefixBits = ((flags >> 1) & 7) + 1;
3427   rangeBits = ((flags >> 4) & 7) + 1;
3428
3429   huffDecoder->reset();
3430   huffTabSize = 8;
3431   huffTab = (JBIG2HuffmanTable *)
3432                 gmalloc(huffTabSize * sizeof(JBIG2HuffmanTable));
3433   i = 0;
3434   val = lowVal;
3435   while (val < highVal) {
3436     if (i == huffTabSize) {
3437       huffTabSize *= 2;
3438       huffTab = (JBIG2HuffmanTable *)
3439                     grealloc(huffTab, huffTabSize * sizeof(JBIG2HuffmanTable));
3440     }
3441     huffTab[i].val = val;
3442     huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3443     huffTab[i].rangeLen = huffDecoder->readBits(rangeBits);
3444     val += 1 << huffTab[i].rangeLen;
3445     ++i;
3446   }
3447   if (i + oob + 3 > huffTabSize) {
3448     huffTabSize = i + oob + 3;
3449     huffTab = (JBIG2HuffmanTable *)
3450                   grealloc(huffTab, huffTabSize * sizeof(JBIG2HuffmanTable));
3451   }
3452   huffTab[i].val = lowVal - 1;
3453   huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3454   huffTab[i].rangeLen = jbig2HuffmanLOW;
3455   ++i;
3456   huffTab[i].val = highVal;
3457   huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3458   huffTab[i].rangeLen = 32;
3459   ++i;
3460   if (oob) {
3461     huffTab[i].val = 0;
3462     huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3463     huffTab[i].rangeLen = jbig2HuffmanOOB;
3464     ++i;
3465   }
3466   huffTab[i].val = 0;
3467   huffTab[i].prefixLen = 0;
3468   huffTab[i].rangeLen = jbig2HuffmanEOT;
3469   huffDecoder->buildTable(huffTab, i);
3470
3471   // create and store the new table segment
3472   segments->append(new JBIG2CodeTable(segNum, huffTab));
3473
3474   return;
3475
3476  eofError:
3477   error(getPos(), "Unexpected EOF in JBIG2 stream");
3478 }
3479
3480 void JBIG2Stream::readExtensionSeg(Guint length) {
3481   Guint i;
3482
3483   // skip the segment
3484   for (i = 0; i < length; ++i) {
3485     curStr->getChar();
3486   }
3487 }
3488
3489 JBIG2Segment *JBIG2Stream::findSegment(Guint segNum) {
3490   JBIG2Segment *seg;
3491   int i;
3492
3493   for (i = 0; i < globalSegments->getLength(); ++i) {
3494     seg = (JBIG2Segment *)globalSegments->get(i);
3495     if (seg->getSegNum() == segNum) {
3496       return seg;
3497     }
3498   }
3499   for (i = 0; i < segments->getLength(); ++i) {
3500     seg = (JBIG2Segment *)segments->get(i);
3501     if (seg->getSegNum() == segNum) {
3502       return seg;
3503     }
3504   }
3505   return NULL;
3506 }
3507
3508 void JBIG2Stream::discardSegment(Guint segNum) {
3509   JBIG2Segment *seg;
3510   int i;
3511
3512   for (i = 0; i < globalSegments->getLength(); ++i) {
3513     seg = (JBIG2Segment *)globalSegments->get(i);
3514     if (seg->getSegNum() == segNum) {
3515       globalSegments->del(i);
3516       return;
3517     }
3518   }
3519   for (i = 0; i < segments->getLength(); ++i) {
3520     seg = (JBIG2Segment *)segments->get(i);
3521     if (seg->getSegNum() == segNum) {
3522       globalSegments->del(i);
3523       return;
3524     }
3525   }
3526 }
3527
3528 void JBIG2Stream::resetGenericStats(Guint templ,
3529                                     JBIG2ArithmeticDecoderStats *prevStats) {
3530   int size;
3531
3532   size = contextSize[templ];
3533   if (prevStats && prevStats->getContextSize() == size) {
3534     if (genericRegionStats->getContextSize() == size) {
3535       genericRegionStats->copyFrom(prevStats);
3536     } else {
3537       delete genericRegionStats;
3538       genericRegionStats = prevStats->copy();
3539     }
3540   } else {
3541     if (genericRegionStats->getContextSize() == size) {
3542       genericRegionStats->reset();
3543     } else {
3544       delete genericRegionStats;
3545       genericRegionStats = new JBIG2ArithmeticDecoderStats(size);
3546     }
3547   }
3548 }
3549
3550 void JBIG2Stream::resetRefinementStats(
3551                       Guint templ,
3552                       JBIG2ArithmeticDecoderStats *prevStats) {
3553   int size;
3554
3555   size = refContextSize[templ];
3556   if (prevStats && prevStats->getContextSize() == size) {
3557     if (refinementRegionStats->getContextSize() == size) {
3558       refinementRegionStats->copyFrom(prevStats);
3559     } else {
3560       delete refinementRegionStats;
3561       refinementRegionStats = prevStats->copy();
3562     }
3563   } else {
3564     if (refinementRegionStats->getContextSize() == size) {
3565       refinementRegionStats->reset();
3566     } else {
3567       delete refinementRegionStats;
3568       refinementRegionStats = new JBIG2ArithmeticDecoderStats(size);
3569     }
3570   }
3571 }
3572
3573 void JBIG2Stream::resetIntStats(int symCodeLen) {
3574   iadhStats->reset();
3575   iadwStats->reset();
3576   iaexStats->reset();
3577   iaaiStats->reset();
3578   iadtStats->reset();
3579   iaitStats->reset();
3580   iafsStats->reset();
3581   iadsStats->reset();
3582   iardxStats->reset();
3583   iardyStats->reset();
3584   iardwStats->reset();
3585   iardhStats->reset();
3586   iariStats->reset();
3587   if (iaidStats->getContextSize() == symCodeLen + 1) {
3588     iaidStats->reset();
3589   } else {
3590     delete iaidStats;
3591     iaidStats = new JBIG2ArithmeticDecoderStats(symCodeLen + 1);
3592   }
3593 }
3594
3595 GBool JBIG2Stream::readUByte(Guint *x) {
3596   int c0;
3597
3598   if ((c0 = curStr->getChar()) == EOF) {
3599     return gFalse;
3600   }
3601   *x = (Guint)c0;
3602   return gTrue;
3603 }
3604
3605 GBool JBIG2Stream::readByte(int *x) {
3606  int c0;
3607
3608   if ((c0 = curStr->getChar()) == EOF) {
3609     return gFalse;
3610   }
3611   *x = c0;
3612   if (c0 & 0x80) {
3613     *x |= -1 - 0xff;
3614   }
3615   return gTrue;
3616 }
3617
3618 GBool JBIG2Stream::readUWord(Guint *x) {
3619   int c0, c1;
3620
3621   if ((c0 = curStr->getChar()) == EOF ||
3622       (c1 = curStr->getChar()) == EOF) {
3623     return gFalse;
3624   }
3625   *x = (Guint)((c0 << 8) | c1);
3626   return gTrue;
3627 }
3628
3629 GBool JBIG2Stream::readULong(Guint *x) {
3630   int c0, c1, c2, c3;
3631
3632   if ((c0 = curStr->getChar()) == EOF ||
3633       (c1 = curStr->getChar()) == EOF ||
3634       (c2 = curStr->getChar()) == EOF ||
3635       (c3 = curStr->getChar()) == EOF) {
3636     return gFalse;
3637   }
3638   *x = (Guint)((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
3639   return gTrue;
3640 }
3641
3642 GBool JBIG2Stream::readLong(int *x) {
3643   int c0, c1, c2, c3;
3644
3645   if ((c0 = curStr->getChar()) == EOF ||
3646       (c1 = curStr->getChar()) == EOF ||
3647       (c2 = curStr->getChar()) == EOF ||
3648       (c3 = curStr->getChar()) == EOF) {
3649     return gFalse;
3650   }
3651   *x = ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
3652   if (c0 & 0x80) {
3653     *x |= -1 - (int)0xffffffff;
3654   }
3655   return gTrue;
3656 }