internal int GetHuff(SimpleBitIO bitIO) { int iSymbol = m_pHuffman.m_hufDecTable[bitIO.PeekBit16(Constant.HUFFMAN_DECODE_ROOT_BITS)]; if (iSymbol < 0) { bitIO.GetBit16(Constant.HUFFMAN_DECODE_ROOT_BITS); } else { bitIO.GetBit16((uint)(iSymbol & ((1 << Constant.HUFFMAN_DECODE_ROOT_BITS_LOG) - 1))); } int iSymbolHuff = iSymbol >> Constant.HUFFMAN_DECODE_ROOT_BITS_LOG; if (iSymbolHuff < 0) { iSymbolHuff = iSymbol; while ((iSymbolHuff = m_pHuffman.m_hufDecTable[iSymbolHuff + Constant.SIGN_BIT[2] + bitIO.GetBit16(1)]) < 0) { ; } } return(iSymbolHuff); }
private static byte ReadQuantizerSB(out byte pQPIndex, SimpleBitIO bitIO) { // Y pQPIndex = (byte)bitIO.GetBit32_SB(Constant.DCQuantNumBits); return(0); }
/************************************************************************* * Huffman decoding with short tables *************************************************************************/ internal int GetHuffShort(SimpleBitIO bitIO) { int iSymbol = m_pHuffman.m_hufDecTable[bitIO.PeekBit16(Constant.HUFFMAN_DECODE_ROOT_BITS)]; System.Diagnostics.Debug.Assert(iSymbol >= 0); bitIO.GetBit16((uint)(iSymbol & ((1 << (byte)Constant.HUFFMAN_DECODE_ROOT_BITS_LOG) - 1))); return(iSymbol >> Constant.HUFFMAN_DECODE_ROOT_BITS_LOG); }
protected void DecodeBitstream(uint offset) { SimpleBitIO bitIO = new SimpleBitIO(data, offset); ReadWMIHeader(bitIO); ReadImagePlaneHeader(bitIO); PKImageDecode_Copy_WMP(bitIO); }
private void ReadImagePlaneHeader(SimpleBitIO bitIO) { // internal color format cfColorFormat = (COLORFORMAT)bitIO.GetBit32_SB(Constant.ColorFormatNumBits); if (cfColorFormat != COLORFORMAT.Y_ONLY /* accept DEM only! */) { throw new ArgumentOutOfRangeException("bitIO", "cfColorFormat = " + cfColorFormat); } // lossless mode bScaledArith = bitIO.GetBit32_SB(Constant.NoScaledFlagNumBits) == 1; // subbands sbSubband = (SUBBAND)bitIO.GetBit32_SB(Constant.BandsPresentNumBits); if (sbSubband != SUBBAND.SB_ALL) { throw new ArgumentOutOfRangeException("bitIO", "sbSubband = " + sbSubband); } cNumChannels = 1; bitIO.GetBit32_SB(8); // pSCP->nLenMantissaOrShift = (U8)GetBit32_SB(pSB, 8); // quantization uQPMode = 0; // DC uniform if (bitIO.GetBit32_SB(Constant.DCFrameUniformNumBits) == 1) { uQPMode += (uint)BitstreamDecoder.ReadQuantizerSB(out uiQPIndexDC, bitIO) << 3; } else { uQPMode++; } if (sbSubband != SUBBAND.SB_DC_ONLY) { if (bitIO.GetBit32_SB(Constant.UseDCQuantizerNumBits) == 0) { // don't use DC QP uQPMode += 0x200; if (bitIO.GetBit32_SB(Constant.LPFrameUniformNumBits) == 1) // LP uniform { uQPMode += (uint)BitstreamDecoder.ReadQuantizerSB(out uiQPIndexLP, bitIO) << 5; } else { uQPMode += 2; } } else { uQPMode += ((uQPMode & 1) << 1) + ((uQPMode & 0x18) << 2); } if (sbSubband != SUBBAND.SB_NO_HIGHPASS) { if (bitIO.GetBit32_SB(Constant.UseLPQuantizerNumBits) == 0) { // don't use LP QP uQPMode += 0x400; if (bitIO.GetBit32_SB(Constant.HPFrameUniformNumBits) == 1) // HP uniform { uQPMode += (uint)BitstreamDecoder.ReadQuantizerSB(out uiQPIndexHP, bitIO) << 7; } else { uQPMode += 4; } } else { uQPMode += ((uQPMode & 2) << 1) + ((uQPMode & 0x60) << 2); } } } if (sbSubband == SUBBAND.SB_DC_ONLY) { uQPMode |= 0x200; } else if (sbSubband == SUBBAND.SB_NO_HIGHPASS) { uQPMode |= 0x400; } if ((uQPMode & 0x600) == 0) { throw new ArgumentOutOfRangeException("bitIO", "Frame level QPs must be specified independently!"); } bitIO.Flush(); }
private void ReadWMIHeader(SimpleBitIO bitIO) { // check signature for (int i = 0; i < Constant.GDISignature.Length; i++) { if ((byte)bitIO.GetBit32_SB(8) != Constant.GDISignature[i]) { throw new ArgumentOutOfRangeException("bitIO", "GDISignature[" + i + "]"); } } // check codec version and ignore subversion if (bitIO.GetBit32_SB(Constant.CodecVersionNumBits) != Constant.CodecVersion) { throw new ArgumentOutOfRangeException("bitIO", "CodecVersion"); } // ignore subversion bitIO.GetBit32_SB(Constant.CodecVersionNumBits); // 9 primary parameters // tiling present bTilingPresent = bitIO.GetBit32_SB(Constant.TilingFlagNumBits) == 1; if (bTilingPresent) { throw new ArgumentOutOfRangeException("bitIO", "bTilingPresent = " + bTilingPresent); } // bitstream layout bfBitstreamFormat = (BITSTREAMFORMAT)bitIO.GetBit32_SB(Constant.BitStreamFormatNumBits); if (bfBitstreamFormat != BITSTREAMFORMAT.SPATIAL) { throw new ArgumentOutOfRangeException("bitIO", "bfBitstreamFormat = " + bfBitstreamFormat); } // presentation orientation // ORIENTATION oOrientation = bitIO.GetBit32_SB(Constant.OriantationNumBits); bitIO.GetBit32_SB(Constant.OriantationNumBits); // bool bIndexTable = bitIO.GetBit32_SB(Constant.IndexTablePresentFlagNumBits) == 1; bitIO.GetBit32_SB(Constant.IndexTablePresentFlagNumBits); // overlap olOverlap = (OVERLAP)bitIO.GetBit32_SB(Constant.OverlapNumBits); if (olOverlap == OVERLAP.OL_MAX) { throw new ArgumentOutOfRangeException("bitIO", "olOverlap = " + olOverlap); } // 11 some other parameters // short words for size and tiles bAbbreviatedHeader = bitIO.GetBit32_SB(Constant.ShortHeaderFlagNumBits) == 1; bitIO.GetBit32_SB(1); //pSCP->bdBitDepth = (BITDEPTH)GetBit32_SB(1); // long word bitIO.GetBit32_SB(1); //pSCP->bdBitDepth = BD_LONG; // remove when optimization is done // windowing bInscribed = bitIO.GetBit32_SB(Constant.WindowingFlagNumBits) == 1; if (bInscribed) { throw new ArgumentOutOfRangeException("bitIO", "bInscribed = " + bInscribed); } // trim flexbits flag bTrimFlexbitsFlag = bitIO.GetBit32_SB(Constant.TrimFlexbitsFlagNumBits) == 1; // tile stretching flag bTileStretch = bitIO.GetBit32_SB(Constant.TileStretchFlagNumBits) == 1; if (bTileStretch) { throw new ArgumentOutOfRangeException("bitIO", "bTileStretch = " + bTileStretch); } bitIO.GetBit32_SB(2); //GetBit32_SB(2); // padding / reserved bits // 10 - informational bitIO.GetBit32_SB(4); //pII->cfColorFormat = GetBit32_SB(pSB, 4); // source color format // source bit depth bdBitDepth = (BITDEPTH_BITS)bitIO.GetBit32_SB(Constant.SourceBitDepthNumBits); // DEM Only if (bdBitDepth != BITDEPTH_BITS.BD_16S) { throw new ArgumentOutOfRangeException("bitIO", "bdBitDepth = " + bdBitDepth); } if (BITDEPTH_BITS.BD_1alt == bdBitDepth) { bdBitDepth = BITDEPTH_BITS.BD_1; } //// 12 - Variable length fields //// size cWidth = bitIO.GetBit32_SB((uint)(bAbbreviatedHeader ? Constant.ShortHeaderNumBits : Constant.LongHeaderNumBits)) + 1; cHeight = bitIO.GetBit32_SB((uint)(bAbbreviatedHeader ? Constant.ShortHeaderNumBits : Constant.LongHeaderNumBits)) + 1; cExtraPixelsTop = cExtraPixelsLeft = cExtraPixelsBottom = cExtraPixelsRight = 0; if (bInscribed == false && ((cWidth & 0xf) != 0)) { cExtraPixelsRight = 0x10 - (cWidth & 0xF); } if (bInscribed == false && ((cHeight & 0xf) != 0)) { cExtraPixelsBottom = 0x10 - (cHeight & 0xF); } //// tiling (note: if tiling is added check code in HDPhotoDecoder.CheckTilePos cNumOfSliceMinus1V = cNumOfSliceMinus1H = 0; if (((cWidth + cExtraPixelsLeft + cExtraPixelsRight) & 0xf) + ((cHeight + cExtraPixelsTop + cExtraPixelsBottom) & 0xf) != 0) { if (((cWidth & 0xf) + (cHeight & 0xf) + cExtraPixelsLeft + cExtraPixelsTop != 0) || (cWidth <= cExtraPixelsRight || cHeight <= cExtraPixelsBottom)) { throw new ArgumentOutOfRangeException("bitIO", "WMP_errInvalidParameter 07"); } cWidth -= cExtraPixelsRight; cHeight -= cExtraPixelsBottom; } }
protected virtual void PKImageDecode_Copy_WMP(SimpleBitIO bitIO) { }
private short[,] decompressedBits; // set to null by the runtime #endregion #region Overridables /// <summary> /// Does the actual decompression /// </summary> protected override void PKImageDecode_Copy_WMP(SimpleBitIO simplebitIO) { this.bitIO = simplebitIO; ImageStrDecInit(); ImageStrDecDecode(); }
/************************************************************************* Huffman decoding with short tables *************************************************************************/ internal int GetHuffShort(SimpleBitIO bitIO) { int iSymbol = m_pHuffman.m_hufDecTable[bitIO.PeekBit16(Constant.HUFFMAN_DECODE_ROOT_BITS)]; Debug.Assert(iSymbol >= 0); bitIO.GetBit16((uint)(iSymbol & ((1 << Constant.HUFFMAN_DECODE_ROOT_BITS_LOG) - 1))); return iSymbol >> Constant.HUFFMAN_DECODE_ROOT_BITS_LOG; }
internal int GetHuff(SimpleBitIO bitIO) { int iSymbol = m_pHuffman.m_hufDecTable[bitIO.PeekBit16(Constant.HUFFMAN_DECODE_ROOT_BITS)]; if (iSymbol < 0) { bitIO.GetBit16(Constant.HUFFMAN_DECODE_ROOT_BITS); } else { bitIO.GetBit16((uint)(iSymbol & ((1 << Constant.HUFFMAN_DECODE_ROOT_BITS_LOG) - 1))); } var iSymbolHuff = iSymbol >> Constant.HUFFMAN_DECODE_ROOT_BITS_LOG; if (iSymbolHuff < 0) { iSymbolHuff = iSymbol; while ((iSymbolHuff = m_pHuffman.m_hufDecTable[iSymbolHuff + Constant.SIGN_BIT[2] + bitIO.GetBit16(1)]) < 0) { } } return iSymbolHuff; }
/// <summary> /// Reads header of image (p.33) /// </summary> /// <param name="bitIO">Stream to read the header from</param> private void ReadWMIHeader(SimpleBitIO bitIO) { // check signature for (int i=0; i<Constant.GDISignature.Length; i++) { if ((byte)bitIO.GetBit32_SB(8) != Constant.GDISignature[i]) { throw new ArgumentOutOfRangeException("bitIO", "GDISignature[" + i + "]"); } } // check codec version and ignore subversion if (bitIO.GetBit32_SB(Constant.CodecVersionNumBits) != Constant.CodecVersion) { throw new ArgumentOutOfRangeException("bitIO", "CodecVersion"); } // ignore subversion bitIO.GetBit32_SB(Constant.CodecVersionNumBits); // 9 primary parameters // tiling present bTilingPresent = bitIO.GetBit32_SB(Constant.TilingFlagNumBits) == 1; if (bTilingPresent) { throw new ArgumentOutOfRangeException("bitIO", "bTilingPresent = " + bTilingPresent); } // bitstream layout bfBitstreamFormat = (BITSTREAMFORMAT)bitIO.GetBit32_SB(Constant.BitStreamFormatNumBits); if (bfBitstreamFormat != BITSTREAMFORMAT.SPATIAL) { throw new ArgumentOutOfRangeException("bitIO", "bfBitstreamFormat = " + bfBitstreamFormat); } // presentation orientation // ORIENTATION oOrientation = bitIO.GetBit32_SB(Constant.OriantationNumBits); bitIO.GetBit32_SB(Constant.OriantationNumBits); // bool bIndexTable = bitIO.GetBit32_SB(Constant.IndexTablePresentFlagNumBits) == 1; bitIO.GetBit32_SB(Constant.IndexTablePresentFlagNumBits); // overlap olOverlap = (OVERLAP)bitIO.GetBit32_SB(Constant.OverlapNumBits); if (olOverlap == OVERLAP.OL_MAX) { throw new ArgumentOutOfRangeException("bitIO", "olOverlap = " + olOverlap); } // 11 some other parameters // short words for size and tiles bAbbreviatedHeader = bitIO.GetBit32_SB(Constant.ShortHeaderFlagNumBits) == 1; bitIO.GetBit32_SB(1);//pSCP->bdBitDepth = (BITDEPTH)GetBit32_SB(1); // long word bitIO.GetBit32_SB(1);//pSCP->bdBitDepth = BD_LONG; // remove when optimization is done // windowing bInscribed = bitIO.GetBit32_SB(Constant.WindowingFlagNumBits) == 1; if (bInscribed) { throw new ArgumentOutOfRangeException("bitIO", "bInscribed = " + bInscribed); } // trim flexbits flag bTrimFlexbitsFlag = bitIO.GetBit32_SB(Constant.TrimFlexbitsFlagNumBits) == 1; // tile stretching flag bTileStretch = bitIO.GetBit32_SB(Constant.TileStretchFlagNumBits) == 1; if (bTileStretch) { throw new ArgumentOutOfRangeException("bitIO", "bTileStretch = " + bTileStretch); } bitIO.GetBit32_SB(2);//GetBit32_SB(2); // padding / reserved bits // 10 - informational bitIO.GetBit32_SB(4);//pII->cfColorFormat = GetBit32_SB(pSB, 4); // source color format // source bit depth bdBitDepth = (BITDEPTH_BITS)bitIO.GetBit32_SB(Constant.SourceBitDepthNumBits); // DEM Only if (bdBitDepth != BITDEPTH_BITS.BD_16S) { throw new ArgumentOutOfRangeException("bitIO", "bdBitDepth = " + bdBitDepth); } if (BITDEPTH_BITS.BD_1alt == bdBitDepth) { bdBitDepth = BITDEPTH_BITS.BD_1; } //// 12 - Variable length fields //// size cWidth = bitIO.GetBit32_SB((uint)(bAbbreviatedHeader ? Constant.ShortHeaderNumBits : Constant.LongHeaderNumBits)) + 1; cHeight = bitIO.GetBit32_SB((uint)(bAbbreviatedHeader ? Constant.ShortHeaderNumBits : Constant.LongHeaderNumBits)) + 1; cExtraPixelsTop = cExtraPixelsLeft = cExtraPixelsBottom = cExtraPixelsRight = 0; if (bInscribed == false && ((cWidth & 0xf) != 0)) cExtraPixelsRight = 0x10 - (cWidth & 0xF); if (bInscribed == false && ((cHeight & 0xf) != 0)) cExtraPixelsBottom = 0x10 - (cHeight & 0xF); //// tiling (note: if tiling is added check code in HDPhotoDecoder.CheckTilePos cNumOfSliceMinus1V = cNumOfSliceMinus1H = 0; if(((cWidth + cExtraPixelsLeft + cExtraPixelsRight) & 0xf) + ((cHeight + cExtraPixelsTop + cExtraPixelsBottom) & 0xf) != 0) { if (((cWidth & 0xf) + (cHeight & 0xf) + cExtraPixelsLeft + cExtraPixelsTop != 0) || (cWidth <= cExtraPixelsRight || cHeight <= cExtraPixelsBottom)) { throw new ArgumentOutOfRangeException("bitIO", "WMP_errInvalidParameter 07"); } cWidth -= cExtraPixelsRight; cHeight -= cExtraPixelsBottom; } }
/// <summary> /// Reads header of FIRST PLANE only (p.39, HD Photo Bitstream Specification) /// </summary> /// <param name="bitIO">Stream to read the image plane header from</param> private void ReadImagePlaneHeader(SimpleBitIO bitIO) { // internal color format cfColorFormat = (COLORFORMAT)bitIO.GetBit32_SB(Constant.ColorFormatNumBits); if (cfColorFormat != COLORFORMAT.Y_ONLY /* accept DEM only! */) { throw new ArgumentOutOfRangeException("bitIO", "cfColorFormat = " + cfColorFormat); } // lossless mode bScaledArith = bitIO.GetBit32_SB(Constant.NoScaledFlagNumBits) == 1; // subbands sbSubband = (SUBBAND)bitIO.GetBit32_SB(Constant.BandsPresentNumBits); if (sbSubband != SUBBAND.SB_ALL) { throw new ArgumentOutOfRangeException("bitIO", "sbSubband = " + sbSubband); } cNumChannels = 1; bitIO.GetBit32_SB(8);// pSCP->nLenMantissaOrShift = (U8)GetBit32_SB(pSB, 8); // quantization uQPMode = 0; // DC uniform if (bitIO.GetBit32_SB(Constant.DCFrameUniformNumBits) == 1) { uQPMode += (uint)BitstreamDecoder.ReadQuantizerSB(out uiQPIndexDC, bitIO) << 3; } else { uQPMode++; } if (sbSubband != SUBBAND.SB_DC_ONLY) { if (bitIO.GetBit32_SB(Constant.UseDCQuantizerNumBits) == 0) { // don't use DC QP uQPMode += 0x200; if (bitIO.GetBit32_SB(Constant.LPFrameUniformNumBits) == 1) // LP uniform { uQPMode += (uint)BitstreamDecoder.ReadQuantizerSB(out uiQPIndexLP, bitIO) << 5; } else { uQPMode += 2; } } else { uQPMode += ((uQPMode & 1) << 1) + ((uQPMode & 0x18) << 2); } if (sbSubband != SUBBAND.SB_NO_HIGHPASS) { if (bitIO.GetBit32_SB(Constant.UseLPQuantizerNumBits) == 0) { // don't use LP QP uQPMode += 0x400; if (bitIO.GetBit32_SB(Constant.HPFrameUniformNumBits) == 1) // HP uniform { uQPMode += (uint)BitstreamDecoder.ReadQuantizerSB(out uiQPIndexHP, bitIO) << 7; } else { uQPMode += 4; } } else { uQPMode += ((uQPMode & 2) << 1) + ((uQPMode & 0x60) << 2); } } } if (sbSubband == SUBBAND.SB_DC_ONLY) { uQPMode |= 0x200; } else if (sbSubband == SUBBAND.SB_NO_HIGHPASS) { uQPMode |= 0x400; } if ((uQPMode & 0x600) == 0) { throw new ArgumentOutOfRangeException("bitIO", "Frame level QPs must be specified independently!"); } bitIO.Flush(); }
private static byte ReadQuantizerSB(out byte pQPIndex, SimpleBitIO bitIO) { // Y pQPIndex = (byte)bitIO.GetBit32_SB(Constant.DCQuantNumBits); return 0; }