1 //========================================================================
5 // Copyright 2002-2003 Glyph & Cog, LLC
7 //========================================================================
11 #ifdef USE_GCC_PRAGMAS
12 #pragma implementation
18 #include "JBIG2Stream.h"
20 //~ share these tables
21 #include "Stream-CCITT.h"
23 //------------------------------------------------------------------------
25 static int contextSize[4] = { 16, 13, 10, 10 };
26 static int refContextSize[2] = { 13, 10 };
28 //------------------------------------------------------------------------
29 // JBIG2ArithmeticDecoderStats
30 //------------------------------------------------------------------------
32 class JBIG2ArithmeticDecoderStats {
35 JBIG2ArithmeticDecoderStats(int contextSizeA);
36 ~JBIG2ArithmeticDecoderStats();
37 JBIG2ArithmeticDecoderStats *copy();
39 int getContextSize() { return contextSize; }
40 void copyFrom(JBIG2ArithmeticDecoderStats *stats);
44 Guchar *cxTab; // cxTab[cx] = (i[cx] << 1) + mps[cx]
47 friend class JBIG2ArithmeticDecoder;
50 JBIG2ArithmeticDecoderStats::JBIG2ArithmeticDecoderStats(int contextSizeA) {
51 contextSize = contextSizeA;
52 cxTab = (Guchar *)gmalloc((1 << contextSize) * sizeof(Guchar));
56 JBIG2ArithmeticDecoderStats::~JBIG2ArithmeticDecoderStats() {
60 JBIG2ArithmeticDecoderStats *JBIG2ArithmeticDecoderStats::copy() {
61 JBIG2ArithmeticDecoderStats *stats;
63 stats = new JBIG2ArithmeticDecoderStats(contextSize);
64 memcpy(stats->cxTab, cxTab, 1 << contextSize);
68 void JBIG2ArithmeticDecoderStats::reset() {
69 memset(cxTab, 0, 1 << contextSize);
72 void JBIG2ArithmeticDecoderStats::copyFrom(
73 JBIG2ArithmeticDecoderStats *stats) {
74 memcpy(cxTab, stats->cxTab, 1 << contextSize);
77 //------------------------------------------------------------------------
78 // JBIG2ArithmeticDecoder
79 //------------------------------------------------------------------------
81 class JBIG2ArithmeticDecoder {
84 JBIG2ArithmeticDecoder();
85 ~JBIG2ArithmeticDecoder();
86 void setStream(Stream *strA) { str = strA; }
88 int decodeBit(Guint context, JBIG2ArithmeticDecoderStats *stats);
89 int decodeByte(Guint context, JBIG2ArithmeticDecoderStats *stats);
91 // Returns false for OOB, otherwise sets *<x> and returns true.
92 GBool decodeInt(int *x, JBIG2ArithmeticDecoderStats *stats);
94 Guint decodeIAID(Guint codeLen,
95 JBIG2ArithmeticDecoderStats *stats);
99 int decodeIntBit(JBIG2ArithmeticDecoderStats *stats);
102 static Guint qeTab[47];
103 static int nmpsTab[47];
104 static int nlpsTab[47];
105 static int switchTab[47];
111 Guint prev; // for the integer decoder
116 Guint JBIG2ArithmeticDecoder::qeTab[47] = {
117 0x56010000, 0x34010000, 0x18010000, 0x0AC10000,
118 0x05210000, 0x02210000, 0x56010000, 0x54010000,
119 0x48010000, 0x38010000, 0x30010000, 0x24010000,
120 0x1C010000, 0x16010000, 0x56010000, 0x54010000,
121 0x51010000, 0x48010000, 0x38010000, 0x34010000,
122 0x30010000, 0x28010000, 0x24010000, 0x22010000,
123 0x1C010000, 0x18010000, 0x16010000, 0x14010000,
124 0x12010000, 0x11010000, 0x0AC10000, 0x09C10000,
125 0x08A10000, 0x05210000, 0x04410000, 0x02A10000,
126 0x02210000, 0x01410000, 0x01110000, 0x00850000,
127 0x00490000, 0x00250000, 0x00150000, 0x00090000,
128 0x00050000, 0x00010000, 0x56010000
131 int JBIG2ArithmeticDecoder::nmpsTab[47] = {
132 1, 2, 3, 4, 5, 38, 7, 8, 9, 10, 11, 12, 13, 29, 15, 16,
133 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
134 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 45, 46
137 int JBIG2ArithmeticDecoder::nlpsTab[47] = {
138 1, 6, 9, 12, 29, 33, 6, 14, 14, 14, 17, 18, 20, 21, 14, 14,
139 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
140 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 46
143 int JBIG2ArithmeticDecoder::switchTab[47] = {
144 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
145 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
146 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
149 JBIG2ArithmeticDecoder::JBIG2ArithmeticDecoder() {
153 JBIG2ArithmeticDecoder::~JBIG2ArithmeticDecoder() {
156 void JBIG2ArithmeticDecoder::start() {
157 buf0 = (Guint)str->getChar() & 0xff;
158 buf1 = (Guint)str->getChar() & 0xff;
161 c = (buf0 ^ 0xff) << 16;
168 int JBIG2ArithmeticDecoder::decodeBit(Guint context,
169 JBIG2ArithmeticDecoderStats *stats) {
174 iCX = stats->cxTab[context] >> 1;
175 mpsCX = stats->cxTab[context] & 1;
179 if (a & 0x80000000) {
185 if (switchTab[iCX]) {
186 stats->cxTab[context] = (nlpsTab[iCX] << 1) | (1 - mpsCX);
188 stats->cxTab[context] = (nlpsTab[iCX] << 1) | mpsCX;
192 stats->cxTab[context] = (nmpsTab[iCX] << 1) | mpsCX;
202 } while (!(a & 0x80000000));
209 stats->cxTab[context] = (nmpsTab[iCX] << 1) | mpsCX;
212 if (switchTab[iCX]) {
213 stats->cxTab[context] = (nlpsTab[iCX] << 1) | (1 - mpsCX);
215 stats->cxTab[context] = (nlpsTab[iCX] << 1) | mpsCX;
227 } while (!(a & 0x80000000));
232 int JBIG2ArithmeticDecoder::decodeByte(Guint context,
233 JBIG2ArithmeticDecoderStats *stats) {
238 for (i = 0; i < 8; ++i) {
239 byte = (byte << 1) | decodeBit(context, stats);
244 GBool JBIG2ArithmeticDecoder::decodeInt(int *x,
245 JBIG2ArithmeticDecoderStats *stats) {
251 s = decodeIntBit(stats);
252 if (decodeIntBit(stats)) {
253 if (decodeIntBit(stats)) {
254 if (decodeIntBit(stats)) {
255 if (decodeIntBit(stats)) {
256 if (decodeIntBit(stats)) {
258 for (i = 0; i < 32; ++i) {
259 v = (v << 1) | decodeIntBit(stats);
264 for (i = 0; i < 12; ++i) {
265 v = (v << 1) | decodeIntBit(stats);
271 for (i = 0; i < 8; ++i) {
272 v = (v << 1) | decodeIntBit(stats);
278 for (i = 0; i < 6; ++i) {
279 v = (v << 1) | decodeIntBit(stats);
284 v = decodeIntBit(stats);
285 v = (v << 1) | decodeIntBit(stats);
286 v = (v << 1) | decodeIntBit(stats);
287 v = (v << 1) | decodeIntBit(stats);
291 v = decodeIntBit(stats);
292 v = (v << 1) | decodeIntBit(stats);
306 int JBIG2ArithmeticDecoder::decodeIntBit(JBIG2ArithmeticDecoderStats *stats) {
309 bit = decodeBit(prev, stats);
311 prev = (prev << 1) | bit;
313 prev = (((prev << 1) | bit) & 0x1ff) | 0x100;
318 Guint JBIG2ArithmeticDecoder::decodeIAID(Guint codeLen,
319 JBIG2ArithmeticDecoderStats *stats) {
324 for (i = 0; i < codeLen; ++i) {
325 bit = decodeBit(prev, stats);
326 prev = (prev << 1) | bit;
328 return prev - (1 << codeLen);
331 void JBIG2ArithmeticDecoder::byteIn() {
337 buf1 = (Guint)str->getChar() & 0xff;
338 c = c + 0xfe00 - (buf0 << 9);
343 buf1 = (Guint)str->getChar() & 0xff;
344 c = c + 0xff00 - (buf0 << 8);
349 //------------------------------------------------------------------------
351 //------------------------------------------------------------------------
353 #define jbig2HuffmanLOW 0xfffffffd
354 #define jbig2HuffmanOOB 0xfffffffe
355 #define jbig2HuffmanEOT 0xffffffff
357 struct JBIG2HuffmanTable {
360 Guint rangeLen; // can also be LOW, OOB, or EOT
364 JBIG2HuffmanTable huffTableA[] = {
367 { 272, 3, 16, 0x006 },
368 { 65808, 3, 32, 0x007 },
369 { 0, 0, jbig2HuffmanEOT, 0 }
372 JBIG2HuffmanTable huffTableB[] = {
378 { 75, 6, 32, 0x03e },
379 { 0, 6, jbig2HuffmanOOB, 0x03f },
380 { 0, 0, jbig2HuffmanEOT, 0 }
383 JBIG2HuffmanTable huffTableC[] = {
389 { 0, 6, jbig2HuffmanOOB, 0x03e },
390 { 75, 7, 32, 0x0fe },
391 { -256, 8, 8, 0x0fe },
392 { -257, 8, jbig2HuffmanLOW, 0x0ff },
393 { 0, 0, jbig2HuffmanEOT, 0 }
396 JBIG2HuffmanTable huffTableD[] = {
402 { 76, 5, 32, 0x01f },
403 { 0, 0, jbig2HuffmanEOT, 0 }
406 JBIG2HuffmanTable huffTableE[] = {
412 { 76, 6, 32, 0x03e },
413 { -255, 7, 8, 0x07e },
414 { -256, 7, jbig2HuffmanLOW, 0x07f },
415 { 0, 0, jbig2HuffmanEOT, 0 }
418 JBIG2HuffmanTable huffTableF[] = {
420 { 128, 3, 7, 0x002 },
421 { 256, 3, 8, 0x003 },
422 { -1024, 4, 9, 0x008 },
423 { -512, 4, 8, 0x009 },
424 { -256, 4, 7, 0x00a },
425 { -32, 4, 5, 0x00b },
426 { 512, 4, 9, 0x00c },
427 { 1024, 4, 10, 0x00d },
428 { -2048, 5, 10, 0x01c },
429 { -128, 5, 6, 0x01d },
430 { -64, 5, 5, 0x01e },
431 { -2049, 6, jbig2HuffmanLOW, 0x03e },
432 { 2048, 6, 32, 0x03f },
433 { 0, 0, jbig2HuffmanEOT, 0 }
436 JBIG2HuffmanTable huffTableG[] = {
437 { -512, 3, 8, 0x000 },
438 { 256, 3, 8, 0x001 },
439 { 512, 3, 9, 0x002 },
440 { 1024, 3, 10, 0x003 },
441 { -1024, 4, 9, 0x008 },
442 { -256, 4, 7, 0x009 },
443 { -32, 4, 5, 0x00a },
445 { 128, 4, 7, 0x00c },
446 { -128, 5, 6, 0x01a },
447 { -64, 5, 5, 0x01b },
450 { -1025, 5, jbig2HuffmanLOW, 0x01e },
451 { 2048, 5, 32, 0x01f },
452 { 0, 0, jbig2HuffmanEOT, 0 }
455 JBIG2HuffmanTable huffTableH[] = {
457 { 0, 2, jbig2HuffmanOOB, 0x001 },
464 { 134, 5, 7, 0x01c },
467 { 262, 6, 7, 0x03c },
468 { 646, 6, 10, 0x03d },
470 { 390, 7, 8, 0x07d },
471 { -15, 8, 3, 0x0fc },
475 { -16, 9, jbig2HuffmanLOW, 0x1fe },
476 { 1670, 9, 32, 0x1ff },
477 { 0, 0, jbig2HuffmanEOT, 0 }
480 JBIG2HuffmanTable huffTableI[] = {
481 { 0, 2, jbig2HuffmanOOB, 0x000 },
489 { 139, 5, 7, 0x01b },
490 { 267, 5, 8, 0x01c },
493 { 523, 6, 8, 0x03c },
494 { 1291, 6, 11, 0x03d },
496 { 779, 7, 9, 0x07d },
497 { -31, 8, 4, 0x0fc },
498 { -11, 8, 2, 0x0fd },
499 { -15, 9, 2, 0x1fc },
501 { -32, 9, jbig2HuffmanLOW, 0x1fe },
502 { 3339, 9, 32, 0x1ff },
503 { 0, 0, jbig2HuffmanEOT, 0 }
506 JBIG2HuffmanTable huffTableJ[] = {
509 { 0, 2, jbig2HuffmanOOB, 0x002 },
514 { 102, 6, 5, 0x037 },
515 { 134, 6, 6, 0x038 },
516 { 198, 6, 7, 0x039 },
517 { 326, 6, 8, 0x03a },
518 { 582, 6, 9, 0x03b },
519 { 1094, 6, 10, 0x03c },
520 { -21, 7, 4, 0x07a },
523 { 2118, 7, 11, 0x07d },
526 { -22, 8, jbig2HuffmanLOW, 0x0fe },
527 { 4166, 8, 32, 0x0ff },
528 { 0, 0, jbig2HuffmanEOT, 0 }
531 JBIG2HuffmanTable huffTableK[] = {
544 { 141, 7, 32, 0x07f },
545 { 0, 0, jbig2HuffmanEOT, 0 }
548 JBIG2HuffmanTable huffTableL[] = {
561 { 73, 8, 32, 0x0ff },
562 { 0, 0, jbig2HuffmanEOT, 0 }
565 JBIG2HuffmanTable huffTableM[] = {
578 { 141, 7, 32, 0x07f },
579 { 0, 0, jbig2HuffmanEOT, 0 }
582 JBIG2HuffmanTable huffTableN[] = {
588 { 0, 0, jbig2HuffmanEOT, 0 }
591 JBIG2HuffmanTable huffTableO[] = {
601 { -24, 7, 4, 0x07c },
603 { -25, 7, jbig2HuffmanLOW, 0x07e },
604 { 25, 7, 32, 0x07f },
605 { 0, 0, jbig2HuffmanEOT, 0 }
608 //------------------------------------------------------------------------
609 // JBIG2HuffmanDecoder
610 //------------------------------------------------------------------------
612 class JBIG2HuffmanDecoder {
615 JBIG2HuffmanDecoder();
616 ~JBIG2HuffmanDecoder();
617 void setStream(Stream *strA) { str = strA; }
621 // Returns false for OOB, otherwise sets *<x> and returns true.
622 GBool decodeInt(int *x, JBIG2HuffmanTable *table);
624 Guint readBits(Guint n);
627 // Sort the table by prefix length and assign prefix values.
628 void buildTable(JBIG2HuffmanTable *table, Guint len);
637 JBIG2HuffmanDecoder::JBIG2HuffmanDecoder() {
642 JBIG2HuffmanDecoder::~JBIG2HuffmanDecoder() {
645 void JBIG2HuffmanDecoder::reset() {
651 GBool JBIG2HuffmanDecoder::decodeInt(int *x, JBIG2HuffmanTable *table) {
652 Guint i, len, prefix;
657 while (table[i].rangeLen != jbig2HuffmanEOT) {
658 while (len < table[i].prefixLen) {
659 prefix = (prefix << 1) | readBit();
662 if (prefix == table[i].prefix) {
663 if (table[i].rangeLen == jbig2HuffmanOOB) {
666 if (table[i].rangeLen == jbig2HuffmanLOW) {
667 *x = table[i].val - readBits(32);
668 } else if (table[i].rangeLen > 0) {
669 *x = table[i].val + readBits(table[i].rangeLen);
680 Guint JBIG2HuffmanDecoder::readBits(Guint n) {
681 Guint x, mask, nLeft;
683 mask = (n == 32) ? 0xffffffff : ((1 << n) - 1);
685 x = (buf >> (bufLen - n)) & mask;
688 x = buf & ((1 << bufLen) - 1);
692 x = (x << 8) | (str->getChar() & 0xff);
696 buf = str->getChar();
698 x = (x << nLeft) | ((buf >> bufLen) & ((1 << nLeft) - 1));
704 Guint JBIG2HuffmanDecoder::readBit() {
706 buf = str->getChar();
710 return (buf >> bufLen) & 1;
713 void JBIG2HuffmanDecoder::buildTable(JBIG2HuffmanTable *table, Guint len) {
714 Guint i, j, k, prefix;
715 JBIG2HuffmanTable tab;
717 // stable selection sort:
718 // - entries with prefixLen > 0, in ascending prefixLen order
719 // - entry with prefixLen = 0, rangeLen = EOT
720 // - all other entries with prefixLen = 0
721 // (on entry, table[len] has prefixLen = 0, rangeLen = EOT)
722 for (i = 0; i < len; ++i) {
723 for (j = i; j < len && table[j].prefixLen == 0; ++j) ;
727 for (k = j + 1; k < len; ++k) {
728 if (table[k].prefixLen > 0 &&
729 table[k].prefixLen < table[j].prefixLen) {
735 for (k = j; k > i; --k) {
736 table[k] = table[k - 1];
741 table[i] = table[len];
746 table[i++].prefix = prefix++;
747 for (; table[i].rangeLen != jbig2HuffmanEOT; ++i) {
748 prefix <<= table[i].prefixLen - table[i-1].prefixLen;
749 table[i].prefix = prefix++;
753 //------------------------------------------------------------------------
755 //------------------------------------------------------------------------
757 class JBIG2MMRDecoder {
762 void setStream(Stream *strA) { str = strA; }
768 void skipTo(Guint length);
778 JBIG2MMRDecoder::JBIG2MMRDecoder() {
783 JBIG2MMRDecoder::~JBIG2MMRDecoder() {
786 void JBIG2MMRDecoder::reset() {
792 int JBIG2MMRDecoder::get2DCode() {
796 buf = str->getChar() & 0xff;
799 p = &twoDimTab1[(buf >> 1) & 0x7f];
800 } else if (bufLen == 8) {
801 p = &twoDimTab1[(buf >> 1) & 0x7f];
803 p = &twoDimTab1[(buf << (7 - bufLen)) & 0x7f];
804 if (p->bits < 0 || p->bits > (int)bufLen) {
805 buf = (buf << 8) | (str->getChar() & 0xff);
808 p = &twoDimTab1[(buf >> (bufLen - 7)) & 0x7f];
812 error(str->getPos(), "Bad two dim code in JBIG2 MMR stream");
819 int JBIG2MMRDecoder::getWhiteCode() {
824 buf = str->getChar() & 0xff;
829 if (bufLen >= 7 && ((buf >> (bufLen - 7)) & 0x7f) == 0) {
831 code = buf << (12 - bufLen);
833 code = buf >> (bufLen - 12);
835 p = &whiteTab1[code & 0x1f];
838 code = buf << (9 - bufLen);
840 code = buf >> (bufLen - 9);
842 p = &whiteTab2[code & 0x1ff];
844 if (p->bits > 0 && p->bits <= (int)bufLen) {
851 buf = (buf << 8) | (str->getChar() & 0xff);
855 error(str->getPos(), "Bad white code in JBIG2 MMR stream");
856 // eat a bit and return a positive number so that the caller doesn't
857 // go into an infinite loop
862 int JBIG2MMRDecoder::getBlackCode() {
867 buf = str->getChar() & 0xff;
872 if (bufLen >= 6 && ((buf >> (bufLen - 6)) & 0x3f) == 0) {
874 code = buf << (13 - bufLen);
876 code = buf >> (bufLen - 13);
878 p = &blackTab1[code & 0x7f];
879 } else if (bufLen >= 4 && ((buf >> (bufLen - 4)) & 0x0f) == 0) {
881 code = buf << (12 - bufLen);
883 code = buf >> (bufLen - 12);
885 p = &blackTab2[(code & 0xff) - 64];
888 code = buf << (6 - bufLen);
890 code = buf >> (bufLen - 6);
892 p = &blackTab3[code & 0x3f];
894 if (p->bits > 0 && p->bits <= (int)bufLen) {
901 buf = (buf << 8) | (str->getChar() & 0xff);
905 error(str->getPos(), "Bad black code in JBIG2 MMR stream");
906 // eat a bit and return a positive number so that the caller doesn't
907 // go into an infinite loop
912 Guint JBIG2MMRDecoder::get24Bits() {
913 while (bufLen < 24) {
914 buf = (buf << 8) | (str->getChar() & 0xff);
918 return (buf >> (bufLen - 24)) & 0xffffff;
921 void JBIG2MMRDecoder::skipTo(Guint length) {
922 while (nBytesRead < length) {
928 //------------------------------------------------------------------------
930 //------------------------------------------------------------------------
932 enum JBIG2SegmentType {
942 JBIG2Segment(Guint segNumA) { segNum = segNumA; }
943 virtual ~JBIG2Segment() {}
944 void setSegNum(Guint segNumA) { segNum = segNumA; }
945 Guint getSegNum() { return segNum; }
946 virtual JBIG2SegmentType getType() = 0;
953 //------------------------------------------------------------------------
955 //------------------------------------------------------------------------
957 struct JBIG2BitmapPtr {
963 class JBIG2Bitmap: public JBIG2Segment {
966 JBIG2Bitmap(Guint segNumA, int wA, int hA);
967 virtual ~JBIG2Bitmap();
968 virtual JBIG2SegmentType getType() { return jbig2SegBitmap; }
969 JBIG2Bitmap *copy() { return new JBIG2Bitmap(0, this); }
970 JBIG2Bitmap *getSlice(Guint x, Guint y, Guint wA, Guint hA);
971 void expand(int newH, Guint pixel);
974 int getWidth() { return w; }
975 int getHeight() { return h; }
976 int getPixel(int x, int y)
977 { return (x < 0 || x >= w || y < 0 || y >= h) ? 0 :
978 (data[y * line + (x >> 3)] >> (7 - (x & 7))) & 1; }
979 void setPixel(int x, int y)
980 { data[y * line + (x >> 3)] |= 1 << (7 - (x & 7)); }
981 void clearPixel(int x, int y)
982 { data[y * line + (x >> 3)] &= 0x7f7f >> (x & 7); }
983 void getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr);
984 int nextPixel(JBIG2BitmapPtr *ptr);
985 void duplicateRow(int yDest, int ySrc);
986 void combine(JBIG2Bitmap *bitmap, int x, int y, Guint combOp);
987 Guchar *getDataPtr() { return data; }
988 int getDataSize() { return h * line; }
992 JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap);
998 JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, int wA, int hA):
999 JBIG2Segment(segNumA)
1003 line = (wA + 7) >> 3;
1004 data = (Guchar *)gmalloc(h * line);
1007 JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap):
1008 JBIG2Segment(segNumA)
1012 line = bitmap->line;
1013 data = (Guchar *)gmalloc(h * line);
1014 memcpy(data, bitmap->data, h * line);
1017 JBIG2Bitmap::~JBIG2Bitmap() {
1022 JBIG2Bitmap *JBIG2Bitmap::getSlice(Guint x, Guint y, Guint wA, Guint hA) {
1026 slice = new JBIG2Bitmap(0, wA, hA);
1027 slice->clearToZero();
1028 for (yy = 0; yy < hA; ++yy) {
1029 for (xx = 0; xx < wA; ++xx) {
1030 if (getPixel(x + xx, y + yy)) {
1031 slice->setPixel(xx, yy);
1038 void JBIG2Bitmap::expand(int newH, Guint pixel) {
1042 data = (Guchar *)grealloc(data, newH * line);
1044 memset(data + h * line, 0xff, (newH - h) * line);
1046 memset(data + h * line, 0x00, (newH - h) * line);
1051 void JBIG2Bitmap::clearToZero() {
1052 memset(data, 0, h * line);
1055 void JBIG2Bitmap::clearToOne() {
1056 memset(data, 0xff, h * line);
1059 inline void JBIG2Bitmap::getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr) {
1060 if (y < 0 || y >= h || x >= w) {
1063 ptr->p = &data[y * line];
1067 ptr->p = &data[y * line + (x >> 3)];
1068 ptr->shift = 7 - (x & 7);
1073 inline int JBIG2Bitmap::nextPixel(JBIG2BitmapPtr *ptr) {
1078 } else if (ptr->x < 0) {
1082 pix = (*ptr->p >> ptr->shift) & 1;
1083 if (++ptr->x == w) {
1085 } else if (ptr->shift == 0) {
1095 void JBIG2Bitmap::duplicateRow(int yDest, int ySrc) {
1096 memcpy(data + yDest * line, data + ySrc * line, line);
1099 void JBIG2Bitmap::combine(JBIG2Bitmap *bitmap, int x, int y,
1101 int x0, x1, y0, y1, xx, yy;
1102 Guchar *srcPtr, *destPtr;
1103 Guint src0, src1, src, dest, s1, s2, m1, m2, m3;
1111 if (y + bitmap->h > h) {
1135 m1 = 0xff >> (x1 & 7);
1136 m2 = 0xff << (((x1 & 7) == 0) ? 0 : 8 - (x1 & 7));
1137 m3 = (0xff >> s1) & m2;
1139 oneByte = x0 == ((x1 - 1) & ~7);
1141 for (yy = y0; yy < y1; ++yy) {
1143 // one byte per line -- need to mask both left and right side
1146 destPtr = data + (y + yy) * line + (x >> 3);
1147 srcPtr = bitmap->data + yy * bitmap->line;
1152 dest |= (src1 >> s1) & m2;
1155 dest &= ((0xff00 | src1) >> s1) | m1;
1158 dest ^= (src1 >> s1) & m2;
1161 dest ^= ((src1 ^ 0xff) >> s1) & m2;
1164 dest = (dest & ~m3) | ((src1 >> s1) & m3);
1169 destPtr = data + (y + yy) * line;
1170 srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
1184 dest ^= (src1 ^ 0xff) & m2;
1187 dest = (src1 & m2) | (dest & m1);
1193 // multiple bytes per line -- need to mask left side of left-most
1194 // byte and right side of right-most byte
1199 destPtr = data + (y + yy) * line + (x >> 3);
1200 srcPtr = bitmap->data + yy * bitmap->line;
1208 dest &= (0xff00 | src1) >> s1;
1214 dest ^= (src1 ^ 0xff) >> s1;
1217 dest = (dest & (0xff << s2)) | (src1 >> s1);
1223 destPtr = data + (y + yy) * line;
1224 srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
1230 for (; xx < x1 - 8; xx += 8) {
1234 src = (((src0 << 8) | src1) >> s1) & 0xff;
1259 src = (((src0 << 8) | src1) >> s1) & 0xff;
1271 dest ^= (src ^ 0xff) & m2;
1274 dest = (src & m2) | (dest & m1);
1282 //------------------------------------------------------------------------
1284 //------------------------------------------------------------------------
1286 class JBIG2SymbolDict: public JBIG2Segment {
1289 JBIG2SymbolDict(Guint segNumA, Guint sizeA);
1290 virtual ~JBIG2SymbolDict();
1291 virtual JBIG2SegmentType getType() { return jbig2SegSymbolDict; }
1292 Guint getSize() { return size; }
1293 void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
1294 JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
1295 void setGenericRegionStats(JBIG2ArithmeticDecoderStats *stats)
1296 { genericRegionStats = stats; }
1297 void setRefinementRegionStats(JBIG2ArithmeticDecoderStats *stats)
1298 { refinementRegionStats = stats; }
1299 JBIG2ArithmeticDecoderStats *getGenericRegionStats()
1300 { return genericRegionStats; }
1301 JBIG2ArithmeticDecoderStats *getRefinementRegionStats()
1302 { return refinementRegionStats; }
1307 JBIG2Bitmap **bitmaps;
1308 JBIG2ArithmeticDecoderStats *genericRegionStats;
1309 JBIG2ArithmeticDecoderStats *refinementRegionStats;
1312 JBIG2SymbolDict::JBIG2SymbolDict(Guint segNumA, Guint sizeA):
1313 JBIG2Segment(segNumA)
1316 bitmaps = (JBIG2Bitmap **)gmalloc(size * sizeof(JBIG2Bitmap *));
1317 genericRegionStats = NULL;
1318 refinementRegionStats = NULL;
1321 JBIG2SymbolDict::~JBIG2SymbolDict() {
1324 for (i = 0; i < size; ++i) {
1328 if (genericRegionStats) {
1329 delete genericRegionStats;
1331 if (refinementRegionStats) {
1332 delete refinementRegionStats;
1336 //------------------------------------------------------------------------
1338 //------------------------------------------------------------------------
1340 class JBIG2PatternDict: public JBIG2Segment {
1343 JBIG2PatternDict(Guint segNumA, Guint sizeA);
1344 virtual ~JBIG2PatternDict();
1345 virtual JBIG2SegmentType getType() { return jbig2SegPatternDict; }
1346 Guint getSize() { return size; }
1347 void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
1348 JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
1353 JBIG2Bitmap **bitmaps;
1356 JBIG2PatternDict::JBIG2PatternDict(Guint segNumA, Guint sizeA):
1357 JBIG2Segment(segNumA)
1360 bitmaps = (JBIG2Bitmap **)gmalloc(size * sizeof(JBIG2Bitmap *));
1363 JBIG2PatternDict::~JBIG2PatternDict() {
1366 for (i = 0; i < size; ++i) {
1372 //------------------------------------------------------------------------
1374 //------------------------------------------------------------------------
1376 class JBIG2CodeTable: public JBIG2Segment {
1379 JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA);
1380 virtual ~JBIG2CodeTable();
1381 virtual JBIG2SegmentType getType() { return jbig2SegCodeTable; }
1382 JBIG2HuffmanTable *getHuffTable() { return table; }
1386 JBIG2HuffmanTable *table;
1389 JBIG2CodeTable::JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA):
1390 JBIG2Segment(segNumA)
1395 JBIG2CodeTable::~JBIG2CodeTable() {
1399 //------------------------------------------------------------------------
1401 //------------------------------------------------------------------------
1403 JBIG2Stream::JBIG2Stream(Stream *strA, Object *globalsStream):
1408 arithDecoder = new JBIG2ArithmeticDecoder();
1409 genericRegionStats = new JBIG2ArithmeticDecoderStats(1);
1410 refinementRegionStats = new JBIG2ArithmeticDecoderStats(1);
1411 iadhStats = new JBIG2ArithmeticDecoderStats(9);
1412 iadwStats = new JBIG2ArithmeticDecoderStats(9);
1413 iaexStats = new JBIG2ArithmeticDecoderStats(9);
1414 iaaiStats = new JBIG2ArithmeticDecoderStats(9);
1415 iadtStats = new JBIG2ArithmeticDecoderStats(9);
1416 iaitStats = new JBIG2ArithmeticDecoderStats(9);
1417 iafsStats = new JBIG2ArithmeticDecoderStats(9);
1418 iadsStats = new JBIG2ArithmeticDecoderStats(9);
1419 iardxStats = new JBIG2ArithmeticDecoderStats(9);
1420 iardyStats = new JBIG2ArithmeticDecoderStats(9);
1421 iardwStats = new JBIG2ArithmeticDecoderStats(9);
1422 iardhStats = new JBIG2ArithmeticDecoderStats(9);
1423 iariStats = new JBIG2ArithmeticDecoderStats(9);
1424 iaidStats = new JBIG2ArithmeticDecoderStats(1);
1425 huffDecoder = new JBIG2HuffmanDecoder();
1426 mmrDecoder = new JBIG2MMRDecoder();
1428 segments = globalSegments = new GList();
1429 if (globalsStream->isStream()) {
1430 curStr = globalsStream->getStream();
1432 arithDecoder->setStream(curStr);
1433 huffDecoder->setStream(curStr);
1434 mmrDecoder->setStream(curStr);
1440 dataPtr = dataEnd = NULL;
1443 JBIG2Stream::~JBIG2Stream() {
1444 delete arithDecoder;
1445 delete genericRegionStats;
1446 delete refinementRegionStats;
1467 deleteGList(segments, JBIG2Segment);
1469 if (globalSegments) {
1470 deleteGList(globalSegments, JBIG2Segment);
1475 void JBIG2Stream::reset() {
1481 deleteGList(segments, JBIG2Segment);
1483 segments = new GList();
1487 arithDecoder->setStream(curStr);
1488 huffDecoder->setStream(curStr);
1489 mmrDecoder->setStream(curStr);
1493 dataPtr = pageBitmap->getDataPtr();
1494 dataEnd = dataPtr + pageBitmap->getDataSize();
1500 int JBIG2Stream::getChar() {
1501 if (dataPtr && dataPtr < dataEnd) {
1502 return (*dataPtr++ ^ 0xff) & 0xff;
1507 int JBIG2Stream::lookChar() {
1508 if (dataPtr && dataPtr < dataEnd) {
1509 return (*dataPtr ^ 0xff) & 0xff;
1514 GString *JBIG2Stream::getPSFilter(char *indent) {
1518 GBool JBIG2Stream::isBinary(GBool last) {
1519 return str->isBinary(gTrue);
1522 void JBIG2Stream::readSegments() {
1523 Guint segNum, segFlags, segType, page, segLength;
1524 Guint refFlags, nRefSegs;
1529 while (readULong(&segNum)) {
1531 // segment header flags
1532 if (!readUByte(&segFlags)) {
1535 segType = segFlags & 0x3f;
1537 // referred-to segment count and retention flags
1538 if (!readUByte(&refFlags)) {
1541 nRefSegs = refFlags >> 5;
1542 if (nRefSegs == 7) {
1543 if ((c1 = curStr->getChar()) == EOF ||
1544 (c2 = curStr->getChar()) == EOF ||
1545 (c3 = curStr->getChar()) == EOF) {
1548 refFlags = (refFlags << 24) | (c1 << 16) | (c2 << 8) | c3;
1549 nRefSegs = refFlags & 0x1fffffff;
1550 for (i = 0; i < (nRefSegs + 9) >> 3; ++i) {
1551 c1 = curStr->getChar();
1555 // referred-to segment numbers
1556 refSegs = (Guint *)gmalloc(nRefSegs * sizeof(Guint));
1557 if (segNum <= 256) {
1558 for (i = 0; i < nRefSegs; ++i) {
1559 if (!readUByte(&refSegs[i])) {
1563 } else if (segNum <= 65536) {
1564 for (i = 0; i < nRefSegs; ++i) {
1565 if (!readUWord(&refSegs[i])) {
1570 for (i = 0; i < nRefSegs; ++i) {
1571 if (!readULong(&refSegs[i])) {
1577 // segment page association
1578 if (segFlags & 0x40) {
1579 if (!readULong(&page)) {
1583 if (!readUByte(&page)) {
1588 // segment data length
1589 if (!readULong(&segLength)) {
1593 // read the segment data
1596 readSymbolDictSeg(segNum, segLength, refSegs, nRefSegs);
1599 readTextRegionSeg(segNum, gFalse, gFalse, segLength, refSegs, nRefSegs);
1602 readTextRegionSeg(segNum, gTrue, gFalse, segLength, refSegs, nRefSegs);
1605 readTextRegionSeg(segNum, gTrue, gTrue, segLength, refSegs, nRefSegs);
1608 readPatternDictSeg(segNum, segLength);
1611 readHalftoneRegionSeg(segNum, gFalse, gFalse, segLength,
1615 readHalftoneRegionSeg(segNum, gTrue, gFalse, segLength,
1619 readHalftoneRegionSeg(segNum, gTrue, gTrue, segLength,
1623 readGenericRegionSeg(segNum, gFalse, gFalse, segLength);
1626 readGenericRegionSeg(segNum, gTrue, gFalse, segLength);
1629 readGenericRegionSeg(segNum, gTrue, gTrue, segLength);
1632 readGenericRefinementRegionSeg(segNum, gFalse, gFalse, segLength,
1636 readGenericRefinementRegionSeg(segNum, gTrue, gFalse, segLength,
1640 readGenericRefinementRegionSeg(segNum, gTrue, gTrue, segLength,
1644 readPageInfoSeg(segLength);
1647 readEndOfStripeSeg(segLength);
1650 readProfilesSeg(segLength);
1653 readCodeTableSeg(segNum, segLength);
1656 readExtensionSeg(segLength);
1659 error(getPos(), "Unknown segment type in JBIG2 stream");
1660 for (i = 0; i < segLength; ++i) {
1661 if ((c1 = curStr->getChar()) == EOF) {
1676 error(getPos(), "Unexpected EOF in JBIG2 stream");
1679 void JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
1680 Guint *refSegs, Guint nRefSegs) {
1681 JBIG2SymbolDict *symbolDict;
1682 JBIG2HuffmanTable *huffDHTable, *huffDWTable;
1683 JBIG2HuffmanTable *huffBMSizeTable, *huffAggInstTable;
1686 JBIG2SymbolDict *inputSymbolDict;
1687 Guint flags, sdTemplate, sdrTemplate, huff, refAgg;
1688 Guint huffDH, huffDW, huffBMSize, huffAggInst;
1689 Guint contextUsed, contextRetained;
1690 int sdATX[4], sdATY[4], sdrATX[2], sdrATY[2];
1691 Guint numExSyms, numNewSyms, numInputSyms, symCodeLen;
1692 JBIG2Bitmap **bitmaps;
1693 JBIG2Bitmap *collBitmap, *refBitmap;
1695 Guint symHeight, symWidth, totalWidth, x, symID;
1696 int dh, dw, refAggNum, refDX, refDY, bmSize;
1702 // symbol dictionary flags
1703 if (!readUWord(&flags)) {
1706 sdTemplate = (flags >> 10) & 3;
1707 sdrTemplate = (flags >> 12) & 1;
1709 refAgg = (flags >> 1) & 1;
1710 huffDH = (flags >> 2) & 3;
1711 huffDW = (flags >> 4) & 3;
1712 huffBMSize = (flags >> 6) & 1;
1713 huffAggInst = (flags >> 7) & 1;
1714 contextUsed = (flags >> 8) & 1;
1715 contextRetained = (flags >> 9) & 1;
1717 // symbol dictionary AT flags
1719 if (sdTemplate == 0) {
1720 if (!readByte(&sdATX[0]) ||
1721 !readByte(&sdATY[0]) ||
1722 !readByte(&sdATX[1]) ||
1723 !readByte(&sdATY[1]) ||
1724 !readByte(&sdATX[2]) ||
1725 !readByte(&sdATY[2]) ||
1726 !readByte(&sdATX[3]) ||
1727 !readByte(&sdATY[3])) {
1731 if (!readByte(&sdATX[0]) ||
1732 !readByte(&sdATY[0])) {
1738 // symbol dictionary refinement AT flags
1739 if (refAgg && !sdrTemplate) {
1740 if (!readByte(&sdrATX[0]) ||
1741 !readByte(&sdrATY[0]) ||
1742 !readByte(&sdrATX[1]) ||
1743 !readByte(&sdrATY[1])) {
1748 // SDNUMEXSYMS and SDNUMNEWSYMS
1749 if (!readULong(&numExSyms) || !readULong(&numNewSyms)) {
1753 // get referenced segments: input symbol dictionaries and code tables
1754 codeTables = new GList();
1756 for (i = 0; i < nRefSegs; ++i) {
1757 seg = findSegment(refSegs[i]);
1758 if (seg->getType() == jbig2SegSymbolDict) {
1759 numInputSyms += ((JBIG2SymbolDict *)seg)->getSize();
1760 } else if (seg->getType() == jbig2SegCodeTable) {
1761 codeTables->append(seg);
1765 // compute symbol code length
1768 while (i < numInputSyms + numNewSyms) {
1773 // get the input symbol bitmaps
1774 bitmaps = (JBIG2Bitmap **)gmalloc((numInputSyms + numNewSyms) *
1775 sizeof(JBIG2Bitmap *));
1777 inputSymbolDict = NULL;
1778 for (i = 0; i < nRefSegs; ++i) {
1779 seg = findSegment(refSegs[i]);
1780 if (seg->getType() == jbig2SegSymbolDict) {
1781 inputSymbolDict = (JBIG2SymbolDict *)seg;
1782 for (j = 0; j < inputSymbolDict->getSize(); ++j) {
1783 bitmaps[k++] = inputSymbolDict->getBitmap(j);
1788 // get the Huffman tables
1789 huffDHTable = huffDWTable = NULL; // make gcc happy
1790 huffBMSizeTable = huffAggInstTable = NULL; // make gcc happy
1794 huffDHTable = huffTableD;
1795 } else if (huffDH == 1) {
1796 huffDHTable = huffTableE;
1798 huffDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1801 huffDWTable = huffTableB;
1802 } else if (huffDW == 1) {
1803 huffDWTable = huffTableC;
1805 huffDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1807 if (huffBMSize == 0) {
1808 huffBMSizeTable = huffTableA;
1811 ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1813 if (huffAggInst == 0) {
1814 huffAggInstTable = huffTableA;
1817 ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1822 // set up the Huffman decoder
1824 huffDecoder->reset();
1826 // set up the arithmetic decoder
1828 if (contextUsed && inputSymbolDict) {
1829 resetGenericStats(sdTemplate, inputSymbolDict->getGenericRegionStats());
1831 resetGenericStats(sdTemplate, NULL);
1833 resetIntStats(symCodeLen);
1834 arithDecoder->start();
1837 // set up the arithmetic decoder for refinement/aggregation
1839 if (contextUsed && inputSymbolDict) {
1840 resetRefinementStats(sdrTemplate,
1841 inputSymbolDict->getRefinementRegionStats());
1843 resetRefinementStats(sdrTemplate, NULL);
1847 // allocate symbol widths storage
1849 if (huff && !refAgg) {
1850 symWidths = (Guint *)gmalloc(numNewSyms * sizeof(Guint));
1855 while (i < numNewSyms) {
1857 // read the height class delta height
1859 huffDecoder->decodeInt(&dh, huffDHTable);
1861 arithDecoder->decodeInt(&dh, iadhStats);
1868 // read the symbols in this height class
1871 // read the delta width
1873 if (!huffDecoder->decodeInt(&dw, huffDWTable)) {
1877 if (!arithDecoder->decodeInt(&dw, iadwStats)) {
1883 // using a collective bitmap, so don't read a bitmap here
1884 if (huff && !refAgg) {
1885 symWidths[i] = symWidth;
1886 totalWidth += symWidth;
1888 // refinement/aggregate coding
1889 } else if (refAgg) {
1891 if (!huffDecoder->decodeInt(&refAggNum, huffAggInstTable)) {
1895 if (!arithDecoder->decodeInt(&refAggNum, iaaiStats)) {
1899 #if 0 //~ This special case was added about a year before the final draft
1900 //~ of the JBIG2 spec was released. I have encountered some old
1901 //~ JBIG2 images that predate it.
1904 if (refAggNum == 1) {
1907 symID = huffDecoder->readBits(symCodeLen);
1908 huffDecoder->decodeInt(&refDX, huffTableO);
1909 huffDecoder->decodeInt(&refDY, huffTableO);
1910 huffDecoder->decodeInt(&bmSize, huffTableA);
1911 huffDecoder->reset();
1912 arithDecoder->start();
1914 symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
1915 arithDecoder->decodeInt(&refDX, iardxStats);
1916 arithDecoder->decodeInt(&refDY, iardyStats);
1918 refBitmap = bitmaps[symID];
1919 bitmaps[numInputSyms + i] =
1920 readGenericRefinementRegion(symWidth, symHeight,
1921 sdrTemplate, gFalse,
1922 refBitmap, refDX, refDY,
1924 //~ do we need to use the bmSize value here (in Huffman mode)?
1926 bitmaps[numInputSyms + i] =
1927 readTextRegion(huff, gTrue, symWidth, symHeight,
1928 refAggNum, 0, numInputSyms + i, NULL,
1929 symCodeLen, bitmaps, 0, 0, 0, 1, 0,
1930 huffTableF, huffTableH, huffTableK, huffTableO,
1931 huffTableO, huffTableO, huffTableO, huffTableA,
1932 sdrTemplate, sdrATX, sdrATY);
1935 // non-ref/agg coding
1937 bitmaps[numInputSyms + i] =
1938 readGenericBitmap(gFalse, symWidth, symHeight,
1939 sdTemplate, gFalse, gFalse, NULL,
1946 // read the collective bitmap
1947 if (huff && !refAgg) {
1948 huffDecoder->decodeInt(&bmSize, huffBMSizeTable);
1949 huffDecoder->reset();
1951 collBitmap = new JBIG2Bitmap(0, totalWidth, symHeight);
1952 bmSize = symHeight * ((totalWidth + 7) >> 3);
1953 p = collBitmap->getDataPtr();
1954 for (k = 0; k < (Guint)bmSize; ++k) {
1955 *p++ = curStr->getChar();
1958 collBitmap = readGenericBitmap(gTrue, totalWidth, symHeight,
1959 0, gFalse, gFalse, NULL, NULL, NULL,
1963 for (; j < i; ++j) {
1964 bitmaps[numInputSyms + j] =
1965 collBitmap->getSlice(x, 0, symWidths[j], symHeight);
1972 // create the symbol dict object
1973 symbolDict = new JBIG2SymbolDict(segNum, numExSyms);
1975 // exported symbol list
1978 while (i < numInputSyms + numNewSyms) {
1980 huffDecoder->decodeInt(&run, huffTableA);
1982 arithDecoder->decodeInt(&run, iaexStats);
1985 for (cnt = 0; cnt < run; ++cnt) {
1986 symbolDict->setBitmap(j++, bitmaps[i++]->copy());
1994 for (i = 0; i < numNewSyms; ++i) {
1995 delete bitmaps[numInputSyms + i];
2002 // save the arithmetic decoder stats
2003 if (!huff && contextRetained) {
2004 symbolDict->setGenericRegionStats(genericRegionStats->copy());
2006 symbolDict->setRefinementRegionStats(refinementRegionStats->copy());
2010 // store the new symbol dict
2011 segments->append(symbolDict);
2016 error(getPos(), "Unexpected EOF in JBIG2 stream");
2019 void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
2020 GBool lossless, Guint length,
2021 Guint *refSegs, Guint nRefSegs) {
2022 JBIG2Bitmap *bitmap;
2023 JBIG2HuffmanTable runLengthTab[36];
2024 JBIG2HuffmanTable *symCodeTab;
2025 JBIG2HuffmanTable *huffFSTable, *huffDSTable, *huffDTTable;
2026 JBIG2HuffmanTable *huffRDWTable, *huffRDHTable;
2027 JBIG2HuffmanTable *huffRDXTable, *huffRDYTable, *huffRSizeTable;
2030 JBIG2SymbolDict *symbolDict;
2032 Guint w, h, x, y, segInfoFlags, extCombOp;
2033 Guint flags, huff, refine, logStrips, refCorner, transposed;
2034 Guint combOp, defPixel, templ;
2036 Guint huffFlags, huffFS, huffDS, huffDT;
2037 Guint huffRDW, huffRDH, huffRDX, huffRDY, huffRSize;
2038 Guint numInstances, numSyms, symCodeLen;
2043 // region segment info field
2044 if (!readULong(&w) || !readULong(&h) ||
2045 !readULong(&x) || !readULong(&y) ||
2046 !readUByte(&segInfoFlags)) {
2049 extCombOp = segInfoFlags & 7;
2051 // rest of the text region header
2052 if (!readUWord(&flags)) {
2056 refine = (flags >> 1) & 1;
2057 logStrips = (flags >> 2) & 3;
2058 refCorner = (flags >> 4) & 3;
2059 transposed = (flags >> 6) & 1;
2060 combOp = (flags >> 7) & 3;
2061 defPixel = (flags >> 9) & 1;
2062 sOffset = (flags >> 10) & 0x1f;
2063 if (sOffset & 0x10) {
2064 sOffset |= -1 - 0x0f;
2066 templ = (flags >> 15) & 1;
2067 huffFS = huffDS = huffDT = 0; // make gcc happy
2068 huffRDW = huffRDH = huffRDX = huffRDY = huffRSize = 0; // make gcc happy
2070 if (!readUWord(&huffFlags)) {
2073 huffFS = huffFlags & 3;
2074 huffDS = (huffFlags >> 2) & 3;
2075 huffDT = (huffFlags >> 4) & 3;
2076 huffRDW = (huffFlags >> 6) & 3;
2077 huffRDH = (huffFlags >> 8) & 3;
2078 huffRDX = (huffFlags >> 10) & 3;
2079 huffRDY = (huffFlags >> 12) & 3;
2080 huffRSize = (huffFlags >> 14) & 1;
2082 if (refine && templ == 0) {
2083 if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
2084 !readByte(&atx[1]) || !readByte(&aty[1])) {
2088 if (!readULong(&numInstances)) {
2092 // get symbol dictionaries and tables
2093 codeTables = new GList();
2095 for (i = 0; i < nRefSegs; ++i) {
2096 seg = findSegment(refSegs[i]);
2097 if (seg->getType() == jbig2SegSymbolDict) {
2098 numSyms += ((JBIG2SymbolDict *)seg)->getSize();
2099 } else if (seg->getType() == jbig2SegCodeTable) {
2100 codeTables->append(seg);
2105 while (i < numSyms) {
2110 // get the symbol bitmaps
2111 syms = (JBIG2Bitmap **)gmalloc(numSyms * sizeof(JBIG2Bitmap *));
2113 for (i = 0; i < nRefSegs; ++i) {
2114 seg = findSegment(refSegs[i]);
2115 if (seg->getType() == jbig2SegSymbolDict) {
2116 symbolDict = (JBIG2SymbolDict *)seg;
2117 for (k = 0; k < symbolDict->getSize(); ++k) {
2118 syms[kk++] = symbolDict->getBitmap(k);
2123 // get the Huffman tables
2124 huffFSTable = huffDSTable = huffDTTable = NULL; // make gcc happy
2125 huffRDWTable = huffRDHTable = NULL; // make gcc happy
2126 huffRDXTable = huffRDYTable = huffRSizeTable = NULL; // make gcc happy
2130 huffFSTable = huffTableF;
2131 } else if (huffFS == 1) {
2132 huffFSTable = huffTableG;
2134 huffFSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2137 huffDSTable = huffTableH;
2138 } else if (huffDS == 1) {
2139 huffDSTable = huffTableI;
2140 } else if (huffDS == 2) {
2141 huffDSTable = huffTableJ;
2143 huffDSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2146 huffDTTable = huffTableK;
2147 } else if (huffDT == 1) {
2148 huffDTTable = huffTableL;
2149 } else if (huffDT == 2) {
2150 huffDTTable = huffTableM;
2152 huffDTTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2155 huffRDWTable = huffTableN;
2156 } else if (huffRDW == 1) {
2157 huffRDWTable = huffTableO;
2159 huffRDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2162 huffRDHTable = huffTableN;
2163 } else if (huffRDH == 1) {
2164 huffRDHTable = huffTableO;
2166 huffRDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2169 huffRDXTable = huffTableN;
2170 } else if (huffRDX == 1) {
2171 huffRDXTable = huffTableO;
2173 huffRDXTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2176 huffRDYTable = huffTableN;
2177 } else if (huffRDY == 1) {
2178 huffRDYTable = huffTableO;
2180 huffRDYTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2182 if (huffRSize == 0) {
2183 huffRSizeTable = huffTableA;
2186 ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2191 // symbol ID Huffman decoding table
2193 huffDecoder->reset();
2194 for (i = 0; i < 32; ++i) {
2195 runLengthTab[i].val = i;
2196 runLengthTab[i].prefixLen = huffDecoder->readBits(4);
2197 runLengthTab[i].rangeLen = 0;
2199 runLengthTab[32].val = 0x103;
2200 runLengthTab[32].prefixLen = huffDecoder->readBits(4);
2201 runLengthTab[32].rangeLen = 2;
2202 runLengthTab[33].val = 0x203;
2203 runLengthTab[33].prefixLen = huffDecoder->readBits(4);
2204 runLengthTab[33].rangeLen = 3;
2205 runLengthTab[34].val = 0x20b;
2206 runLengthTab[34].prefixLen = huffDecoder->readBits(4);
2207 runLengthTab[34].rangeLen = 7;
2208 runLengthTab[35].prefixLen = 0;
2209 runLengthTab[35].rangeLen = jbig2HuffmanEOT;
2210 huffDecoder->buildTable(runLengthTab, 35);
2211 symCodeTab = (JBIG2HuffmanTable *)gmalloc((numSyms + 1) *
2212 sizeof(JBIG2HuffmanTable));
2213 for (i = 0; i < numSyms; ++i) {
2214 symCodeTab[i].val = i;
2215 symCodeTab[i].rangeLen = 0;
2218 while (i < numSyms) {
2219 huffDecoder->decodeInt(&j, runLengthTab);
2221 for (j -= 0x200; j && i < numSyms; --j) {
2222 symCodeTab[i++].prefixLen = 0;
2224 } else if (j > 0x100) {
2225 for (j -= 0x100; j && i < numSyms; --j) {
2226 symCodeTab[i].prefixLen = symCodeTab[i-1].prefixLen;
2230 symCodeTab[i++].prefixLen = j;
2233 symCodeTab[numSyms].prefixLen = 0;
2234 symCodeTab[numSyms].rangeLen = jbig2HuffmanEOT;
2235 huffDecoder->buildTable(symCodeTab, numSyms);
2236 huffDecoder->reset();
2238 // set up the arithmetic decoder
2241 resetIntStats(symCodeLen);
2242 arithDecoder->start();
2245 resetRefinementStats(templ, NULL);
2248 bitmap = readTextRegion(huff, refine, w, h, numInstances,
2249 logStrips, numSyms, symCodeTab, symCodeLen, syms,
2250 defPixel, combOp, transposed, refCorner, sOffset,
2251 huffFSTable, huffDSTable, huffDTTable,
2252 huffRDWTable, huffRDHTable,
2253 huffRDXTable, huffRDYTable, huffRSizeTable,
2258 // combine the region bitmap into the page bitmap
2260 if (pageH == 0xffffffff && y + h > curPageH) {
2261 pageBitmap->expand(y + h, pageDefPixel);
2263 pageBitmap->combine(bitmap, x, y, extCombOp);
2266 // store the region bitmap
2268 bitmap->setSegNum(segNum);
2269 segments->append(bitmap);
2272 // clean up the Huffman decoder
2280 error(getPos(), "Unexpected EOF in JBIG2 stream");
2283 JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
2288 JBIG2HuffmanTable *symCodeTab,
2291 Guint defPixel, Guint combOp,
2292 Guint transposed, Guint refCorner,
2294 JBIG2HuffmanTable *huffFSTable,
2295 JBIG2HuffmanTable *huffDSTable,
2296 JBIG2HuffmanTable *huffDTTable,
2297 JBIG2HuffmanTable *huffRDWTable,
2298 JBIG2HuffmanTable *huffRDHTable,
2299 JBIG2HuffmanTable *huffRDXTable,
2300 JBIG2HuffmanTable *huffRDYTable,
2301 JBIG2HuffmanTable *huffRSizeTable,
2303 int *atx, int *aty) {
2304 JBIG2Bitmap *bitmap;
2305 JBIG2Bitmap *symbolBitmap;
2307 int t, dt, tt, s, ds, sFirst, j;
2308 int rdw, rdh, rdx, rdy, ri, refDX, refDY, bmSize;
2309 Guint symID, inst, bw, bh;
2311 strips = 1 << logStrips;
2313 // allocate the bitmap
2314 bitmap = new JBIG2Bitmap(0, w, h);
2316 bitmap->clearToOne();
2318 bitmap->clearToZero();
2321 // decode initial T value
2323 huffDecoder->decodeInt(&t, huffDTTable);
2325 arithDecoder->decodeInt(&t, iadtStats);
2331 while (inst < numInstances) {
2335 huffDecoder->decodeInt(&dt, huffDTTable);
2337 arithDecoder->decodeInt(&dt, iadtStats);
2343 huffDecoder->decodeInt(&ds, huffFSTable);
2345 arithDecoder->decodeInt(&ds, iafsStats);
2350 // read the instances
2357 dt = huffDecoder->readBits(logStrips);
2359 arithDecoder->decodeInt(&dt, iaitStats);
2366 huffDecoder->decodeInt(&j, symCodeTab);
2369 symID = huffDecoder->readBits(symCodeLen);
2372 symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
2375 // get the symbol bitmap
2376 symbolBitmap = NULL;
2379 ri = (int)huffDecoder->readBit();
2381 arithDecoder->decodeInt(&ri, iariStats);
2388 huffDecoder->decodeInt(&rdw, huffRDWTable);
2389 huffDecoder->decodeInt(&rdh, huffRDHTable);
2390 huffDecoder->decodeInt(&rdx, huffRDXTable);
2391 huffDecoder->decodeInt(&rdy, huffRDYTable);
2392 huffDecoder->decodeInt(&bmSize, huffRSizeTable);
2393 huffDecoder->reset();
2394 arithDecoder->start();
2396 arithDecoder->decodeInt(&rdw, iardwStats);
2397 arithDecoder->decodeInt(&rdh, iardhStats);
2398 arithDecoder->decodeInt(&rdx, iardxStats);
2399 arithDecoder->decodeInt(&rdy, iardyStats);
2401 refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
2402 refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
2405 readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
2406 rdh + syms[symID]->getHeight(),
2407 templ, gFalse, syms[symID],
2408 refDX, refDY, atx, aty);
2409 //~ do we need to use the bmSize value here (in Huffman mode)?
2411 symbolBitmap = syms[symID];
2414 // combine the symbol bitmap into the region bitmap
2415 //~ something is wrong here - refCorner shouldn't degenerate into
2417 bw = symbolBitmap->getWidth() - 1;
2418 bh = symbolBitmap->getHeight() - 1;
2420 switch (refCorner) {
2421 case 0: // bottom left
2422 bitmap->combine(symbolBitmap, tt, s, combOp);
2425 bitmap->combine(symbolBitmap, tt, s, combOp);
2427 case 2: // bottom right
2428 bitmap->combine(symbolBitmap, tt - bw, s, combOp);
2430 case 3: // top right
2431 bitmap->combine(symbolBitmap, tt - bw, s, combOp);
2436 switch (refCorner) {
2437 case 0: // bottom left
2438 bitmap->combine(symbolBitmap, s, tt - bh, combOp);
2441 bitmap->combine(symbolBitmap, s, tt, combOp);
2443 case 2: // bottom right
2444 bitmap->combine(symbolBitmap, s, tt - bh, combOp);
2446 case 3: // top right
2447 bitmap->combine(symbolBitmap, s, tt, combOp);
2453 delete symbolBitmap;
2461 if (!huffDecoder->decodeInt(&ds, huffDSTable)) {
2465 if (!arithDecoder->decodeInt(&ds, iadsStats)) {
2476 void JBIG2Stream::readPatternDictSeg(Guint segNum, Guint length) {
2477 JBIG2PatternDict *patternDict;
2478 JBIG2Bitmap *bitmap;
2479 Guint flags, patternW, patternH, grayMax, templ, mmr;
2483 // halftone dictionary flags, pattern width and height, max gray value
2484 if (!readUByte(&flags) ||
2485 !readUByte(&patternW) ||
2486 !readUByte(&patternH) ||
2487 !readULong(&grayMax)) {
2490 templ = (flags >> 1) & 3;
2493 // set up the arithmetic decoder
2495 resetGenericStats(templ, NULL);
2496 arithDecoder->start();
2500 atx[0] = -(int)patternW; aty[0] = 0;
2501 atx[1] = -3; aty[1] = -1;
2502 atx[2] = 2; aty[2] = -2;
2503 atx[3] = -2; aty[3] = -2;
2504 bitmap = readGenericBitmap(mmr, (grayMax + 1) * patternW, patternH,
2505 templ, gFalse, gFalse, NULL,
2506 atx, aty, length - 7);
2508 // create the pattern dict object
2509 patternDict = new JBIG2PatternDict(segNum, grayMax + 1);
2511 // split up the bitmap
2513 for (i = 0; i <= grayMax; ++i) {
2514 patternDict->setBitmap(i, bitmap->getSlice(x, 0, patternW, patternH));
2521 // store the new pattern dict
2522 segments->append(patternDict);
2527 error(getPos(), "Unexpected EOF in JBIG2 stream");
2530 void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm,
2531 GBool lossless, Guint length,
2532 Guint *refSegs, Guint nRefSegs) {
2533 JBIG2Bitmap *bitmap;
2535 JBIG2PatternDict *patternDict;
2536 JBIG2Bitmap *skipBitmap;
2538 JBIG2Bitmap *grayBitmap;
2539 JBIG2Bitmap *patternBitmap;
2540 Guint w, h, x, y, segInfoFlags, extCombOp;
2541 Guint flags, mmr, templ, enableSkip, combOp;
2542 Guint gridW, gridH, stepX, stepY, patW, patH;
2544 int gridX, gridY, xx, yy, bit, j;
2547 // region segment info field
2548 if (!readULong(&w) || !readULong(&h) ||
2549 !readULong(&x) || !readULong(&y) ||
2550 !readUByte(&segInfoFlags)) {
2553 extCombOp = segInfoFlags & 7;
2555 // rest of the halftone region header
2556 if (!readUByte(&flags)) {
2560 templ = (flags >> 1) & 3;
2561 enableSkip = (flags >> 3) & 1;
2562 combOp = (flags >> 4) & 7;
2563 if (!readULong(&gridW) || !readULong(&gridH) ||
2564 !readLong(&gridX) || !readLong(&gridY) ||
2565 !readUWord(&stepX) || !readUWord(&stepY)) {
2569 // get pattern dictionary
2570 if (nRefSegs != 1) {
2571 error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
2574 seg = findSegment(refSegs[0]);
2575 if (seg->getType() != jbig2SegPatternDict) {
2576 error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
2579 patternDict = (JBIG2PatternDict *)seg;
2582 while (i < patternDict->getSize()) {
2586 patW = patternDict->getBitmap(0)->getWidth();
2587 patH = patternDict->getBitmap(0)->getHeight();
2589 // set up the arithmetic decoder
2591 resetGenericStats(templ, NULL);
2592 arithDecoder->start();
2595 // allocate the bitmap
2596 bitmap = new JBIG2Bitmap(segNum, w, h);
2597 if (flags & 0x80) { // HDEFPIXEL
2598 bitmap->clearToOne();
2600 bitmap->clearToZero();
2603 // compute the skip bitmap
2606 skipBitmap = new JBIG2Bitmap(0, gridW, gridH);
2607 skipBitmap->clearToZero();
2608 for (m = 0; m < gridH; ++m) {
2609 xx = gridX + m * stepY;
2610 yy = gridY + m * stepX;
2611 for (n = 0; n < gridW; ++n) {
2612 if (((xx + (int)patW) >> 8) <= 0 || (xx >> 8) >= (int)w ||
2613 ((yy + (int)patH) >> 8) <= 0 || (yy >> 8) >= (int)h) {
2614 skipBitmap->setPixel(n, m);
2620 // read the gray-scale image
2621 grayImg = (Guint *)gmalloc(gridW * gridH * sizeof(Guint));
2622 memset(grayImg, 0, gridW * gridH * sizeof(Guint));
2623 atx[0] = templ <= 1 ? 3 : 2; aty[0] = -1;
2624 atx[1] = -3; aty[1] = -1;
2625 atx[2] = 2; aty[2] = -2;
2626 atx[3] = -2; aty[3] = -2;
2627 for (j = bpp - 1; j >= 0; --j) {
2628 grayBitmap = readGenericBitmap(mmr, gridW, gridH, templ, gFalse,
2629 enableSkip, skipBitmap, atx, aty, -1);
2631 for (m = 0; m < gridH; ++m) {
2632 for (n = 0; n < gridW; ++n) {
2633 bit = grayBitmap->getPixel(n, m) ^ (grayImg[i] & 1);
2634 grayImg[i] = (grayImg[i] << 1) | bit;
2643 for (m = 0; m < gridH; ++m) {
2644 xx = gridX + m * stepY;
2645 yy = gridY + m * stepX;
2646 for (n = 0; n < gridW; ++n) {
2647 if (!(enableSkip && skipBitmap->getPixel(n, m))) {
2648 patternBitmap = patternDict->getBitmap(grayImg[i]);
2649 bitmap->combine(patternBitmap, xx >> 8, yy >> 8, combOp);
2659 // combine the region bitmap into the page bitmap
2661 if (pageH == 0xffffffff && y + h > curPageH) {
2662 pageBitmap->expand(y + h, pageDefPixel);
2664 pageBitmap->combine(bitmap, x, y, extCombOp);
2667 // store the region bitmap
2669 segments->append(bitmap);
2675 error(getPos(), "Unexpected EOF in JBIG2 stream");
2678 void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm,
2679 GBool lossless, Guint length) {
2680 JBIG2Bitmap *bitmap;
2681 Guint w, h, x, y, segInfoFlags, extCombOp;
2682 Guint flags, mmr, templ, tpgdOn;
2685 // region segment info field
2686 if (!readULong(&w) || !readULong(&h) ||
2687 !readULong(&x) || !readULong(&y) ||
2688 !readUByte(&segInfoFlags)) {
2691 extCombOp = segInfoFlags & 7;
2693 // rest of the generic region segment header
2694 if (!readUByte(&flags)) {
2698 templ = (flags >> 1) & 3;
2699 tpgdOn = (flags >> 3) & 1;
2704 if (!readByte(&atx[0]) ||
2705 !readByte(&aty[0]) ||
2706 !readByte(&atx[1]) ||
2707 !readByte(&aty[1]) ||
2708 !readByte(&atx[2]) ||
2709 !readByte(&aty[2]) ||
2710 !readByte(&atx[3]) ||
2711 !readByte(&aty[3])) {
2715 if (!readByte(&atx[0]) ||
2716 !readByte(&aty[0])) {
2722 // set up the arithmetic decoder
2724 resetGenericStats(templ, NULL);
2725 arithDecoder->start();
2729 bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse,
2730 NULL, atx, aty, mmr ? 0 : length - 18);
2732 // combine the region bitmap into the page bitmap
2734 if (pageH == 0xffffffff && y + h > curPageH) {
2735 pageBitmap->expand(y + h, pageDefPixel);
2737 pageBitmap->combine(bitmap, x, y, extCombOp);
2740 // store the region bitmap
2742 bitmap->setSegNum(segNum);
2743 segments->append(bitmap);
2749 error(getPos(), "Unexpected EOF in JBIG2 stream");
2752 JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
2753 int templ, GBool tpgdOn,
2754 GBool useSkip, JBIG2Bitmap *skip,
2756 int mmrDataLength) {
2757 JBIG2Bitmap *bitmap;
2759 Guint ltpCX, cx, cx0, cx1, cx2;
2760 JBIG2BitmapPtr cxPtr0, cxPtr1;
2761 JBIG2BitmapPtr atPtr0, atPtr1, atPtr2, atPtr3;
2762 int *refLine, *codingLine;
2763 int code1, code2, code3;
2764 int x, y, a0, pix, i, refI, codingI;
2766 bitmap = new JBIG2Bitmap(0, w, h);
2767 bitmap->clearToZero();
2773 mmrDecoder->reset();
2774 refLine = (int *)gmalloc((w + 2) * sizeof(int));
2775 codingLine = (int *)gmalloc((w + 2) * sizeof(int));
2776 codingLine[0] = codingLine[1] = w;
2778 for (y = 0; y < h; ++y) {
2780 // copy coding line to ref line
2781 for (i = 0; codingLine[i] < w; ++i) {
2782 refLine[i] = codingLine[i];
2784 refLine[i] = refLine[i + 1] = w;
2787 refI = 0; // b1 = refLine[refI]
2788 codingI = 0; // a1 = codingLine[codingI]
2791 code1 = mmrDecoder->get2DCode();
2794 if (refLine[refI] < w) {
2795 a0 = refLine[refI + 1];
2803 code1 += code3 = mmrDecoder->getBlackCode();
2804 } while (code3 >= 64);
2807 code2 += code3 = mmrDecoder->getWhiteCode();
2808 } while (code3 >= 64);
2812 code1 += code3 = mmrDecoder->getWhiteCode();
2813 } while (code3 >= 64);
2816 code2 += code3 = mmrDecoder->getBlackCode();
2817 } while (code3 >= 64);
2819 if (code1 > 0 || code2 > 0) {
2820 a0 = codingLine[codingI++] = a0 + code1;
2821 a0 = codingLine[codingI++] = a0 + code2;
2822 while (refLine[refI] <= a0 && refLine[refI] < w) {
2828 a0 = codingLine[codingI++] = refLine[refI];
2829 if (refLine[refI] < w) {
2834 a0 = codingLine[codingI++] = refLine[refI] + 1;
2835 if (refLine[refI] < w) {
2837 while (refLine[refI] <= a0 && refLine[refI] < w) {
2843 a0 = codingLine[codingI++] = refLine[refI] + 2;
2844 if (refLine[refI] < w) {
2846 while (refLine[refI] <= a0 && refLine[refI] < w) {
2852 a0 = codingLine[codingI++] = refLine[refI] + 3;
2853 if (refLine[refI] < w) {
2855 while (refLine[refI] <= a0 && refLine[refI] < w) {
2861 a0 = codingLine[codingI++] = refLine[refI] - 1;
2867 while (refLine[refI] <= a0 && refLine[refI] < w) {
2872 a0 = codingLine[codingI++] = refLine[refI] - 2;
2878 while (refLine[refI] <= a0 && refLine[refI] < w) {
2883 a0 = codingLine[codingI++] = refLine[refI] - 3;
2889 while (refLine[refI] <= a0 && refLine[refI] < w) {
2894 error(getPos(), "Illegal code in JBIG2 MMR bitmap data");
2898 codingLine[codingI++] = w;
2900 // convert the run lengths to a bitmap line
2902 while (codingLine[i] < w) {
2903 for (x = codingLine[i]; x < codingLine[i+1]; ++x) {
2904 bitmap->setPixel(x, y);
2910 if (mmrDataLength >= 0) {
2911 mmrDecoder->skipTo(mmrDataLength);
2913 if (mmrDecoder->get24Bits() != 0x001001) {
2914 error(getPos(), "Missing EOFB in JBIG2 MMR bitmap data");
2921 //----- arithmetic decode
2924 // set up the typical row context
2925 ltpCX = 0; // make gcc happy
2929 ltpCX = 0x3953; // 001 11001 0101 0011
2932 ltpCX = 0x079a; // 0011 11001 101 0
2935 ltpCX = 0x0e3; // 001 1100 01 1
2938 ltpCX = 0x18a; // 01100 0101 1
2944 cx = cx0 = cx1 = cx2 = 0; // make gcc happy
2945 for (y = 0; y < h; ++y) {
2947 // check for a "typical" (duplicate) row
2949 if (arithDecoder->decodeBit(ltpCX, genericRegionStats)) {
2953 bitmap->duplicateRow(y, y-1);
2961 // set up the context
2962 bitmap->getPixelPtr(0, y-2, &cxPtr0);
2963 cx0 = bitmap->nextPixel(&cxPtr0);
2964 cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
2965 bitmap->getPixelPtr(0, y-1, &cxPtr1);
2966 cx1 = bitmap->nextPixel(&cxPtr1);
2967 cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
2968 cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
2970 bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
2971 bitmap->getPixelPtr(atx[1], y + aty[1], &atPtr1);
2972 bitmap->getPixelPtr(atx[2], y + aty[2], &atPtr2);
2973 bitmap->getPixelPtr(atx[3], y + aty[3], &atPtr3);
2976 for (x = 0; x < w; ++x) {
2978 // build the context
2979 cx = (cx0 << 13) | (cx1 << 8) | (cx2 << 4) |
2980 (bitmap->nextPixel(&atPtr0) << 3) |
2981 (bitmap->nextPixel(&atPtr1) << 2) |
2982 (bitmap->nextPixel(&atPtr2) << 1) |
2983 bitmap->nextPixel(&atPtr3);
2985 // check for a skipped pixel
2986 if (useSkip && skip->getPixel(x, y)) {
2990 } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
2991 bitmap->setPixel(x, y);
2994 // update the context
2995 cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07;
2996 cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
2997 cx2 = ((cx2 << 1) | pix) & 0x0f;
3003 // set up the context
3004 bitmap->getPixelPtr(0, y-2, &cxPtr0);
3005 cx0 = bitmap->nextPixel(&cxPtr0);
3006 cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
3007 cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
3008 bitmap->getPixelPtr(0, y-1, &cxPtr1);
3009 cx1 = bitmap->nextPixel(&cxPtr1);
3010 cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
3011 cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
3013 bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
3016 for (x = 0; x < w; ++x) {
3018 // build the context
3019 cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
3020 bitmap->nextPixel(&atPtr0);
3022 // check for a skipped pixel
3023 if (useSkip && skip->getPixel(x, y)) {
3027 } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3028 bitmap->setPixel(x, y);
3031 // update the context
3032 cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x0f;
3033 cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
3034 cx2 = ((cx2 << 1) | pix) & 0x07;
3040 // set up the context
3041 bitmap->getPixelPtr(0, y-2, &cxPtr0);
3042 cx0 = bitmap->nextPixel(&cxPtr0);
3043 cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
3044 bitmap->getPixelPtr(0, y-1, &cxPtr1);
3045 cx1 = bitmap->nextPixel(&cxPtr1);
3046 cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
3048 bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
3051 for (x = 0; x < w; ++x) {
3053 // build the context
3054 cx = (cx0 << 7) | (cx1 << 3) | (cx2 << 1) |
3055 bitmap->nextPixel(&atPtr0);
3057 // check for a skipped pixel
3058 if (useSkip && skip->getPixel(x, y)) {
3062 } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3063 bitmap->setPixel(x, y);
3066 // update the context
3067 cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07;
3068 cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x0f;
3069 cx2 = ((cx2 << 1) | pix) & 0x03;
3075 // set up the context
3076 bitmap->getPixelPtr(0, y-1, &cxPtr1);
3077 cx1 = bitmap->nextPixel(&cxPtr1);
3078 cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
3080 bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
3083 for (x = 0; x < w; ++x) {
3085 // build the context
3086 cx = (cx1 << 5) | (cx2 << 1) |
3087 bitmap->nextPixel(&atPtr0);
3089 // check for a skipped pixel
3090 if (useSkip && skip->getPixel(x, y)) {
3094 } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3095 bitmap->setPixel(x, y);
3098 // update the context
3099 cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
3100 cx2 = ((cx2 << 1) | pix) & 0x0f;
3110 void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum, GBool imm,
3111 GBool lossless, Guint length,
3114 JBIG2Bitmap *bitmap, *refBitmap;
3115 Guint w, h, x, y, segInfoFlags, extCombOp;
3116 Guint flags, templ, tpgrOn;
3120 // region segment info field
3121 if (!readULong(&w) || !readULong(&h) ||
3122 !readULong(&x) || !readULong(&y) ||
3123 !readUByte(&segInfoFlags)) {
3126 extCombOp = segInfoFlags & 7;
3128 // rest of the generic refinement region segment header
3129 if (!readUByte(&flags)) {
3133 tpgrOn = (flags >> 1) & 1;
3137 if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
3138 !readByte(&atx[1]) || !readByte(&aty[1])) {
3143 // resize the page bitmap if needed
3144 if (nRefSegs == 0 || imm) {
3145 if (pageH == 0xffffffff && y + h > curPageH) {
3146 pageBitmap->expand(y + h, pageDefPixel);
3150 // get referenced bitmap
3152 error(getPos(), "Bad reference in JBIG2 generic refinement segment");
3155 if (nRefSegs == 1) {
3156 seg = findSegment(refSegs[0]);
3157 if (seg->getType() != jbig2SegBitmap) {
3158 error(getPos(), "Bad bitmap reference in JBIG2 generic refinement segment");
3161 refBitmap = (JBIG2Bitmap *)seg;
3163 refBitmap = pageBitmap->getSlice(x, y, w, h);
3166 // set up the arithmetic decoder
3167 resetRefinementStats(templ, NULL);
3168 arithDecoder->start();
3171 bitmap = readGenericRefinementRegion(w, h, templ, tpgrOn,
3172 refBitmap, 0, 0, atx, aty);
3174 // combine the region bitmap into the page bitmap
3176 pageBitmap->combine(bitmap, x, y, extCombOp);
3179 // store the region bitmap
3181 bitmap->setSegNum(segNum);
3182 segments->append(bitmap);
3185 // delete the referenced bitmap
3186 if (nRefSegs == 1) {
3187 discardSegment(refSegs[0]);
3195 error(getPos(), "Unexpected EOF in JBIG2 stream");
3198 JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion(int w, int h,
3199 int templ, GBool tpgrOn,
3200 JBIG2Bitmap *refBitmap,
3201 int refDX, int refDY,
3202 int *atx, int *aty) {
3203 JBIG2Bitmap *bitmap;
3205 Guint ltpCX, cx, cx0, cx2, cx3, cx4, tpgrCX0, tpgrCX1, tpgrCX2;
3206 JBIG2BitmapPtr cxPtr0, cxPtr1, cxPtr2, cxPtr3, cxPtr4, cxPtr5, cxPtr6;
3207 JBIG2BitmapPtr tpgrCXPtr0, tpgrCXPtr1, tpgrCXPtr2;
3210 bitmap = new JBIG2Bitmap(0, w, h);
3211 bitmap->clearToZero();
3213 // set up the typical row context
3221 for (y = 0; y < h; ++y) {
3225 // set up the context
3226 bitmap->getPixelPtr(0, y-1, &cxPtr0);
3227 cx0 = bitmap->nextPixel(&cxPtr0);
3228 bitmap->getPixelPtr(-1, y, &cxPtr1);
3229 refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2);
3230 refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3);
3231 cx3 = refBitmap->nextPixel(&cxPtr3);
3232 cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3);
3233 refBitmap->getPixelPtr(-refDX, y+1-refDY, &cxPtr4);
3234 cx4 = refBitmap->nextPixel(&cxPtr4);
3236 // set up the typical prediction context
3237 tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy
3239 refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0);
3240 tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0);
3241 tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3242 tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3243 refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1);
3244 tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1);
3245 tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3246 tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3247 refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2);
3248 tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
3249 tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3250 tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3253 for (x = 0; x < w; ++x) {
3255 // update the context
3256 cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 7;
3257 cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7;
3258 cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 3;
3261 // update the typical predictor context
3262 tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7;
3263 tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7;
3264 tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7;
3266 // check for a "typical" pixel
3267 if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
3270 if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
3271 bitmap->clearPixel(x, y);
3273 } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
3274 bitmap->setPixel(x, y);
3279 // build the context
3280 cx = (cx0 << 7) | (bitmap->nextPixel(&cxPtr1) << 6) |
3281 (refBitmap->nextPixel(&cxPtr2) << 5) |
3285 if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
3286 bitmap->setPixel(x, y);
3292 // set up the context
3293 bitmap->getPixelPtr(0, y-1, &cxPtr0);
3294 cx0 = bitmap->nextPixel(&cxPtr0);
3295 bitmap->getPixelPtr(-1, y, &cxPtr1);
3296 refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2);
3297 cx2 = refBitmap->nextPixel(&cxPtr2);
3298 refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3);
3299 cx3 = refBitmap->nextPixel(&cxPtr3);
3300 cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3);
3301 refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &cxPtr4);
3302 cx4 = refBitmap->nextPixel(&cxPtr4);
3303 cx4 = (cx4 << 1) | refBitmap->nextPixel(&cxPtr4);
3304 bitmap->getPixelPtr(atx[0], y+aty[0], &cxPtr5);
3305 refBitmap->getPixelPtr(atx[1]-refDX, y+aty[1]-refDY, &cxPtr6);
3307 // set up the typical prediction context
3308 tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy
3310 refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0);
3311 tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0);
3312 tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3313 tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3314 refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1);
3315 tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1);
3316 tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3317 tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3318 refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2);
3319 tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
3320 tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3321 tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3324 for (x = 0; x < w; ++x) {
3326 // update the context
3327 cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 3;
3328 cx2 = ((cx2 << 1) | refBitmap->nextPixel(&cxPtr2)) & 3;
3329 cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7;
3330 cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 7;
3333 // update the typical predictor context
3334 tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7;
3335 tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7;
3336 tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7;
3338 // check for a "typical" pixel
3339 if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
3342 if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
3343 bitmap->clearPixel(x, y);
3345 } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
3346 bitmap->setPixel(x, y);
3351 // build the context
3352 cx = (cx0 << 11) | (bitmap->nextPixel(&cxPtr1) << 10) |
3353 (cx2 << 8) | (cx3 << 5) | (cx4 << 2) |
3354 (bitmap->nextPixel(&cxPtr5) << 1) |
3355 refBitmap->nextPixel(&cxPtr6);
3358 if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
3359 bitmap->setPixel(x, y);
3368 void JBIG2Stream::readPageInfoSeg(Guint length) {
3369 Guint xRes, yRes, flags, striping;
3371 if (!readULong(&pageW) || !readULong(&pageH) ||
3372 !readULong(&xRes) || !readULong(&yRes) ||
3373 !readUByte(&flags) || !readUWord(&striping)) {
3376 pageDefPixel = (flags >> 2) & 1;
3377 defCombOp = (flags >> 3) & 3;
3379 // allocate the page bitmap
3380 if (pageH == 0xffffffff) {
3381 curPageH = striping & 0x7fff;
3385 pageBitmap = new JBIG2Bitmap(0, pageW, curPageH);
3387 // default pixel value
3389 pageBitmap->clearToOne();
3391 pageBitmap->clearToZero();
3397 error(getPos(), "Unexpected EOF in JBIG2 stream");
3400 void JBIG2Stream::readEndOfStripeSeg(Guint length) {
3404 for (i = 0; i < length; ++i) {
3409 void JBIG2Stream::readProfilesSeg(Guint length) {
3413 for (i = 0; i < length; ++i) {
3418 void JBIG2Stream::readCodeTableSeg(Guint segNum, Guint length) {
3419 JBIG2HuffmanTable *huffTab;
3420 Guint flags, oob, prefixBits, rangeBits;
3421 int lowVal, highVal, val;
3422 Guint huffTabSize, i;
3424 if (!readUByte(&flags) || !readLong(&lowVal) || !readLong(&highVal)) {
3428 prefixBits = ((flags >> 1) & 7) + 1;
3429 rangeBits = ((flags >> 4) & 7) + 1;
3431 huffDecoder->reset();
3433 huffTab = (JBIG2HuffmanTable *)
3434 gmalloc(huffTabSize * sizeof(JBIG2HuffmanTable));
3437 while (val < highVal) {
3438 if (i == huffTabSize) {
3440 huffTab = (JBIG2HuffmanTable *)
3441 grealloc(huffTab, huffTabSize * sizeof(JBIG2HuffmanTable));
3443 huffTab[i].val = val;
3444 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3445 huffTab[i].rangeLen = huffDecoder->readBits(rangeBits);
3446 val += 1 << huffTab[i].rangeLen;
3449 if (i + oob + 3 > huffTabSize) {
3450 huffTabSize = i + oob + 3;
3451 huffTab = (JBIG2HuffmanTable *)
3452 grealloc(huffTab, huffTabSize * sizeof(JBIG2HuffmanTable));
3454 huffTab[i].val = lowVal - 1;
3455 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3456 huffTab[i].rangeLen = jbig2HuffmanLOW;
3458 huffTab[i].val = highVal;
3459 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3460 huffTab[i].rangeLen = 32;
3464 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3465 huffTab[i].rangeLen = jbig2HuffmanOOB;
3469 huffTab[i].prefixLen = 0;
3470 huffTab[i].rangeLen = jbig2HuffmanEOT;
3471 huffDecoder->buildTable(huffTab, i);
3473 // create and store the new table segment
3474 segments->append(new JBIG2CodeTable(segNum, huffTab));
3479 error(getPos(), "Unexpected EOF in JBIG2 stream");
3482 void JBIG2Stream::readExtensionSeg(Guint length) {
3486 for (i = 0; i < length; ++i) {
3491 JBIG2Segment *JBIG2Stream::findSegment(Guint segNum) {
3495 for (i = 0; i < globalSegments->getLength(); ++i) {
3496 seg = (JBIG2Segment *)globalSegments->get(i);
3497 if (seg->getSegNum() == segNum) {
3501 for (i = 0; i < segments->getLength(); ++i) {
3502 seg = (JBIG2Segment *)segments->get(i);
3503 if (seg->getSegNum() == segNum) {
3510 void JBIG2Stream::discardSegment(Guint segNum) {
3514 for (i = 0; i < globalSegments->getLength(); ++i) {
3515 seg = (JBIG2Segment *)globalSegments->get(i);
3516 if (seg->getSegNum() == segNum) {
3517 globalSegments->del(i);
3521 for (i = 0; i < segments->getLength(); ++i) {
3522 seg = (JBIG2Segment *)segments->get(i);
3523 if (seg->getSegNum() == segNum) {
3530 void JBIG2Stream::resetGenericStats(Guint templ,
3531 JBIG2ArithmeticDecoderStats *prevStats) {
3534 size = contextSize[templ];
3535 if (prevStats && prevStats->getContextSize() == size) {
3536 if (genericRegionStats->getContextSize() == size) {
3537 genericRegionStats->copyFrom(prevStats);
3539 delete genericRegionStats;
3540 genericRegionStats = prevStats->copy();
3543 if (genericRegionStats->getContextSize() == size) {
3544 genericRegionStats->reset();
3546 delete genericRegionStats;
3547 genericRegionStats = new JBIG2ArithmeticDecoderStats(size);
3552 void JBIG2Stream::resetRefinementStats(
3554 JBIG2ArithmeticDecoderStats *prevStats) {
3557 size = refContextSize[templ];
3558 if (prevStats && prevStats->getContextSize() == size) {
3559 if (refinementRegionStats->getContextSize() == size) {
3560 refinementRegionStats->copyFrom(prevStats);
3562 delete refinementRegionStats;
3563 refinementRegionStats = prevStats->copy();
3566 if (refinementRegionStats->getContextSize() == size) {
3567 refinementRegionStats->reset();
3569 delete refinementRegionStats;
3570 refinementRegionStats = new JBIG2ArithmeticDecoderStats(size);
3575 void JBIG2Stream::resetIntStats(int symCodeLen) {
3584 iardxStats->reset();
3585 iardyStats->reset();
3586 iardwStats->reset();
3587 iardhStats->reset();
3589 if (iaidStats->getContextSize() == symCodeLen + 1) {
3593 iaidStats = new JBIG2ArithmeticDecoderStats(symCodeLen + 1);
3597 GBool JBIG2Stream::readUByte(Guint *x) {
3600 if ((c0 = curStr->getChar()) == EOF) {
3607 GBool JBIG2Stream::readByte(int *x) {
3610 if ((c0 = curStr->getChar()) == EOF) {
3620 GBool JBIG2Stream::readUWord(Guint *x) {
3623 if ((c0 = curStr->getChar()) == EOF ||
3624 (c1 = curStr->getChar()) == EOF) {
3627 *x = (Guint)((c0 << 8) | c1);
3631 GBool JBIG2Stream::readULong(Guint *x) {
3634 if ((c0 = curStr->getChar()) == EOF ||
3635 (c1 = curStr->getChar()) == EOF ||
3636 (c2 = curStr->getChar()) == EOF ||
3637 (c3 = curStr->getChar()) == EOF) {
3640 *x = (Guint)((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
3644 GBool JBIG2Stream::readLong(int *x) {
3647 if ((c0 = curStr->getChar()) == EOF ||
3648 (c1 = curStr->getChar()) == EOF ||
3649 (c2 = curStr->getChar()) == EOF ||
3650 (c3 = curStr->getChar()) == EOF) {
3653 *x = ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
3655 *x |= -1 - (int)0xffffffff;