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(); }
/// <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(); }