📄 jbig2stream.cc
字号:
JBIG2HuffmanTable *huffRSizeTable, Guint templ, int *atx, int *aty) { JBIG2Bitmap *bitmap; JBIG2Bitmap *symbolBitmap; Guint strips; int t, dt, tt, s, ds, sFirst, j; int rdw, rdh, rdx, rdy, ri, refDX, refDY, bmSize; Guint symID, inst, bw, bh; strips = 1 << logStrips; // allocate the bitmap bitmap = new JBIG2Bitmap(0, w, h); if (defPixel) { bitmap->clearToOne(); } else { bitmap->clearToZero(); } // decode initial T value if (huff) { huffDecoder->decodeInt(&t, huffDTTable); } else { arithDecoder->decodeInt(&t, iadtStats); } t *= -(int)strips; inst = 0; sFirst = 0; while (inst < numInstances) { // decode delta-T if (huff) { huffDecoder->decodeInt(&dt, huffDTTable); } else { arithDecoder->decodeInt(&dt, iadtStats); } t += dt * strips; // first S value if (huff) { huffDecoder->decodeInt(&ds, huffFSTable); } else { arithDecoder->decodeInt(&ds, iafsStats); } sFirst += ds; s = sFirst; // read the instances while (1) { // T value if (strips == 1) { dt = 0; } else if (huff) { dt = huffDecoder->readBits(logStrips); } else { arithDecoder->decodeInt(&dt, iaitStats); } tt = t + dt; // symbol ID if (huff) { if (symCodeTab) { huffDecoder->decodeInt(&j, symCodeTab); symID = (Guint)j; } else { symID = huffDecoder->readBits(symCodeLen); } } else { symID = arithDecoder->decodeIAID(symCodeLen, iaidStats); } if (symID >= (Guint)numSyms) { error(getPos(), "Invalid symbol number in JBIG2 text region"); } else { // get the symbol bitmap symbolBitmap = NULL; if (refine) { if (huff) { ri = (int)huffDecoder->readBit(); } else { arithDecoder->decodeInt(&ri, iariStats); } } else { ri = 0; } if (ri) { if (huff) { huffDecoder->decodeInt(&rdw, huffRDWTable); huffDecoder->decodeInt(&rdh, huffRDHTable); huffDecoder->decodeInt(&rdx, huffRDXTable); huffDecoder->decodeInt(&rdy, huffRDYTable); huffDecoder->decodeInt(&bmSize, huffRSizeTable); huffDecoder->reset(); arithDecoder->start(); } else { arithDecoder->decodeInt(&rdw, iardwStats); arithDecoder->decodeInt(&rdh, iardhStats); arithDecoder->decodeInt(&rdx, iardxStats); arithDecoder->decodeInt(&rdy, iardyStats); } refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx; refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy; symbolBitmap = readGenericRefinementRegion(rdw + syms[symID]->getWidth(), rdh + syms[symID]->getHeight(), templ, gFalse, syms[symID], refDX, refDY, atx, aty); //~ do we need to use the bmSize value here (in Huffman mode)? } else { symbolBitmap = syms[symID]; } // combine the symbol bitmap into the region bitmap //~ something is wrong here - refCorner shouldn't degenerate into //~ two cases bw = symbolBitmap->getWidth() - 1; bh = symbolBitmap->getHeight() - 1; if (transposed) { switch (refCorner) { case 0: // bottom left bitmap->combine(symbolBitmap, tt, s, combOp); break; case 1: // top left bitmap->combine(symbolBitmap, tt, s, combOp); break; case 2: // bottom right bitmap->combine(symbolBitmap, tt - bw, s, combOp); break; case 3: // top right bitmap->combine(symbolBitmap, tt - bw, s, combOp); break; } s += bh; } else { switch (refCorner) { case 0: // bottom left bitmap->combine(symbolBitmap, s, tt - bh, combOp); break; case 1: // top left bitmap->combine(symbolBitmap, s, tt, combOp); break; case 2: // bottom right bitmap->combine(symbolBitmap, s, tt - bh, combOp); break; case 3: // top right bitmap->combine(symbolBitmap, s, tt, combOp); break; } s += bw; } if (ri) { delete symbolBitmap; } } // next instance ++inst; // next S value if (huff) { if (!huffDecoder->decodeInt(&ds, huffDSTable)) { break; } } else { if (!arithDecoder->decodeInt(&ds, iadsStats)) { break; } } s += sOffset + ds; } } return bitmap;}void JBIG2Stream::readPatternDictSeg(Guint segNum, Guint length) { JBIG2PatternDict *patternDict; JBIG2Bitmap *bitmap; Guint flags, patternW, patternH, grayMax, templ, mmr; int atx[4], aty[4]; Guint i, x; // halftone dictionary flags, pattern width and height, max gray value if (!readUByte(&flags) || !readUByte(&patternW) || !readUByte(&patternH) || !readULong(&grayMax)) { goto eofError; } templ = (flags >> 1) & 3; mmr = flags & 1; // set up the arithmetic decoder if (!mmr) { resetGenericStats(templ, NULL); arithDecoder->start(); } // read the bitmap atx[0] = -(int)patternW; aty[0] = 0; atx[1] = -3; aty[1] = -1; atx[2] = 2; aty[2] = -2; atx[3] = -2; aty[3] = -2; bitmap = readGenericBitmap(mmr, (grayMax + 1) * patternW, patternH, templ, gFalse, gFalse, NULL, atx, aty, length - 7); // create the pattern dict object patternDict = new JBIG2PatternDict(segNum, grayMax + 1); // split up the bitmap x = 0; for (i = 0; i <= grayMax; ++i) { patternDict->setBitmap(i, bitmap->getSlice(x, 0, patternW, patternH)); x += patternW; } // free memory delete bitmap; // store the new pattern dict segments->append(patternDict); return; eofError: error(getPos(), "Unexpected EOF in JBIG2 stream");}void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm, GBool lossless, Guint length, Guint *refSegs, Guint nRefSegs) { JBIG2Bitmap *bitmap; JBIG2Segment *seg; JBIG2PatternDict *patternDict; JBIG2Bitmap *skipBitmap; Guint *grayImg; JBIG2Bitmap *grayBitmap; JBIG2Bitmap *patternBitmap; Guint w, h, x, y, segInfoFlags, extCombOp; Guint flags, mmr, templ, enableSkip, combOp; Guint gridW, gridH, stepX, stepY, patW, patH; int atx[4], aty[4]; int gridX, gridY, xx, yy, bit, j; Guint bpp, m, n, i; // region segment info field if (!readULong(&w) || !readULong(&h) || !readULong(&x) || !readULong(&y) || !readUByte(&segInfoFlags)) { goto eofError; } extCombOp = segInfoFlags & 7; // rest of the halftone region header if (!readUByte(&flags)) { goto eofError; } mmr = flags & 1; templ = (flags >> 1) & 3; enableSkip = (flags >> 3) & 1; combOp = (flags >> 4) & 7; if (!readULong(&gridW) || !readULong(&gridH) || !readLong(&gridX) || !readLong(&gridY) || !readUWord(&stepX) || !readUWord(&stepY)) { goto eofError; } if (w == 0 || h == 0 || w >= INT_MAX / h) { error(getPos(), "Bad bitmap size in JBIG2 halftone segment"); return; } if (gridH == 0 || gridW >= INT_MAX / gridH) { error(getPos(), "Bad grid size in JBIG2 halftone segment"); return; } // get pattern dictionary if (nRefSegs != 1) { error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment"); return; } seg = findSegment(refSegs[0]); if (seg->getType() != jbig2SegPatternDict) { error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment"); return; } patternDict = (JBIG2PatternDict *)seg; bpp = 0; i = 1; while (i < patternDict->getSize()) { ++bpp; i <<= 1; } patW = patternDict->getBitmap(0)->getWidth(); patH = patternDict->getBitmap(0)->getHeight(); // set up the arithmetic decoder if (!mmr) { resetGenericStats(templ, NULL); arithDecoder->start(); } // allocate the bitmap bitmap = new JBIG2Bitmap(segNum, w, h); if (flags & 0x80) { // HDEFPIXEL bitmap->clearToOne(); } else { bitmap->clearToZero(); } // compute the skip bitmap skipBitmap = NULL; if (enableSkip) { skipBitmap = new JBIG2Bitmap(0, gridW, gridH); skipBitmap->clearToZero(); for (m = 0; m < gridH; ++m) { for (n = 0; n < gridW; ++n) { xx = gridX + m * stepY + n * stepX; yy = gridY + m * stepX - n * stepY; if (((xx + (int)patW) >> 8) <= 0 || (xx >> 8) >= (int)w || ((yy + (int)patH) >> 8) <= 0 || (yy >> 8) >= (int)h) { skipBitmap->setPixel(n, m); } } } } // read the gray-scale image grayImg = (Guint *)gmallocn(gridW * gridH, sizeof(Guint)); memset(grayImg, 0, gridW * gridH * sizeof(Guint)); atx[0] = templ <= 1 ? 3 : 2; aty[0] = -1; atx[1] = -3; aty[1] = -1; atx[2] = 2; aty[2] = -2; atx[3] = -2; aty[3] = -2; for (j = bpp - 1; j >= 0; --j) { grayBitmap = readGenericBitmap(mmr, gridW, gridH, templ, gFalse, enableSkip, skipBitmap, atx, aty, -1); i = 0; for (m = 0; m < gridH; ++m) { for (n = 0; n < gridW; ++n) { bit = grayBitmap->getPixel(n, m) ^ (grayImg[i] & 1); grayImg[i] = (grayImg[i] << 1) | bit; ++i; } } delete grayBitmap; } // decode the image i = 0; for (m = 0; m < gridH; ++m) { xx = gridX + m * stepY; yy = gridY + m * stepX; for (n = 0; n < gridW; ++n) { if (!(enableSkip && skipBitmap->getPixel(n, m))) { patternBitmap = patternDict->getBitmap(grayImg[i]); bitmap->combine(patternBitmap, xx >> 8, yy >> 8, combOp); } xx += stepX; yy -= stepY; ++i; } } gfree(grayImg); if (skipBitmap) { delete skipBitmap; } // combine the region bitmap into the page bitmap if (imm) { if (pageH == 0xffffffff && y + h > curPageH) { pageBitmap->expand(y + h, pageDefPixel); } pageBitmap->combine(bitmap, x, y, extCombOp); delete bitmap; // store the region bitmap } else { segments->append(bitmap); } return; eofError: error(getPos(), "Unexpected EOF in JBIG2 stream");}void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm, GBool lossless, Guint length) { JBIG2Bitmap *bitmap; Guint w, h, x, y, segInfoFlags, extCombOp; Guint flags, mmr, templ, tpgdOn; int atx[4], aty[4]; // region segment info field if (!readULong(&w) || !readULong(&h) || !readULong(&x) || !readULong(&y) || !readUByte(&segInfoFlags)) { goto eofError; } extCombOp = segInfoFlags & 7; // rest of the generic region segment header if (!readUByte(&flags)) { goto eofError; } mmr = flags & 1; templ = (flags >> 1) & 3; tpgdOn = (flags >> 3) & 1; // AT flags if (!mmr) { if (templ == 0) { if (!readByte(&atx[0]) || !readByte(&aty[0]) || !readByte(&atx[1]) || !readByte(&aty[1]) || !readByte(&atx[2]) || !readByte(&aty[2]) || !readByte(&atx[3]) || !readByte(&aty[3])) { goto eofError; } } else { if (!readByte(&atx[0]) || !readByte(&aty[0])) { goto eofError; } } } // set up the arithmetic decoder if (!mmr) { resetGenericStats(templ, NULL); arithDecoder->start(); } // read the bitmap bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse, NULL, atx, aty, mmr ? 0 : length - 18); // combine the region bitmap into the page bitmap if (imm) { if (pageH == 0xffffffff && y + h > curPageH) { pageBitmap->expand(y + h, pageDefPixel); } pageBitmap->combine(bitmap, x, y, extCombOp); delete bitmap; // store the region bitmap } else { bitmap->setSegNum(segNum); segments->append(bitmap); } return; eofError: error(getPos(), "Unexpected EOF in JBIG2 stream");}JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, int templ, GBool tpgdOn, GBool useSkip, JBIG2Bitmap *skip, int *atx, int *aty, int mmrDataLength) { JBIG2Bitmap *bitmap; GBool ltp; Guint ltpCX, cx, cx0, cx1, cx2; JBIG2BitmapPtr cxPtr0, cxPtr1; JBIG2BitmapPtr atPtr0, atPtr1, atPtr2, atPtr3; int *refLine, *codingLine; int code1, code2, code3; int x, y, a0, pix, i, refI, codingI; bitmap = new JBIG2Bitmap(0, w, h); bitmap->clearToZero(); //----- MMR decode if (mmr) { mmrDecoder->reset(); refLine = (int *)gmallocn(w + 2, sizeof(int)); codingLine = (int *)gmallocn(w + 2, sizeof(int)); codingLine[0] = codingLine[1] = w; for (y = 0; y < h; ++y) { // copy coding line to ref line for (i = 0; codingLine[i] < w; ++i) { refLine[i] = codingLine[i]; } refLine[i] = refLine[i + 1] = w; // decode a line refI = 0; // b1 = refLine[refI] codingI = 0; // a1 = codingLine[codingI] a0 = 0; do { co
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -