public void resetGenericStats(int template, ArithmeticDecoderStats previousStats) { int size = contextSize[template]; if (previousStats != null && previousStats.getContextSize() == size) { if (genericRegionStats.getContextSize() == size) { genericRegionStats.overwrite(previousStats); } else { genericRegionStats = previousStats.copy(); } } else { if (genericRegionStats.getContextSize() == size) { genericRegionStats.reset(); } else { genericRegionStats = new ArithmeticDecoderStats(1 << size); } } }
public void resetRefinementStats(int template, ArithmeticDecoderStats previousStats) { int size = referredToContextSize[template]; if (previousStats != null && previousStats.getContextSize() == size) { if (refinementRegionStats.getContextSize() == size) { refinementRegionStats.overwrite(previousStats); } else { refinementRegionStats = previousStats.copy(); } } else { if (refinementRegionStats.getContextSize() == size) { refinementRegionStats.reset(); } else { refinementRegionStats = new ArithmeticDecoderStats(1 << size); } } }
public void resetIntStats(int symbolCodeLength) { iadhStats.reset(); iadwStats.reset(); iaexStats.reset(); iaaiStats.reset(); iadtStats.reset(); iaitStats.reset(); iafsStats.reset(); iadsStats.reset(); iardxStats.reset(); iardyStats.reset(); iardwStats.reset(); iardhStats.reset(); iariStats.reset(); if (iaidStats.getContextSize() == 1 << (symbolCodeLength + 1)) { iaidStats.reset(); } else { iaidStats = new ArithmeticDecoderStats(1 << (symbolCodeLength + 1)); } }
public ArithmeticDecoderStats copy() { ArithmeticDecoderStats stats = new ArithmeticDecoderStats(contextSize); Array.Copy(codingContextTable, 0, stats.codingContextTable, 0, contextSize); return(stats); }
public long decodeIAID(long codeLen, ArithmeticDecoderStats stats) { previous = 1; for (long i = 0; i < codeLen; i++) { int bit = decodeBit(previous, stats); previous = BinaryOperation.bit32ShiftL(previous, 1) | bit; } return(previous - (1 << (int)codeLen)); }
private int decodeIntBit(ArithmeticDecoderStats stats) { int bit; bit = decodeBit(previous, stats); if (previous < 0x100) { previous = BinaryOperation.bit32ShiftL(previous, 1) | bit; } else { previous = (((BinaryOperation.bit32ShiftL(previous, 1)) | bit) & 0x1ff) | 0x100; } return(bit); }
public ArithmeticDecoder(Big2StreamReader reader) { this.reader = reader; genericRegionStats = new ArithmeticDecoderStats(1 << 1); refinementRegionStats = new ArithmeticDecoderStats(1 << 1); iadhStats = new ArithmeticDecoderStats(1 << 9); iadwStats = new ArithmeticDecoderStats(1 << 9); iaexStats = new ArithmeticDecoderStats(1 << 9); iaaiStats = new ArithmeticDecoderStats(1 << 9); iadtStats = new ArithmeticDecoderStats(1 << 9); iaitStats = new ArithmeticDecoderStats(1 << 9); iafsStats = new ArithmeticDecoderStats(1 << 9); iadsStats = new ArithmeticDecoderStats(1 << 9); iardxStats = new ArithmeticDecoderStats(1 << 9); iardyStats = new ArithmeticDecoderStats(1 << 9); iardwStats = new ArithmeticDecoderStats(1 << 9); iardhStats = new ArithmeticDecoderStats(1 << 9); iariStats = new ArithmeticDecoderStats(1 << 9); iaidStats = new ArithmeticDecoderStats(1 << 1); }
private void setRefinementRegionStats(ArithmeticDecoderStats refinementRegionStats) { this.refinementRegionStats = refinementRegionStats; }
private void setGenericRegionStats(ArithmeticDecoderStats genericRegionStats) { this.genericRegionStats = genericRegionStats; }
public override void readSegment() { if (JBIG2StreamDecoder.debug) { Console.WriteLine("==== Read Segment Symbol Dictionary ===="); } /** read symbol dictionary flags */ readSymbolDictionaryFlags(); //List codeTables = new ArrayList(); int numberOfInputSymbols = 0; int noOfReferredToSegments = segmentHeader.getReferredToSegmentCount(); int[] referredToSegments = segmentHeader.getReferredToSegments(); long i = 0; for (i = 0; i < noOfReferredToSegments; i++) { Segment seg = decoder.findSegment(referredToSegments[i]); int type = seg.getSegmentHeader().getSegmentType(); if (type == Segment.SYMBOL_DICTIONARY) { numberOfInputSymbols += ((SymbolDictionarySegment)seg).noOfExportedSymbols; } else if (type == Segment.TABLES) { //codeTables.add(seg); } } int symbolCodeLength = 0; i = 1; while (i < numberOfInputSymbols + noOfNewSymbols) { symbolCodeLength++; i <<= 1; } JBIG2Bitmap[] bitmaps = new JBIG2Bitmap[numberOfInputSymbols + noOfNewSymbols]; long j, k = 0; SymbolDictionarySegment inputSymbolDictionary = null; for (i = 0; i < noOfReferredToSegments; i++) { Segment seg = decoder.findSegment(referredToSegments[i]); if (seg.getSegmentHeader().getSegmentType() == Segment.SYMBOL_DICTIONARY) { inputSymbolDictionary = (SymbolDictionarySegment)seg; for (j = 0; j < inputSymbolDictionary.noOfExportedSymbols; j++) { bitmaps[k++] = inputSymbolDictionary.bitmaps[j]; } } } long[,] huffmanDHTable = null; long[,] huffmanDWTable = null; long[,] huffmanBMSizeTable = null; long[,] huffmanAggInstTable = null; bool sdHuffman = symbolDictionaryFlags.getFlagValue(SymbolDictionaryFlags.SD_HUFF) != 0; int sdHuffmanDifferenceHeight = symbolDictionaryFlags.getFlagValue(SymbolDictionaryFlags.SD_HUFF_DH); int sdHuffmanDiferrenceWidth = symbolDictionaryFlags.getFlagValue(SymbolDictionaryFlags.SD_HUFF_DW); int sdHuffBitmapSize = symbolDictionaryFlags.getFlagValue(SymbolDictionaryFlags.SD_HUFF_BM_SIZE); int sdHuffAggregationInstances = symbolDictionaryFlags.getFlagValue(SymbolDictionaryFlags.SD_HUFF_AGG_INST); i = 0; if (sdHuffman) { if (sdHuffmanDifferenceHeight == 0) { huffmanDHTable = HuffmanDecoder.huffmanTableD; } else if (sdHuffmanDifferenceHeight == 1) { huffmanDHTable = HuffmanDecoder.huffmanTableE; } else { //huffmanDHTable = ((JBIG2CodeTable) codeTables.get(i++)).getHuffTable(); } if (sdHuffmanDiferrenceWidth == 0) { huffmanDWTable = HuffmanDecoder.huffmanTableB; } else if (sdHuffmanDiferrenceWidth == 1) { huffmanDWTable = HuffmanDecoder.huffmanTableC; } else { //huffmanDWTable = ((JBIG2CodeTable) codeTables.get(i++)).getHuffTable(); } if (sdHuffBitmapSize == 0) { huffmanBMSizeTable = HuffmanDecoder.huffmanTableA; } else { //huffmanBMSizeTable = ((JBIG2CodeTable) codeTables.get(i++)).getHuffTable(); } if (sdHuffAggregationInstances == 0) { huffmanAggInstTable = HuffmanDecoder.huffmanTableA; } else { //huffmanAggInstTable = ((JBIG2CodeTable) codeTables.get(i++)).getHuffTable(); } } int contextUsed = symbolDictionaryFlags.getFlagValue(SymbolDictionaryFlags.BITMAP_CC_USED); int sdTemplate = symbolDictionaryFlags.getFlagValue(SymbolDictionaryFlags.SD_TEMPLATE); if (!sdHuffman) { if (contextUsed != 0 && inputSymbolDictionary != null) { arithmeticDecoder.resetGenericStats(sdTemplate, inputSymbolDictionary.genericRegionStats); } else { arithmeticDecoder.resetGenericStats(sdTemplate, null); } arithmeticDecoder.resetIntStats(symbolCodeLength); arithmeticDecoder.start(); } int sdRefinementAggregate = symbolDictionaryFlags.getFlagValue(SymbolDictionaryFlags.SD_REF_AGG); int sdRefinementTemplate = symbolDictionaryFlags.getFlagValue(SymbolDictionaryFlags.SD_R_TEMPLATE); if (sdRefinementAggregate != 0) { if (contextUsed != 0 && inputSymbolDictionary != null) { arithmeticDecoder.resetRefinementStats(sdRefinementTemplate, inputSymbolDictionary.refinementRegionStats); } else { arithmeticDecoder.resetRefinementStats(sdRefinementTemplate, null); } } long[] deltaWidths = new long[noOfNewSymbols]; long deltaHeight = 0; i = 0; while (i < noOfNewSymbols) { long instanceDeltaHeight = 0; if (sdHuffman) { instanceDeltaHeight = huffmanDecoder.decodeInt(huffmanDHTable).intResult(); } else { instanceDeltaHeight = arithmeticDecoder.decodeInt(arithmeticDecoder.iadhStats).intResult(); } if (instanceDeltaHeight < 0 && -instanceDeltaHeight >= deltaHeight) { if (JBIG2StreamDecoder.debug) { Console.WriteLine("Bad delta-height value in JBIG2 symbol dictionary"); } } deltaHeight += instanceDeltaHeight; long symbolWidth = 0; long totalWidth = 0; j = i; while (true) { long deltaWidth = 0; DecodeIntResult decodeIntResult; if (sdHuffman) { decodeIntResult = huffmanDecoder.decodeInt(huffmanDWTable); } else { decodeIntResult = arithmeticDecoder.decodeInt(arithmeticDecoder.iadwStats); } if (!decodeIntResult.booleanResult()) { break; } deltaWidth = decodeIntResult.intResult(); if (deltaWidth < 0 && -deltaWidth >= symbolWidth) { if (JBIG2StreamDecoder.debug) { Console.WriteLine("Bad delta-width value in JBIG2 symbol dictionary"); } } symbolWidth += deltaWidth; if (sdHuffman && sdRefinementAggregate == 0) { deltaWidths[i] = symbolWidth; totalWidth += symbolWidth; } else if (sdRefinementAggregate == 1) { long refAggNum = 0; if (sdHuffman) { refAggNum = huffmanDecoder.decodeInt(huffmanAggInstTable).intResult(); } else { refAggNum = arithmeticDecoder.decodeInt(arithmeticDecoder.iaaiStats).intResult(); } if (refAggNum == 1) { long symbolID = 0, referenceDX = 0, referenceDY = 0; if (sdHuffman) { symbolID = decoder.readBits(symbolCodeLength); referenceDX = huffmanDecoder.decodeInt(HuffmanDecoder.huffmanTableO).intResult(); referenceDY = huffmanDecoder.decodeInt(HuffmanDecoder.huffmanTableO).intResult(); decoder.consumeRemainingBits(); arithmeticDecoder.start(); } else { symbolID = (int)arithmeticDecoder.decodeIAID(symbolCodeLength, arithmeticDecoder.iaidStats); referenceDX = arithmeticDecoder.decodeInt(arithmeticDecoder.iardxStats).intResult(); referenceDY = arithmeticDecoder.decodeInt(arithmeticDecoder.iardyStats).intResult(); } JBIG2Bitmap referredToBitmap = bitmaps[symbolID]; JBIG2Bitmap bitmap = new JBIG2Bitmap(symbolWidth, deltaHeight, arithmeticDecoder, huffmanDecoder, mmrDecoder); bitmap.readGenericRefinementRegion(sdRefinementTemplate, false, referredToBitmap, referenceDX, referenceDY, symbolDictionaryRAdaptiveTemplateX, symbolDictionaryRAdaptiveTemplateY); bitmaps[numberOfInputSymbols + i] = bitmap; } else { JBIG2Bitmap bitmap = new JBIG2Bitmap(symbolWidth, deltaHeight, arithmeticDecoder, huffmanDecoder, mmrDecoder); bitmap.readTextRegion(sdHuffman, true, refAggNum, 0, numberOfInputSymbols + i, null, symbolCodeLength, bitmaps, 0, 0, false, 1, 0, HuffmanDecoder.huffmanTableF, HuffmanDecoder.huffmanTableH, HuffmanDecoder.huffmanTableK, HuffmanDecoder.huffmanTableO, HuffmanDecoder.huffmanTableO, HuffmanDecoder.huffmanTableO, HuffmanDecoder.huffmanTableO, HuffmanDecoder.huffmanTableA, sdRefinementTemplate, symbolDictionaryRAdaptiveTemplateX, symbolDictionaryRAdaptiveTemplateY, decoder); bitmaps[numberOfInputSymbols + i] = bitmap; } } else { JBIG2Bitmap bitmap = new JBIG2Bitmap(symbolWidth, deltaHeight, arithmeticDecoder, huffmanDecoder, mmrDecoder); bitmap.readBitmap(false, sdTemplate, false, false, null, symbolDictionaryAdaptiveTemplateX, symbolDictionaryAdaptiveTemplateY, 0); bitmaps[numberOfInputSymbols + i] = bitmap; } i++; } if (sdHuffman && sdRefinementAggregate == 0) { long bmSize = huffmanDecoder.decodeInt(huffmanBMSizeTable).intResult(); decoder.consumeRemainingBits(); JBIG2Bitmap collectiveBitmap = new JBIG2Bitmap(totalWidth, deltaHeight, arithmeticDecoder, huffmanDecoder, mmrDecoder); if (bmSize == 0) { long padding = totalWidth % 8; long bytesPerRow = (int)Math.Ceiling(totalWidth / 8d); //short[] bitmap = new short[totalWidth]; //decoder.readbyte(bitmap); long size = deltaHeight * ((totalWidth + 7) >> 3); short[] bitmap = new short[size]; decoder.readbyte(bitmap); short[][] logicalMap = new short[deltaHeight][]; int count = 0; for (int row = 0; row < deltaHeight; row++) { for (int col = 0; col < bytesPerRow; col++) { logicalMap[row][col] = bitmap[count]; count++; } } int collectiveBitmapRow = 0, collectiveBitmapCol = 0; for (int row = 0; row < deltaHeight; row++) { for (int col = 0; col < bytesPerRow; col++) { if (col == (bytesPerRow - 1)) // this is the last // byte in the row { short currentbyte = logicalMap[row][col]; for (int bitPointer = 7; bitPointer >= padding; bitPointer--) { short mask = (short)(1 << bitPointer); int bit = (currentbyte & mask) >> bitPointer; collectiveBitmap.setPixel(collectiveBitmapCol, collectiveBitmapRow, bit); collectiveBitmapCol++; } collectiveBitmapRow++; collectiveBitmapCol = 0; } else { short currentbyte = logicalMap[row][col]; for (int bitPointer = 7; bitPointer >= 0; bitPointer--) { short mask = (short)(1 << bitPointer); int bit = (currentbyte & mask) >> bitPointer; collectiveBitmap.setPixel(collectiveBitmapCol, collectiveBitmapRow, bit); collectiveBitmapCol++; } } } } } else { collectiveBitmap.readBitmap(true, 0, false, false, null, null, null, bmSize); } long x = 0; while (j < i) { bitmaps[numberOfInputSymbols + j] = collectiveBitmap.getSlice(x, 0, deltaWidths[j], deltaHeight); x += deltaWidths[j]; j++; } } } this.bitmaps = new JBIG2Bitmap[noOfExportedSymbols]; j = i = 0; bool export = false; while (i < numberOfInputSymbols + noOfNewSymbols) { long run = 0; if (sdHuffman) { run = huffmanDecoder.decodeInt(HuffmanDecoder.huffmanTableA).intResult(); } else { run = arithmeticDecoder.decodeInt(arithmeticDecoder.iaexStats).intResult(); } if (export) { for (int cnt = 0; cnt < run; cnt++) { this.bitmaps[j++] = bitmaps[i++]; } } else { i += run; } export = !export; } int contextRetained = symbolDictionaryFlags.getFlagValue(SymbolDictionaryFlags.BITMAP_CC_RETAINED); if (!sdHuffman && contextRetained == 1) { genericRegionStats = genericRegionStats.copy(); if (sdRefinementAggregate == 1) { refinementRegionStats = refinementRegionStats.copy(); } } /** consume any remaining bits */ decoder.consumeRemainingBits(); }
public void overwrite(ArithmeticDecoderStats stats) { Array.Copy(stats.codingContextTable, 0, codingContextTable, 0, contextSize); }
public int decodeBit(long context, ArithmeticDecoderStats stats) { int iCX = BinaryOperation.bit8Shift(stats.getContextCodingTableValue((int)context), 1, BinaryOperation.RIGHT_SHIFT); int mpsCX = stats.getContextCodingTableValue((int)context) & 1; int qe = qeTable[iCX]; a -= qe; int bit; if (c < a) { if ((a & 0x80000000) != 0) { bit = mpsCX; } else { if (a < qe) { bit = 1 - mpsCX; if (switchTable[iCX] != 0) { stats.setContextCodingTableValue((int)context, (nlpsTable[iCX] << 1) | (1 - mpsCX)); } else { stats.setContextCodingTableValue((int)context, (nlpsTable[iCX] << 1) | mpsCX); } } else { bit = mpsCX; stats.setContextCodingTableValue((int)context, (nmpsTable[iCX] << 1) | mpsCX); } do { if (counter == 0) { readbyte(); } a = BinaryOperation.bit32ShiftL(a, 1); c = BinaryOperation.bit32ShiftL(c, 1); counter--; } while ((a & 0x80000000) == 0); } } else { c -= a; if (a < qe) { bit = mpsCX; stats.setContextCodingTableValue((int)context, (nmpsTable[iCX] << 1) | mpsCX); } else { bit = 1 - mpsCX; if (switchTable[iCX] != 0) { stats.setContextCodingTableValue((int)context, (nlpsTable[iCX] << 1) | (1 - mpsCX)); } else { stats.setContextCodingTableValue((int)context, (nlpsTable[iCX] << 1) | mpsCX); } } a = qe; do { if (counter == 0) { readbyte(); } a = BinaryOperation.bit32ShiftL(a, 1); c = BinaryOperation.bit32ShiftL(c, 1); counter--; } while ((a & 0x80000000) == 0); } return(bit); }
public DecodeIntResult decodeInt(ArithmeticDecoderStats stats) { long value; previous = 1; int s = decodeIntBit(stats); if (decodeIntBit(stats) != 0) { if (decodeIntBit(stats) != 0) { if (decodeIntBit(stats) != 0) { if (decodeIntBit(stats) != 0) { if (decodeIntBit(stats) != 0) { value = 0; for (int i = 0; i < 32; i++) { value = BinaryOperation.bit32ShiftL(value, 1) | decodeIntBit(stats); } value += 4436; } else { value = 0; for (int i = 0; i < 12; i++) { value = BinaryOperation.bit32ShiftL(value, 1) | decodeIntBit(stats); } value += 340; } } else { value = 0; for (int i = 0; i < 8; i++) { value = BinaryOperation.bit32ShiftL(value, 1) | decodeIntBit(stats); } value += 84; } } else { value = 0; for (int i = 0; i < 6; i++) { value = BinaryOperation.bit32ShiftL(value, 1) | decodeIntBit(stats); } value += 20; } } else { value = decodeIntBit(stats); value = BinaryOperation.bit32ShiftL(value, 1) | decodeIntBit(stats); value = BinaryOperation.bit32ShiftL(value, 1) | decodeIntBit(stats); value = BinaryOperation.bit32ShiftL(value, 1) | decodeIntBit(stats); value += 4; } } else { value = decodeIntBit(stats); value = BinaryOperation.bit32ShiftL(value, 1) | decodeIntBit(stats); } int decodedInt; if (s != 0) { if (value == 0) { return(new DecodeIntResult((int)value, false)); } decodedInt = (int)-value; } else { decodedInt = (int)value; } return(new DecodeIntResult(decodedInt, true)); }