19#include "JBIG2Stream.h"
22#include "Stream-CCITT.h"
26static int contextSize[4] = { 16, 13, 10, 10 };
27static int refContextSize[2] = { 13, 10 };
33class JBIG2ArithmeticDecoderStats {
36 JBIG2ArithmeticDecoderStats( int contextSizeA);
37 ~JBIG2ArithmeticDecoderStats();
38 JBIG2ArithmeticDecoderStats *copy();
40 int getContextSize() { return contextSize; }
41 void copyFrom(JBIG2ArithmeticDecoderStats *stats);
48 friend class JBIG2ArithmeticDecoder;
51JBIG2ArithmeticDecoderStats::JBIG2ArithmeticDecoderStats( int contextSizeA) {
52 contextSize = contextSizeA;
53 cxTab = (Guchar *)gmalloc((1 << contextSize) * sizeof(Guchar));
57JBIG2ArithmeticDecoderStats::~JBIG2ArithmeticDecoderStats() {
61JBIG2ArithmeticDecoderStats *JBIG2ArithmeticDecoderStats::copy() {
62 JBIG2ArithmeticDecoderStats *stats;
64 stats = new JBIG2ArithmeticDecoderStats(contextSize);
65 memcpy(stats->cxTab, cxTab, 1 << contextSize);
69void JBIG2ArithmeticDecoderStats::reset() {
70 memset(cxTab, 0, 1 << contextSize);
73void JBIG2ArithmeticDecoderStats::copyFrom(
74 JBIG2ArithmeticDecoderStats *stats) {
75 memcpy(cxTab, stats->cxTab, 1 << contextSize);
82class JBIG2ArithmeticDecoder {
85 JBIG2ArithmeticDecoder();
86 ~JBIG2ArithmeticDecoder();
87 void setStream(Stream *strA) { str = strA; }
89 int decodeBit(Guint context, JBIG2ArithmeticDecoderStats *stats);
90 int decodeByte(Guint context, JBIG2ArithmeticDecoderStats *stats);
93 GBool decodeInt( int *x, JBIG2ArithmeticDecoderStats *stats);
95 Guint decodeIAID(Guint codeLen,
96 JBIG2ArithmeticDecoderStats *stats);
100 int decodeIntBit(JBIG2ArithmeticDecoderStats *stats);
103 static Guint qeTab[47];
104 static int nmpsTab[47];
105 static int nlpsTab[47];
106 static int switchTab[47];
117Guint JBIG2ArithmeticDecoder::qeTab[47] = {
118 0x56010000, 0x34010000, 0x18010000, 0x0AC10000,
119 0x05210000, 0x02210000, 0x56010000, 0x54010000,
120 0x48010000, 0x38010000, 0x30010000, 0x24010000,
121 0x1C010000, 0x16010000, 0x56010000, 0x54010000,
122 0x51010000, 0x48010000, 0x38010000, 0x34010000,
123 0x30010000, 0x28010000, 0x24010000, 0x22010000,
124 0x1C010000, 0x18010000, 0x16010000, 0x14010000,
125 0x12010000, 0x11010000, 0x0AC10000, 0x09C10000,
126 0x08A10000, 0x05210000, 0x04410000, 0x02A10000,
127 0x02210000, 0x01410000, 0x01110000, 0x00850000,
128 0x00490000, 0x00250000, 0x00150000, 0x00090000,
129 0x00050000, 0x00010000, 0x56010000
132int JBIG2ArithmeticDecoder::nmpsTab[47] = {
133 1, 2, 3, 4, 5, 38, 7, 8, 9, 10, 11, 12, 13, 29, 15, 16,
134 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
135 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 45, 46
138int JBIG2ArithmeticDecoder::nlpsTab[47] = {
139 1, 6, 9, 12, 29, 33, 6, 14, 14, 14, 17, 18, 20, 21, 14, 14,
140 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
141 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 46
144int JBIG2ArithmeticDecoder::switchTab[47] = {
145 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
146 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
147 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
150JBIG2ArithmeticDecoder::JBIG2ArithmeticDecoder() {
154JBIG2ArithmeticDecoder::~JBIG2ArithmeticDecoder() {
157void JBIG2ArithmeticDecoder::start() {
158 buf0 = (Guint)str->getChar() & 0xff;
159 buf1 = (Guint)str->getChar() & 0xff;
162 c = (buf0 ^ 0xff) << 16;
169int JBIG2ArithmeticDecoder::decodeBit(Guint context,
170 JBIG2ArithmeticDecoderStats *stats) {
175 iCX = stats->cxTab[context] >> 1;
176 mpsCX = stats->cxTab[context] & 1;
180 if (a & 0x80000000) {
186 if (switchTab[iCX]) {
187 stats->cxTab[context] = (nlpsTab[iCX] << 1) | (1 - mpsCX);
189 stats->cxTab[context] = (nlpsTab[iCX] << 1) | mpsCX;
193 stats->cxTab[context] = (nmpsTab[iCX] << 1) | mpsCX;
203 } while (!(a & 0x80000000));
210 stats->cxTab[context] = (nmpsTab[iCX] << 1) | mpsCX;
213 if (switchTab[iCX]) {
214 stats->cxTab[context] = (nlpsTab[iCX] << 1) | (1 - mpsCX);
216 stats->cxTab[context] = (nlpsTab[iCX] << 1) | mpsCX;
228 } while (!(a & 0x80000000));
233int JBIG2ArithmeticDecoder::decodeByte(Guint context,
234 JBIG2ArithmeticDecoderStats *stats) {
239 for (i = 0; i < 8; ++i) {
240 byte = ( byte << 1) | decodeBit(context, stats);
245GBool JBIG2ArithmeticDecoder::decodeInt( int *x,
246 JBIG2ArithmeticDecoderStats *stats) {
252 s = decodeIntBit(stats);
253 if (decodeIntBit(stats)) {
254 if (decodeIntBit(stats)) {
255 if (decodeIntBit(stats)) {
256 if (decodeIntBit(stats)) {
257 if (decodeIntBit(stats)) {
259 for (i = 0; i < 32; ++i) {
260 v = (v << 1) | decodeIntBit(stats);
265 for (i = 0; i < 12; ++i) {
266 v = (v << 1) | decodeIntBit(stats);
272 for (i = 0; i < 8; ++i) {
273 v = (v << 1) | decodeIntBit(stats);
279 for (i = 0; i < 6; ++i) {
280 v = (v << 1) | decodeIntBit(stats);
285 v = decodeIntBit(stats);
286 v = (v << 1) | decodeIntBit(stats);
287 v = (v << 1) | decodeIntBit(stats);
288 v = (v << 1) | decodeIntBit(stats);
292 v = decodeIntBit(stats);
293 v = (v << 1) | decodeIntBit(stats);
307int JBIG2ArithmeticDecoder::decodeIntBit(JBIG2ArithmeticDecoderStats *stats) {
310 bit = decodeBit(prev, stats);
312 prev = (prev << 1) | bit;
314 prev = (((prev << 1) | bit) & 0x1ff) | 0x100;
319Guint JBIG2ArithmeticDecoder::decodeIAID(Guint codeLen,
320 JBIG2ArithmeticDecoderStats *stats) {
325 for (i = 0; i < codeLen; ++i) {
326 bit = decodeBit(prev, stats);
327 prev = (prev << 1) | bit;
329 return prev - (1 << codeLen);
332void JBIG2ArithmeticDecoder::byteIn() {
338 buf1 = (Guint)str->getChar() & 0xff;
339 c = c + 0xfe00 - (buf0 << 9);
344 buf1 = (Guint)str->getChar() & 0xff;
345 c = c + 0xff00 - (buf0 << 8);
354#define jbig2HuffmanLOW 0xfffffffd
355#define jbig2HuffmanOOB 0xfffffffe
356#define jbig2HuffmanEOT 0xffffffff
358struct JBIG2HuffmanTable {
365JBIG2HuffmanTable huffTableA[] = {
368 { 272, 3, 16, 0x006 },
369 { 65808, 3, 32, 0x007 },
370 { 0, 0, jbig2HuffmanEOT, 0 }
373JBIG2HuffmanTable huffTableB[] = {
379 { 75, 6, 32, 0x03e },
380 { 0, 6, jbig2HuffmanOOB, 0x03f },
381 { 0, 0, jbig2HuffmanEOT, 0 }
384JBIG2HuffmanTable huffTableC[] = {
390 { 0, 6, jbig2HuffmanOOB, 0x03e },
391 { 75, 7, 32, 0x0fe },
392 { -256, 8, 8, 0x0fe },
393 { -257, 8, jbig2HuffmanLOW, 0x0ff },
394 { 0, 0, jbig2HuffmanEOT, 0 }
397JBIG2HuffmanTable huffTableD[] = {
403 { 76, 5, 32, 0x01f },
404 { 0, 0, jbig2HuffmanEOT, 0 }
407JBIG2HuffmanTable huffTableE[] = {
413 { 76, 6, 32, 0x03e },
414 { -255, 7, 8, 0x07e },
415 { -256, 7, jbig2HuffmanLOW, 0x07f },
416 { 0, 0, jbig2HuffmanEOT, 0 }
419JBIG2HuffmanTable huffTableF[] = {
421 { 128, 3, 7, 0x002 },
422 { 256, 3, 8, 0x003 },
423 { -1024, 4, 9, 0x008 },
424 { -512, 4, 8, 0x009 },
425 { -256, 4, 7, 0x00a },
426 { -32, 4, 5, 0x00b },
427 { 512, 4, 9, 0x00c },
428 { 1024, 4, 10, 0x00d },
429 { -2048, 5, 10, 0x01c },
430 { -128, 5, 6, 0x01d },
431 { -64, 5, 5, 0x01e },
432 { -2049, 6, jbig2HuffmanLOW, 0x03e },
433 { 2048, 6, 32, 0x03f },
434 { 0, 0, jbig2HuffmanEOT, 0 }
437JBIG2HuffmanTable huffTableG[] = {
438 { -512, 3, 8, 0x000 },
439 { 256, 3, 8, 0x001 },
440 { 512, 3, 9, 0x002 },
441 { 1024, 3, 10, 0x003 },
442 { -1024, 4, 9, 0x008 },
443 { -256, 4, 7, 0x009 },
444 { -32, 4, 5, 0x00a },
446 { 128, 4, 7, 0x00c },
447 { -128, 5, 6, 0x01a },
448 { -64, 5, 5, 0x01b },
451 { -1025, 5, jbig2HuffmanLOW, 0x01e },
452 { 2048, 5, 32, 0x01f },
453 { 0, 0, jbig2HuffmanEOT, 0 }
456JBIG2HuffmanTable huffTableH[] = {
458 { 0, 2, jbig2HuffmanOOB, 0x001 },
465 { 134, 5, 7, 0x01c },
468 { 262, 6, 7, 0x03c },
469 { 646, 6, 10, 0x03d },
471 { 390, 7, 8, 0x07d },
472 { -15, 8, 3, 0x0fc },
476 { -16, 9, jbig2HuffmanLOW, 0x1fe },
477 { 1670, 9, 32, 0x1ff },
478 { 0, 0, jbig2HuffmanEOT, 0 }
481JBIG2HuffmanTable huffTableI[] = {
482 { 0, 2, jbig2HuffmanOOB, 0x000 },
490 { 139, 5, 7, 0x01b },
491 { 267, 5, 8, 0x01c },
494 { 523, 6, 8, 0x03c },
495 { 1291, 6, 11, 0x03d },
497 { 779, 7, 9, 0x07d },
498 { -31, 8, 4, 0x0fc },
499 { -11, 8, 2, 0x0fd },
500 { -15, 9, 2, 0x1fc },
502 { -32, 9, jbig2HuffmanLOW, 0x1fe },
503 { 3339, 9, 32, 0x1ff },
504 { 0, 0, jbig2HuffmanEOT, 0 }
507JBIG2HuffmanTable huffTableJ[] = {
510 { 0, 2, jbig2HuffmanOOB, 0x002 },
515 { 102, 6, 5, 0x037 },
516 { 134, 6, 6, 0x038 },
517 { 198, 6, 7, 0x039 },
518 { 326, 6, 8, 0x03a },
519 { 582, 6, 9, 0x03b },
520 { 1094, 6, 10, 0x03c },
521 { -21, 7, 4, 0x07a },
524 { 2118, 7, 11, 0x07d },
527 { -22, 8, jbig2HuffmanLOW, 0x0fe },
528 { 4166, 8, 32, 0x0ff },
529 { 0, 0, jbig2HuffmanEOT, 0 }
532JBIG2HuffmanTable huffTableK[] = {
545 { 141, 7, 32, 0x07f },
546 { 0, 0, jbig2HuffmanEOT, 0 }
549JBIG2HuffmanTable huffTableL[] = {
562 { 73, 8, 32, 0x0ff },
563 { 0, 0, jbig2HuffmanEOT, 0 }
566JBIG2HuffmanTable huffTableM[] = {
579 { 141, 7, 32, 0x07f },
580 { 0, 0, jbig2HuffmanEOT, 0 }
583JBIG2HuffmanTable huffTableN[] = {
589 { 0, 0, jbig2HuffmanEOT, 0 }
592JBIG2HuffmanTable huffTableO[] = {
602 { -24, 7, 4, 0x07c },
604 { -25, 7, jbig2HuffmanLOW, 0x07e },
605 { 25, 7, 32, 0x07f },
606 { 0, 0, jbig2HuffmanEOT, 0 }
613class JBIG2HuffmanDecoder {
616 JBIG2HuffmanDecoder();
617 ~JBIG2HuffmanDecoder();
618 void setStream(Stream *strA) { str = strA; }
623 GBool decodeInt( int *x, JBIG2HuffmanTable *table);
625 Guint readBits(Guint n);
629 void buildTable(JBIG2HuffmanTable *table, Guint len);
638JBIG2HuffmanDecoder::JBIG2HuffmanDecoder() {
643JBIG2HuffmanDecoder::~JBIG2HuffmanDecoder() {
646void JBIG2HuffmanDecoder::reset() {
652GBool JBIG2HuffmanDecoder::decodeInt( int *x, JBIG2HuffmanTable *table) {
653 Guint i, len, prefix;
658 while (table[i].rangeLen != jbig2HuffmanEOT) {
660 if (table[i].prefixLen > 0) {
661 while (len < table[i].prefixLen) {
662 prefix = (prefix << 1) | readBit();
665 if (prefix == table[i].prefix) {
666 if (table[i].rangeLen == jbig2HuffmanOOB) {
669 if (table[i].rangeLen == jbig2HuffmanLOW) {
670 *x = table[i].val - readBits(32);
671 } else if (table[i].rangeLen > 0) {
672 *x = table[i].val + readBits(table[i].rangeLen);
684Guint JBIG2HuffmanDecoder::readBits(Guint n) {
685 Guint x, mask, nLeft;
687 mask = (n == 32) ? 0xffffffff : ((1 << n) - 1);
689 x = (buf >> (bufLen - n)) & mask;
692 x = buf & ((1 << bufLen) - 1);
696 x = (x << 8) | (str->getChar() & 0xff);
700 buf = str->getChar();
702 x = (x << nLeft) | ((buf >> bufLen) & ((1 << nLeft) - 1));
708Guint JBIG2HuffmanDecoder::readBit() {
710 buf = str->getChar();
714 return (buf >> bufLen) & 1;
717static int cmpHuffmanTabEntries( const void *p1, const void *p2) {
718 return ((JBIG2HuffmanTable *)p1)->prefixLen
719 - ((JBIG2HuffmanTable *)p2)->prefixLen;
723void JBIG2HuffmanDecoder::buildTable(JBIG2HuffmanTable *table, Guint len) {
726 qsort(table, len, sizeof(JBIG2HuffmanTable), &cmpHuffmanTabEntries);
727 for (i = 0; i < len && table[i].prefixLen == 0; ++i) {
731 table[i++].prefix = prefix++;
732 for (; i < len; ++i) {
733 prefix <<= table[i].prefixLen - table[i-1].prefixLen;
734 table[i].prefix = prefix++;
742class JBIG2MMRDecoder {
747 void setStream(Stream *strA) { str = strA; }
753 void skipTo(Guint length);
763JBIG2MMRDecoder::JBIG2MMRDecoder() {
768JBIG2MMRDecoder::~JBIG2MMRDecoder() {
771void JBIG2MMRDecoder::reset() {
777int JBIG2MMRDecoder::get2DCode() {
781 buf = str->getChar() & 0xff;
784 p = &twoDimTab1[(buf >> 1) & 0x7f];
785 } else if (bufLen == 8) {
786 p = &twoDimTab1[(buf >> 1) & 0x7f];
788 p = &twoDimTab1[(buf << (7 - bufLen)) & 0x7f];
789 if (p->bits < 0 || p->bits > ( int)bufLen) {
790 buf = (buf << 8) | (str->getChar() & 0xff);
793 p = &twoDimTab1[(buf >> (bufLen - 7)) & 0x7f];
797 error(str->getPos(), "Bad two dim code in JBIG2 MMR stream");
804int JBIG2MMRDecoder::getWhiteCode() {
809 buf = str->getChar() & 0xff;
814 if (bufLen > 7 && ((buf >> (bufLen - 7)) & 0x7f) == 0) {
816 code = buf << (12 - bufLen);
818 code = buf >> (bufLen - 12);
820 p = &whiteTab1[code & 0x1f];
823 code = buf << (9 - bufLen);
825 code = buf >> (bufLen - 9);
827 p = &whiteTab2[code & 0x1ff];
829 if (p->bits > 0 && p->bits < ( int)bufLen) {
836 buf = (buf << 8) | (str->getChar() & 0xff);
840 error(str->getPos(), "Bad white code in JBIG2 MMR stream");
847int JBIG2MMRDecoder::getBlackCode() {
852 buf = str->getChar() & 0xff;
857 if (bufLen > 6 && ((buf >> (bufLen - 6)) & 0x3f) == 0) {
859 code = buf << (13 - bufLen);
861 code = buf >> (bufLen - 13);
863 p = &blackTab1[code & 0x7f];
864 } else if (bufLen > 4 && ((buf >> (bufLen - 4)) & 0x0f) == 0) {
866 code = buf << (12 - bufLen);
868 code = buf >> (bufLen - 12);
870 p = &blackTab2[(code & 0xff) - 64];
873 code = buf << (6 - bufLen);
875 code = buf >> (bufLen - 6);
877 p = &blackTab3[code & 0x3f];
879 if (p->bits > 0 && p->bits < ( int)bufLen) {
886 buf = (buf << 8) | (str->getChar() & 0xff);
890 error(str->getPos(), "Bad black code in JBIG2 MMR stream");
897Guint JBIG2MMRDecoder::get24Bits() {
898 while (bufLen < 24) {
899 buf = (buf << 8) | (str->getChar() & 0xff);
903 return (buf >> (bufLen - 24)) & 0xffffff;
906void JBIG2MMRDecoder::skipTo(Guint length) {
907 while (nBytesRead < length) {
917enum JBIG2SegmentType {
927 JBIG2Segment(Guint segNumA) { segNum = segNumA; }
928 virtual ~JBIG2Segment() {}
929 void setSegNum(Guint segNumA) { segNum = segNumA; }
930 Guint getSegNum() { return segNum; }
931 virtual JBIG2SegmentType getType() = 0;
942class JBIG2Bitmap: public JBIG2Segment {
945 JBIG2Bitmap(Guint segNumA, int wA, int hA);
946 virtual ~JBIG2Bitmap();
947 virtual JBIG2SegmentType getType() { return jbig2SegBitmap; }
948 JBIG2Bitmap *copy() { return new JBIG2Bitmap(0, this); }
949 JBIG2Bitmap *getSlice(Guint x, Guint y, Guint wA, Guint hA);
950 void expand( int newH, Guint pixel);
953 int getWidth() { return w; }
954 int getHeight() { return h; }
955 int getPixel( int x, int y)
956 { return (x < 0 || x >= w || y < 0 || y >= h) ? 0 :
957 (data[y * line + (x >> 3)] >> (7 - (x & 7))) & 1; }
958 void setPixel( int x, int y)
959 { data[y * line + (x >> 3)] |= 1 << (7 - (x & 7)); }
960 void clearPixel( int x, int y)
961 { data[y * line + (x >> 3)] &= 0x7f7f >> (x & 7); }
962 void duplicateRow( int yDest, int ySrc);
963 void combine(JBIG2Bitmap *bitmap, int x, int y, Guint combOp);
964 Guchar *getDataPtr() { return data; }
965 int getDataSize() { return h * line; }
969 JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap);
975JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, int wA, int hA):
976 JBIG2Segment(segNumA)
980 line = (wA + 7) >> 3;
982 if (h < 0 || line <= 0 || h >= (INT_MAX - 1)/ line) {
983 error(-1, "invalid width/height");
989 data = (Guchar *)gmalloc(h * line + 1);
992JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap):
993 JBIG2Segment(segNumA)
999 if (h < 0 || line <= 0 || h >= (INT_MAX - 1) / line) {
1000 error(-1, "invalid width/height");
1006 data = (Guchar *)gmalloc(h * line + 1);
1007 memcpy(data, bitmap->data, h * line);
1010JBIG2Bitmap::~JBIG2Bitmap() {
1015JBIG2Bitmap *JBIG2Bitmap::getSlice(Guint x, Guint y, Guint wA, Guint hA) {
1019 slice = new JBIG2Bitmap(0, wA, hA);
1020 slice->clearToZero();
1021 for (yy = 0; yy < hA; ++yy) {
1022 for (xx = 0; xx < wA; ++xx) {
1023 if (getPixel(x + xx, y + yy)) {
1024 slice->setPixel(xx, yy);
1031void JBIG2Bitmap::expand( int newH, Guint pixel) {
1032 if (newH <= h || line <= 0 || newH >= (INT_MAX-1) / line) {
1033 error(-1, "invalid width/height");
1039 data = (Guchar *)grealloc(data, newH * line + 1);
1041 memset(data + h * line, 0xff, (newH - h) * line);
1043 memset(data + h * line, 0x00, (newH - h) * line);
1048void JBIG2Bitmap::clearToZero() {
1049 memset(data, 0, h * line);
1052void JBIG2Bitmap::clearToOne() {
1053 memset(data, 0xff, h * line);
1056void JBIG2Bitmap::duplicateRow( int yDest, int ySrc) {
1057 memcpy(data + yDest * line, data + ySrc * line, line);
1060void JBIG2Bitmap::combine(JBIG2Bitmap *bitmap, int x, int y,
1062 int x0, x1, y0, y1, xx, yy;
1063 Guchar *srcPtr, *destPtr;
1064 Guint src0, src1, src, dest, s1, s2, m1, m2, m3;
1072 if (y + bitmap->h > h) {
1096 m1 = 0xff >> (x1 & 7);
1097 m2 = 0xff << (((x1 & 7) == 0) ? 0 : 8 - (x1 & 7));
1098 m3 = (0xff >> s1) & m2;
1100 oneByte = x0 == ((x1 - 1) & ~7);
1102 for (yy = y0; yy < y1; ++yy) {
1107 destPtr = data + (y + yy) * line + (x >> 3);
1108 srcPtr = bitmap->data + yy * bitmap->line;
1113 dest |= (src1 >> s1) & m2;
1116 dest &= ((0xff00 | src1) >> s1) | m1;
1119 dest ^= (src1 >> s1) & m2;
1122 dest ^= ((src1 ^ 0xff) >> s1) & m2;
1125 dest = (dest & ~m3) | ((src1 >> s1) & m3);
1130 destPtr = data + (y + yy) * line;
1131 srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
1145 dest ^= (src1 ^ 0xff) & m2;
1148 dest = (src1 & m2) | (dest & m1);
1160 destPtr = data + (y + yy) * line + (x >> 3);
1161 srcPtr = bitmap->data + yy * bitmap->line;
1169 dest &= (0xff00 | src1) >> s1;
1175 dest ^= (src1 ^ 0xff) >> s1;
1178 dest = (dest & (0xff << s2)) | (src1 >> s1);
1184 destPtr = data + (y + yy) * line;
1185 srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
1191 for (; xx < x1 - 8; xx += 8) {
1195 src = (((src0 << 8) | src1) >> s1) & 0xff;
1220 src = (((src0 << 8) | src1) >> s1) & 0xff;
1232 dest ^= (src ^ 0xff) & m2;
1235 dest = (src & m2) | (dest & m1);
1247class JBIG2SymbolDict: public JBIG2Segment {
1250 JBIG2SymbolDict(Guint segNumA, Guint sizeA);
1251 virtual ~JBIG2SymbolDict();
1252 virtual JBIG2SegmentType getType() { return jbig2SegSymbolDict; }
1253 Guint getSize() { return size; }
1254 void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
1255 JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
1256 void setGenericRegionStats(JBIG2ArithmeticDecoderStats *stats)
1257 { genericRegionStats = stats; }
1258 void setRefinementRegionStats(JBIG2ArithmeticDecoderStats *stats)
1259 { refinementRegionStats = stats; }
1260 JBIG2ArithmeticDecoderStats *getGenericRegionStats()
1261 { return genericRegionStats; }
1262 JBIG2ArithmeticDecoderStats *getRefinementRegionStats()
1263 { return refinementRegionStats; }
1268 JBIG2Bitmap **bitmaps;
1269 JBIG2ArithmeticDecoderStats *genericRegionStats;
1270 JBIG2ArithmeticDecoderStats *refinementRegionStats;
1273JBIG2SymbolDict::JBIG2SymbolDict(Guint segNumA, Guint sizeA):
1274 JBIG2Segment(segNumA)
1277 bitmaps = (JBIG2Bitmap **)gmalloc(size * sizeof(JBIG2Bitmap *));
1278 genericRegionStats = NULL;
1279 refinementRegionStats = NULL;
1282JBIG2SymbolDict::~JBIG2SymbolDict() {
1285 for (i = 0; i < size; ++i) {
1289 if (genericRegionStats) {
1290 delete genericRegionStats;
1292 if (refinementRegionStats) {
1293 delete refinementRegionStats;
1301class JBIG2PatternDict: public JBIG2Segment {
1304 JBIG2PatternDict(Guint segNumA, Guint sizeA);
1305 virtual ~JBIG2PatternDict();
1306 virtual JBIG2SegmentType getType() { return jbig2SegPatternDict; }
1307 Guint getSize() { return size; }
1308 void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
1309 JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
1314 JBIG2Bitmap **bitmaps;
1317JBIG2PatternDict::JBIG2PatternDict(Guint segNumA, Guint sizeA):
1318 JBIG2Segment(segNumA)
1321 bitmaps = (JBIG2Bitmap **)gmalloc(size * sizeof(JBIG2Bitmap *));
1324JBIG2PatternDict::~JBIG2PatternDict() {
1327 for (i = 0; i < size; ++i) {
1337class JBIG2CodeTable: public JBIG2Segment {
1340 JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA);
1341 virtual ~JBIG2CodeTable();
1342 virtual JBIG2SegmentType getType() { return jbig2SegCodeTable; }
1343 JBIG2HuffmanTable *getHuffTable() { return table; }
1347 JBIG2HuffmanTable *table;
1350JBIG2CodeTable::JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA):
1351 JBIG2Segment(segNumA)
1356JBIG2CodeTable::~JBIG2CodeTable() {
1364JBIG2Stream::JBIG2Stream(Stream *strA, Object *globalsStream):
1369 arithDecoder = new JBIG2ArithmeticDecoder();
1370 genericRegionStats = new JBIG2ArithmeticDecoderStats(1);
1371 refinementRegionStats = new JBIG2ArithmeticDecoderStats(1);
1372 iadhStats = new JBIG2ArithmeticDecoderStats(9);
1373 iadwStats = new JBIG2ArithmeticDecoderStats(9);
1374 iaexStats = new JBIG2ArithmeticDecoderStats(9);
1375 iaaiStats = new JBIG2ArithmeticDecoderStats(9);
1376 iadtStats = new JBIG2ArithmeticDecoderStats(9);
1377 iaitStats = new JBIG2ArithmeticDecoderStats(9);
1378 iafsStats = new JBIG2ArithmeticDecoderStats(9);
1379 iadsStats = new JBIG2ArithmeticDecoderStats(9);
1380 iardxStats = new JBIG2ArithmeticDecoderStats(9);
1381 iardyStats = new JBIG2ArithmeticDecoderStats(9);
1382 iardwStats = new JBIG2ArithmeticDecoderStats(9);
1383 iardhStats = new JBIG2ArithmeticDecoderStats(9);
1384 iariStats = new JBIG2ArithmeticDecoderStats(9);
1385 iaidStats = new JBIG2ArithmeticDecoderStats(1);
1386 huffDecoder = new JBIG2HuffmanDecoder();
1387 mmrDecoder = new JBIG2MMRDecoder();
1389 segments = new GList();
1390 if (globalsStream->isStream()) {
1391 curStr = globalsStream->getStream();
1393 arithDecoder->setStream(curStr);
1394 huffDecoder->setStream(curStr);
1395 mmrDecoder->setStream(curStr);
1398 globalSegments = segments;
1402 dataPtr = dataEnd = NULL;
1405JBIG2Stream::~JBIG2Stream() {
1406 delete arithDecoder;
1407 delete genericRegionStats;
1408 delete refinementRegionStats;
1429 deleteGList(segments, JBIG2Segment);
1431 if (globalSegments) {
1432 deleteGList(globalSegments, JBIG2Segment);
1437void JBIG2Stream::reset() {
1443 deleteGList(segments, JBIG2Segment);
1445 segments = new GList();
1449 arithDecoder->setStream(curStr);
1450 huffDecoder->setStream(curStr);
1451 mmrDecoder->setStream(curStr);
1455 dataPtr = pageBitmap->getDataPtr();
1456 dataEnd = dataPtr + pageBitmap->getDataSize();
1462int JBIG2Stream::getChar() {
1463 if (dataPtr && dataPtr < dataEnd) {
1464 return (*dataPtr++ ^ 0xff) & 0xff;
1469int JBIG2Stream::lookChar() {
1470 if (dataPtr && dataPtr < dataEnd) {
1471 return (*dataPtr ^ 0xff) & 0xff;
1476GString *JBIG2Stream::getPSFilter( const char *) {
1480GBool JBIG2Stream::isBinary(GBool ) {
1481 return str->isBinary(gTrue);
1484void JBIG2Stream::readSegments() {
1485 Guint segNum, segFlags, segType, page, segLength;
1486 Guint refFlags, nRefSegs;
1491 while (readULong(&segNum)) {
1494 if (!readUByte(&segFlags)) {
1497 segType = segFlags & 0x3f;
1500 if (!readUByte(&refFlags)) {
1503 nRefSegs = refFlags >> 5;
1504 if (nRefSegs == 7) {
1505 if ((c1 = curStr->getChar()) == EOF ||
1506 (c2 = curStr->getChar()) == EOF ||
1507 (c3 = curStr->getChar()) == EOF) {
1510 refFlags = (refFlags << 24) | (c1 << 16) | (c2 << 8) | c3;
1511 nRefSegs = refFlags & 0x1fffffff;
1512 for (i = 0; i < (nRefSegs + 9) >> 3; ++i) {
1513 c1 = curStr->getChar();
1518 refSegs = (Guint *)gmalloc(nRefSegs * sizeof(Guint));
1519 if (segNum <= 256) {
1520 for (i = 0; i < nRefSegs; ++i) {
1521 if (!readUByte(&refSegs[i])) {
1525 } else if (segNum <= 65536) {
1526 for (i = 0; i < nRefSegs; ++i) {
1527 if (!readUWord(&refSegs[i])) {
1532 for (i = 0; i < nRefSegs; ++i) {
1533 if (!readULong(&refSegs[i])) {
1540 if (segFlags & 0x40) {
1541 if (!readULong(&page)) {
1545 if (!readUByte(&page)) {
1551 if (!readULong(&segLength)) {
1558 readSymbolDictSeg(segNum, segLength, refSegs, nRefSegs);
1561 readTextRegionSeg(segNum, gFalse, gFalse, segLength, refSegs, nRefSegs);
1564 readTextRegionSeg(segNum, gTrue, gFalse, segLength, refSegs, nRefSegs);
1567 readTextRegionSeg(segNum, gTrue, gTrue, segLength, refSegs, nRefSegs);
1570 readPatternDictSeg(segNum, segLength);
1573 readHalftoneRegionSeg(segNum, gFalse, gFalse, segLength,
1577 readHalftoneRegionSeg(segNum, gTrue, gFalse, segLength,
1581 readHalftoneRegionSeg(segNum, gTrue, gTrue, segLength,
1585 readGenericRegionSeg(segNum, gFalse, gFalse, segLength);
1588 readGenericRegionSeg(segNum, gTrue, gFalse, segLength);
1591 readGenericRegionSeg(segNum, gTrue, gTrue, segLength);
1594 readGenericRefinementRegionSeg(segNum, gFalse, gFalse, segLength,
1598 readGenericRefinementRegionSeg(segNum, gTrue, gFalse, segLength,
1602 readGenericRefinementRegionSeg(segNum, gTrue, gTrue, segLength,
1606 readPageInfoSeg(segLength);
1609 readEndOfStripeSeg(segLength);
1612 readProfilesSeg(segLength);
1615 readCodeTableSeg(segNum, segLength);
1618 readExtensionSeg(segLength);
1621 error(getPos(), "Unknown segment type in JBIG2 stream");
1622 for (i = 0; i < segLength; ++i) {
1623 if ((c1 = curStr->getChar()) == EOF) {
1638 error(getPos(), "Unexpected EOF in JBIG2 stream");
1641void JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint ,
1642 Guint *refSegs, Guint nRefSegs) {
1643 JBIG2SymbolDict *symbolDict;
1644 JBIG2HuffmanTable *huffDHTable, *huffDWTable;
1645 JBIG2HuffmanTable *huffBMSizeTable, *huffAggInstTable;
1648 JBIG2SymbolDict *inputSymbolDict;
1649 Guint flags, sdTemplate, sdrTemplate, huff, refAgg;
1650 Guint huffDH, huffDW, huffBMSize, huffAggInst;
1651 Guint contextUsed, contextRetained;
1652 int sdATX[4], sdATY[4], sdrATX[2], sdrATY[2];
1653 Guint numExSyms, numNewSyms, numInputSyms, symCodeLen;
1654 JBIG2Bitmap **bitmaps;
1655 JBIG2Bitmap *collBitmap, *refBitmap;
1657 Guint symHeight, symWidth, totalWidth, x, symID;
1658 int dh, dw, refAggNum, refDX, refDY, bmSize;
1665 if (!readUWord(&flags)) {
1668 sdTemplate = (flags >> 10) & 3;
1669 sdrTemplate = (flags >> 12) & 1;
1671 refAgg = (flags >> 1) & 1;
1672 huffDH = (flags >> 2) & 3;
1673 huffDW = (flags >> 4) & 3;
1674 huffBMSize = (flags >> 6) & 1;
1675 huffAggInst = (flags >> 7) & 1;
1676 contextUsed = (flags >> 8) & 1;
1677 contextRetained = (flags >> 9) & 1;
1681 if (sdTemplate == 0) {
1682 if (!readByte(&sdATX[0]) ||
1683 !readByte(&sdATY[0]) ||
1684 !readByte(&sdATX[1]) ||
1685 !readByte(&sdATY[1]) ||
1686 !readByte(&sdATX[2]) ||
1687 !readByte(&sdATY[2]) ||
1688 !readByte(&sdATX[3]) ||
1689 !readByte(&sdATY[3])) {
1693 if (!readByte(&sdATX[0]) ||
1694 !readByte(&sdATY[0])) {
1701 if (refAgg && !sdrTemplate) {
1702 if (!readByte(&sdrATX[0]) ||
1703 !readByte(&sdrATY[0]) ||
1704 !readByte(&sdrATX[1]) ||
1705 !readByte(&sdrATY[1])) {
1711 if (!readULong(&numExSyms) || !readULong(&numNewSyms)) {
1716 codeTables = new GList();
1718 for (i = 0; i < nRefSegs; ++i) {
1719 seg = findSegment(refSegs[i]);
1720 if (seg->getType() == jbig2SegSymbolDict) {
1721 numInputSyms += ((JBIG2SymbolDict *)seg)->getSize();
1722 } else if (seg->getType() == jbig2SegCodeTable) {
1723 codeTables->append(seg);
1730 while (i < numInputSyms + numNewSyms) {
1736 bitmaps = (JBIG2Bitmap **)gmalloc((numInputSyms + numNewSyms) *
1737 sizeof(JBIG2Bitmap *));
1739 inputSymbolDict = NULL;
1740 for (i = 0; i < nRefSegs; ++i) {
1741 seg = findSegment(refSegs[i]);
1742 if (seg->getType() == jbig2SegSymbolDict) {
1743 inputSymbolDict = (JBIG2SymbolDict *)seg;
1744 for (j = 0; j < inputSymbolDict->getSize(); ++j) {
1745 bitmaps[k++] = inputSymbolDict->getBitmap(j);
1751 huffDHTable = huffDWTable = NULL;
1752 huffBMSizeTable = huffAggInstTable = NULL;
1756 huffDHTable = huffTableD;
1757 } else if (huffDH == 1) {
1758 huffDHTable = huffTableE;
1760 huffDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1763 huffDWTable = huffTableB;
1764 } else if (huffDW == 1) {
1765 huffDWTable = huffTableC;
1767 huffDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1769 if (huffBMSize == 0) {
1770 huffBMSizeTable = huffTableA;
1773 ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1775 if (huffAggInst == 0) {
1776 huffAggInstTable = huffTableA;
1779 ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1786 huffDecoder->reset();
1790 if (contextUsed && inputSymbolDict) {
1791 resetGenericStats(sdTemplate, inputSymbolDict->getGenericRegionStats());
1793 resetRefinementStats(sdrTemplate,
1794 inputSymbolDict->getRefinementRegionStats());
1797 resetGenericStats(sdTemplate, NULL);
1799 resetRefinementStats(sdrTemplate, NULL);
1802 resetIntStats(symCodeLen);
1803 arithDecoder->start();
1808 if (huff && !refAgg) {
1809 symWidths = (Guint *)gmalloc(numNewSyms * sizeof(Guint));
1814 while (i < numNewSyms) {
1818 huffDecoder->decodeInt(&dh, huffDHTable);
1820 arithDecoder->decodeInt(&dh, iadhStats);
1832 if (!huffDecoder->decodeInt(&dw, huffDWTable)) {
1836 if (!arithDecoder->decodeInt(&dw, iadwStats)) {
1843 if (huff && !refAgg) {
1844 symWidths[i] = symWidth;
1845 totalWidth += symWidth;
1848 } else if (refAgg) {
1850 if (!huffDecoder->decodeInt(&refAggNum, huffAggInstTable)) {
1854 if (!arithDecoder->decodeInt(&refAggNum, iaaiStats)) {
1858 if (refAggNum == 1) {
1860 symID = huffDecoder->readBits(symCodeLen);
1861 huffDecoder->decodeInt(&refDX, huffTableO);
1862 huffDecoder->decodeInt(&refDY, huffTableO);
1863 huffDecoder->decodeInt(&bmSize, huffTableA);
1864 huffDecoder->reset();
1865 arithDecoder->start();
1867 symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
1868 arithDecoder->decodeInt(&refDX, iardxStats);
1869 arithDecoder->decodeInt(&refDY, iardyStats);
1871 refBitmap = bitmaps[symID];
1872 bitmaps[numInputSyms + i] =
1873 readGenericRefinementRegion(symWidth, symHeight,
1874 sdrTemplate, gFalse,
1875 refBitmap, refDX, refDY,
1879 bitmaps[numInputSyms + i] =
1880 readTextRegion(huff, gTrue, symWidth, symHeight,
1881 refAggNum, 0, numInputSyms + i, NULL,
1882 symCodeLen, bitmaps, 0, 0, 0, 1, 0,
1883 huffTableF, huffTableH, huffTableK, huffTableO,
1884 huffTableO, huffTableO, huffTableO, huffTableA,
1885 sdrTemplate, sdrATX, sdrATY);
1890 bitmaps[numInputSyms + i] =
1891 readGenericBitmap(gFalse, symWidth, symHeight,
1892 sdTemplate, gFalse, gFalse, NULL,
1900 if (huff && !refAgg) {
1901 huffDecoder->decodeInt(&bmSize, huffBMSizeTable);
1903 huffDecoder->reset();
1906 collBitmap = new JBIG2Bitmap(0, totalWidth, symHeight);
1907 bmSize = symHeight * ((totalWidth + 7) >> 3);
1908 p = collBitmap->getDataPtr();
1909 for (k = 0; k < (Guint)bmSize; ++k) {
1910 *p++ = str->getChar();
1913 collBitmap = readGenericBitmap(gTrue, totalWidth, symHeight,
1914 0, gFalse, gFalse, NULL, NULL, NULL,
1918 for (; j < i; ++j) {
1919 bitmaps[numInputSyms + j] =
1920 collBitmap->getSlice(x, 0, symWidths[j], symHeight);
1928 symbolDict = new JBIG2SymbolDict(segNum, numExSyms);
1933 while (i < numInputSyms + numNewSyms) {
1935 huffDecoder->decodeInt(&run, huffTableA);
1937 arithDecoder->decodeInt(&run, iaexStats);
1940 for (cnt = 0; cnt < run; ++cnt) {
1941 symbolDict->setBitmap(j++, bitmaps[i++]->copy());
1949 for (i = 0; i < numNewSyms; ++i) {
1950 delete bitmaps[numInputSyms + i];
1958 if (!huff && contextRetained) {
1959 symbolDict->setGenericRegionStats(genericRegionStats->copy());
1961 symbolDict->setRefinementRegionStats(refinementRegionStats->copy());
1966 segments->append(symbolDict);
1971 error(getPos(), "Unexpected EOF in JBIG2 stream");
1974void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
1976 Guint *refSegs, Guint nRefSegs) {
1977 JBIG2Bitmap *bitmap;
1978 JBIG2HuffmanTable runLengthTab[36];
1979 JBIG2HuffmanTable *symCodeTab;
1980 JBIG2HuffmanTable *huffFSTable, *huffDSTable, *huffDTTable;
1981 JBIG2HuffmanTable *huffRDWTable, *huffRDHTable;
1982 JBIG2HuffmanTable *huffRDXTable, *huffRDYTable, *huffRSizeTable;
1985 JBIG2SymbolDict *symbolDict;
1987 Guint w, h, x, y, segInfoFlags, extCombOp;
1988 Guint flags, huff, refine, logStrips, refCorner, transposed;
1989 Guint combOp, defPixel, sOffset, templ;
1990 Guint huffFlags, huffFS, huffDS, huffDT;
1991 Guint huffRDW, huffRDH, huffRDX, huffRDY, huffRSize;
1992 Guint numInstances, numSyms, symCodeLen;
1998 if (!readULong(&w) || !readULong(&h) ||
1999 !readULong(&x) || !readULong(&y) ||
2000 !readUByte(&segInfoFlags)) {
2003 extCombOp = segInfoFlags & 7;
2006 if (!readUWord(&flags)) {
2010 refine = (flags >> 1) & 1;
2011 logStrips = (flags >> 2) & 3;
2012 refCorner = (flags >> 4) & 3;
2013 transposed = (flags >> 6) & 1;
2014 combOp = (flags >> 7) & 3;
2015 defPixel = (flags >> 9) & 1;
2016 sOffset = (flags >> 10) & 0x1f;
2017 templ = (flags >> 15) & 1;
2018 huffFS = huffDS = huffDT = 0;
2019 huffRDW = huffRDH = huffRDX = huffRDY = huffRSize = 0;
2021 if (!readUWord(&huffFlags)) {
2024 huffFS = huffFlags & 3;
2025 huffDS = (huffFlags >> 2) & 3;
2026 huffDT = (huffFlags >> 4) & 3;
2027 huffRDW = (huffFlags >> 6) & 3;
2028 huffRDH = (huffFlags >> 8) & 3;
2029 huffRDX = (huffFlags >> 10) & 3;
2030 huffRDY = (huffFlags >> 12) & 3;
2031 huffRSize = (huffFlags >> 14) & 1;
2033 if (refine && templ == 0) {
2034 if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
2035 !readByte(&atx[1]) || !readByte(&aty[1])) {
2039 if (!readULong(&numInstances)) {
2044 codeTables = new GList();
2046 for (i = 0; i < nRefSegs; ++i) {
2047 seg = findSegment(refSegs[i]);
2048 if (seg->getType() == jbig2SegSymbolDict) {
2049 numSyms += ((JBIG2SymbolDict *)seg)->getSize();
2050 } else if (seg->getType() == jbig2SegCodeTable) {
2051 codeTables->append(seg);
2056 while (i < numSyms) {
2062 syms = (JBIG2Bitmap **)gmalloc(numSyms * sizeof(JBIG2Bitmap *));
2064 for (i = 0; i < nRefSegs; ++i) {
2065 seg = findSegment(refSegs[i]);
2066 if (seg->getType() == jbig2SegSymbolDict) {
2067 symbolDict = (JBIG2SymbolDict *)seg;
2068 for (k = 0; k < symbolDict->getSize(); ++k) {
2069 syms[kk++] = symbolDict->getBitmap(k);
2075 huffFSTable = huffDSTable = huffDTTable = NULL;
2076 huffRDWTable = huffRDHTable = NULL;
2077 huffRDXTable = huffRDYTable = huffRSizeTable = NULL;
2081 huffFSTable = huffTableF;
2082 } else if (huffFS == 1) {
2083 huffFSTable = huffTableG;
2085 huffFSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2088 huffDSTable = huffTableH;
2089 } else if (huffDS == 1) {
2090 huffDSTable = huffTableI;
2091 } else if (huffDS == 2) {
2092 huffDSTable = huffTableJ;
2094 huffDSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2097 huffDTTable = huffTableK;
2098 } else if (huffDT == 1) {
2099 huffDTTable = huffTableL;
2100 } else if (huffDT == 2) {
2101 huffDTTable = huffTableM;
2103 huffDTTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2106 huffRDWTable = huffTableN;
2107 } else if (huffRDW == 1) {
2108 huffRDWTable = huffTableO;
2110 huffRDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2113 huffRDHTable = huffTableN;
2114 } else if (huffRDH == 1) {
2115 huffRDHTable = huffTableO;
2117 huffRDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2120 huffRDXTable = huffTableN;
2121 } else if (huffRDX == 1) {
2122 huffRDXTable = huffTableO;
2124 huffRDXTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2127 huffRDYTable = huffTableN;
2128 } else if (huffRDY == 1) {
2129 huffRDYTable = huffTableO;
2131 huffRDYTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2133 if (huffRSize == 0) {
2134 huffRSizeTable = huffTableA;
2137 ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2144 huffDecoder->reset();
2145 for (i = 0; i < 32; ++i) {
2146 runLengthTab[i].val = i;
2147 runLengthTab[i].prefixLen = huffDecoder->readBits(4);
2148 runLengthTab[i].rangeLen = 0;
2150 runLengthTab[32].val = 0x103;
2151 runLengthTab[32].prefixLen = huffDecoder->readBits(4);
2152 runLengthTab[32].rangeLen = 2;
2153 runLengthTab[33].val = 0x203;
2154 runLengthTab[33].prefixLen = huffDecoder->readBits(4);
2155 runLengthTab[33].rangeLen = 3;
2156 runLengthTab[34].val = 0x20b;
2157 runLengthTab[34].prefixLen = huffDecoder->readBits(4);
2158 runLengthTab[34].rangeLen = 7;
2159 runLengthTab[35].rangeLen = jbig2HuffmanEOT;
2160 huffDecoder->buildTable(runLengthTab, 35);
2161 symCodeTab = (JBIG2HuffmanTable *)gmalloc((numSyms + 1) *
2162 sizeof(JBIG2HuffmanTable));
2163 for (i = 0; i < numSyms; ++i) {
2164 symCodeTab[i].val = i;
2165 symCodeTab[i].rangeLen = 0;
2168 while (i < numSyms) {
2169 huffDecoder->decodeInt(&j, runLengthTab);
2171 for (j -= 0x200; j && i < numSyms; --j) {
2172 symCodeTab[i++].prefixLen = 0;
2174 } else if (j > 0x100) {
2175 for (j -= 0x100; j && i < numSyms; --j) {
2176 symCodeTab[i].prefixLen = symCodeTab[i-1].prefixLen;
2180 symCodeTab[i++].prefixLen = j;
2184 symCodeTab[numSyms].rangeLen = jbig2HuffmanEOT;
2185 huffDecoder->buildTable(symCodeTab, numSyms);
2186 huffDecoder->reset();
2191 resetIntStats(symCodeLen);
2193 resetRefinementStats(templ, NULL);
2195 arithDecoder->start();
2198 bitmap = readTextRegion(huff, refine, w, h, numInstances,
2199 logStrips, numSyms, symCodeTab, symCodeLen, syms,
2200 defPixel, combOp, transposed, refCorner, sOffset,
2201 huffFSTable, huffDSTable, huffDTTable,
2202 huffRDWTable, huffRDHTable,
2203 huffRDXTable, huffRDYTable, huffRSizeTable,
2210 if (pageH == 0xffffffff && y + h > curPageH) {
2211 pageBitmap->expand(y + h, pageDefPixel);
2213 pageBitmap->combine(bitmap, x, y, extCombOp);
2218 bitmap->setSegNum(segNum);
2219 segments->append(bitmap);
2230 error(getPos(), "Unexpected EOF in JBIG2 stream");
2233JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
2238 JBIG2HuffmanTable *symCodeTab,
2241 Guint defPixel, Guint combOp,
2242 Guint transposed, Guint refCorner,
2244 JBIG2HuffmanTable *huffFSTable,
2245 JBIG2HuffmanTable *huffDSTable,
2246 JBIG2HuffmanTable *huffDTTable,
2247 JBIG2HuffmanTable *huffRDWTable,
2248 JBIG2HuffmanTable *huffRDHTable,
2249 JBIG2HuffmanTable *huffRDXTable,
2250 JBIG2HuffmanTable *huffRDYTable,
2251 JBIG2HuffmanTable *huffRSizeTable,
2253 int *atx, int *aty) {
2254 JBIG2Bitmap *bitmap;
2255 JBIG2Bitmap *symbolBitmap;
2257 int t, dt, tt, s, ds, sFirst, j;
2258 int rdw, rdh, rdx, rdy, ri, refDX, refDY, bmSize;
2259 Guint symID, inst, bw, bh;
2261 strips = 1 << logStrips;
2263 if (w < 0 || h <= 0 || w >= INT_MAX / h) {
2264 error(-1, "invalid width/height");
2269 bitmap = new JBIG2Bitmap(0, w, h);
2271 bitmap->clearToOne();
2273 bitmap->clearToZero();
2278 huffDecoder->decodeInt(&t, huffDTTable);
2280 arithDecoder->decodeInt(&t, iadtStats);
2286 while (inst < numInstances) {
2290 huffDecoder->decodeInt(&dt, huffDTTable);
2292 arithDecoder->decodeInt(&dt, iadtStats);
2298 huffDecoder->decodeInt(&ds, huffFSTable);
2300 arithDecoder->decodeInt(&ds, iafsStats);
2312 dt = huffDecoder->readBits(logStrips);
2314 arithDecoder->decodeInt(&dt, iaitStats);
2321 huffDecoder->decodeInt(&j, symCodeTab);
2324 symID = huffDecoder->readBits(symCodeLen);
2327 symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
2331 symbolBitmap = NULL;
2334 ri = (int)huffDecoder->readBit();
2336 arithDecoder->decodeInt(&ri, iariStats);
2343 huffDecoder->decodeInt(&rdw, huffRDWTable);
2344 huffDecoder->decodeInt(&rdh, huffRDHTable);
2345 huffDecoder->decodeInt(&rdx, huffRDXTable);
2346 huffDecoder->decodeInt(&rdy, huffRDYTable);
2347 huffDecoder->decodeInt(&bmSize, huffRSizeTable);
2348 huffDecoder->reset();
2349 arithDecoder->start();
2351 arithDecoder->decodeInt(&rdw, iardwStats);
2352 arithDecoder->decodeInt(&rdh, iardhStats);
2353 arithDecoder->decodeInt(&rdx, iardxStats);
2354 arithDecoder->decodeInt(&rdy, iardyStats);
2356 refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
2357 refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
2360 readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
2361 rdh + syms[symID]->getHeight(),
2362 templ, gFalse, syms[symID],
2363 refDX, refDY, atx, aty);
2366 symbolBitmap = syms[symID];
2372 bw = symbolBitmap->getWidth() - 1;
2373 bh = symbolBitmap->getHeight() - 1;
2375 switch (refCorner) {
2377 bitmap->combine(symbolBitmap, tt, s, combOp);
2380 bitmap->combine(symbolBitmap, tt, s, combOp);
2383 bitmap->combine(symbolBitmap, tt - bw, s, combOp);
2386 bitmap->combine(symbolBitmap, tt - bw, s, combOp);
2391 switch (refCorner) {
2393 bitmap->combine(symbolBitmap, s, tt - bh, combOp);
2396 bitmap->combine(symbolBitmap, s, tt, combOp);
2399 bitmap->combine(symbolBitmap, s, tt - bh, combOp);
2402 bitmap->combine(symbolBitmap, s, tt, combOp);
2408 delete symbolBitmap;
2416 if (!huffDecoder->decodeInt(&ds, huffDSTable)) {
2420 if (!arithDecoder->decodeInt(&ds, iadsStats)) {
2431void JBIG2Stream::readPatternDictSeg(Guint segNum, Guint length) {
2432 JBIG2PatternDict *patternDict;
2433 JBIG2Bitmap *bitmap;
2434 Guint flags, patternW, patternH, grayMax, templ, mmr;
2439 if (!readUByte(&flags) ||
2440 !readUByte(&patternW) ||
2441 !readUByte(&patternH) ||
2442 !readULong(&grayMax)) {
2445 templ = (flags >> 1) & 3;
2450 resetGenericStats(templ, NULL);
2451 arithDecoder->start();
2455 atx[0] = -patternW; aty[0] = 0;
2456 atx[1] = -3; aty[1] = -1;
2457 atx[2] = 2; aty[2] = -2;
2458 atx[3] = -2; aty[3] = -2;
2459 bitmap = readGenericBitmap(mmr, (grayMax + 1) * patternW, patternH,
2460 templ, gFalse, gFalse, NULL,
2461 atx, aty, length - 7);
2464 patternDict = new JBIG2PatternDict(segNum, grayMax + 1);
2468 for (i = 0; i <= grayMax; ++i) {
2469 patternDict->setBitmap(i, bitmap->getSlice(x, 0, patternW, patternH));
2477 segments->append(patternDict);
2482 error(getPos(), "Unexpected EOF in JBIG2 stream");
2485void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm,
2487 Guint *refSegs, Guint nRefSegs) {
2488 JBIG2Bitmap *bitmap;
2490 JBIG2PatternDict *patternDict;
2491 JBIG2Bitmap *skipBitmap;
2493 JBIG2Bitmap *grayBitmap;
2494 JBIG2Bitmap *patternBitmap;
2495 Guint w, h, x, y, segInfoFlags, extCombOp;
2496 Guint flags, mmr, templ, enableSkip, combOp;
2497 Guint gridW, gridH, stepX, stepY, patW, patH;
2499 int gridX, gridY, xx, yy, bit, j;
2503 if (!readULong(&w) || !readULong(&h) ||
2504 !readULong(&x) || !readULong(&y) ||
2505 !readUByte(&segInfoFlags)) {
2508 extCombOp = segInfoFlags & 7;
2511 if (!readUByte(&flags)) {
2515 templ = (flags >> 1) & 3;
2516 enableSkip = (flags >> 3) & 1;
2517 combOp = (flags >> 4) & 7;
2518 if (!readULong(&gridW) || !readULong(&gridH) ||
2519 !readLong(&gridX) || !readLong(&gridY) ||
2520 !readUWord(&stepX) || !readUWord(&stepY)) {
2525 if (nRefSegs != 1) {
2526 error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
2529 seg = findSegment(refSegs[0]);
2530 if (seg->getType() != jbig2SegPatternDict) {
2531 error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
2534 if (gridH == 0 || gridW >= INT_MAX / gridH) {
2535 error(getPos(), "Bad size in JBIG2 halftone segment");
2538 if (w == 0 || h >= INT_MAX / w) {
2539 error(getPos(), "Bad size in JBIG2 bitmap segment");
2543 patternDict = (JBIG2PatternDict *)seg;
2546 while (i < patternDict->getSize()) {
2550 patW = patternDict->getBitmap(0)->getWidth();
2551 patH = patternDict->getBitmap(0)->getHeight();
2555 resetGenericStats(templ, NULL);
2556 arithDecoder->start();
2560 bitmap = new JBIG2Bitmap(segNum, w, h);
2562 bitmap->clearToOne();
2564 bitmap->clearToZero();
2570 skipBitmap = new JBIG2Bitmap(0, gridW, gridH);
2571 skipBitmap->clearToZero();
2572 for (m = 0; m < gridH; ++m) {
2573 xx = gridX + m * stepY;
2574 yy = gridY + m * stepX;
2575 for (n = 0; n < gridW; ++n) {
2576 if (((xx + ( int)patW) >> 8) <= 0 || (xx >> 8) >= ( int)w ||
2577 ((yy + ( int)patH) >> 8) <= 0 || (yy >> 8) >= ( int)h) {
2578 skipBitmap->setPixel(n, m);
2585 grayImg = (Guint *)gmalloc(gridW * gridH * sizeof(Guint));
2586 memset(grayImg, 0, gridW * gridH * sizeof(Guint));
2587 atx[0] = templ <= 1 ? 3 : 2; aty[0] = -1;
2588 atx[1] = -3; aty[1] = -1;
2589 atx[2] = 2; aty[2] = -2;
2590 atx[3] = -2; aty[3] = -2;
2591 for (j = bpp - 1; j >= 0; --j) {
2592 grayBitmap = readGenericBitmap(mmr, gridW, gridH, templ, gFalse,
2593 enableSkip, skipBitmap, atx, aty, -1);
2595 for (m = 0; m < gridH; ++m) {
2596 for (n = 0; n < gridW; ++n) {
2597 bit = grayBitmap->getPixel(n, m) ^ (grayImg[i] & 1);
2598 grayImg[i] = (grayImg[i] << 1) | bit;
2607 for (m = 0; m < gridH; ++m) {
2608 xx = gridX + m * stepY;
2609 yy = gridY + m * stepX;
2610 for (n = 0; n < gridW; ++n) {
2611 if (!(enableSkip && skipBitmap->getPixel(n, m))) {
2612 patternBitmap = patternDict->getBitmap(grayImg[i]);
2613 bitmap->combine(patternBitmap, xx >> 8, yy >> 8, combOp);
2625 if (pageH == 0xffffffff && y + h > curPageH) {
2626 pageBitmap->expand(y + h, pageDefPixel);
2628 pageBitmap->combine(bitmap, x, y, extCombOp);
2633 segments->append(bitmap);
2639 error(getPos(), "Unexpected EOF in JBIG2 stream");
2642void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm,
2643 GBool , Guint length) {
2644 JBIG2Bitmap *bitmap;
2645 Guint w, h, x, y, segInfoFlags, extCombOp;
2646 Guint flags, mmr, templ, tpgdOn;
2650 if (!readULong(&w) || !readULong(&h) ||
2651 !readULong(&x) || !readULong(&y) ||
2652 !readUByte(&segInfoFlags)) {
2655 extCombOp = segInfoFlags & 7;
2658 if (!readUByte(&flags)) {
2662 templ = (flags >> 1) & 3;
2663 tpgdOn = (flags >> 3) & 1;
2668 if (!readByte(&atx[0]) ||
2669 !readByte(&aty[0]) ||
2670 !readByte(&atx[1]) ||
2671 !readByte(&aty[1]) ||
2672 !readByte(&atx[2]) ||
2673 !readByte(&aty[2]) ||
2674 !readByte(&atx[3]) ||
2675 !readByte(&aty[3])) {
2679 if (!readByte(&atx[0]) ||
2680 !readByte(&aty[0])) {
2688 resetGenericStats(templ, NULL);
2689 arithDecoder->start();
2693 bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse,
2694 NULL, atx, aty, mmr ? 0 : length - 18);
2698 if (pageH == 0xffffffff && y + h > curPageH) {
2699 pageBitmap->expand(y + h, pageDefPixel);
2701 pageBitmap->combine(bitmap, x, y, extCombOp);
2706 bitmap->setSegNum(segNum);
2707 segments->append(bitmap);
2713 error(getPos(), "Unexpected EOF in JBIG2 stream");
2716JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
2717 int templ, GBool tpgdOn,
2718 GBool useSkip, JBIG2Bitmap *skip,
2720 int mmrDataLength) {
2721 JBIG2Bitmap *bitmap;
2723 Guint ltpCX, cx, cx0, cx1, cx2;
2724 int *refLine, *codingLine;
2725 int code1, code2, code3;
2726 int x, y, a0, pix, i, refI, codingI;
2728 bitmap = new JBIG2Bitmap(0, w, h);
2729 bitmap->clearToZero();
2735 mmrDecoder->reset();
2736 refLine = ( int *)gmalloc((w + 2) * sizeof(int));
2737 codingLine = ( int *)gmalloc((w + 2) * sizeof(int));
2738 codingLine[0] = codingLine[1] = w;
2740 for (y = 0; y < h; ++y) {
2743 for (i = 0; codingLine[i] < w; ++i) {
2744 refLine[i] = codingLine[i];
2746 refLine[i] = refLine[i + 1] = w;
2753 code1 = mmrDecoder->get2DCode();
2756 if (refLine[refI] < w) {
2757 a0 = refLine[refI + 1];
2765 code1 += code3 = mmrDecoder->getBlackCode();
2766 } while (code3 >= 64);
2769 code2 += code3 = mmrDecoder->getWhiteCode();
2770 } while (code3 >= 64);
2774 code1 += code3 = mmrDecoder->getWhiteCode();
2775 } while (code3 >= 64);
2778 code2 += code3 = mmrDecoder->getBlackCode();
2779 } while (code3 >= 64);
2781 a0 = codingLine[codingI++] = a0 + code1;
2782 a0 = codingLine[codingI++] = a0 + code2;
2783 while (refLine[refI] <= a0 && refLine[refI] < w) {
2788 a0 = codingLine[codingI++] = refLine[refI];
2789 if (refLine[refI] < w) {
2794 a0 = codingLine[codingI++] = refLine[refI] + 1;
2795 if (refLine[refI] < w) {
2797 while (refLine[refI] <= a0 && refLine[refI] < w) {
2803 a0 = codingLine[codingI++] = refLine[refI] + 2;
2804 if (refLine[refI] < w) {
2806 while (refLine[refI] <= a0 && refLine[refI] < w) {
2812 a0 = codingLine[codingI++] = refLine[refI] + 3;
2813 if (refLine[refI] < w) {
2815 while (refLine[refI] <= a0 && refLine[refI] < w) {
2821 a0 = codingLine[codingI++] = refLine[refI] - 1;
2827 while (refLine[refI] <= a0 && refLine[refI] < w) {
2832 a0 = codingLine[codingI++] = refLine[refI] - 2;
2838 while (refLine[refI] <= a0 && refLine[refI] < w) {
2843 a0 = codingLine[codingI++] = refLine[refI] - 3;
2849 while (refLine[refI] <= a0 && refLine[refI] < w) {
2854 error(getPos(), "Illegal code in JBIG2 MMR bitmap data");
2858 codingLine[codingI++] = w;
2862 while (codingLine[i] < w) {
2863 for (x = codingLine[i]; x < codingLine[i+1]; ++x) {
2864 bitmap->setPixel(x, y);
2870 if (mmrDataLength >= 0) {
2871 mmrDecoder->skipTo(mmrDataLength);
2873 if (mmrDecoder->get24Bits() != 0x001001) {
2874 error(getPos(), "Missing EOFB in JBIG2 MMR bitmap data");
2904 cx = cx0 = cx1 = cx2 = 0;
2905 for (y = 0; y < h; ++y) {
2909 if (arithDecoder->decodeBit(ltpCX, genericRegionStats)) {
2913 bitmap->duplicateRow(y, y-1);
2921 cx0 = (bitmap->getPixel(0, y-2) << 1) |
2922 bitmap->getPixel(1, y-2);
2923 cx1 = (bitmap->getPixel(0, y-1) << 2) |
2924 (bitmap->getPixel(1, y-1) << 1) |
2925 bitmap->getPixel(2, y-1);
2929 cx0 = (bitmap->getPixel(0, y-2) << 2) |
2930 (bitmap->getPixel(1, y-2) << 1) |
2931 bitmap->getPixel(2, y-2);
2932 cx1 = (bitmap->getPixel(0, y-1) << 2) |
2933 (bitmap->getPixel(1, y-1) << 1) |
2934 bitmap->getPixel(2, y-1);
2938 cx0 = (bitmap->getPixel(0, y-2) << 1) |
2939 bitmap->getPixel(1, y-2);
2940 cx1 = (bitmap->getPixel(0, y-1) << 1) |
2941 bitmap->getPixel(1, y-1);
2945 cx1 = (bitmap->getPixel(0, y-1) << 1) |
2946 bitmap->getPixel(1, y-1);
2952 for (x = 0; x < w; ++x) {
2955 if (useSkip && skip->getPixel(x, y)) {
2963 cx = (cx0 << 13) | (cx1 << 8) | (cx2 << 4) |
2964 (bitmap->getPixel(x + atx[0], y + aty[0]) << 3) |
2965 (bitmap->getPixel(x + atx[1], y + aty[1]) << 2) |
2966 (bitmap->getPixel(x + atx[2], y + aty[2]) << 1) |
2967 bitmap->getPixel(x + atx[3], y + aty[3]);
2970 cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
2971 bitmap->getPixel(x + atx[0], y + aty[0]);
2974 cx = (cx0 << 7) | (cx1 << 3) | (cx2 << 1) |
2975 bitmap->getPixel(x + atx[0], y + aty[0]);
2978 cx = (cx1 << 5) | (cx2 << 1) |
2979 bitmap->getPixel(x + atx[0], y + aty[0]);
2984 if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
2985 bitmap->setPixel(x, y);
2992 cx0 = ((cx0 << 1) | bitmap->getPixel(x+2, y-2)) & 0x07;
2993 cx1 = ((cx1 << 1) | bitmap->getPixel(x+3, y-1)) & 0x1f;
2994 cx2 = ((cx2 << 1) | pix) & 0x0f;
2997 cx0 = ((cx0 << 1) | bitmap->getPixel(x+3, y-2)) & 0x0f;
2998 cx1 = ((cx1 << 1) | bitmap->getPixel(x+3, y-1)) & 0x1f;
2999 cx2 = ((cx2 << 1) | pix) & 0x07;
3002 cx0 = ((cx0 << 1) | bitmap->getPixel(x+2, y-2)) & 0x07;
3003 cx1 = ((cx1 << 1) | bitmap->getPixel(x+2, y-1)) & 0x0f;
3004 cx2 = ((cx2 << 1) | pix) & 0x03;
3007 cx1 = ((cx1 << 1) | bitmap->getPixel(x+2, y-1)) & 0x1f;
3008 cx2 = ((cx2 << 1) | pix) & 0x0f;
3018void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum, GBool imm,
3022 JBIG2Bitmap *bitmap, *refBitmap;
3023 Guint w, h, x, y, segInfoFlags, extCombOp;
3024 Guint flags, templ, tpgrOn;
3029 if (!readULong(&w) || !readULong(&h) ||
3030 !readULong(&x) || !readULong(&y) ||
3031 !readUByte(&segInfoFlags)) {
3034 extCombOp = segInfoFlags & 7;
3037 if (!readUByte(&flags)) {
3041 tpgrOn = (flags >> 1) & 1;
3045 if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
3046 !readByte(&atx[1]) || !readByte(&aty[1])) {
3052 if (nRefSegs == 0 || imm) {
3053 if (pageH == 0xffffffff && y + h > curPageH) {
3054 pageBitmap->expand(y + h, pageDefPixel);
3060 error(getPos(), "Bad reference in JBIG2 generic refinement segment");
3063 if (nRefSegs == 1) {
3064 seg = findSegment(refSegs[0]);
3065 if (seg->getType() != jbig2SegBitmap) {
3066 error(getPos(), "Bad bitmap reference in JBIG2 generic refinement segment");
3069 refBitmap = (JBIG2Bitmap *)seg;
3071 refBitmap = pageBitmap->getSlice(x, y, w, h);
3075 resetRefinementStats(templ, NULL);
3076 arithDecoder->start();
3079 bitmap = readGenericRefinementRegion(w, h, templ, tpgrOn,
3080 refBitmap, 0, 0, atx, aty);
3084 pageBitmap->combine(bitmap, x, y, extCombOp);
3089 bitmap->setSegNum(segNum);
3090 segments->append(bitmap);
3094 if (nRefSegs == 1) {
3095 discardSegment(refSegs[0]);
3103 error(getPos(), "Unexpected EOF in JBIG2 stream");
3106JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion( int w, int h,
3107 int templ, GBool tpgrOn,
3108 JBIG2Bitmap *refBitmap,
3109 int refDX, int refDY,
3110 int *atx, int *aty) {
3111 JBIG2Bitmap *bitmap;
3113 Guint ltpCX, cx, cx0, cx2, cx3, cx4, tpgrCX0, tpgrCX1, tpgrCX2;
3116 if (w < 0 || h <= 0 || w >= INT_MAX / h) {
3117 error(-1, "invalid width/height");
3121 bitmap = new JBIG2Bitmap(0, w, h);
3122 bitmap->clearToZero();
3132 for (y = 0; y < h; ++y) {
3136 cx0 = bitmap->getPixel(0, y-1);
3138 cx3 = (refBitmap->getPixel(-1-refDX, y-refDY) << 1) |
3139 refBitmap->getPixel(-refDX, y-refDY);
3140 cx4 = refBitmap->getPixel(-refDX, y+1-refDY);
3142 cx0 = bitmap->getPixel(0, y-1);
3143 cx2 = refBitmap->getPixel(-refDX, y-1-refDY);
3144 cx3 = (refBitmap->getPixel(-1-refDX, y-refDY) << 1) |
3145 refBitmap->getPixel(-refDX, y-refDY);
3146 cx4 = (refBitmap->getPixel(-1-refDX, y+1-refDY) << 1) |
3147 refBitmap->getPixel(-refDX, y+1-refDY);
3151 tpgrCX0 = tpgrCX1 = tpgrCX2 = 0;
3153 tpgrCX0 = (refBitmap->getPixel(-1-refDX, y-1-refDY) << 2) |
3154 (refBitmap->getPixel(-refDX, y-1-refDY) << 1) |
3155 refBitmap->getPixel(1-refDX, y-1-refDY);
3156 tpgrCX1 = (refBitmap->getPixel(-1-refDX, y-refDY) << 2) |
3157 (refBitmap->getPixel(-refDX, y-refDY) << 1) |
3158 refBitmap->getPixel(1-refDX, y-refDY);
3159 tpgrCX2 = (refBitmap->getPixel(-1-refDX, y+1-refDY) << 2) |
3160 (refBitmap->getPixel(-refDX, y+1-refDY) << 1) |
3161 refBitmap->getPixel(1-refDX, y+1-refDY);
3164 for (x = 0; x < w; ++x) {
3168 cx0 = ((cx0 << 1) | bitmap->getPixel(x+1, y-1)) & 7;
3169 cx3 = ((cx3 << 1) | refBitmap->getPixel(x+1-refDX, y-refDY)) & 7;
3170 cx4 = ((cx4 << 1) | refBitmap->getPixel(x+1-refDX, y+1-refDY)) & 3;
3172 cx0 = ((cx0 << 1) | bitmap->getPixel(x+1, y-1)) & 3;
3173 cx2 = ((cx2 << 1) | refBitmap->getPixel(x+1-refDX, y-1-refDY)) & 3;
3174 cx3 = ((cx3 << 1) | refBitmap->getPixel(x+1-refDX, y-refDY)) & 7;
3175 cx4 = ((cx4 << 1) | refBitmap->getPixel(x+1-refDX, y+1-refDY)) & 7;
3180 tpgrCX0 = ((tpgrCX0 << 1) |
3181 refBitmap->getPixel(x+1-refDX, y-1-refDY)) & 7;
3182 tpgrCX1 = ((tpgrCX1 << 1) |
3183 refBitmap->getPixel(x+1-refDX, y-refDY)) & 7;
3184 tpgrCX2 = ((tpgrCX2 << 1) |
3185 refBitmap->getPixel(x+1-refDX, y+1-refDY)) & 7;
3188 if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
3191 if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
3192 bitmap->clearPixel(x, y);
3194 } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
3195 bitmap->setPixel(x, y);
3202 cx = (cx0 << 7) | (bitmap->getPixel(x-1, y) << 6) |
3203 (refBitmap->getPixel(x-refDX, y-1-refDY) << 5) |
3206 cx = (cx0 << 11) | (bitmap->getPixel(x-1, y) << 10) |
3207 (cx2 << 8) | (cx3 << 5) | (cx4 << 2) |
3208 (bitmap->getPixel(x+atx[0], y+aty[0]) << 1) |
3209 refBitmap->getPixel(x+atx[1]-refDX, y+aty[1]-refDY);
3213 if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
3214 bitmap->setPixel(x, y);
3222void JBIG2Stream::readPageInfoSeg(Guint ) {
3223 Guint xRes, yRes, flags, striping;
3225 if (!readULong(&pageW) || !readULong(&pageH) ||
3226 !readULong(&xRes) || !readULong(&yRes) ||
3227 !readUByte(&flags) || !readUWord(&striping)) {
3230 pageDefPixel = (flags >> 2) & 1;
3231 defCombOp = (flags >> 3) & 3;
3234 if (pageH == 0xffffffff) {
3235 curPageH = striping & 0x7fff;
3239 pageBitmap = new JBIG2Bitmap(0, pageW, curPageH);
3243 pageBitmap->clearToOne();
3245 pageBitmap->clearToZero();
3251 error(getPos(), "Unexpected EOF in JBIG2 stream");
3254void JBIG2Stream::readEndOfStripeSeg(Guint length) {
3258 for (i = 0; i < length; ++i) {
3263void JBIG2Stream::readProfilesSeg(Guint length) {
3267 for (i = 0; i < length; ++i) {
3272void JBIG2Stream::readCodeTableSeg(Guint segNum, Guint ) {
3273 JBIG2HuffmanTable *huffTab;
3274 Guint flags, oob, prefixBits, rangeBits;
3275 int lowVal, highVal, val;
3276 Guint huffTabSize, i;
3278 if (!readUByte(&flags) || !readLong(&lowVal) || !readLong(&highVal)) {
3282 prefixBits = (flags >> 1) & 7;
3283 rangeBits = (flags >> 4) & 7;
3285 huffDecoder->reset();
3287 huffTab = (JBIG2HuffmanTable *)
3288 gmalloc(huffTabSize * sizeof(JBIG2HuffmanTable));
3291 while (val < highVal) {
3292 if (i == huffTabSize) {
3294 huffTab = (JBIG2HuffmanTable *)
3295 grealloc(huffTab, huffTabSize * sizeof(JBIG2HuffmanTable));
3297 huffTab[i].val = val;
3298 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3299 huffTab[i].rangeLen = huffDecoder->readBits(rangeBits);
3300 val += 1 << huffTab[i].rangeLen;
3303 if (i + oob + 3 > huffTabSize) {
3304 huffTabSize = i + oob + 3;
3305 huffTab = (JBIG2HuffmanTable *)
3306 grealloc(huffTab, huffTabSize * sizeof(JBIG2HuffmanTable));
3308 huffTab[i].val = lowVal - 1;
3309 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3310 huffTab[i].rangeLen = jbig2HuffmanLOW;
3312 huffTab[i].val = highVal;
3313 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3314 huffTab[i].rangeLen = 32;
3318 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3319 huffTab[i].rangeLen = jbig2HuffmanOOB;
3323 huffTab[i].prefixLen = 0;
3324 huffTab[i].rangeLen = jbig2HuffmanEOT;
3326 huffDecoder->buildTable(huffTab, i);
3329 segments->append( new JBIG2CodeTable(segNum, huffTab));
3334 error(getPos(), "Unexpected EOF in JBIG2 stream");
3337void JBIG2Stream::readExtensionSeg(Guint length) {
3341 for (i = 0; i < length; ++i) {
3346JBIG2Segment *JBIG2Stream::findSegment(Guint segNum) {
3350 for (i = 0; i < globalSegments->getLength(); ++i) {
3351 seg = (JBIG2Segment *)globalSegments->get(i);
3352 if (seg->getSegNum() == segNum) {
3356 for (i = 0; i < segments->getLength(); ++i) {
3357 seg = (JBIG2Segment *)segments->get(i);
3358 if (seg->getSegNum() == segNum) {
3365void JBIG2Stream::discardSegment(Guint segNum) {
3369 for (i = 0; i < globalSegments->getLength(); ++i) {
3370 seg = (JBIG2Segment *)globalSegments->get(i);
3371 if (seg->getSegNum() == segNum) {
3372 globalSegments->del(i);
3376 for (i = 0; i < segments->getLength(); ++i) {
3377 seg = (JBIG2Segment *)segments->get(i);
3378 if (seg->getSegNum() == segNum) {
3379 globalSegments->del(i);
3385void JBIG2Stream::resetGenericStats(Guint templ,
3386 JBIG2ArithmeticDecoderStats *prevStats) {
3389 size = contextSize[templ];
3390 if (prevStats && prevStats->getContextSize() == size) {
3391 if (genericRegionStats->getContextSize() == size) {
3392 genericRegionStats->copyFrom(prevStats);
3394 delete genericRegionStats;
3395 genericRegionStats = prevStats->copy();
3398 if (genericRegionStats->getContextSize() == size) {
3399 genericRegionStats->reset();
3401 delete genericRegionStats;
3402 genericRegionStats = new JBIG2ArithmeticDecoderStats(size);
3407void JBIG2Stream::resetRefinementStats(
3409 JBIG2ArithmeticDecoderStats *prevStats) {
3412 size = refContextSize[templ];
3413 if (prevStats && prevStats->getContextSize() == size) {
3414 if (refinementRegionStats->getContextSize() == size) {
3415 refinementRegionStats->copyFrom(prevStats);
3417 delete refinementRegionStats;
3418 refinementRegionStats = prevStats->copy();
3421 if (refinementRegionStats->getContextSize() == size) {
3422 refinementRegionStats->reset();
3424 delete refinementRegionStats;
3425 refinementRegionStats = new JBIG2ArithmeticDecoderStats(size);
3430void JBIG2Stream::resetIntStats( int symCodeLen) {
3439 iardxStats->reset();
3440 iardyStats->reset();
3441 iardwStats->reset();
3442 iardhStats->reset();
3444 if (iaidStats->getContextSize() == symCodeLen + 1) {
3448 iaidStats = new JBIG2ArithmeticDecoderStats(symCodeLen + 1);
3452GBool JBIG2Stream::readUByte(Guint *x) {
3455 if ((c0 = curStr->getChar()) == EOF) {
3462GBool JBIG2Stream::readByte( int *x) {
3465 if ((c0 = curStr->getChar()) == EOF) {
3475GBool JBIG2Stream::readUWord(Guint *x) {
3478 if ((c0 = curStr->getChar()) == EOF ||
3479 (c1 = curStr->getChar()) == EOF) {
3482 *x = (Guint)((c0 << 8) | c1);
3486GBool JBIG2Stream::readULong(Guint *x) {
3489 if ((c0 = curStr->getChar()) == EOF ||
3490 (c1 = curStr->getChar()) == EOF ||
3491 (c2 = curStr->getChar()) == EOF ||
3492 (c3 = curStr->getChar()) == EOF) {
3495 *x = (Guint)((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
3499GBool JBIG2Stream::readLong( int *x) {
3502 if ((c0 = curStr->getChar()) == EOF ||
3503 (c1 = curStr->getChar()) == EOF ||
3504 (c2 = curStr->getChar()) == EOF ||
3505 (c3 = curStr->getChar()) == EOF) {
3508 *x = ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
3510 *x |= -1 - 0xffffffff;
|