📄 jbig2stream.cc
字号:
huffAggInstTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); } } delete codeTables; // set up the Huffman decoder if (huff) { huffDecoder->reset(); // set up the arithmetic decoder } else { if (contextUsed && inputSymbolDict) { resetGenericStats(sdTemplate, inputSymbolDict->getGenericRegionStats()); } else { resetGenericStats(sdTemplate, NULL); } resetIntStats(symCodeLen); arithDecoder->start(); } // set up the arithmetic decoder for refinement/aggregation if (refAgg) { if (contextUsed && inputSymbolDict) { resetRefinementStats(sdrTemplate, inputSymbolDict->getRefinementRegionStats()); } else { resetRefinementStats(sdrTemplate, NULL); } } // allocate symbol widths storage symWidths = NULL; if (huff && !refAgg) { symWidths = (Guint *)gmallocn(numNewSyms, sizeof(Guint)); } symHeight = 0; i = 0; while (i < numNewSyms) { // read the height class delta height if (huff) { huffDecoder->decodeInt(&dh, huffDHTable); } else { arithDecoder->decodeInt(&dh, iadhStats); } if (dh < 0 && (Guint)-dh >= symHeight) { error(getPos(), "Bad delta-height value in JBIG2 symbol dictionary"); goto syntaxError; } symHeight += dh; symWidth = 0; totalWidth = 0; j = i; // read the symbols in this height class while (1) { // read the delta width if (huff) { if (!huffDecoder->decodeInt(&dw, huffDWTable)) { break; } } else { if (!arithDecoder->decodeInt(&dw, iadwStats)) { break; } } if (dw < 0 && (Guint)-dw >= symWidth) { error(getPos(), "Bad delta-height value in JBIG2 symbol dictionary"); goto syntaxError; } symWidth += dw; // using a collective bitmap, so don't read a bitmap here if (huff && !refAgg) { symWidths[i] = symWidth; totalWidth += symWidth; // refinement/aggregate coding } else if (refAgg) { if (huff) { if (!huffDecoder->decodeInt(&refAggNum, huffAggInstTable)) { break; } } else { if (!arithDecoder->decodeInt(&refAggNum, iaaiStats)) { break; } }#if 0 //~ This special case was added about a year before the final draft //~ of the JBIG2 spec was released. I have encountered some old //~ JBIG2 images that predate it. if (0) {#else if (refAggNum == 1) {#endif if (huff) { symID = huffDecoder->readBits(symCodeLen); huffDecoder->decodeInt(&refDX, huffTableO); huffDecoder->decodeInt(&refDY, huffTableO); huffDecoder->decodeInt(&bmSize, huffTableA); huffDecoder->reset(); arithDecoder->start(); } else { symID = arithDecoder->decodeIAID(symCodeLen, iaidStats); arithDecoder->decodeInt(&refDX, iardxStats); arithDecoder->decodeInt(&refDY, iardyStats); } refBitmap = bitmaps[symID]; bitmaps[numInputSyms + i] = readGenericRefinementRegion(symWidth, symHeight, sdrTemplate, gFalse, refBitmap, refDX, refDY, sdrATX, sdrATY); //~ do we need to use the bmSize value here (in Huffman mode)? } else { bitmaps[numInputSyms + i] = readTextRegion(huff, gTrue, symWidth, symHeight, refAggNum, 0, numInputSyms + i, NULL, symCodeLen, bitmaps, 0, 0, 0, 1, 0, huffTableF, huffTableH, huffTableK, huffTableO, huffTableO, huffTableO, huffTableO, huffTableA, sdrTemplate, sdrATX, sdrATY); } // non-ref/agg coding } else { bitmaps[numInputSyms + i] = readGenericBitmap(gFalse, symWidth, symHeight, sdTemplate, gFalse, gFalse, NULL, sdATX, sdATY, 0); } ++i; } // read the collective bitmap if (huff && !refAgg) { huffDecoder->decodeInt(&bmSize, huffBMSizeTable); huffDecoder->reset(); if (bmSize == 0) { collBitmap = new JBIG2Bitmap(0, totalWidth, symHeight); bmSize = symHeight * ((totalWidth + 7) >> 3); p = collBitmap->getDataPtr(); for (k = 0; k < (Guint)bmSize; ++k) { *p++ = curStr->getChar(); } } else { collBitmap = readGenericBitmap(gTrue, totalWidth, symHeight, 0, gFalse, gFalse, NULL, NULL, NULL, bmSize); } x = 0; for (; j < i; ++j) { bitmaps[numInputSyms + j] = collBitmap->getSlice(x, 0, symWidths[j], symHeight); x += symWidths[j]; } delete collBitmap; } } // create the symbol dict object symbolDict = new JBIG2SymbolDict(segNum, numExSyms); // exported symbol list i = j = 0; ex = gFalse; while (i < numInputSyms + numNewSyms) { if (huff) { huffDecoder->decodeInt(&run, huffTableA); } else { arithDecoder->decodeInt(&run, iaexStats); } if (ex) { for (cnt = 0; cnt < run; ++cnt) { symbolDict->setBitmap(j++, bitmaps[i++]->copy()); } } else { i += run; } ex = !ex; } for (i = 0; i < numNewSyms; ++i) { delete bitmaps[numInputSyms + i]; } gfree(bitmaps); if (symWidths) { gfree(symWidths); } // save the arithmetic decoder stats if (!huff && contextRetained) { symbolDict->setGenericRegionStats(genericRegionStats->copy()); if (refAgg) { symbolDict->setRefinementRegionStats(refinementRegionStats->copy()); } } // store the new symbol dict segments->append(symbolDict); return gTrue; syntaxError: for (i = 0; i < numNewSyms; ++i) { if (bitmaps[numInputSyms + i]) { delete bitmaps[numInputSyms + i]; } } gfree(bitmaps); if (symWidths) { gfree(symWidths); } return gFalse; eofError: error(getPos(), "Unexpected EOF in JBIG2 stream"); return gFalse;}void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm, GBool lossless, Guint length, Guint *refSegs, Guint nRefSegs) { JBIG2Bitmap *bitmap; JBIG2HuffmanTable runLengthTab[36]; JBIG2HuffmanTable *symCodeTab; JBIG2HuffmanTable *huffFSTable, *huffDSTable, *huffDTTable; JBIG2HuffmanTable *huffRDWTable, *huffRDHTable; JBIG2HuffmanTable *huffRDXTable, *huffRDYTable, *huffRSizeTable; JBIG2Segment *seg; GList *codeTables; JBIG2SymbolDict *symbolDict; JBIG2Bitmap **syms; Guint w, h, x, y, segInfoFlags, extCombOp; Guint flags, huff, refine, logStrips, refCorner, transposed; Guint combOp, defPixel, templ; int sOffset; Guint huffFlags, huffFS, huffDS, huffDT; Guint huffRDW, huffRDH, huffRDX, huffRDY, huffRSize; Guint numInstances, numSyms, symCodeLen; int atx[2], aty[2]; Guint i, k, kk; int j; // region segment info field if (!readULong(&w) || !readULong(&h) || !readULong(&x) || !readULong(&y) || !readUByte(&segInfoFlags)) { goto eofError; } extCombOp = segInfoFlags & 7; // rest of the text region header if (!readUWord(&flags)) { goto eofError; } huff = flags & 1; refine = (flags >> 1) & 1; logStrips = (flags >> 2) & 3; refCorner = (flags >> 4) & 3; transposed = (flags >> 6) & 1; combOp = (flags >> 7) & 3; defPixel = (flags >> 9) & 1; sOffset = (flags >> 10) & 0x1f; if (sOffset & 0x10) { sOffset |= -1 - 0x0f; } templ = (flags >> 15) & 1; huffFS = huffDS = huffDT = 0; // make gcc happy huffRDW = huffRDH = huffRDX = huffRDY = huffRSize = 0; // make gcc happy if (huff) { if (!readUWord(&huffFlags)) { goto eofError; } huffFS = huffFlags & 3; huffDS = (huffFlags >> 2) & 3; huffDT = (huffFlags >> 4) & 3; huffRDW = (huffFlags >> 6) & 3; huffRDH = (huffFlags >> 8) & 3; huffRDX = (huffFlags >> 10) & 3; huffRDY = (huffFlags >> 12) & 3; huffRSize = (huffFlags >> 14) & 1; } if (refine && templ == 0) { if (!readByte(&atx[0]) || !readByte(&aty[0]) || !readByte(&atx[1]) || !readByte(&aty[1])) { goto eofError; } } if (!readULong(&numInstances)) { goto eofError; } // get symbol dictionaries and tables codeTables = new GList(); numSyms = 0; for (i = 0; i < nRefSegs; ++i) { if ((seg = findSegment(refSegs[i]))) { if (seg->getType() == jbig2SegSymbolDict) { numSyms += ((JBIG2SymbolDict *)seg)->getSize(); } else if (seg->getType() == jbig2SegCodeTable) { codeTables->append(seg); } } else { error(getPos(), "Invalid segment reference in JBIG2 text region"); } } symCodeLen = 0; i = 1; while (i < numSyms) { ++symCodeLen; i <<= 1; } // get the symbol bitmaps syms = (JBIG2Bitmap **)gmallocn(numSyms, sizeof(JBIG2Bitmap *)); kk = 0; for (i = 0; i < nRefSegs; ++i) { if ((seg = findSegment(refSegs[i]))) { if (seg->getType() == jbig2SegSymbolDict) { symbolDict = (JBIG2SymbolDict *)seg; for (k = 0; k < symbolDict->getSize(); ++k) { syms[kk++] = symbolDict->getBitmap(k); } } } } // get the Huffman tables huffFSTable = huffDSTable = huffDTTable = NULL; // make gcc happy huffRDWTable = huffRDHTable = NULL; // make gcc happy huffRDXTable = huffRDYTable = huffRSizeTable = NULL; // make gcc happy i = 0; if (huff) { if (huffFS == 0) { huffFSTable = huffTableF; } else if (huffFS == 1) { huffFSTable = huffTableG; } else { huffFSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); } if (huffDS == 0) { huffDSTable = huffTableH; } else if (huffDS == 1) { huffDSTable = huffTableI; } else if (huffDS == 2) { huffDSTable = huffTableJ; } else { huffDSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); } if (huffDT == 0) { huffDTTable = huffTableK; } else if (huffDT == 1) { huffDTTable = huffTableL; } else if (huffDT == 2) { huffDTTable = huffTableM; } else { huffDTTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); } if (huffRDW == 0) { huffRDWTable = huffTableN; } else if (huffRDW == 1) { huffRDWTable = huffTableO; } else { huffRDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); } if (huffRDH == 0) { huffRDHTable = huffTableN; } else if (huffRDH == 1) { huffRDHTable = huffTableO; } else { huffRDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); } if (huffRDX == 0) { huffRDXTable = huffTableN; } else if (huffRDX == 1) { huffRDXTable = huffTableO; } else { huffRDXTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); } if (huffRDY == 0) { huffRDYTable = huffTableN; } else if (huffRDY == 1) { huffRDYTable = huffTableO; } else { huffRDYTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); } if (huffRSize == 0) { huffRSizeTable = huffTableA; } else { huffRSizeTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); } } delete codeTables; // symbol ID Huffman decoding table if (huff) { huffDecoder->reset(); for (i = 0; i < 32; ++i) { runLengthTab[i].val = i; runLengthTab[i].prefixLen = huffDecoder->readBits(4); runLengthTab[i].rangeLen = 0; } runLengthTab[32].val = 0x103; runLengthTab[32].prefixLen = huffDecoder->readBits(4); runLengthTab[32].rangeLen = 2; runLengthTab[33].val = 0x203; runLengthTab[33].prefixLen = huffDecoder->readBits(4); runLengthTab[33].rangeLen = 3; runLengthTab[34].val = 0x20b; runLengthTab[34].prefixLen = huffDecoder->readBits(4); runLengthTab[34].rangeLen = 7; runLengthTab[35].prefixLen = 0; runLengthTab[35].rangeLen = jbig2HuffmanEOT; huffDecoder->buildTable(runLengthTab, 35); symCodeTab = (JBIG2HuffmanTable *)gmallocn(numSyms + 1, sizeof(JBIG2HuffmanTable)); for (i = 0; i < numSyms; ++i) { symCodeTab[i].val = i; symCodeTab[i].rangeLen = 0; } i = 0; while (i < numSyms) { huffDecoder->decodeInt(&j, runLengthTab); if (j > 0x200) { for (j -= 0x200; j && i < numSyms; --j) { symCodeTab[i++].prefixLen = 0; } } else if (j > 0x100) { for (j -= 0x100; j && i < numSyms; --j) { symCodeTab[i].prefixLen = symCodeTab[i-1].prefixLen; ++i; } } else { symCodeTab[i++].prefixLen = j; } } symCodeTab[numSyms].prefixLen = 0; symCodeTab[numSyms].rangeLen = jbig2HuffmanEOT; huffDecoder->buildTable(symCodeTab, numSyms); huffDecoder->reset(); // set up the arithmetic decoder } else { symCodeTab = NULL; resetIntStats(symCodeLen); arithDecoder->start(); } if (refine) { resetRefinementStats(templ, NULL); } bitmap = readTextRegion(huff, refine, w, h, numInstances, logStrips, numSyms, symCodeTab, symCodeLen, syms, defPixel, combOp, transposed, refCorner, sOffset, huffFSTable, huffDSTable, huffDTTable, huffRDWTable, huffRDHTable, huffRDXTable, huffRDYTable, huffRSizeTable, templ, atx, aty); gfree(syms); // 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); } // clean up the Huffman decoder if (huff) { gfree(symCodeTab); } return; eofError: error(getPos(), "Unexpected EOF in JBIG2 stream");}JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine, int w, int h, Guint numInstances, Guint logStrips, int numSyms, JBIG2HuffmanTable *symCodeTab, Guint symCodeLen, JBIG2Bitmap **syms, Guint defPixel, Guint combOp, Guint transposed, Guint refCorner, int sOffset, JBIG2HuffmanTable *huffFSTable, JBIG2HuffmanTable *huffDSTable, JBIG2HuffmanTable *huffDTTable, JBIG2HuffmanTable *huffRDWTable, JBIG2HuffmanTable *huffRDHTable, JBIG2HuffmanTable *huffRDXTable, JBIG2HuffmanTable *huffRDYTable,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -