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