jbig2stream.cc
来自「source code: Covert TXT to PDF」· CC 代码 · 共 2,563 行 · 第 1/5 页
CC
2,563 行
{ 102, 6, 5, 0x037 }, { 134, 6, 6, 0x038 }, { 198, 6, 7, 0x039 }, { 326, 6, 8, 0x03a }, { 582, 6, 9, 0x03b }, { 1094, 6, 10, 0x03c }, { -21, 7, 4, 0x07a }, { -4, 7, 0, 0x07b }, { 4, 7, 0, 0x07c }, { 2118, 7, 11, 0x07d }, { -5, 8, 0, 0x0fc }, { 5, 8, 0, 0x0fd }, { -22, 8, jbig2HuffmanLOW, 0x0fe }, { 4166, 8, 32, 0x0ff }, { 0, 0, jbig2HuffmanEOT, 0 }};JBIG2HuffmanTable huffTableK[] = { { 1, 1, 0, 0x000 }, { 2, 2, 1, 0x002 }, { 4, 4, 0, 0x00c }, { 5, 4, 1, 0x00d }, { 7, 5, 1, 0x01c }, { 9, 5, 2, 0x01d }, { 13, 6, 2, 0x03c }, { 17, 7, 2, 0x07a }, { 21, 7, 3, 0x07b }, { 29, 7, 4, 0x07c }, { 45, 7, 5, 0x07d }, { 77, 7, 6, 0x07e }, { 141, 7, 32, 0x07f }, { 0, 0, jbig2HuffmanEOT, 0 }};JBIG2HuffmanTable huffTableL[] = { { 1, 1, 0, 0x000 }, { 2, 2, 0, 0x002 }, { 3, 3, 1, 0x006 }, { 5, 5, 0, 0x01c }, { 6, 5, 1, 0x01d }, { 8, 6, 1, 0x03c }, { 10, 7, 0, 0x07a }, { 11, 7, 1, 0x07b }, { 13, 7, 2, 0x07c }, { 17, 7, 3, 0x07d }, { 25, 7, 4, 0x07e }, { 41, 8, 5, 0x0fe }, { 73, 8, 32, 0x0ff }, { 0, 0, jbig2HuffmanEOT, 0 }};JBIG2HuffmanTable huffTableM[] = { { 1, 1, 0, 0x000 }, { 2, 3, 0, 0x004 }, { 7, 3, 3, 0x005 }, { 3, 4, 0, 0x00c }, { 5, 4, 1, 0x00d }, { 4, 5, 0, 0x01c }, { 15, 6, 1, 0x03a }, { 17, 6, 2, 0x03b }, { 21, 6, 3, 0x03c }, { 29, 6, 4, 0x03d }, { 45, 6, 5, 0x03e }, { 77, 7, 6, 0x07e }, { 141, 7, 32, 0x07f }, { 0, 0, jbig2HuffmanEOT, 0 }};JBIG2HuffmanTable huffTableN[] = { { 0, 1, 0, 0x000 }, { -2, 3, 0, 0x004 }, { -1, 3, 0, 0x005 }, { 1, 3, 0, 0x006 }, { 2, 3, 0, 0x007 }, { 0, 0, jbig2HuffmanEOT, 0 }};JBIG2HuffmanTable huffTableO[] = { { 0, 1, 0, 0x000 }, { -1, 3, 0, 0x004 }, { 1, 3, 0, 0x005 }, { -2, 4, 0, 0x00c }, { 2, 4, 0, 0x00d }, { -4, 5, 1, 0x01c }, { 3, 5, 1, 0x01d }, { -8, 6, 2, 0x03c }, { 5, 6, 2, 0x03d }, { -24, 7, 4, 0x07c }, { 9, 7, 4, 0x07d }, { -25, 7, jbig2HuffmanLOW, 0x07e }, { 25, 7, 32, 0x07f }, { 0, 0, jbig2HuffmanEOT, 0 }};//------------------------------------------------------------------------// JBIG2HuffmanDecoder//------------------------------------------------------------------------class JBIG2HuffmanDecoder {public: JBIG2HuffmanDecoder(); ~JBIG2HuffmanDecoder(); void setStream(Stream *strA) { str = strA; } void reset(); // Returns false for OOB, otherwise sets *<x> and returns true. GBool decodeInt(int *x, JBIG2HuffmanTable *table); Guint readBits(Guint n); Guint readBit(); // Sort the table by prefix length and assign prefix values. void buildTable(JBIG2HuffmanTable *table, Guint len);private: Stream *str; Guint buf; Guint bufLen;};JBIG2HuffmanDecoder::JBIG2HuffmanDecoder() { str = NULL; reset();}JBIG2HuffmanDecoder::~JBIG2HuffmanDecoder() {}void JBIG2HuffmanDecoder::reset() { buf = 0; bufLen = 0;}//~ optimize thisGBool JBIG2HuffmanDecoder::decodeInt(int *x, JBIG2HuffmanTable *table) { Guint i, len, prefix; i = 0; len = 0; prefix = 0; while (table[i].rangeLen != jbig2HuffmanEOT) { //~ if buildTable removes the entries with prefixLen=0, this is unneeded if (table[i].prefixLen > 0) { while (len < table[i].prefixLen) { prefix = (prefix << 1) | readBit(); ++len; } if (prefix == table[i].prefix) { if (table[i].rangeLen == jbig2HuffmanOOB) { return gFalse; } if (table[i].rangeLen == jbig2HuffmanLOW) { *x = table[i].val - readBits(32); } else if (table[i].rangeLen > 0) { *x = table[i].val + readBits(table[i].rangeLen); } else { *x = table[i].val; } return gTrue; } } ++i; } return gFalse;}Guint JBIG2HuffmanDecoder::readBits(Guint n) { Guint x, mask, nLeft; mask = (n == 32) ? 0xffffffff : ((1 << n) - 1); if (bufLen >= n) { x = (buf >> (bufLen - n)) & mask; bufLen -= n; } else { x = buf & ((1 << bufLen) - 1); nLeft = n - bufLen; bufLen = 0; while (nLeft >= 8) { x = (x << 8) | (str->getChar() & 0xff); nLeft -= 8; } if (nLeft > 0) { buf = str->getChar(); bufLen = 8 - nLeft; x = (x << nLeft) | ((buf >> bufLen) & ((1 << nLeft) - 1)); } } return x;}Guint JBIG2HuffmanDecoder::readBit() { if (bufLen == 0) { buf = str->getChar(); bufLen = 8; } --bufLen; return (buf >> bufLen) & 1;}static int cmpHuffmanTabEntries(const void *p1, const void *p2) { return ((JBIG2HuffmanTable *)p1)->prefixLen - ((JBIG2HuffmanTable *)p2)->prefixLen;}//~ should remove entries with prefixLen = 0void JBIG2HuffmanDecoder::buildTable(JBIG2HuffmanTable *table, Guint len) { Guint i, prefix; qsort(table, len, sizeof(JBIG2HuffmanTable), &cmpHuffmanTabEntries); for (i = 0; i < len && table[i].prefixLen == 0; ++i) { table[i].prefix = 0; } prefix = 0; table[i++].prefix = prefix++; for (; i < len; ++i) { prefix <<= table[i].prefixLen - table[i-1].prefixLen; table[i].prefix = prefix++; }}//------------------------------------------------------------------------// JBIG2MMRDecoder//------------------------------------------------------------------------class JBIG2MMRDecoder {public: JBIG2MMRDecoder(); ~JBIG2MMRDecoder(); void setStream(Stream *strA) { str = strA; } void reset(); int get2DCode(); int getBlackCode(); int getWhiteCode(); Guint get24Bits(); void skipTo(Guint length);private: Stream *str; Guint buf; Guint bufLen; Guint nBytesRead;};JBIG2MMRDecoder::JBIG2MMRDecoder() { str = NULL; reset();}JBIG2MMRDecoder::~JBIG2MMRDecoder() {}void JBIG2MMRDecoder::reset() { buf = 0; bufLen = 0; nBytesRead = 0;}int JBIG2MMRDecoder::get2DCode() { CCITTCode *p; if (bufLen == 0) { buf = str->getChar() & 0xff; bufLen = 8; ++nBytesRead; p = &twoDimTab1[(buf >> 1) & 0x7f]; } else if (bufLen == 8) { p = &twoDimTab1[(buf >> 1) & 0x7f]; } else { p = &twoDimTab1[(buf << (7 - bufLen)) & 0x7f]; if (p->bits < 0 || p->bits > (int)bufLen) { buf = (buf << 8) | (str->getChar() & 0xff); bufLen += 8; ++nBytesRead; p = &twoDimTab1[(buf >> (bufLen - 7)) & 0x7f]; } } if (p->bits < 0) { error(str->getPos(), "Bad two dim code in JBIG2 MMR stream"); return 0; } bufLen -= p->bits; return p->n;}int JBIG2MMRDecoder::getWhiteCode() { CCITTCode *p; Guint code; if (bufLen == 0) { buf = str->getChar() & 0xff; bufLen = 8; ++nBytesRead; } while (1) { if (bufLen > 7 && ((buf >> (bufLen - 7)) & 0x7f) == 0) { if (bufLen <= 12) { code = buf << (12 - bufLen); } else { code = buf >> (bufLen - 12); } p = &whiteTab1[code & 0x1f]; } else { if (bufLen <= 9) { code = buf << (9 - bufLen); } else { code = buf >> (bufLen - 9); } p = &whiteTab2[code & 0x1ff]; } if (p->bits > 0 && p->bits < (int)bufLen) { bufLen -= p->bits; return p->n; } if (bufLen >= 12) { break; } buf = (buf << 8) | (str->getChar() & 0xff); bufLen += 8; ++nBytesRead; } error(str->getPos(), "Bad white code in JBIG2 MMR stream"); // eat a bit and return a positive number so that the caller doesn't // go into an infinite loop --bufLen; return 1;}int JBIG2MMRDecoder::getBlackCode() { CCITTCode *p; Guint code; if (bufLen == 0) { buf = str->getChar() & 0xff; bufLen = 8; ++nBytesRead; } while (1) { if (bufLen > 6 && ((buf >> (bufLen - 6)) & 0x3f) == 0) { if (bufLen <= 13) { code = buf << (13 - bufLen); } else { code = buf >> (bufLen - 13); } p = &blackTab1[code & 0x7f]; } else if (bufLen > 4 && ((buf >> (bufLen - 4)) & 0x0f) == 0) { if (bufLen <= 12) { code = buf << (12 - bufLen); } else { code = buf >> (bufLen - 12); } p = &blackTab2[(code & 0xff) - 64]; } else { if (bufLen <= 6) { code = buf << (6 - bufLen); } else { code = buf >> (bufLen - 6); } p = &blackTab3[code & 0x3f]; } if (p->bits > 0 && p->bits < (int)bufLen) { bufLen -= p->bits; return p->n; } if (bufLen >= 13) { break; } buf = (buf << 8) | (str->getChar() & 0xff); bufLen += 8; ++nBytesRead; } error(str->getPos(), "Bad black code in JBIG2 MMR stream"); // eat a bit and return a positive number so that the caller doesn't // go into an infinite loop --bufLen; return 1;}Guint JBIG2MMRDecoder::get24Bits() { while (bufLen < 24) { buf = (buf << 8) | (str->getChar() & 0xff); bufLen += 8; ++nBytesRead; } return (buf >> (bufLen - 24)) & 0xffffff;}void JBIG2MMRDecoder::skipTo(Guint length) { while (nBytesRead < length) { str->getChar(); ++nBytesRead; }}//------------------------------------------------------------------------// JBIG2Segment//------------------------------------------------------------------------enum JBIG2SegmentType { jbig2SegBitmap, jbig2SegSymbolDict, jbig2SegPatternDict, jbig2SegCodeTable};class JBIG2Segment {public: JBIG2Segment(Guint segNumA) { segNum = segNumA; } virtual ~JBIG2Segment() {} void setSegNum(Guint segNumA) { segNum = segNumA; } Guint getSegNum() { return segNum; } virtual JBIG2SegmentType getType() = 0;private: Guint segNum;};//------------------------------------------------------------------------// JBIG2Bitmap//------------------------------------------------------------------------class JBIG2Bitmap: public JBIG2Segment {public: JBIG2Bitmap(Guint segNumA, int wA, int hA); virtual ~JBIG2Bitmap(); virtual JBIG2SegmentType getType() { return jbig2SegBitmap; } JBIG2Bitmap *copy() { return new JBIG2Bitmap(0, this); } JBIG2Bitmap *getSlice(Guint x, Guint y, Guint wA, Guint hA); void expand(int newH, Guint pixel); void clearToZero(); void clearToOne(); int getWidth() { return w; } int getHeight() { return h; } int getPixel(int x, int y) { return (x < 0 || x >= w || y < 0 || y >= h) ? 0 : (data[y * line + (x >> 3)] >> (7 - (x & 7))) & 1; } void setPixel(int x, int y) { data[y * line + (x >> 3)] |= 1 << (7 - (x & 7)); } void clearPixel(int x, int y) { data[y * line + (x >> 3)] &= 0x7f7f >> (x & 7); } void duplicateRow(int yDest, int ySrc); void combine(JBIG2Bitmap *bitmap, int x, int y, Guint combOp); Guchar *getDataPtr() { return data; } int getDataSize() { return h * line; }private: JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap); int w, h, line; Guchar *data;};JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, int wA, int hA): JBIG2Segment(segNumA){ w = wA; h = hA; line = (wA + 7) >> 3; data = (Guchar *)gmalloc(h * line);}JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap): JBIG2Segment(segNumA){ w = bitmap->w; h = bitmap->h; line = bitmap->line; data = (Guchar *)gmalloc(h * line); memcpy(data, bitmap->data, h * line);}JBIG2Bitmap::~JBIG2Bitmap() { gfree(data);}//~ optimize thisJBIG2Bitmap *JBIG2Bitmap::getSlice(Guint x, Guint y, Guint wA, Guint hA) { JBIG2Bitmap *slice; Guint xx, yy; slice = new JBIG2Bitmap(0, wA, hA); slice->clearToZero(); for (yy = 0; yy < hA; ++yy) { for (xx = 0; xx < wA; ++xx) { if (getPixel(x + xx, y + yy)) { slice->setPixel(xx, yy); } } } return slice;}void JBIG2Bitmap::expand(int newH, Guint pixel) { if (newH <= h) { return; } data = (Guchar *)grealloc(data, newH * line); if (pixel) { memset(data + h * line, 0xff, (newH - h) * line); } else { memset(data + h * line, 0x00, (newH - h) * line); } h = newH;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?