📄 jbig2stream.cc
字号:
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//------------------------------------------------------------------------struct JBIG2BitmapPtr { Guchar *p; int shift; int x;};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 getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr); int nextPixel(JBIG2BitmapPtr *ptr); 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; if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) { data = NULL; return; } // need to allocate one extra guard byte for use in combine() data = (Guchar *)gmalloc(h * line + 1); data[h * line] = 0;}JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap): JBIG2Segment(segNumA){ w = bitmap->w; h = bitmap->h; line = bitmap->line; if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) { data = NULL; return; } // need to allocate one extra guard byte for use in combine() data = (Guchar *)gmalloc(h * line + 1); memcpy(data, bitmap->data, h * line); data[h * line] = 0;}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 || line <= 0 || newH >= (INT_MAX - 1) / line) { return; } // need to allocate one extra guard byte for use in combine() data = (Guchar *)grealloc(data, newH * line + 1); if (pixel) { memset(data + h * line, 0xff, (newH - h) * line); } else { memset(data + h * line, 0x00, (newH - h) * line); } h = newH; data[h * line] = 0;}void JBIG2Bitmap::clearToZero() { memset(data, 0, h * line);}void JBIG2Bitmap::clearToOne() { memset(data, 0xff, h * line);}inline void JBIG2Bitmap::getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr) { if (y < 0 || y >= h || x >= w) { ptr->p = NULL; } else if (x < 0) { ptr->p = &data[y * line]; ptr->shift = 7; ptr->x = x; } else { ptr->p = &data[y * line + (x >> 3)]; ptr->shift = 7 - (x & 7); ptr->x = x; }}inline int JBIG2Bitmap::nextPixel(JBIG2BitmapPtr *ptr) { int pix; if (!ptr->p) { pix = 0; } else if (ptr->x < 0) { ++ptr->x; pix = 0; } else { pix = (*ptr->p >> ptr->shift) & 1; if (++ptr->x == w) { ptr->p = NULL; } else if (ptr->shift == 0) { ++ptr->p; ptr->shift = 7; } else { --ptr->shift; } } return pix;}void JBIG2Bitmap::duplicateRow(int yDest, int ySrc) { memcpy(data + yDest * line, data + ySrc * line, line);}void JBIG2Bitmap::combine(JBIG2Bitmap *bitmap, int x, int y, Guint combOp) { int x0, x1, y0, y1, xx, yy; Guchar *srcPtr, *destPtr; Guint src0, src1, src, dest, s1, s2, m1, m2, m3; GBool oneByte; if (y < 0) { y0 = -y; } else { y0 = 0; } if (y + bitmap->h > h) { y1 = h - y; } else { y1 = bitmap->h; } if (y0 >= y1) { return; } if (x >= 0) { x0 = x & ~7; } else { x0 = 0; } x1 = x + bitmap->w; if (x1 > w) { x1 = w; } if (x0 >= x1) { return; } s1 = x & 7; s2 = 8 - s1; m1 = 0xff >> (x1 & 7); m2 = 0xff << (((x1 & 7) == 0) ? 0 : 8 - (x1 & 7)); m3 = (0xff >> s1) & m2; oneByte = x0 == ((x1 - 1) & ~7); for (yy = y0; yy < y1; ++yy) { // one byte per line -- need to mask both left and right side if (oneByte) { if (x >= 0) { destPtr = data + (y + yy) * line + (x >> 3); srcPtr = bitmap->data + yy * bitmap->line; dest = *destPtr; src1 = *srcPtr; switch (combOp) { case 0: // or dest |= (src1 >> s1) & m2; break; case 1: // and dest &= ((0xff00 | src1) >> s1) | m1; break; case 2: // xor dest ^= (src1 >> s1) & m2; break; case 3: // xnor dest ^= ((src1 ^ 0xff) >> s1) & m2; break; case 4: // replace dest = (dest & ~m3) | ((src1 >> s1) & m3); break; } *destPtr = dest; } else { destPtr = data + (y + yy) * line; srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3); dest = *destPtr; src1 = *srcPtr; switch (combOp) { case 0: // or dest |= src1 & m2; break; case 1: // and dest &= src1 | m1; break; case 2: // xor dest ^= src1 & m2; break; case 3: // xnor dest ^= (src1 ^ 0xff) & m2; break; case 4: // replace dest = (src1 & m2) | (dest & m1); break; } *destPtr = dest; } // multiple bytes per line -- need to mask left side of left-most // byte and right side of right-most byte } else { // left-most byte if (x >= 0) { destPtr = data + (y + yy) * line + (x >> 3); srcPtr = bitmap->data + yy * bitmap->line; src1 = *srcPtr++; dest = *destPtr; switch (combOp) { case 0: // or dest |= src1 >> s1; break; case 1: // and dest &= (0xff00 | src1) >> s1; break; case 2: // xor dest ^= src1 >> s1; break; case 3: // xnor dest ^= (src1 ^ 0xff) >> s1; break; case 4: // replace dest = (dest & (0xff << s2)) | (src1 >> s1); break; } *destPtr++ = dest; xx = x0 + 8; } else { destPtr = data + (y + yy) * line; srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3); src1 = *srcPtr++; xx = x0; } // middle bytes for (; xx < x1 - 8; xx += 8) { dest = *destPtr; src0 = src1; src1 = *srcPtr++; src = (((src0 << 8) | src1) >> s1) & 0xff; switch (combOp) { case 0: // or dest |= src; break; case 1: // and dest &= src; break; case 2: // xor dest ^= src; break; case 3: // xnor dest ^= src ^ 0xff; break; case 4: // replace dest = src; break; } *destPtr++ = dest; } // right-most byte // note: this last byte (src1) may not actually be used, depending // on the values of s1, m1, and m2 - and in fact, it may be off // the edge of the source bitmap, which means we need to allocate // one extra guard byte at the end of each bitmap dest = *destPtr; src0 = src1; src1 = *srcPtr++; src = (((src0 << 8) | src1) >> s1) & 0xff; switch (combOp) { case 0: // or dest |= src & m2; break; case 1: // and dest &= src | m1; break; case 2: // xor dest ^= src & m2; break; case 3: // xnor dest ^= (src ^ 0xff) & m2; break; case 4: // replace dest = (src & m2) | (dest & m1); break; } *destPtr = dest; } }}//------------------------------------------------------------------------// JBIG2SymbolDict//------------------------------------------------------------------------class JBIG2SymbolDict: public JBIG2Segment {public: JBIG2SymbolDict(Guint segNumA, Guint sizeA); virtual ~JBIG2SymbolDict(); virtual JBIG2SegmentType getType() { return jbig2SegSymbolDict; } Guint getSize() { return size; } void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; } JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; } void setGenericRegionStats(JArithmeticDecoderStats *stats) { genericRegionStats = stats; } void setRefinementRegionStats(JArithmeticDecoderStats *stats) { refinementRegionStats = stats; } JArithmeticDecoderStats *getGenericRegionStats() { return genericRegionStats; } JArithmeticDecoderStats *getRefinementRegionStats() { return refinementRegionStats; }private: Guint size; JBIG2Bitmap **bitmaps; JArithmeticDecoderStats *genericRegionStats; JArithmeticDecoderStats *refinementRegionStats;};JBIG2SymbolDict::JBIG2SymbolDict(Guint segNumA, Guint sizeA): JBIG2Segment(segNumA){ size = sizeA; bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *)); genericRegionStats = NULL; refinementRegionStats = NULL;}JBIG2SymbolDict::~JBIG2SymbolDict() {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -