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] = -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 a0 = codingLine[codingI++] = a0 + code1;
2820 a0 = codingLine[codingI++] = a0 + code2;
2821 while (refLine[refI] <= a0 && refLine[refI] < w) {
2826 a0 = codingLine[codingI++] = refLine[refI];
2827 if (refLine[refI] < w) {
2832 a0 = codingLine[codingI++] = refLine[refI] + 1;
2833 if (refLine[refI] < w) {
2835 while (refLine[refI] <= a0 && refLine[refI] < w) {
2841 a0 = codingLine[codingI++] = refLine[refI] + 2;
2842 if (refLine[refI] < w) {
2844 while (refLine[refI] <= a0 && refLine[refI] < w) {
2850 a0 = codingLine[codingI++] = refLine[refI] + 3;
2851 if (refLine[refI] < w) {
2853 while (refLine[refI] <= a0 && refLine[refI] < w) {
2859 a0 = codingLine[codingI++] = refLine[refI] - 1;
2865 while (refLine[refI] <= a0 && refLine[refI] < w) {
2870 a0 = codingLine[codingI++] = refLine[refI] - 2;
2876 while (refLine[refI] <= a0 && refLine[refI] < w) {
2881 a0 = codingLine[codingI++] = refLine[refI] - 3;
2887 while (refLine[refI] <= a0 && refLine[refI] < w) {
2892 error(getPos(), "Illegal code in JBIG2 MMR bitmap data");
2896 codingLine[codingI++] = w;
2898 // convert the run lengths to a bitmap line
2900 while (codingLine[i] < w) {
2901 for (x = codingLine[i]; x < codingLine[i+1]; ++x) {
2902 bitmap->setPixel(x, y);
2908 if (mmrDataLength >= 0) {
2909 mmrDecoder->skipTo(mmrDataLength);
2911 if (mmrDecoder->get24Bits() != 0x001001) {
2912 error(getPos(), "Missing EOFB in JBIG2 MMR bitmap data");
2919 //----- arithmetic decode
2922 // set up the typical row context
2923 ltpCX = 0; // make gcc happy
2927 ltpCX = 0x3953; // 001 11001 0101 0011
2930 ltpCX = 0x079a; // 0011 11001 101 0
2933 ltpCX = 0x0e3; // 001 1100 01 1
2936 ltpCX = 0x18a; // 01100 0101 1
2942 cx = cx0 = cx1 = cx2 = 0; // make gcc happy
2943 for (y = 0; y < h; ++y) {
2945 // check for a "typical" (duplicate) row
2947 if (arithDecoder->decodeBit(ltpCX, genericRegionStats)) {
2951 bitmap->duplicateRow(y, y-1);
2959 // set up the context
2960 bitmap->getPixelPtr(0, y-2, &cxPtr0);
2961 cx0 = bitmap->nextPixel(&cxPtr0);
2962 cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
2963 bitmap->getPixelPtr(0, y-1, &cxPtr1);
2964 cx1 = bitmap->nextPixel(&cxPtr1);
2965 cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
2966 cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
2968 bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
2969 bitmap->getPixelPtr(atx[1], y + aty[1], &atPtr1);
2970 bitmap->getPixelPtr(atx[2], y + aty[2], &atPtr2);
2971 bitmap->getPixelPtr(atx[3], y + aty[3], &atPtr3);
2974 for (x = 0; x < w; ++x) {
2976 // build the context
2977 cx = (cx0 << 13) | (cx1 << 8) | (cx2 << 4) |
2978 (bitmap->nextPixel(&atPtr0) << 3) |
2979 (bitmap->nextPixel(&atPtr1) << 2) |
2980 (bitmap->nextPixel(&atPtr2) << 1) |
2981 bitmap->nextPixel(&atPtr3);
2983 // check for a skipped pixel
2984 if (useSkip && skip->getPixel(x, y)) {
2988 } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
2989 bitmap->setPixel(x, y);
2992 // update the context
2993 cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07;
2994 cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
2995 cx2 = ((cx2 << 1) | pix) & 0x0f;
3001 // set up the context
3002 bitmap->getPixelPtr(0, y-2, &cxPtr0);
3003 cx0 = bitmap->nextPixel(&cxPtr0);
3004 cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
3005 cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
3006 bitmap->getPixelPtr(0, y-1, &cxPtr1);
3007 cx1 = bitmap->nextPixel(&cxPtr1);
3008 cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
3009 cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
3011 bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
3014 for (x = 0; x < w; ++x) {
3016 // build the context
3017 cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
3018 bitmap->nextPixel(&atPtr0);
3020 // check for a skipped pixel
3021 if (useSkip && skip->getPixel(x, y)) {
3025 } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3026 bitmap->setPixel(x, y);
3029 // update the context
3030 cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07;
3031 cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
3032 cx2 = ((cx2 << 1) | pix) & 0x0f;
3038 // set up the context
3039 bitmap->getPixelPtr(0, y-2, &cxPtr0);
3040 cx0 = bitmap->nextPixel(&cxPtr0);
3041 cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
3042 bitmap->getPixelPtr(0, y-1, &cxPtr1);
3043 cx1 = bitmap->nextPixel(&cxPtr1);
3044 cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
3046 bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
3049 for (x = 0; x < w; ++x) {
3051 // build the context
3052 cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
3053 bitmap->nextPixel(&atPtr0);
3055 // check for a skipped pixel
3056 if (useSkip && skip->getPixel(x, y)) {
3060 } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3061 bitmap->setPixel(x, y);
3064 // update the context
3065 cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x0f;
3066 cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
3067 cx2 = ((cx2 << 1) | pix) & 0x07;
3073 // set up the context
3074 bitmap->getPixelPtr(0, y-1, &cxPtr1);
3075 cx1 = bitmap->nextPixel(&cxPtr1);
3076 cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
3078 bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
3081 for (x = 0; x < w; ++x) {
3083 // build the context
3084 cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
3085 bitmap->nextPixel(&atPtr0);
3087 // check for a skipped pixel
3088 if (useSkip && skip->getPixel(x, y)) {
3092 } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3093 bitmap->setPixel(x, y);
3096 // update the context
3097 cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
3098 cx2 = ((cx2 << 1) | pix) & 0x0f;
3108 void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum, GBool imm,
3109 GBool lossless, Guint length,
3112 JBIG2Bitmap *bitmap, *refBitmap;
3113 Guint w, h, x, y, segInfoFlags, extCombOp;
3114 Guint flags, templ, tpgrOn;
3118 // region segment info field
3119 if (!readULong(&w) || !readULong(&h) ||
3120 !readULong(&x) || !readULong(&y) ||
3121 !readUByte(&segInfoFlags)) {
3124 extCombOp = segInfoFlags & 7;
3126 // rest of the generic refinement region segment header
3127 if (!readUByte(&flags)) {
3131 tpgrOn = (flags >> 1) & 1;
3135 if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
3136 !readByte(&atx[1]) || !readByte(&aty[1])) {
3141 // resize the page bitmap if needed
3142 if (nRefSegs == 0 || imm) {
3143 if (pageH == 0xffffffff && y + h > curPageH) {
3144 pageBitmap->expand(y + h, pageDefPixel);
3148 // get referenced bitmap
3150 error(getPos(), "Bad reference in JBIG2 generic refinement segment");
3153 if (nRefSegs == 1) {
3154 seg = findSegment(refSegs[0]);
3155 if (seg->getType() != jbig2SegBitmap) {
3156 error(getPos(), "Bad bitmap reference in JBIG2 generic refinement segment");
3159 refBitmap = (JBIG2Bitmap *)seg;
3161 refBitmap = pageBitmap->getSlice(x, y, w, h);
3164 // set up the arithmetic decoder
3165 resetRefinementStats(templ, NULL);
3166 arithDecoder->start();
3169 bitmap = readGenericRefinementRegion(w, h, templ, tpgrOn,
3170 refBitmap, 0, 0, atx, aty);
3172 // combine the region bitmap into the page bitmap
3174 pageBitmap->combine(bitmap, x, y, extCombOp);
3177 // store the region bitmap
3179 bitmap->setSegNum(segNum);
3180 segments->append(bitmap);
3183 // delete the referenced bitmap
3184 if (nRefSegs == 1) {
3185 discardSegment(refSegs[0]);
3193 error(getPos(), "Unexpected EOF in JBIG2 stream");
3196 JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion(int w, int h,
3197 int templ, GBool tpgrOn,
3198 JBIG2Bitmap *refBitmap,
3199 int refDX, int refDY,
3200 int *atx, int *aty) {
3201 JBIG2Bitmap *bitmap;
3203 Guint ltpCX, cx, cx0, cx2, cx3, cx4, tpgrCX0, tpgrCX1, tpgrCX2;
3204 JBIG2BitmapPtr cxPtr0, cxPtr1, cxPtr2, cxPtr3, cxPtr4, cxPtr5, cxPtr6;
3205 JBIG2BitmapPtr tpgrCXPtr0, tpgrCXPtr1, tpgrCXPtr2;
3208 bitmap = new JBIG2Bitmap(0, w, h);
3209 bitmap->clearToZero();
3211 // set up the typical row context
3219 for (y = 0; y < h; ++y) {
3223 // set up the context
3224 bitmap->getPixelPtr(0, y-1, &cxPtr0);
3225 cx0 = bitmap->nextPixel(&cxPtr0);
3226 bitmap->getPixelPtr(-1, y, &cxPtr1);
3227 refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2);
3228 refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3);
3229 cx3 = refBitmap->nextPixel(&cxPtr3);
3230 cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3);
3231 refBitmap->getPixelPtr(-refDX, y+1-refDY, &cxPtr4);
3232 cx4 = refBitmap->nextPixel(&cxPtr4);
3234 // set up the typical prediction context
3235 tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy
3237 refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0);
3238 tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0);
3239 tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3240 tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3241 refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1);
3242 tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1);
3243 tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3244 tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3245 refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2);
3246 tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
3247 tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3248 tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3251 for (x = 0; x < w; ++x) {
3253 // update the context
3254 cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 7;
3255 cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7;
3256 cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 3;
3259 // update the typical predictor context
3260 tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7;
3261 tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7;
3262 tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7;
3264 // check for a "typical" pixel
3265 if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
3268 if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
3269 bitmap->clearPixel(x, y);
3271 } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
3272 bitmap->setPixel(x, y);
3277 // build the context
3278 cx = (cx0 << 7) | (bitmap->nextPixel(&cxPtr1) << 6) |
3279 (refBitmap->nextPixel(&cxPtr2) << 5) |
3283 if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
3284 bitmap->setPixel(x, y);
3290 // set up the context
3291 bitmap->getPixelPtr(0, y-1, &cxPtr0);
3292 cx0 = bitmap->nextPixel(&cxPtr0);
3293 bitmap->getPixelPtr(-1, y, &cxPtr1);
3294 refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2);
3295 cx2 = refBitmap->nextPixel(&cxPtr2);
3296 refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3);
3297 cx3 = refBitmap->nextPixel(&cxPtr3);
3298 cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3);
3299 refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &cxPtr4);
3300 cx4 = refBitmap->nextPixel(&cxPtr4);
3301 cx4 = (cx4 << 1) | refBitmap->nextPixel(&cxPtr4);
3302 bitmap->getPixelPtr(atx[0], y+aty[0], &cxPtr5);
3303 refBitmap->getPixelPtr(atx[1]-refDX, y+aty[1]-refDY, &cxPtr6);
3305 // set up the typical prediction context
3306 tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy
3308 refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0);
3309 tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0);
3310 tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3311 tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3312 refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1);
3313 tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1);
3314 tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3315 tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3316 refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2);
3317 tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
3318 tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3319 tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3322 for (x = 0; x < w; ++x) {
3324 // update the context
3325 cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 3;
3326 cx2 = ((cx2 << 1) | refBitmap->nextPixel(&cxPtr2)) & 3;
3327 cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7;
3328 cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 7;
3331 // update the typical predictor context
3332 tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7;
3333 tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7;
3334 tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7;
3336 // check for a "typical" pixel
3337 if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
3340 if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
3341 bitmap->clearPixel(x, y);
3343 } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
3344 bitmap->setPixel(x, y);
3349 // build the context
3350 cx = (cx0 << 11) | (bitmap->nextPixel(&cxPtr1) << 10) |
3351 (cx2 << 8) | (cx3 << 5) | (cx4 << 2) |
3352 (bitmap->nextPixel(&cxPtr5) << 1) |
3353 refBitmap->nextPixel(&cxPtr6);
3356 if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
3357 bitmap->setPixel(x, y);
3366 void JBIG2Stream::readPageInfoSeg(Guint length) {
3367 Guint xRes, yRes, flags, striping;
3369 if (!readULong(&pageW) || !readULong(&pageH) ||
3370 !readULong(&xRes) || !readULong(&yRes) ||
3371 !readUByte(&flags) || !readUWord(&striping)) {
3374 pageDefPixel = (flags >> 2) & 1;
3375 defCombOp = (flags >> 3) & 3;
3377 // allocate the page bitmap
3378 if (pageH == 0xffffffff) {
3379 curPageH = striping & 0x7fff;
3383 pageBitmap = new JBIG2Bitmap(0, pageW, curPageH);
3385 // default pixel value
3387 pageBitmap->clearToOne();
3389 pageBitmap->clearToZero();
3395 error(getPos(), "Unexpected EOF in JBIG2 stream");
3398 void JBIG2Stream::readEndOfStripeSeg(Guint length) {
3402 for (i = 0; i < length; ++i) {
3407 void JBIG2Stream::readProfilesSeg(Guint length) {
3411 for (i = 0; i < length; ++i) {
3416 void JBIG2Stream::readCodeTableSeg(Guint segNum, Guint length) {
3417 JBIG2HuffmanTable *huffTab;
3418 Guint flags, oob, prefixBits, rangeBits;
3419 int lowVal, highVal, val;
3420 Guint huffTabSize, i;
3422 if (!readUByte(&flags) || !readLong(&lowVal) || !readLong(&highVal)) {
3426 prefixBits = ((flags >> 1) & 7) + 1;
3427 rangeBits = ((flags >> 4) & 7) + 1;
3429 huffDecoder->reset();
3431 huffTab = (JBIG2HuffmanTable *)
3432 gmalloc(huffTabSize * sizeof(JBIG2HuffmanTable));
3435 while (val < highVal) {
3436 if (i == huffTabSize) {
3438 huffTab = (JBIG2HuffmanTable *)
3439 grealloc(huffTab, huffTabSize * sizeof(JBIG2HuffmanTable));
3441 huffTab[i].val = val;
3442 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3443 huffTab[i].rangeLen = huffDecoder->readBits(rangeBits);
3444 val += 1 << huffTab[i].rangeLen;
3447 if (i + oob + 3 > huffTabSize) {
3448 huffTabSize = i + oob + 3;
3449 huffTab = (JBIG2HuffmanTable *)
3450 grealloc(huffTab, huffTabSize * sizeof(JBIG2HuffmanTable));
3452 huffTab[i].val = lowVal - 1;
3453 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3454 huffTab[i].rangeLen = jbig2HuffmanLOW;
3456 huffTab[i].val = highVal;
3457 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3458 huffTab[i].rangeLen = 32;
3462 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3463 huffTab[i].rangeLen = jbig2HuffmanOOB;
3467 huffTab[i].prefixLen = 0;
3468 huffTab[i].rangeLen = jbig2HuffmanEOT;
3469 huffDecoder->buildTable(huffTab, i);
3471 // create and store the new table segment
3472 segments->append(new JBIG2CodeTable(segNum, huffTab));
3477 error(getPos(), "Unexpected EOF in JBIG2 stream");
3480 void JBIG2Stream::readExtensionSeg(Guint length) {
3484 for (i = 0; i < length; ++i) {
3489 JBIG2Segment *JBIG2Stream::findSegment(Guint segNum) {
3493 for (i = 0; i < globalSegments->getLength(); ++i) {
3494 seg = (JBIG2Segment *)globalSegments->get(i);
3495 if (seg->getSegNum() == segNum) {
3499 for (i = 0; i < segments->getLength(); ++i) {
3500 seg = (JBIG2Segment *)segments->get(i);
3501 if (seg->getSegNum() == segNum) {
3508 void JBIG2Stream::discardSegment(Guint segNum) {
3512 for (i = 0; i < globalSegments->getLength(); ++i) {
3513 seg = (JBIG2Segment *)globalSegments->get(i);
3514 if (seg->getSegNum() == segNum) {
3515 globalSegments->del(i);
3519 for (i = 0; i < segments->getLength(); ++i) {
3520 seg = (JBIG2Segment *)segments->get(i);
3521 if (seg->getSegNum() == segNum) {
3522 globalSegments->del(i);
3528 void JBIG2Stream::resetGenericStats(Guint templ,
3529 JBIG2ArithmeticDecoderStats *prevStats) {
3532 size = contextSize[templ];
3533 if (prevStats && prevStats->getContextSize() == size) {
3534 if (genericRegionStats->getContextSize() == size) {
3535 genericRegionStats->copyFrom(prevStats);
3537 delete genericRegionStats;
3538 genericRegionStats = prevStats->copy();
3541 if (genericRegionStats->getContextSize() == size) {
3542 genericRegionStats->reset();
3544 delete genericRegionStats;
3545 genericRegionStats = new JBIG2ArithmeticDecoderStats(size);
3550 void JBIG2Stream::resetRefinementStats(
3552 JBIG2ArithmeticDecoderStats *prevStats) {
3555 size = refContextSize[templ];
3556 if (prevStats && prevStats->getContextSize() == size) {
3557 if (refinementRegionStats->getContextSize() == size) {
3558 refinementRegionStats->copyFrom(prevStats);
3560 delete refinementRegionStats;
3561 refinementRegionStats = prevStats->copy();
3564 if (refinementRegionStats->getContextSize() == size) {
3565 refinementRegionStats->reset();
3567 delete refinementRegionStats;
3568 refinementRegionStats = new JBIG2ArithmeticDecoderStats(size);
3573 void JBIG2Stream::resetIntStats(int symCodeLen) {
3582 iardxStats->reset();
3583 iardyStats->reset();
3584 iardwStats->reset();
3585 iardhStats->reset();
3587 if (iaidStats->getContextSize() == symCodeLen + 1) {
3591 iaidStats = new JBIG2ArithmeticDecoderStats(symCodeLen + 1);
3595 GBool JBIG2Stream::readUByte(Guint *x) {
3598 if ((c0 = curStr->getChar()) == EOF) {
3605 GBool JBIG2Stream::readByte(int *x) {
3608 if ((c0 = curStr->getChar()) == EOF) {
3618 GBool JBIG2Stream::readUWord(Guint *x) {
3621 if ((c0 = curStr->getChar()) == EOF ||
3622 (c1 = curStr->getChar()) == EOF) {
3625 *x = (Guint)((c0 << 8) | c1);
3629 GBool JBIG2Stream::readULong(Guint *x) {
3632 if ((c0 = curStr->getChar()) == EOF ||
3633 (c1 = curStr->getChar()) == EOF ||
3634 (c2 = curStr->getChar()) == EOF ||
3635 (c3 = curStr->getChar()) == EOF) {
3638 *x = (Guint)((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
3642 GBool JBIG2Stream::readLong(int *x) {
3645 if ((c0 = curStr->getChar()) == EOF ||
3646 (c1 = curStr->getChar()) == EOF ||
3647 (c2 = curStr->getChar()) == EOF ||
3648 (c3 = curStr->getChar()) == EOF) {
3651 *x = ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
3653 *x |= -1 - (int)0xffffffff;