source: trunk/poppler/mypoppler/poppler/JBIG2Stream.cc @ 44

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

poppler updated to version 0.5.2, also needed changes to be compatible with new poppler

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