1 //========================================================================
5 // Copyright 2002-2003 Glyph & Cog, LLC
7 //========================================================================
11 #ifdef USE_GCC_PRAGMAS
12 #pragma implementation
18 #include "JArithmeticDecoder.h"
19 #include "JBIG2Stream.h"
21 //~ share these tables
22 #include "Stream-CCITT.h"
24 //------------------------------------------------------------------------
26 static int contextSize[4] = { 16, 13, 10, 10 };
27 static int refContextSize[2] = { 13, 10 };
29 //------------------------------------------------------------------------
31 //------------------------------------------------------------------------
33 #define jbig2HuffmanLOW 0xfffffffd
34 #define jbig2HuffmanOOB 0xfffffffe
35 #define jbig2HuffmanEOT 0xffffffff
37 struct JBIG2HuffmanTable {
40 Guint rangeLen; // can also be LOW, OOB, or EOT
44 JBIG2HuffmanTable huffTableA[] = {
47 { 272, 3, 16, 0x006 },
48 { 65808, 3, 32, 0x007 },
49 { 0, 0, jbig2HuffmanEOT, 0 }
52 JBIG2HuffmanTable huffTableB[] = {
59 { 0, 6, jbig2HuffmanOOB, 0x03f },
60 { 0, 0, jbig2HuffmanEOT, 0 }
63 JBIG2HuffmanTable huffTableC[] = {
69 { 0, 6, jbig2HuffmanOOB, 0x03e },
71 { -256, 8, 8, 0x0fe },
72 { -257, 8, jbig2HuffmanLOW, 0x0ff },
73 { 0, 0, jbig2HuffmanEOT, 0 }
76 JBIG2HuffmanTable huffTableD[] = {
83 { 0, 0, jbig2HuffmanEOT, 0 }
86 JBIG2HuffmanTable huffTableE[] = {
93 { -255, 7, 8, 0x07e },
94 { -256, 7, jbig2HuffmanLOW, 0x07f },
95 { 0, 0, jbig2HuffmanEOT, 0 }
98 JBIG2HuffmanTable huffTableF[] = {
100 { 128, 3, 7, 0x002 },
101 { 256, 3, 8, 0x003 },
102 { -1024, 4, 9, 0x008 },
103 { -512, 4, 8, 0x009 },
104 { -256, 4, 7, 0x00a },
105 { -32, 4, 5, 0x00b },
106 { 512, 4, 9, 0x00c },
107 { 1024, 4, 10, 0x00d },
108 { -2048, 5, 10, 0x01c },
109 { -128, 5, 6, 0x01d },
110 { -64, 5, 5, 0x01e },
111 { -2049, 6, jbig2HuffmanLOW, 0x03e },
112 { 2048, 6, 32, 0x03f },
113 { 0, 0, jbig2HuffmanEOT, 0 }
116 JBIG2HuffmanTable huffTableG[] = {
117 { -512, 3, 8, 0x000 },
118 { 256, 3, 8, 0x001 },
119 { 512, 3, 9, 0x002 },
120 { 1024, 3, 10, 0x003 },
121 { -1024, 4, 9, 0x008 },
122 { -256, 4, 7, 0x009 },
123 { -32, 4, 5, 0x00a },
125 { 128, 4, 7, 0x00c },
126 { -128, 5, 6, 0x01a },
127 { -64, 5, 5, 0x01b },
130 { -1025, 5, jbig2HuffmanLOW, 0x01e },
131 { 2048, 5, 32, 0x01f },
132 { 0, 0, jbig2HuffmanEOT, 0 }
135 JBIG2HuffmanTable huffTableH[] = {
137 { 0, 2, jbig2HuffmanOOB, 0x001 },
144 { 134, 5, 7, 0x01c },
147 { 262, 6, 7, 0x03c },
148 { 646, 6, 10, 0x03d },
150 { 390, 7, 8, 0x07d },
151 { -15, 8, 3, 0x0fc },
155 { -16, 9, jbig2HuffmanLOW, 0x1fe },
156 { 1670, 9, 32, 0x1ff },
157 { 0, 0, jbig2HuffmanEOT, 0 }
160 JBIG2HuffmanTable huffTableI[] = {
161 { 0, 2, jbig2HuffmanOOB, 0x000 },
169 { 139, 5, 7, 0x01b },
170 { 267, 5, 8, 0x01c },
173 { 523, 6, 8, 0x03c },
174 { 1291, 6, 11, 0x03d },
176 { 779, 7, 9, 0x07d },
177 { -31, 8, 4, 0x0fc },
178 { -11, 8, 2, 0x0fd },
179 { -15, 9, 2, 0x1fc },
181 { -32, 9, jbig2HuffmanLOW, 0x1fe },
182 { 3339, 9, 32, 0x1ff },
183 { 0, 0, jbig2HuffmanEOT, 0 }
186 JBIG2HuffmanTable huffTableJ[] = {
189 { 0, 2, jbig2HuffmanOOB, 0x002 },
194 { 102, 6, 5, 0x037 },
195 { 134, 6, 6, 0x038 },
196 { 198, 6, 7, 0x039 },
197 { 326, 6, 8, 0x03a },
198 { 582, 6, 9, 0x03b },
199 { 1094, 6, 10, 0x03c },
200 { -21, 7, 4, 0x07a },
203 { 2118, 7, 11, 0x07d },
206 { -22, 8, jbig2HuffmanLOW, 0x0fe },
207 { 4166, 8, 32, 0x0ff },
208 { 0, 0, jbig2HuffmanEOT, 0 }
211 JBIG2HuffmanTable huffTableK[] = {
224 { 141, 7, 32, 0x07f },
225 { 0, 0, jbig2HuffmanEOT, 0 }
228 JBIG2HuffmanTable huffTableL[] = {
241 { 73, 8, 32, 0x0ff },
242 { 0, 0, jbig2HuffmanEOT, 0 }
245 JBIG2HuffmanTable huffTableM[] = {
258 { 141, 7, 32, 0x07f },
259 { 0, 0, jbig2HuffmanEOT, 0 }
262 JBIG2HuffmanTable huffTableN[] = {
268 { 0, 0, jbig2HuffmanEOT, 0 }
271 JBIG2HuffmanTable huffTableO[] = {
281 { -24, 7, 4, 0x07c },
283 { -25, 7, jbig2HuffmanLOW, 0x07e },
284 { 25, 7, 32, 0x07f },
285 { 0, 0, jbig2HuffmanEOT, 0 }
288 //------------------------------------------------------------------------
289 // JBIG2HuffmanDecoder
290 //------------------------------------------------------------------------
292 class JBIG2HuffmanDecoder {
295 JBIG2HuffmanDecoder();
296 ~JBIG2HuffmanDecoder();
297 void setStream(Stream *strA) { str = strA; }
301 // Returns false for OOB, otherwise sets *<x> and returns true.
302 GBool decodeInt(int *x, JBIG2HuffmanTable *table);
304 Guint readBits(Guint n);
307 // Sort the table by prefix length and assign prefix values.
308 void buildTable(JBIG2HuffmanTable *table, Guint len);
317 JBIG2HuffmanDecoder::JBIG2HuffmanDecoder() {
322 JBIG2HuffmanDecoder::~JBIG2HuffmanDecoder() {
325 void JBIG2HuffmanDecoder::reset() {
331 GBool JBIG2HuffmanDecoder::decodeInt(int *x, JBIG2HuffmanTable *table) {
332 Guint i, len, prefix;
337 while (table[i].rangeLen != jbig2HuffmanEOT) {
338 while (len < table[i].prefixLen) {
339 prefix = (prefix << 1) | readBit();
342 if (prefix == table[i].prefix) {
343 if (table[i].rangeLen == jbig2HuffmanOOB) {
346 if (table[i].rangeLen == jbig2HuffmanLOW) {
347 *x = table[i].val - readBits(32);
348 } else if (table[i].rangeLen > 0) {
349 *x = table[i].val + readBits(table[i].rangeLen);
360 Guint JBIG2HuffmanDecoder::readBits(Guint n) {
361 Guint x, mask, nLeft;
363 mask = (n == 32) ? 0xffffffff : ((1 << n) - 1);
365 x = (buf >> (bufLen - n)) & mask;
368 x = buf & ((1 << bufLen) - 1);
372 x = (x << 8) | (str->getChar() & 0xff);
376 buf = str->getChar();
378 x = (x << nLeft) | ((buf >> bufLen) & ((1 << nLeft) - 1));
384 Guint JBIG2HuffmanDecoder::readBit() {
386 buf = str->getChar();
390 return (buf >> bufLen) & 1;
393 void JBIG2HuffmanDecoder::buildTable(JBIG2HuffmanTable *table, Guint len) {
394 Guint i, j, k, prefix;
395 JBIG2HuffmanTable tab;
397 // stable selection sort:
398 // - entries with prefixLen > 0, in ascending prefixLen order
399 // - entry with prefixLen = 0, rangeLen = EOT
400 // - all other entries with prefixLen = 0
401 // (on entry, table[len] has prefixLen = 0, rangeLen = EOT)
402 for (i = 0; i < len; ++i) {
403 for (j = i; j < len && table[j].prefixLen == 0; ++j) ;
407 for (k = j + 1; k < len; ++k) {
408 if (table[k].prefixLen > 0 &&
409 table[k].prefixLen < table[j].prefixLen) {
415 for (k = j; k > i; --k) {
416 table[k] = table[k - 1];
421 table[i] = table[len];
426 table[i++].prefix = prefix++;
427 for (; table[i].rangeLen != jbig2HuffmanEOT; ++i) {
428 prefix <<= table[i].prefixLen - table[i-1].prefixLen;
429 table[i].prefix = prefix++;
433 //------------------------------------------------------------------------
435 //------------------------------------------------------------------------
437 class JBIG2MMRDecoder {
442 void setStream(Stream *strA) { str = strA; }
448 void skipTo(Guint length);
458 JBIG2MMRDecoder::JBIG2MMRDecoder() {
463 JBIG2MMRDecoder::~JBIG2MMRDecoder() {
466 void JBIG2MMRDecoder::reset() {
472 int JBIG2MMRDecoder::get2DCode() {
476 buf = str->getChar() & 0xff;
479 p = &twoDimTab1[(buf >> 1) & 0x7f];
480 } else if (bufLen == 8) {
481 p = &twoDimTab1[(buf >> 1) & 0x7f];
483 p = &twoDimTab1[(buf << (7 - bufLen)) & 0x7f];
484 if (p->bits < 0 || p->bits > (int)bufLen) {
485 buf = (buf << 8) | (str->getChar() & 0xff);
488 p = &twoDimTab1[(buf >> (bufLen - 7)) & 0x7f];
492 error(str->getPos(), "Bad two dim code in JBIG2 MMR stream");
499 int JBIG2MMRDecoder::getWhiteCode() {
504 buf = str->getChar() & 0xff;
509 if (bufLen >= 7 && ((buf >> (bufLen - 7)) & 0x7f) == 0) {
511 code = buf << (12 - bufLen);
513 code = buf >> (bufLen - 12);
515 p = &whiteTab1[code & 0x1f];
518 code = buf << (9 - bufLen);
520 code = buf >> (bufLen - 9);
522 p = &whiteTab2[code & 0x1ff];
524 if (p->bits > 0 && p->bits <= (int)bufLen) {
531 buf = (buf << 8) | (str->getChar() & 0xff);
535 error(str->getPos(), "Bad white code in JBIG2 MMR stream");
536 // eat a bit and return a positive number so that the caller doesn't
537 // go into an infinite loop
542 int JBIG2MMRDecoder::getBlackCode() {
547 buf = str->getChar() & 0xff;
552 if (bufLen >= 6 && ((buf >> (bufLen - 6)) & 0x3f) == 0) {
554 code = buf << (13 - bufLen);
556 code = buf >> (bufLen - 13);
558 p = &blackTab1[code & 0x7f];
559 } else if (bufLen >= 4 && ((buf >> (bufLen - 4)) & 0x0f) == 0) {
561 code = buf << (12 - bufLen);
563 code = buf >> (bufLen - 12);
565 p = &blackTab2[(code & 0xff) - 64];
568 code = buf << (6 - bufLen);
570 code = buf >> (bufLen - 6);
572 p = &blackTab3[code & 0x3f];
574 if (p->bits > 0 && p->bits <= (int)bufLen) {
581 buf = (buf << 8) | (str->getChar() & 0xff);
585 error(str->getPos(), "Bad black code in JBIG2 MMR stream");
586 // eat a bit and return a positive number so that the caller doesn't
587 // go into an infinite loop
592 Guint JBIG2MMRDecoder::get24Bits() {
593 while (bufLen < 24) {
594 buf = (buf << 8) | (str->getChar() & 0xff);
598 return (buf >> (bufLen - 24)) & 0xffffff;
601 void JBIG2MMRDecoder::skipTo(Guint length) {
602 while (nBytesRead < length) {
608 //------------------------------------------------------------------------
610 //------------------------------------------------------------------------
612 enum JBIG2SegmentType {
622 JBIG2Segment(Guint segNumA) { segNum = segNumA; }
623 virtual ~JBIG2Segment() {}
624 void setSegNum(Guint segNumA) { segNum = segNumA; }
625 Guint getSegNum() { return segNum; }
626 virtual JBIG2SegmentType getType() = 0;
633 //------------------------------------------------------------------------
635 //------------------------------------------------------------------------
637 struct JBIG2BitmapPtr {
643 class JBIG2Bitmap: public JBIG2Segment {
646 JBIG2Bitmap(Guint segNumA, int wA, int hA);
647 virtual ~JBIG2Bitmap();
648 virtual JBIG2SegmentType getType() { return jbig2SegBitmap; }
649 JBIG2Bitmap *copy() { return new JBIG2Bitmap(0, this); }
650 JBIG2Bitmap *getSlice(Guint x, Guint y, Guint wA, Guint hA);
651 void expand(int newH, Guint pixel);
654 int getWidth() { return w; }
655 int getHeight() { return h; }
656 int getPixel(int x, int y)
657 { return (x < 0 || x >= w || y < 0 || y >= h) ? 0 :
658 (data[y * line + (x >> 3)] >> (7 - (x & 7))) & 1; }
659 void setPixel(int x, int y)
660 { data[y * line + (x >> 3)] |= 1 << (7 - (x & 7)); }
661 void clearPixel(int x, int y)
662 { data[y * line + (x >> 3)] &= 0x7f7f >> (x & 7); }
663 void getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr);
664 int nextPixel(JBIG2BitmapPtr *ptr);
665 void duplicateRow(int yDest, int ySrc);
666 void combine(JBIG2Bitmap *bitmap, int x, int y, Guint combOp);
667 Guchar *getDataPtr() { return data; }
668 int getDataSize() { return h * line; }
672 JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap);
678 JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, int wA, int hA):
679 JBIG2Segment(segNumA)
683 line = (wA + 7) >> 3;
684 data = (Guchar *)gmalloc(h * line);
687 JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap):
688 JBIG2Segment(segNumA)
693 data = (Guchar *)gmalloc(h * line);
694 memcpy(data, bitmap->data, h * line);
697 JBIG2Bitmap::~JBIG2Bitmap() {
702 JBIG2Bitmap *JBIG2Bitmap::getSlice(Guint x, Guint y, Guint wA, Guint hA) {
706 slice = new JBIG2Bitmap(0, wA, hA);
707 slice->clearToZero();
708 for (yy = 0; yy < hA; ++yy) {
709 for (xx = 0; xx < wA; ++xx) {
710 if (getPixel(x + xx, y + yy)) {
711 slice->setPixel(xx, yy);
718 void JBIG2Bitmap::expand(int newH, Guint pixel) {
722 data = (Guchar *)grealloc(data, newH * line);
724 memset(data + h * line, 0xff, (newH - h) * line);
726 memset(data + h * line, 0x00, (newH - h) * line);
731 void JBIG2Bitmap::clearToZero() {
732 memset(data, 0, h * line);
735 void JBIG2Bitmap::clearToOne() {
736 memset(data, 0xff, h * line);
739 inline void JBIG2Bitmap::getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr) {
740 if (y < 0 || y >= h || x >= w) {
743 ptr->p = &data[y * line];
747 ptr->p = &data[y * line + (x >> 3)];
748 ptr->shift = 7 - (x & 7);
753 inline int JBIG2Bitmap::nextPixel(JBIG2BitmapPtr *ptr) {
758 } else if (ptr->x < 0) {
762 pix = (*ptr->p >> ptr->shift) & 1;
765 } else if (ptr->shift == 0) {
775 void JBIG2Bitmap::duplicateRow(int yDest, int ySrc) {
776 memcpy(data + yDest * line, data + ySrc * line, line);
779 void JBIG2Bitmap::combine(JBIG2Bitmap *bitmap, int x, int y,
781 int x0, x1, y0, y1, xx, yy;
782 Guchar *srcPtr, *destPtr;
783 Guint src0, src1, src, dest, s1, s2, m1, m2, m3;
791 if (y + bitmap->h > h) {
815 m1 = 0xff >> (x1 & 7);
816 m2 = 0xff << (((x1 & 7) == 0) ? 0 : 8 - (x1 & 7));
817 m3 = (0xff >> s1) & m2;
819 oneByte = x0 == ((x1 - 1) & ~7);
821 for (yy = y0; yy < y1; ++yy) {
823 // one byte per line -- need to mask both left and right side
826 destPtr = data + (y + yy) * line + (x >> 3);
827 srcPtr = bitmap->data + yy * bitmap->line;
832 dest |= (src1 >> s1) & m2;
835 dest &= ((0xff00 | src1) >> s1) | m1;
838 dest ^= (src1 >> s1) & m2;
841 dest ^= ((src1 ^ 0xff) >> s1) & m2;
844 dest = (dest & ~m3) | ((src1 >> s1) & m3);
849 destPtr = data + (y + yy) * line;
850 srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
864 dest ^= (src1 ^ 0xff) & m2;
867 dest = (src1 & m2) | (dest & m1);
873 // multiple bytes per line -- need to mask left side of left-most
874 // byte and right side of right-most byte
879 destPtr = data + (y + yy) * line + (x >> 3);
880 srcPtr = bitmap->data + yy * bitmap->line;
888 dest &= (0xff00 | src1) >> s1;
894 dest ^= (src1 ^ 0xff) >> s1;
897 dest = (dest & (0xff << s2)) | (src1 >> s1);
903 destPtr = data + (y + yy) * line;
904 srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
910 for (; xx < x1 - 8; xx += 8) {
914 src = (((src0 << 8) | src1) >> s1) & 0xff;
939 src = (((src0 << 8) | src1) >> s1) & 0xff;
951 dest ^= (src ^ 0xff) & m2;
954 dest = (src & m2) | (dest & m1);
962 //------------------------------------------------------------------------
964 //------------------------------------------------------------------------
966 class JBIG2SymbolDict: public JBIG2Segment {
969 JBIG2SymbolDict(Guint segNumA, Guint sizeA);
970 virtual ~JBIG2SymbolDict();
971 virtual JBIG2SegmentType getType() { return jbig2SegSymbolDict; }
972 Guint getSize() { return size; }
973 void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
974 JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
975 void setGenericRegionStats(JArithmeticDecoderStats *stats)
976 { genericRegionStats = stats; }
977 void setRefinementRegionStats(JArithmeticDecoderStats *stats)
978 { refinementRegionStats = stats; }
979 JArithmeticDecoderStats *getGenericRegionStats()
980 { return genericRegionStats; }
981 JArithmeticDecoderStats *getRefinementRegionStats()
982 { return refinementRegionStats; }
987 JBIG2Bitmap **bitmaps;
988 JArithmeticDecoderStats *genericRegionStats;
989 JArithmeticDecoderStats *refinementRegionStats;
992 JBIG2SymbolDict::JBIG2SymbolDict(Guint segNumA, Guint sizeA):
993 JBIG2Segment(segNumA)
996 bitmaps = (JBIG2Bitmap **)gmalloc(size * sizeof(JBIG2Bitmap *));
997 genericRegionStats = NULL;
998 refinementRegionStats = NULL;
1001 JBIG2SymbolDict::~JBIG2SymbolDict() {
1004 for (i = 0; i < size; ++i) {
1008 if (genericRegionStats) {
1009 delete genericRegionStats;
1011 if (refinementRegionStats) {
1012 delete refinementRegionStats;
1016 //------------------------------------------------------------------------
1018 //------------------------------------------------------------------------
1020 class JBIG2PatternDict: public JBIG2Segment {
1023 JBIG2PatternDict(Guint segNumA, Guint sizeA);
1024 virtual ~JBIG2PatternDict();
1025 virtual JBIG2SegmentType getType() { return jbig2SegPatternDict; }
1026 Guint getSize() { return size; }
1027 void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
1028 JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
1033 JBIG2Bitmap **bitmaps;
1036 JBIG2PatternDict::JBIG2PatternDict(Guint segNumA, Guint sizeA):
1037 JBIG2Segment(segNumA)
1040 bitmaps = (JBIG2Bitmap **)gmalloc(size * sizeof(JBIG2Bitmap *));
1043 JBIG2PatternDict::~JBIG2PatternDict() {
1046 for (i = 0; i < size; ++i) {
1052 //------------------------------------------------------------------------
1054 //------------------------------------------------------------------------
1056 class JBIG2CodeTable: public JBIG2Segment {
1059 JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA);
1060 virtual ~JBIG2CodeTable();
1061 virtual JBIG2SegmentType getType() { return jbig2SegCodeTable; }
1062 JBIG2HuffmanTable *getHuffTable() { return table; }
1066 JBIG2HuffmanTable *table;
1069 JBIG2CodeTable::JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA):
1070 JBIG2Segment(segNumA)
1075 JBIG2CodeTable::~JBIG2CodeTable() {
1079 //------------------------------------------------------------------------
1081 //------------------------------------------------------------------------
1083 JBIG2Stream::JBIG2Stream(Stream *strA, Object *globalsStream):
1088 arithDecoder = new JArithmeticDecoder();
1089 genericRegionStats = new JArithmeticDecoderStats(1 << 1);
1090 refinementRegionStats = new JArithmeticDecoderStats(1 << 1);
1091 iadhStats = new JArithmeticDecoderStats(1 << 9);
1092 iadwStats = new JArithmeticDecoderStats(1 << 9);
1093 iaexStats = new JArithmeticDecoderStats(1 << 9);
1094 iaaiStats = new JArithmeticDecoderStats(1 << 9);
1095 iadtStats = new JArithmeticDecoderStats(1 << 9);
1096 iaitStats = new JArithmeticDecoderStats(1 << 9);
1097 iafsStats = new JArithmeticDecoderStats(1 << 9);
1098 iadsStats = new JArithmeticDecoderStats(1 << 9);
1099 iardxStats = new JArithmeticDecoderStats(1 << 9);
1100 iardyStats = new JArithmeticDecoderStats(1 << 9);
1101 iardwStats = new JArithmeticDecoderStats(1 << 9);
1102 iardhStats = new JArithmeticDecoderStats(1 << 9);
1103 iariStats = new JArithmeticDecoderStats(1 << 9);
1104 iaidStats = new JArithmeticDecoderStats(1 << 1);
1105 huffDecoder = new JBIG2HuffmanDecoder();
1106 mmrDecoder = new JBIG2MMRDecoder();
1108 segments = globalSegments = new GList();
1109 if (globalsStream->isStream()) {
1110 curStr = globalsStream->getStream();
1112 arithDecoder->setStream(curStr);
1113 huffDecoder->setStream(curStr);
1114 mmrDecoder->setStream(curStr);
1120 dataPtr = dataEnd = NULL;
1123 JBIG2Stream::~JBIG2Stream() {
1124 delete arithDecoder;
1125 delete genericRegionStats;
1126 delete refinementRegionStats;
1147 deleteGList(segments, JBIG2Segment);
1149 if (globalSegments) {
1150 deleteGList(globalSegments, JBIG2Segment);
1155 void JBIG2Stream::reset() {
1161 deleteGList(segments, JBIG2Segment);
1163 segments = new GList();
1167 arithDecoder->setStream(curStr);
1168 huffDecoder->setStream(curStr);
1169 mmrDecoder->setStream(curStr);
1173 dataPtr = pageBitmap->getDataPtr();
1174 dataEnd = dataPtr + pageBitmap->getDataSize();
1180 int JBIG2Stream::getChar() {
1181 if (dataPtr && dataPtr < dataEnd) {
1182 return (*dataPtr++ ^ 0xff) & 0xff;
1187 int JBIG2Stream::lookChar() {
1188 if (dataPtr && dataPtr < dataEnd) {
1189 return (*dataPtr ^ 0xff) & 0xff;
1194 GString *JBIG2Stream::getPSFilter(int psLevel, char *indent) {
1198 GBool JBIG2Stream::isBinary(GBool last) {
1199 return str->isBinary(gTrue);
1202 void JBIG2Stream::readSegments() {
1203 Guint segNum, segFlags, segType, page, segLength;
1204 Guint refFlags, nRefSegs;
1209 while (readULong(&segNum)) {
1211 // segment header flags
1212 if (!readUByte(&segFlags)) {
1215 segType = segFlags & 0x3f;
1217 // referred-to segment count and retention flags
1218 if (!readUByte(&refFlags)) {
1221 nRefSegs = refFlags >> 5;
1222 if (nRefSegs == 7) {
1223 if ((c1 = curStr->getChar()) == EOF ||
1224 (c2 = curStr->getChar()) == EOF ||
1225 (c3 = curStr->getChar()) == EOF) {
1228 refFlags = (refFlags << 24) | (c1 << 16) | (c2 << 8) | c3;
1229 nRefSegs = refFlags & 0x1fffffff;
1230 for (i = 0; i < (nRefSegs + 9) >> 3; ++i) {
1231 c1 = curStr->getChar();
1235 // referred-to segment numbers
1236 refSegs = (Guint *)gmalloc(nRefSegs * sizeof(Guint));
1237 if (segNum <= 256) {
1238 for (i = 0; i < nRefSegs; ++i) {
1239 if (!readUByte(&refSegs[i])) {
1243 } else if (segNum <= 65536) {
1244 for (i = 0; i < nRefSegs; ++i) {
1245 if (!readUWord(&refSegs[i])) {
1250 for (i = 0; i < nRefSegs; ++i) {
1251 if (!readULong(&refSegs[i])) {
1257 // segment page association
1258 if (segFlags & 0x40) {
1259 if (!readULong(&page)) {
1263 if (!readUByte(&page)) {
1268 // segment data length
1269 if (!readULong(&segLength)) {
1273 // read the segment data
1276 readSymbolDictSeg(segNum, segLength, refSegs, nRefSegs);
1279 readTextRegionSeg(segNum, gFalse, gFalse, segLength, refSegs, nRefSegs);
1282 readTextRegionSeg(segNum, gTrue, gFalse, segLength, refSegs, nRefSegs);
1285 readTextRegionSeg(segNum, gTrue, gTrue, segLength, refSegs, nRefSegs);
1288 readPatternDictSeg(segNum, segLength);
1291 readHalftoneRegionSeg(segNum, gFalse, gFalse, segLength,
1295 readHalftoneRegionSeg(segNum, gTrue, gFalse, segLength,
1299 readHalftoneRegionSeg(segNum, gTrue, gTrue, segLength,
1303 readGenericRegionSeg(segNum, gFalse, gFalse, segLength);
1306 readGenericRegionSeg(segNum, gTrue, gFalse, segLength);
1309 readGenericRegionSeg(segNum, gTrue, gTrue, segLength);
1312 readGenericRefinementRegionSeg(segNum, gFalse, gFalse, segLength,
1316 readGenericRefinementRegionSeg(segNum, gTrue, gFalse, segLength,
1320 readGenericRefinementRegionSeg(segNum, gTrue, gTrue, segLength,
1324 readPageInfoSeg(segLength);
1327 readEndOfStripeSeg(segLength);
1330 readProfilesSeg(segLength);
1333 readCodeTableSeg(segNum, segLength);
1336 readExtensionSeg(segLength);
1339 error(getPos(), "Unknown segment type in JBIG2 stream");
1340 for (i = 0; i < segLength; ++i) {
1341 if ((c1 = curStr->getChar()) == EOF) {
1356 error(getPos(), "Unexpected EOF in JBIG2 stream");
1359 void JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
1360 Guint *refSegs, Guint nRefSegs) {
1361 JBIG2SymbolDict *symbolDict;
1362 JBIG2HuffmanTable *huffDHTable, *huffDWTable;
1363 JBIG2HuffmanTable *huffBMSizeTable, *huffAggInstTable;
1366 JBIG2SymbolDict *inputSymbolDict;
1367 Guint flags, sdTemplate, sdrTemplate, huff, refAgg;
1368 Guint huffDH, huffDW, huffBMSize, huffAggInst;
1369 Guint contextUsed, contextRetained;
1370 int sdATX[4], sdATY[4], sdrATX[2], sdrATY[2];
1371 Guint numExSyms, numNewSyms, numInputSyms, symCodeLen;
1372 JBIG2Bitmap **bitmaps;
1373 JBIG2Bitmap *collBitmap, *refBitmap;
1375 Guint symHeight, symWidth, totalWidth, x, symID;
1376 int dh, dw, refAggNum, refDX, refDY, bmSize;
1382 // symbol dictionary flags
1383 if (!readUWord(&flags)) {
1386 sdTemplate = (flags >> 10) & 3;
1387 sdrTemplate = (flags >> 12) & 1;
1389 refAgg = (flags >> 1) & 1;
1390 huffDH = (flags >> 2) & 3;
1391 huffDW = (flags >> 4) & 3;
1392 huffBMSize = (flags >> 6) & 1;
1393 huffAggInst = (flags >> 7) & 1;
1394 contextUsed = (flags >> 8) & 1;
1395 contextRetained = (flags >> 9) & 1;
1397 // symbol dictionary AT flags
1399 if (sdTemplate == 0) {
1400 if (!readByte(&sdATX[0]) ||
1401 !readByte(&sdATY[0]) ||
1402 !readByte(&sdATX[1]) ||
1403 !readByte(&sdATY[1]) ||
1404 !readByte(&sdATX[2]) ||
1405 !readByte(&sdATY[2]) ||
1406 !readByte(&sdATX[3]) ||
1407 !readByte(&sdATY[3])) {
1411 if (!readByte(&sdATX[0]) ||
1412 !readByte(&sdATY[0])) {
1418 // symbol dictionary refinement AT flags
1419 if (refAgg && !sdrTemplate) {
1420 if (!readByte(&sdrATX[0]) ||
1421 !readByte(&sdrATY[0]) ||
1422 !readByte(&sdrATX[1]) ||
1423 !readByte(&sdrATY[1])) {
1428 // SDNUMEXSYMS and SDNUMNEWSYMS
1429 if (!readULong(&numExSyms) || !readULong(&numNewSyms)) {
1433 // get referenced segments: input symbol dictionaries and code tables
1434 codeTables = new GList();
1436 for (i = 0; i < nRefSegs; ++i) {
1437 seg = findSegment(refSegs[i]);
1438 if (seg->getType() == jbig2SegSymbolDict) {
1439 numInputSyms += ((JBIG2SymbolDict *)seg)->getSize();
1440 } else if (seg->getType() == jbig2SegCodeTable) {
1441 codeTables->append(seg);
1445 // compute symbol code length
1448 while (i < numInputSyms + numNewSyms) {
1453 // get the input symbol bitmaps
1454 bitmaps = (JBIG2Bitmap **)gmalloc((numInputSyms + numNewSyms) *
1455 sizeof(JBIG2Bitmap *));
1457 inputSymbolDict = NULL;
1458 for (i = 0; i < nRefSegs; ++i) {
1459 seg = findSegment(refSegs[i]);
1460 if (seg->getType() == jbig2SegSymbolDict) {
1461 inputSymbolDict = (JBIG2SymbolDict *)seg;
1462 for (j = 0; j < inputSymbolDict->getSize(); ++j) {
1463 bitmaps[k++] = inputSymbolDict->getBitmap(j);
1468 // get the Huffman tables
1469 huffDHTable = huffDWTable = NULL; // make gcc happy
1470 huffBMSizeTable = huffAggInstTable = NULL; // make gcc happy
1474 huffDHTable = huffTableD;
1475 } else if (huffDH == 1) {
1476 huffDHTable = huffTableE;
1478 huffDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1481 huffDWTable = huffTableB;
1482 } else if (huffDW == 1) {
1483 huffDWTable = huffTableC;
1485 huffDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1487 if (huffBMSize == 0) {
1488 huffBMSizeTable = huffTableA;
1491 ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1493 if (huffAggInst == 0) {
1494 huffAggInstTable = huffTableA;
1497 ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1502 // set up the Huffman decoder
1504 huffDecoder->reset();
1506 // set up the arithmetic decoder
1508 if (contextUsed && inputSymbolDict) {
1509 resetGenericStats(sdTemplate, inputSymbolDict->getGenericRegionStats());
1511 resetGenericStats(sdTemplate, NULL);
1513 resetIntStats(symCodeLen);
1514 arithDecoder->start();
1517 // set up the arithmetic decoder for refinement/aggregation
1519 if (contextUsed && inputSymbolDict) {
1520 resetRefinementStats(sdrTemplate,
1521 inputSymbolDict->getRefinementRegionStats());
1523 resetRefinementStats(sdrTemplate, NULL);
1527 // allocate symbol widths storage
1529 if (huff && !refAgg) {
1530 symWidths = (Guint *)gmalloc(numNewSyms * sizeof(Guint));
1535 while (i < numNewSyms) {
1537 // read the height class delta height
1539 huffDecoder->decodeInt(&dh, huffDHTable);
1541 arithDecoder->decodeInt(&dh, iadhStats);
1548 // read the symbols in this height class
1551 // read the delta width
1553 if (!huffDecoder->decodeInt(&dw, huffDWTable)) {
1557 if (!arithDecoder->decodeInt(&dw, iadwStats)) {
1563 // using a collective bitmap, so don't read a bitmap here
1564 if (huff && !refAgg) {
1565 symWidths[i] = symWidth;
1566 totalWidth += symWidth;
1568 // refinement/aggregate coding
1569 } else if (refAgg) {
1571 if (!huffDecoder->decodeInt(&refAggNum, huffAggInstTable)) {
1575 if (!arithDecoder->decodeInt(&refAggNum, iaaiStats)) {
1579 #if 0 //~ This special case was added about a year before the final draft
1580 //~ of the JBIG2 spec was released. I have encountered some old
1581 //~ JBIG2 images that predate it.
1584 if (refAggNum == 1) {
1587 symID = huffDecoder->readBits(symCodeLen);
1588 huffDecoder->decodeInt(&refDX, huffTableO);
1589 huffDecoder->decodeInt(&refDY, huffTableO);
1590 huffDecoder->decodeInt(&bmSize, huffTableA);
1591 huffDecoder->reset();
1592 arithDecoder->start();
1594 symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
1595 arithDecoder->decodeInt(&refDX, iardxStats);
1596 arithDecoder->decodeInt(&refDY, iardyStats);
1598 refBitmap = bitmaps[symID];
1599 bitmaps[numInputSyms + i] =
1600 readGenericRefinementRegion(symWidth, symHeight,
1601 sdrTemplate, gFalse,
1602 refBitmap, refDX, refDY,
1604 //~ do we need to use the bmSize value here (in Huffman mode)?
1606 bitmaps[numInputSyms + i] =
1607 readTextRegion(huff, gTrue, symWidth, symHeight,
1608 refAggNum, 0, numInputSyms + i, NULL,
1609 symCodeLen, bitmaps, 0, 0, 0, 1, 0,
1610 huffTableF, huffTableH, huffTableK, huffTableO,
1611 huffTableO, huffTableO, huffTableO, huffTableA,
1612 sdrTemplate, sdrATX, sdrATY);
1615 // non-ref/agg coding
1617 bitmaps[numInputSyms + i] =
1618 readGenericBitmap(gFalse, symWidth, symHeight,
1619 sdTemplate, gFalse, gFalse, NULL,
1626 // read the collective bitmap
1627 if (huff && !refAgg) {
1628 huffDecoder->decodeInt(&bmSize, huffBMSizeTable);
1629 huffDecoder->reset();
1631 collBitmap = new JBIG2Bitmap(0, totalWidth, symHeight);
1632 bmSize = symHeight * ((totalWidth + 7) >> 3);
1633 p = collBitmap->getDataPtr();
1634 for (k = 0; k < (Guint)bmSize; ++k) {
1635 *p++ = curStr->getChar();
1638 collBitmap = readGenericBitmap(gTrue, totalWidth, symHeight,
1639 0, gFalse, gFalse, NULL, NULL, NULL,
1643 for (; j < i; ++j) {
1644 bitmaps[numInputSyms + j] =
1645 collBitmap->getSlice(x, 0, symWidths[j], symHeight);
1652 // create the symbol dict object
1653 symbolDict = new JBIG2SymbolDict(segNum, numExSyms);
1655 // exported symbol list
1658 while (i < numInputSyms + numNewSyms) {
1660 huffDecoder->decodeInt(&run, huffTableA);
1662 arithDecoder->decodeInt(&run, iaexStats);
1665 for (cnt = 0; cnt < run; ++cnt) {
1666 symbolDict->setBitmap(j++, bitmaps[i++]->copy());
1674 for (i = 0; i < numNewSyms; ++i) {
1675 delete bitmaps[numInputSyms + i];
1682 // save the arithmetic decoder stats
1683 if (!huff && contextRetained) {
1684 symbolDict->setGenericRegionStats(genericRegionStats->copy());
1686 symbolDict->setRefinementRegionStats(refinementRegionStats->copy());
1690 // store the new symbol dict
1691 segments->append(symbolDict);
1696 error(getPos(), "Unexpected EOF in JBIG2 stream");
1699 void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
1700 GBool lossless, Guint length,
1701 Guint *refSegs, Guint nRefSegs) {
1702 JBIG2Bitmap *bitmap;
1703 JBIG2HuffmanTable runLengthTab[36];
1704 JBIG2HuffmanTable *symCodeTab;
1705 JBIG2HuffmanTable *huffFSTable, *huffDSTable, *huffDTTable;
1706 JBIG2HuffmanTable *huffRDWTable, *huffRDHTable;
1707 JBIG2HuffmanTable *huffRDXTable, *huffRDYTable, *huffRSizeTable;
1710 JBIG2SymbolDict *symbolDict;
1712 Guint w, h, x, y, segInfoFlags, extCombOp;
1713 Guint flags, huff, refine, logStrips, refCorner, transposed;
1714 Guint combOp, defPixel, templ;
1716 Guint huffFlags, huffFS, huffDS, huffDT;
1717 Guint huffRDW, huffRDH, huffRDX, huffRDY, huffRSize;
1718 Guint numInstances, numSyms, symCodeLen;
1723 // region segment info field
1724 if (!readULong(&w) || !readULong(&h) ||
1725 !readULong(&x) || !readULong(&y) ||
1726 !readUByte(&segInfoFlags)) {
1729 extCombOp = segInfoFlags & 7;
1731 // rest of the text region header
1732 if (!readUWord(&flags)) {
1736 refine = (flags >> 1) & 1;
1737 logStrips = (flags >> 2) & 3;
1738 refCorner = (flags >> 4) & 3;
1739 transposed = (flags >> 6) & 1;
1740 combOp = (flags >> 7) & 3;
1741 defPixel = (flags >> 9) & 1;
1742 sOffset = (flags >> 10) & 0x1f;
1743 if (sOffset & 0x10) {
1744 sOffset |= -1 - 0x0f;
1746 templ = (flags >> 15) & 1;
1747 huffFS = huffDS = huffDT = 0; // make gcc happy
1748 huffRDW = huffRDH = huffRDX = huffRDY = huffRSize = 0; // make gcc happy
1750 if (!readUWord(&huffFlags)) {
1753 huffFS = huffFlags & 3;
1754 huffDS = (huffFlags >> 2) & 3;
1755 huffDT = (huffFlags >> 4) & 3;
1756 huffRDW = (huffFlags >> 6) & 3;
1757 huffRDH = (huffFlags >> 8) & 3;
1758 huffRDX = (huffFlags >> 10) & 3;
1759 huffRDY = (huffFlags >> 12) & 3;
1760 huffRSize = (huffFlags >> 14) & 1;
1762 if (refine && templ == 0) {
1763 if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
1764 !readByte(&atx[1]) || !readByte(&aty[1])) {
1768 if (!readULong(&numInstances)) {
1772 // get symbol dictionaries and tables
1773 codeTables = new GList();
1775 for (i = 0; i < nRefSegs; ++i) {
1776 seg = findSegment(refSegs[i]);
1777 if (seg->getType() == jbig2SegSymbolDict) {
1778 numSyms += ((JBIG2SymbolDict *)seg)->getSize();
1779 } else if (seg->getType() == jbig2SegCodeTable) {
1780 codeTables->append(seg);
1785 while (i < numSyms) {
1790 // get the symbol bitmaps
1791 syms = (JBIG2Bitmap **)gmalloc(numSyms * sizeof(JBIG2Bitmap *));
1793 for (i = 0; i < nRefSegs; ++i) {
1794 seg = findSegment(refSegs[i]);
1795 if (seg->getType() == jbig2SegSymbolDict) {
1796 symbolDict = (JBIG2SymbolDict *)seg;
1797 for (k = 0; k < symbolDict->getSize(); ++k) {
1798 syms[kk++] = symbolDict->getBitmap(k);
1803 // get the Huffman tables
1804 huffFSTable = huffDSTable = huffDTTable = NULL; // make gcc happy
1805 huffRDWTable = huffRDHTable = NULL; // make gcc happy
1806 huffRDXTable = huffRDYTable = huffRSizeTable = NULL; // make gcc happy
1810 huffFSTable = huffTableF;
1811 } else if (huffFS == 1) {
1812 huffFSTable = huffTableG;
1814 huffFSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1817 huffDSTable = huffTableH;
1818 } else if (huffDS == 1) {
1819 huffDSTable = huffTableI;
1820 } else if (huffDS == 2) {
1821 huffDSTable = huffTableJ;
1823 huffDSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1826 huffDTTable = huffTableK;
1827 } else if (huffDT == 1) {
1828 huffDTTable = huffTableL;
1829 } else if (huffDT == 2) {
1830 huffDTTable = huffTableM;
1832 huffDTTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1835 huffRDWTable = huffTableN;
1836 } else if (huffRDW == 1) {
1837 huffRDWTable = huffTableO;
1839 huffRDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1842 huffRDHTable = huffTableN;
1843 } else if (huffRDH == 1) {
1844 huffRDHTable = huffTableO;
1846 huffRDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1849 huffRDXTable = huffTableN;
1850 } else if (huffRDX == 1) {
1851 huffRDXTable = huffTableO;
1853 huffRDXTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1856 huffRDYTable = huffTableN;
1857 } else if (huffRDY == 1) {
1858 huffRDYTable = huffTableO;
1860 huffRDYTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1862 if (huffRSize == 0) {
1863 huffRSizeTable = huffTableA;
1866 ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1871 // symbol ID Huffman decoding table
1873 huffDecoder->reset();
1874 for (i = 0; i < 32; ++i) {
1875 runLengthTab[i].val = i;
1876 runLengthTab[i].prefixLen = huffDecoder->readBits(4);
1877 runLengthTab[i].rangeLen = 0;
1879 runLengthTab[32].val = 0x103;
1880 runLengthTab[32].prefixLen = huffDecoder->readBits(4);
1881 runLengthTab[32].rangeLen = 2;
1882 runLengthTab[33].val = 0x203;
1883 runLengthTab[33].prefixLen = huffDecoder->readBits(4);
1884 runLengthTab[33].rangeLen = 3;
1885 runLengthTab[34].val = 0x20b;
1886 runLengthTab[34].prefixLen = huffDecoder->readBits(4);
1887 runLengthTab[34].rangeLen = 7;
1888 runLengthTab[35].prefixLen = 0;
1889 runLengthTab[35].rangeLen = jbig2HuffmanEOT;
1890 huffDecoder->buildTable(runLengthTab, 35);
1891 symCodeTab = (JBIG2HuffmanTable *)gmalloc((numSyms + 1) *
1892 sizeof(JBIG2HuffmanTable));
1893 for (i = 0; i < numSyms; ++i) {
1894 symCodeTab[i].val = i;
1895 symCodeTab[i].rangeLen = 0;
1898 while (i < numSyms) {
1899 huffDecoder->decodeInt(&j, runLengthTab);
1901 for (j -= 0x200; j && i < numSyms; --j) {
1902 symCodeTab[i++].prefixLen = 0;
1904 } else if (j > 0x100) {
1905 for (j -= 0x100; j && i < numSyms; --j) {
1906 symCodeTab[i].prefixLen = symCodeTab[i-1].prefixLen;
1910 symCodeTab[i++].prefixLen = j;
1913 symCodeTab[numSyms].prefixLen = 0;
1914 symCodeTab[numSyms].rangeLen = jbig2HuffmanEOT;
1915 huffDecoder->buildTable(symCodeTab, numSyms);
1916 huffDecoder->reset();
1918 // set up the arithmetic decoder
1921 resetIntStats(symCodeLen);
1922 arithDecoder->start();
1925 resetRefinementStats(templ, NULL);
1928 bitmap = readTextRegion(huff, refine, w, h, numInstances,
1929 logStrips, numSyms, symCodeTab, symCodeLen, syms,
1930 defPixel, combOp, transposed, refCorner, sOffset,
1931 huffFSTable, huffDSTable, huffDTTable,
1932 huffRDWTable, huffRDHTable,
1933 huffRDXTable, huffRDYTable, huffRSizeTable,
1938 // combine the region bitmap into the page bitmap
1940 if (pageH == 0xffffffff && y + h > curPageH) {
1941 pageBitmap->expand(y + h, pageDefPixel);
1943 pageBitmap->combine(bitmap, x, y, extCombOp);
1946 // store the region bitmap
1948 bitmap->setSegNum(segNum);
1949 segments->append(bitmap);
1952 // clean up the Huffman decoder
1960 error(getPos(), "Unexpected EOF in JBIG2 stream");
1963 JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
1968 JBIG2HuffmanTable *symCodeTab,
1971 Guint defPixel, Guint combOp,
1972 Guint transposed, Guint refCorner,
1974 JBIG2HuffmanTable *huffFSTable,
1975 JBIG2HuffmanTable *huffDSTable,
1976 JBIG2HuffmanTable *huffDTTable,
1977 JBIG2HuffmanTable *huffRDWTable,
1978 JBIG2HuffmanTable *huffRDHTable,
1979 JBIG2HuffmanTable *huffRDXTable,
1980 JBIG2HuffmanTable *huffRDYTable,
1981 JBIG2HuffmanTable *huffRSizeTable,
1983 int *atx, int *aty) {
1984 JBIG2Bitmap *bitmap;
1985 JBIG2Bitmap *symbolBitmap;
1987 int t, dt, tt, s, ds, sFirst, j;
1988 int rdw, rdh, rdx, rdy, ri, refDX, refDY, bmSize;
1989 Guint symID, inst, bw, bh;
1991 strips = 1 << logStrips;
1993 // allocate the bitmap
1994 bitmap = new JBIG2Bitmap(0, w, h);
1996 bitmap->clearToOne();
1998 bitmap->clearToZero();
2001 // decode initial T value
2003 huffDecoder->decodeInt(&t, huffDTTable);
2005 arithDecoder->decodeInt(&t, iadtStats);
2011 while (inst < numInstances) {
2015 huffDecoder->decodeInt(&dt, huffDTTable);
2017 arithDecoder->decodeInt(&dt, iadtStats);
2023 huffDecoder->decodeInt(&ds, huffFSTable);
2025 arithDecoder->decodeInt(&ds, iafsStats);
2030 // read the instances
2037 dt = huffDecoder->readBits(logStrips);
2039 arithDecoder->decodeInt(&dt, iaitStats);
2046 huffDecoder->decodeInt(&j, symCodeTab);
2049 symID = huffDecoder->readBits(symCodeLen);
2052 symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
2055 // get the symbol bitmap
2056 symbolBitmap = NULL;
2059 ri = (int)huffDecoder->readBit();
2061 arithDecoder->decodeInt(&ri, iariStats);
2068 huffDecoder->decodeInt(&rdw, huffRDWTable);
2069 huffDecoder->decodeInt(&rdh, huffRDHTable);
2070 huffDecoder->decodeInt(&rdx, huffRDXTable);
2071 huffDecoder->decodeInt(&rdy, huffRDYTable);
2072 huffDecoder->decodeInt(&bmSize, huffRSizeTable);
2073 huffDecoder->reset();
2074 arithDecoder->start();
2076 arithDecoder->decodeInt(&rdw, iardwStats);
2077 arithDecoder->decodeInt(&rdh, iardhStats);
2078 arithDecoder->decodeInt(&rdx, iardxStats);
2079 arithDecoder->decodeInt(&rdy, iardyStats);
2081 refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
2082 refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
2085 readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
2086 rdh + syms[symID]->getHeight(),
2087 templ, gFalse, syms[symID],
2088 refDX, refDY, atx, aty);
2089 //~ do we need to use the bmSize value here (in Huffman mode)?
2091 symbolBitmap = syms[symID];
2094 // combine the symbol bitmap into the region bitmap
2095 //~ something is wrong here - refCorner shouldn't degenerate into
2097 bw = symbolBitmap->getWidth() - 1;
2098 bh = symbolBitmap->getHeight() - 1;
2100 switch (refCorner) {
2101 case 0: // bottom left
2102 bitmap->combine(symbolBitmap, tt, s, combOp);
2105 bitmap->combine(symbolBitmap, tt, s, combOp);
2107 case 2: // bottom right
2108 bitmap->combine(symbolBitmap, tt - bw, s, combOp);
2110 case 3: // top right
2111 bitmap->combine(symbolBitmap, tt - bw, s, combOp);
2116 switch (refCorner) {
2117 case 0: // bottom left
2118 bitmap->combine(symbolBitmap, s, tt - bh, combOp);
2121 bitmap->combine(symbolBitmap, s, tt, combOp);
2123 case 2: // bottom right
2124 bitmap->combine(symbolBitmap, s, tt - bh, combOp);
2126 case 3: // top right
2127 bitmap->combine(symbolBitmap, s, tt, combOp);
2133 delete symbolBitmap;
2141 if (!huffDecoder->decodeInt(&ds, huffDSTable)) {
2145 if (!arithDecoder->decodeInt(&ds, iadsStats)) {
2156 void JBIG2Stream::readPatternDictSeg(Guint segNum, Guint length) {
2157 JBIG2PatternDict *patternDict;
2158 JBIG2Bitmap *bitmap;
2159 Guint flags, patternW, patternH, grayMax, templ, mmr;
2163 // halftone dictionary flags, pattern width and height, max gray value
2164 if (!readUByte(&flags) ||
2165 !readUByte(&patternW) ||
2166 !readUByte(&patternH) ||
2167 !readULong(&grayMax)) {
2170 templ = (flags >> 1) & 3;
2173 // set up the arithmetic decoder
2175 resetGenericStats(templ, NULL);
2176 arithDecoder->start();
2180 atx[0] = -(int)patternW; aty[0] = 0;
2181 atx[1] = -3; aty[1] = -1;
2182 atx[2] = 2; aty[2] = -2;
2183 atx[3] = -2; aty[3] = -2;
2184 bitmap = readGenericBitmap(mmr, (grayMax + 1) * patternW, patternH,
2185 templ, gFalse, gFalse, NULL,
2186 atx, aty, length - 7);
2188 // create the pattern dict object
2189 patternDict = new JBIG2PatternDict(segNum, grayMax + 1);
2191 // split up the bitmap
2193 for (i = 0; i <= grayMax; ++i) {
2194 patternDict->setBitmap(i, bitmap->getSlice(x, 0, patternW, patternH));
2201 // store the new pattern dict
2202 segments->append(patternDict);
2207 error(getPos(), "Unexpected EOF in JBIG2 stream");
2210 void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm,
2211 GBool lossless, Guint length,
2212 Guint *refSegs, Guint nRefSegs) {
2213 JBIG2Bitmap *bitmap;
2215 JBIG2PatternDict *patternDict;
2216 JBIG2Bitmap *skipBitmap;
2218 JBIG2Bitmap *grayBitmap;
2219 JBIG2Bitmap *patternBitmap;
2220 Guint w, h, x, y, segInfoFlags, extCombOp;
2221 Guint flags, mmr, templ, enableSkip, combOp;
2222 Guint gridW, gridH, stepX, stepY, patW, patH;
2224 int gridX, gridY, xx, yy, bit, j;
2227 // region segment info field
2228 if (!readULong(&w) || !readULong(&h) ||
2229 !readULong(&x) || !readULong(&y) ||
2230 !readUByte(&segInfoFlags)) {
2233 extCombOp = segInfoFlags & 7;
2235 // rest of the halftone region header
2236 if (!readUByte(&flags)) {
2240 templ = (flags >> 1) & 3;
2241 enableSkip = (flags >> 3) & 1;
2242 combOp = (flags >> 4) & 7;
2243 if (!readULong(&gridW) || !readULong(&gridH) ||
2244 !readLong(&gridX) || !readLong(&gridY) ||
2245 !readUWord(&stepX) || !readUWord(&stepY)) {
2249 // get pattern dictionary
2250 if (nRefSegs != 1) {
2251 error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
2254 seg = findSegment(refSegs[0]);
2255 if (seg->getType() != jbig2SegPatternDict) {
2256 error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
2259 patternDict = (JBIG2PatternDict *)seg;
2262 while (i < patternDict->getSize()) {
2266 patW = patternDict->getBitmap(0)->getWidth();
2267 patH = patternDict->getBitmap(0)->getHeight();
2269 // set up the arithmetic decoder
2271 resetGenericStats(templ, NULL);
2272 arithDecoder->start();
2275 // allocate the bitmap
2276 bitmap = new JBIG2Bitmap(segNum, w, h);
2277 if (flags & 0x80) { // HDEFPIXEL
2278 bitmap->clearToOne();
2280 bitmap->clearToZero();
2283 // compute the skip bitmap
2286 skipBitmap = new JBIG2Bitmap(0, gridW, gridH);
2287 skipBitmap->clearToZero();
2288 for (m = 0; m < gridH; ++m) {
2289 xx = gridX + m * stepY;
2290 yy = gridY + m * stepX;
2291 for (n = 0; n < gridW; ++n) {
2292 if (((xx + (int)patW) >> 8) <= 0 || (xx >> 8) >= (int)w ||
2293 ((yy + (int)patH) >> 8) <= 0 || (yy >> 8) >= (int)h) {
2294 skipBitmap->setPixel(n, m);
2300 // read the gray-scale image
2301 grayImg = (Guint *)gmalloc(gridW * gridH * sizeof(Guint));
2302 memset(grayImg, 0, gridW * gridH * sizeof(Guint));
2303 atx[0] = templ <= 1 ? 3 : 2; aty[0] = -1;
2304 atx[1] = -3; aty[1] = -1;
2305 atx[2] = 2; aty[2] = -2;
2306 atx[3] = -2; aty[3] = -2;
2307 for (j = bpp - 1; j >= 0; --j) {
2308 grayBitmap = readGenericBitmap(mmr, gridW, gridH, templ, gFalse,
2309 enableSkip, skipBitmap, atx, aty, -1);
2311 for (m = 0; m < gridH; ++m) {
2312 for (n = 0; n < gridW; ++n) {
2313 bit = grayBitmap->getPixel(n, m) ^ (grayImg[i] & 1);
2314 grayImg[i] = (grayImg[i] << 1) | bit;
2323 for (m = 0; m < gridH; ++m) {
2324 xx = gridX + m * stepY;
2325 yy = gridY + m * stepX;
2326 for (n = 0; n < gridW; ++n) {
2327 if (!(enableSkip && skipBitmap->getPixel(n, m))) {
2328 patternBitmap = patternDict->getBitmap(grayImg[i]);
2329 bitmap->combine(patternBitmap, xx >> 8, yy >> 8, combOp);
2339 // combine the region bitmap into the page bitmap
2341 if (pageH == 0xffffffff && y + h > curPageH) {
2342 pageBitmap->expand(y + h, pageDefPixel);
2344 pageBitmap->combine(bitmap, x, y, extCombOp);
2347 // store the region bitmap
2349 segments->append(bitmap);
2355 error(getPos(), "Unexpected EOF in JBIG2 stream");
2358 void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm,
2359 GBool lossless, Guint length) {
2360 JBIG2Bitmap *bitmap;
2361 Guint w, h, x, y, segInfoFlags, extCombOp;
2362 Guint flags, mmr, templ, tpgdOn;
2365 // region segment info field
2366 if (!readULong(&w) || !readULong(&h) ||
2367 !readULong(&x) || !readULong(&y) ||
2368 !readUByte(&segInfoFlags)) {
2371 extCombOp = segInfoFlags & 7;
2373 // rest of the generic region segment header
2374 if (!readUByte(&flags)) {
2378 templ = (flags >> 1) & 3;
2379 tpgdOn = (flags >> 3) & 1;
2384 if (!readByte(&atx[0]) ||
2385 !readByte(&aty[0]) ||
2386 !readByte(&atx[1]) ||
2387 !readByte(&aty[1]) ||
2388 !readByte(&atx[2]) ||
2389 !readByte(&aty[2]) ||
2390 !readByte(&atx[3]) ||
2391 !readByte(&aty[3])) {
2395 if (!readByte(&atx[0]) ||
2396 !readByte(&aty[0])) {
2402 // set up the arithmetic decoder
2404 resetGenericStats(templ, NULL);
2405 arithDecoder->start();
2409 bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse,
2410 NULL, atx, aty, mmr ? 0 : length - 18);
2412 // combine the region bitmap into the page bitmap
2414 if (pageH == 0xffffffff && y + h > curPageH) {
2415 pageBitmap->expand(y + h, pageDefPixel);
2417 pageBitmap->combine(bitmap, x, y, extCombOp);
2420 // store the region bitmap
2422 bitmap->setSegNum(segNum);
2423 segments->append(bitmap);
2429 error(getPos(), "Unexpected EOF in JBIG2 stream");
2432 JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
2433 int templ, GBool tpgdOn,
2434 GBool useSkip, JBIG2Bitmap *skip,
2436 int mmrDataLength) {
2437 JBIG2Bitmap *bitmap;
2439 Guint ltpCX, cx, cx0, cx1, cx2;
2440 JBIG2BitmapPtr cxPtr0, cxPtr1;
2441 JBIG2BitmapPtr atPtr0, atPtr1, atPtr2, atPtr3;
2442 int *refLine, *codingLine;
2443 int code1, code2, code3;
2444 int x, y, a0, pix, i, refI, codingI;
2446 bitmap = new JBIG2Bitmap(0, w, h);
2447 bitmap->clearToZero();
2453 mmrDecoder->reset();
2454 refLine = (int *)gmalloc((w + 2) * sizeof(int));
2455 codingLine = (int *)gmalloc((w + 2) * sizeof(int));
2456 codingLine[0] = codingLine[1] = w;
2458 for (y = 0; y < h; ++y) {
2460 // copy coding line to ref line
2461 for (i = 0; codingLine[i] < w; ++i) {
2462 refLine[i] = codingLine[i];
2464 refLine[i] = refLine[i + 1] = w;
2467 refI = 0; // b1 = refLine[refI]
2468 codingI = 0; // a1 = codingLine[codingI]
2471 code1 = mmrDecoder->get2DCode();
2474 if (refLine[refI] < w) {
2475 a0 = refLine[refI + 1];
2483 code1 += code3 = mmrDecoder->getBlackCode();
2484 } while (code3 >= 64);
2487 code2 += code3 = mmrDecoder->getWhiteCode();
2488 } while (code3 >= 64);
2492 code1 += code3 = mmrDecoder->getWhiteCode();
2493 } while (code3 >= 64);
2496 code2 += code3 = mmrDecoder->getBlackCode();
2497 } while (code3 >= 64);
2499 if (code1 > 0 || code2 > 0) {
2500 a0 = codingLine[codingI++] = a0 + code1;
2501 a0 = codingLine[codingI++] = a0 + code2;
2502 while (refLine[refI] <= a0 && refLine[refI] < w) {
2508 a0 = codingLine[codingI++] = refLine[refI];
2509 if (refLine[refI] < w) {
2514 a0 = codingLine[codingI++] = refLine[refI] + 1;
2515 if (refLine[refI] < w) {
2517 while (refLine[refI] <= a0 && refLine[refI] < w) {
2523 a0 = codingLine[codingI++] = refLine[refI] + 2;
2524 if (refLine[refI] < w) {
2526 while (refLine[refI] <= a0 && refLine[refI] < w) {
2532 a0 = codingLine[codingI++] = refLine[refI] + 3;
2533 if (refLine[refI] < w) {
2535 while (refLine[refI] <= a0 && refLine[refI] < w) {
2541 a0 = codingLine[codingI++] = refLine[refI] - 1;
2547 while (refLine[refI] <= a0 && refLine[refI] < w) {
2552 a0 = codingLine[codingI++] = refLine[refI] - 2;
2558 while (refLine[refI] <= a0 && refLine[refI] < w) {
2563 a0 = codingLine[codingI++] = refLine[refI] - 3;
2569 while (refLine[refI] <= a0 && refLine[refI] < w) {
2574 error(getPos(), "Illegal code in JBIG2 MMR bitmap data");
2578 codingLine[codingI++] = w;
2580 // convert the run lengths to a bitmap line
2582 while (codingLine[i] < w) {
2583 for (x = codingLine[i]; x < codingLine[i+1]; ++x) {
2584 bitmap->setPixel(x, y);
2590 if (mmrDataLength >= 0) {
2591 mmrDecoder->skipTo(mmrDataLength);
2593 if (mmrDecoder->get24Bits() != 0x001001) {
2594 error(getPos(), "Missing EOFB in JBIG2 MMR bitmap data");
2601 //----- arithmetic decode
2604 // set up the typical row context
2605 ltpCX = 0; // make gcc happy
2609 ltpCX = 0x3953; // 001 11001 0101 0011
2612 ltpCX = 0x079a; // 0011 11001 101 0
2615 ltpCX = 0x0e3; // 001 1100 01 1
2618 ltpCX = 0x18a; // 01100 0101 1
2624 cx = cx0 = cx1 = cx2 = 0; // make gcc happy
2625 for (y = 0; y < h; ++y) {
2627 // check for a "typical" (duplicate) row
2629 if (arithDecoder->decodeBit(ltpCX, genericRegionStats)) {
2633 bitmap->duplicateRow(y, y-1);
2641 // set up the context
2642 bitmap->getPixelPtr(0, y-2, &cxPtr0);
2643 cx0 = bitmap->nextPixel(&cxPtr0);
2644 cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
2645 bitmap->getPixelPtr(0, y-1, &cxPtr1);
2646 cx1 = bitmap->nextPixel(&cxPtr1);
2647 cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
2648 cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
2650 bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
2651 bitmap->getPixelPtr(atx[1], y + aty[1], &atPtr1);
2652 bitmap->getPixelPtr(atx[2], y + aty[2], &atPtr2);
2653 bitmap->getPixelPtr(atx[3], y + aty[3], &atPtr3);
2656 for (x = 0; x < w; ++x) {
2658 // build the context
2659 cx = (cx0 << 13) | (cx1 << 8) | (cx2 << 4) |
2660 (bitmap->nextPixel(&atPtr0) << 3) |
2661 (bitmap->nextPixel(&atPtr1) << 2) |
2662 (bitmap->nextPixel(&atPtr2) << 1) |
2663 bitmap->nextPixel(&atPtr3);
2665 // check for a skipped pixel
2666 if (useSkip && skip->getPixel(x, y)) {
2670 } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
2671 bitmap->setPixel(x, y);
2674 // update the context
2675 cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07;
2676 cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
2677 cx2 = ((cx2 << 1) | pix) & 0x0f;
2683 // set up the context
2684 bitmap->getPixelPtr(0, y-2, &cxPtr0);
2685 cx0 = bitmap->nextPixel(&cxPtr0);
2686 cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
2687 cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
2688 bitmap->getPixelPtr(0, y-1, &cxPtr1);
2689 cx1 = bitmap->nextPixel(&cxPtr1);
2690 cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
2691 cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
2693 bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
2696 for (x = 0; x < w; ++x) {
2698 // build the context
2699 cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
2700 bitmap->nextPixel(&atPtr0);
2702 // check for a skipped pixel
2703 if (useSkip && skip->getPixel(x, y)) {
2707 } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
2708 bitmap->setPixel(x, y);
2711 // update the context
2712 cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x0f;
2713 cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
2714 cx2 = ((cx2 << 1) | pix) & 0x07;
2720 // set up the context
2721 bitmap->getPixelPtr(0, y-2, &cxPtr0);
2722 cx0 = bitmap->nextPixel(&cxPtr0);
2723 cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
2724 bitmap->getPixelPtr(0, y-1, &cxPtr1);
2725 cx1 = bitmap->nextPixel(&cxPtr1);
2726 cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
2728 bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
2731 for (x = 0; x < w; ++x) {
2733 // build the context
2734 cx = (cx0 << 7) | (cx1 << 3) | (cx2 << 1) |
2735 bitmap->nextPixel(&atPtr0);
2737 // check for a skipped pixel
2738 if (useSkip && skip->getPixel(x, y)) {
2742 } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
2743 bitmap->setPixel(x, y);
2746 // update the context
2747 cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07;
2748 cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x0f;
2749 cx2 = ((cx2 << 1) | pix) & 0x03;
2755 // set up the context
2756 bitmap->getPixelPtr(0, y-1, &cxPtr1);
2757 cx1 = bitmap->nextPixel(&cxPtr1);
2758 cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
2760 bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
2763 for (x = 0; x < w; ++x) {
2765 // build the context
2766 cx = (cx1 << 5) | (cx2 << 1) |
2767 bitmap->nextPixel(&atPtr0);
2769 // check for a skipped pixel
2770 if (useSkip && skip->getPixel(x, y)) {
2774 } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
2775 bitmap->setPixel(x, y);
2778 // update the context
2779 cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
2780 cx2 = ((cx2 << 1) | pix) & 0x0f;
2790 void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum, GBool imm,
2791 GBool lossless, Guint length,
2794 JBIG2Bitmap *bitmap, *refBitmap;
2795 Guint w, h, x, y, segInfoFlags, extCombOp;
2796 Guint flags, templ, tpgrOn;
2800 // region segment info field
2801 if (!readULong(&w) || !readULong(&h) ||
2802 !readULong(&x) || !readULong(&y) ||
2803 !readUByte(&segInfoFlags)) {
2806 extCombOp = segInfoFlags & 7;
2808 // rest of the generic refinement region segment header
2809 if (!readUByte(&flags)) {
2813 tpgrOn = (flags >> 1) & 1;
2817 if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
2818 !readByte(&atx[1]) || !readByte(&aty[1])) {
2823 // resize the page bitmap if needed
2824 if (nRefSegs == 0 || imm) {
2825 if (pageH == 0xffffffff && y + h > curPageH) {
2826 pageBitmap->expand(y + h, pageDefPixel);
2830 // get referenced bitmap
2832 error(getPos(), "Bad reference in JBIG2 generic refinement segment");
2835 if (nRefSegs == 1) {
2836 seg = findSegment(refSegs[0]);
2837 if (seg->getType() != jbig2SegBitmap) {
2838 error(getPos(), "Bad bitmap reference in JBIG2 generic refinement segment");
2841 refBitmap = (JBIG2Bitmap *)seg;
2843 refBitmap = pageBitmap->getSlice(x, y, w, h);
2846 // set up the arithmetic decoder
2847 resetRefinementStats(templ, NULL);
2848 arithDecoder->start();
2851 bitmap = readGenericRefinementRegion(w, h, templ, tpgrOn,
2852 refBitmap, 0, 0, atx, aty);
2854 // combine the region bitmap into the page bitmap
2856 pageBitmap->combine(bitmap, x, y, extCombOp);
2859 // store the region bitmap
2861 bitmap->setSegNum(segNum);
2862 segments->append(bitmap);
2865 // delete the referenced bitmap
2866 if (nRefSegs == 1) {
2867 discardSegment(refSegs[0]);
2875 error(getPos(), "Unexpected EOF in JBIG2 stream");
2878 JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion(int w, int h,
2879 int templ, GBool tpgrOn,
2880 JBIG2Bitmap *refBitmap,
2881 int refDX, int refDY,
2882 int *atx, int *aty) {
2883 JBIG2Bitmap *bitmap;
2885 Guint ltpCX, cx, cx0, cx2, cx3, cx4, tpgrCX0, tpgrCX1, tpgrCX2;
2886 JBIG2BitmapPtr cxPtr0, cxPtr1, cxPtr2, cxPtr3, cxPtr4, cxPtr5, cxPtr6;
2887 JBIG2BitmapPtr tpgrCXPtr0, tpgrCXPtr1, tpgrCXPtr2;
2890 bitmap = new JBIG2Bitmap(0, w, h);
2891 bitmap->clearToZero();
2893 // set up the typical row context
2901 for (y = 0; y < h; ++y) {
2905 // set up the context
2906 bitmap->getPixelPtr(0, y-1, &cxPtr0);
2907 cx0 = bitmap->nextPixel(&cxPtr0);
2908 bitmap->getPixelPtr(-1, y, &cxPtr1);
2909 refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2);
2910 refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3);
2911 cx3 = refBitmap->nextPixel(&cxPtr3);
2912 cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3);
2913 refBitmap->getPixelPtr(-refDX, y+1-refDY, &cxPtr4);
2914 cx4 = refBitmap->nextPixel(&cxPtr4);
2916 // set up the typical prediction context
2917 tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy
2919 refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0);
2920 tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0);
2921 tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
2922 tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
2923 refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1);
2924 tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1);
2925 tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
2926 tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
2927 refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2);
2928 tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
2929 tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
2930 tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
2933 for (x = 0; x < w; ++x) {
2935 // update the context
2936 cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 7;
2937 cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7;
2938 cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 3;
2941 // update the typical predictor context
2942 tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7;
2943 tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7;
2944 tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7;
2946 // check for a "typical" pixel
2947 if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
2950 if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
2951 bitmap->clearPixel(x, y);
2953 } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
2954 bitmap->setPixel(x, y);
2959 // build the context
2960 cx = (cx0 << 7) | (bitmap->nextPixel(&cxPtr1) << 6) |
2961 (refBitmap->nextPixel(&cxPtr2) << 5) |
2965 if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
2966 bitmap->setPixel(x, y);
2972 // set up the context
2973 bitmap->getPixelPtr(0, y-1, &cxPtr0);
2974 cx0 = bitmap->nextPixel(&cxPtr0);
2975 bitmap->getPixelPtr(-1, y, &cxPtr1);
2976 refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2);
2977 cx2 = refBitmap->nextPixel(&cxPtr2);
2978 refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3);
2979 cx3 = refBitmap->nextPixel(&cxPtr3);
2980 cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3);
2981 refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &cxPtr4);
2982 cx4 = refBitmap->nextPixel(&cxPtr4);
2983 cx4 = (cx4 << 1) | refBitmap->nextPixel(&cxPtr4);
2984 bitmap->getPixelPtr(atx[0], y+aty[0], &cxPtr5);
2985 refBitmap->getPixelPtr(atx[1]-refDX, y+aty[1]-refDY, &cxPtr6);
2987 // set up the typical prediction context
2988 tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy
2990 refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0);
2991 tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0);
2992 tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
2993 tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
2994 refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1);
2995 tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1);
2996 tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
2997 tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
2998 refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2);
2999 tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
3000 tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3001 tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3004 for (x = 0; x < w; ++x) {
3006 // update the context
3007 cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 3;
3008 cx2 = ((cx2 << 1) | refBitmap->nextPixel(&cxPtr2)) & 3;
3009 cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7;
3010 cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 7;
3013 // update the typical predictor context
3014 tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7;
3015 tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7;
3016 tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7;
3018 // check for a "typical" pixel
3019 if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
3022 if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
3023 bitmap->clearPixel(x, y);
3025 } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
3026 bitmap->setPixel(x, y);
3031 // build the context
3032 cx = (cx0 << 11) | (bitmap->nextPixel(&cxPtr1) << 10) |
3033 (cx2 << 8) | (cx3 << 5) | (cx4 << 2) |
3034 (bitmap->nextPixel(&cxPtr5) << 1) |
3035 refBitmap->nextPixel(&cxPtr6);
3038 if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
3039 bitmap->setPixel(x, y);
3048 void JBIG2Stream::readPageInfoSeg(Guint length) {
3049 Guint xRes, yRes, flags, striping;
3051 if (!readULong(&pageW) || !readULong(&pageH) ||
3052 !readULong(&xRes) || !readULong(&yRes) ||
3053 !readUByte(&flags) || !readUWord(&striping)) {
3056 pageDefPixel = (flags >> 2) & 1;
3057 defCombOp = (flags >> 3) & 3;
3059 // allocate the page bitmap
3060 if (pageH == 0xffffffff) {
3061 curPageH = striping & 0x7fff;
3065 pageBitmap = new JBIG2Bitmap(0, pageW, curPageH);
3067 // default pixel value
3069 pageBitmap->clearToOne();
3071 pageBitmap->clearToZero();
3077 error(getPos(), "Unexpected EOF in JBIG2 stream");
3080 void JBIG2Stream::readEndOfStripeSeg(Guint length) {
3084 for (i = 0; i < length; ++i) {
3089 void JBIG2Stream::readProfilesSeg(Guint length) {
3093 for (i = 0; i < length; ++i) {
3098 void JBIG2Stream::readCodeTableSeg(Guint segNum, Guint length) {
3099 JBIG2HuffmanTable *huffTab;
3100 Guint flags, oob, prefixBits, rangeBits;
3101 int lowVal, highVal, val;
3102 Guint huffTabSize, i;
3104 if (!readUByte(&flags) || !readLong(&lowVal) || !readLong(&highVal)) {
3108 prefixBits = ((flags >> 1) & 7) + 1;
3109 rangeBits = ((flags >> 4) & 7) + 1;
3111 huffDecoder->reset();
3113 huffTab = (JBIG2HuffmanTable *)
3114 gmalloc(huffTabSize * sizeof(JBIG2HuffmanTable));
3117 while (val < highVal) {
3118 if (i == huffTabSize) {
3120 huffTab = (JBIG2HuffmanTable *)
3121 grealloc(huffTab, huffTabSize * sizeof(JBIG2HuffmanTable));
3123 huffTab[i].val = val;
3124 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3125 huffTab[i].rangeLen = huffDecoder->readBits(rangeBits);
3126 val += 1 << huffTab[i].rangeLen;
3129 if (i + oob + 3 > huffTabSize) {
3130 huffTabSize = i + oob + 3;
3131 huffTab = (JBIG2HuffmanTable *)
3132 grealloc(huffTab, huffTabSize * sizeof(JBIG2HuffmanTable));
3134 huffTab[i].val = lowVal - 1;
3135 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3136 huffTab[i].rangeLen = jbig2HuffmanLOW;
3138 huffTab[i].val = highVal;
3139 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3140 huffTab[i].rangeLen = 32;
3144 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3145 huffTab[i].rangeLen = jbig2HuffmanOOB;
3149 huffTab[i].prefixLen = 0;
3150 huffTab[i].rangeLen = jbig2HuffmanEOT;
3151 huffDecoder->buildTable(huffTab, i);
3153 // create and store the new table segment
3154 segments->append(new JBIG2CodeTable(segNum, huffTab));
3159 error(getPos(), "Unexpected EOF in JBIG2 stream");
3162 void JBIG2Stream::readExtensionSeg(Guint length) {
3166 for (i = 0; i < length; ++i) {
3171 JBIG2Segment *JBIG2Stream::findSegment(Guint segNum) {
3175 for (i = 0; i < globalSegments->getLength(); ++i) {
3176 seg = (JBIG2Segment *)globalSegments->get(i);
3177 if (seg->getSegNum() == segNum) {
3181 for (i = 0; i < segments->getLength(); ++i) {
3182 seg = (JBIG2Segment *)segments->get(i);
3183 if (seg->getSegNum() == segNum) {
3190 void JBIG2Stream::discardSegment(Guint segNum) {
3194 for (i = 0; i < globalSegments->getLength(); ++i) {
3195 seg = (JBIG2Segment *)globalSegments->get(i);
3196 if (seg->getSegNum() == segNum) {
3197 globalSegments->del(i);
3201 for (i = 0; i < segments->getLength(); ++i) {
3202 seg = (JBIG2Segment *)segments->get(i);
3203 if (seg->getSegNum() == segNum) {
3210 void JBIG2Stream::resetGenericStats(Guint templ,
3211 JArithmeticDecoderStats *prevStats) {
3214 size = contextSize[templ];
3215 if (prevStats && prevStats->getContextSize() == size) {
3216 if (genericRegionStats->getContextSize() == size) {
3217 genericRegionStats->copyFrom(prevStats);
3219 delete genericRegionStats;
3220 genericRegionStats = prevStats->copy();
3223 if (genericRegionStats->getContextSize() == size) {
3224 genericRegionStats->reset();
3226 delete genericRegionStats;
3227 genericRegionStats = new JArithmeticDecoderStats(1 << size);
3232 void JBIG2Stream::resetRefinementStats(Guint templ,
3233 JArithmeticDecoderStats *prevStats) {
3236 size = refContextSize[templ];
3237 if (prevStats && prevStats->getContextSize() == size) {
3238 if (refinementRegionStats->getContextSize() == size) {
3239 refinementRegionStats->copyFrom(prevStats);
3241 delete refinementRegionStats;
3242 refinementRegionStats = prevStats->copy();
3245 if (refinementRegionStats->getContextSize() == size) {
3246 refinementRegionStats->reset();
3248 delete refinementRegionStats;
3249 refinementRegionStats = new JArithmeticDecoderStats(1 << size);
3254 void JBIG2Stream::resetIntStats(int symCodeLen) {
3263 iardxStats->reset();
3264 iardyStats->reset();
3265 iardwStats->reset();
3266 iardhStats->reset();
3268 if (iaidStats->getContextSize() == symCodeLen + 1) {
3272 iaidStats = new JArithmeticDecoderStats(1 << (symCodeLen + 1));
3276 GBool JBIG2Stream::readUByte(Guint *x) {
3279 if ((c0 = curStr->getChar()) == EOF) {
3286 GBool JBIG2Stream::readByte(int *x) {
3289 if ((c0 = curStr->getChar()) == EOF) {
3299 GBool JBIG2Stream::readUWord(Guint *x) {
3302 if ((c0 = curStr->getChar()) == EOF ||
3303 (c1 = curStr->getChar()) == EOF) {
3306 *x = (Guint)((c0 << 8) | c1);
3310 GBool JBIG2Stream::readULong(Guint *x) {
3313 if ((c0 = curStr->getChar()) == EOF ||
3314 (c1 = curStr->getChar()) == EOF ||
3315 (c2 = curStr->getChar()) == EOF ||
3316 (c3 = curStr->getChar()) == EOF) {
3319 *x = (Guint)((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
3323 GBool JBIG2Stream::readLong(int *x) {
3326 if ((c0 = curStr->getChar()) == EOF ||
3327 (c1 = curStr->getChar()) == EOF ||
3328 (c2 = curStr->getChar()) == EOF ||
3329 (c3 = curStr->getChar()) == EOF) {
3332 *x = ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
3334 *x |= -1 - (int)0xffffffff;