/************************************************************************* * Initialize an adaptive huffman table *************************************************************************/ internal void InitializeAH(int iNSymbols) { if (iNSymbols > 255 || iNSymbols <= 0) { throw new ArgumentOutOfRangeException("iNSymbols", "iNSymbols = " + iNSymbols); } this.m_iNSymbols = iNSymbols; m_pDelta = null; m_iDiscriminant = m_iUpperBound = m_iLowerBound = 0; m_pHuffman = new Huffman(); }
/************************************************************************* DecodeBlockHighpass : Combines DecodeBlock and InverseScanAdaptive *************************************************************************/ private int DecodeBlockHighpass(int iQP, ref PointerArray pCoeffs, ref CCodingContext.CAdaptiveScan[] pScan) { int iNumNonzero = 1; uint iLoc = 1; int iIndex, iSign; /** first symbol **/ DecodeFirstIndex(out iIndex, out iSign, m_pCodingContext.m_pAHexpt[Constant.CTDC + Constant.CONTEXTX + 0]); int iSR = (iIndex & 1); int iSRn = iIndex >> 2; int iCont = iSR & iSRn; int iLevel = (iQP ^ iSign) - iSign; if ((iIndex & 2) != 0 /* iSL */) { iLevel *= DecodeSignificantAbsLevel(m_pCodingContext.m_pAHexpt[6 + Constant.CTDC + Constant.CONTEXTX + iCont]); } if (iSR == 0) { iLoc += (uint)DecodeSignificantRun((int)(15 - iLoc), m_pCodingContext.m_pAHexpt[0]); } iLoc &= 0xf; pCoeffs[(uint)pScan[iLoc].uScan] = iLevel; pScan[iLoc].uTotal++; if ((iLoc != 0) && (pScan[iLoc].uTotal > pScan[iLoc - 1].uTotal)) { CCodingContext.CAdaptiveScan cTemp = pScan[iLoc]; pScan[iLoc] = pScan[iLoc - 1]; pScan[iLoc - 1] = cTemp; } iLoc = (iLoc + 1) & 0xf; while (iSRn != 0) { iSR = iSRn & 1; if (iSR == 0) { iLoc += (uint)DecodeSignificantRun((int)(15 - iLoc), m_pCodingContext.m_pAHexpt[0]); if (iLoc >= 16) return 16; } DecodeIndex(out iIndex, out iSign, (int)(iLoc + 1), m_pCodingContext.m_pAHexpt[Constant.CTDC + Constant.CONTEXTX + iCont + 1]); iSRn = iIndex >> 1; System.Diagnostics.Debug.Assert(iSRn >= 0 && iSRn < 3); iCont &= iSRn; /** huge difference! **/ iLevel = (iQP ^ iSign) - iSign; if ((iIndex & 1) != 0 /* iSL */) { iLevel *= DecodeSignificantAbsLevel(m_pCodingContext.m_pAHexpt[6 + Constant.CTDC + Constant.CONTEXTX + iCont]); } pCoeffs[(uint)pScan[iLoc].uScan] = iLevel; pScan[iLoc].uTotal++; if ((iLoc != 0) && (pScan[iLoc].uTotal > pScan[iLoc - 1].uTotal)) { CCodingContext.CAdaptiveScan cTemp = pScan[iLoc]; pScan[iLoc] = pScan[iLoc - 1]; pScan[iLoc - 1] = cTemp; } iLoc = (iLoc + 1) & 0xf; iNumNonzero++; } return iNumNonzero; }
/************************************************************************* DecodeBlockAdaptive *************************************************************************/ private int DecodeBlockAdaptive(bool bNoSkip, ref PointerArray pCoeffs, ref CCodingContext.CAdaptiveScan[] pScan) { int iNumNonzero = 0, iFlex = m_pCodingContext.m_aModelAC.m_iFlcBits[0] - m_pCodingContext.m_iTrimFlexBits; if (iFlex < 0 || sbSubband == SUBBAND.SB_NO_FLEXBITS) { iFlex = 0; } if (bNoSkip) { int iQP1 = pQuantizerHP.iQP << m_pCodingContext.m_aModelAC.m_iFlcBits[0]; iNumNonzero = DecodeBlockHighpass(iQP1, ref pCoeffs, ref pScan); } if (iFlex != 0) { if (pQuantizerHP.iQP + m_pCodingContext.m_iTrimFlexBits == 1) { // only iTrim = 0, pQuantizerHP.iQP = 1 is legal System.Diagnostics.Debug.Assert(m_pCodingContext.m_iTrimFlexBits == 0); System.Diagnostics.Debug.Assert(pQuantizerHP.iQP == 1); for (int k = 1; k < 16; k++) { if (pCoeffs[(uint)Constant.dctIndex[0][k]] < 0) { int fine = bitIO.GetBit16((uint)iFlex); pCoeffs[(uint)Constant.dctIndex[0][k]] -= fine; } else if (pCoeffs[(uint)Constant.dctIndex[0][k]] > 0) { int fine = bitIO.GetBit16((uint)iFlex); pCoeffs[(uint)Constant.dctIndex[0][k]] += fine; } else { int fine = bitIO.GetBit16s((uint)iFlex); pCoeffs[(uint)Constant.dctIndex[0][k]] = fine; } } } else { int iQP1 = pQuantizerHP.iQP << m_pCodingContext.m_iTrimFlexBits; for (int k = 1; k < 16; k++) { int kk = pCoeffs[(uint)Constant.dctIndex[0][k]]; if (kk < 0) { int fine = bitIO.GetBit16((uint)iFlex); pCoeffs[(uint)Constant.dctIndex[0][k]] -= iQP1 * fine; } else if (kk > 0) { int fine = bitIO.GetBit16((uint)iFlex); pCoeffs[(uint)Constant.dctIndex[0][k]] += iQP1 * fine; } else { int fine = bitIO.GetBit16s((uint)iFlex); pCoeffs[(uint)Constant.dctIndex[0][k]] = iQP1 * fine; } } } } return iNumNonzero; }
private void DecodeCoeffs() { CCodingContext.CAdaptiveScan[] pScan; int[] aLaplacianMean = new int[2] { 0, 0}; int iCBPCY = iCBP; /** set scan arrays and other MB level constants **/ if (iOrientation == 1) { pScan = m_pCodingContext.m_aScanVert; } else { pScan = m_pCodingContext.m_aScanHoriz; } int iIndex = 0; for (int iBlock = 0; iBlock < 4; iBlock++) { for (int iSubblock = 0; iSubblock < 4; iSubblock++, iIndex++, iCBPCY >>= 1) { PointerArray pCoeffs = new PointerArray(p1MBbuffer,Constant.blkOffset[iIndex & 0xf]); /** read AC values **/ int iNumNonZero = DecodeBlockAdaptive((iCBPCY & 1) != 0,ref pCoeffs, ref pScan); if (iNumNonZero > 16) { throw new ArgumentOutOfRangeException("Corrupted bitstream in DecodeCoeffs"); } aLaplacianMean[0] += iNumNonZero; } } /** update model at end of MB **/ HDPhotoDecoder.UpdateModelMB(aLaplacianMean, m_pCodingContext.m_aModelAC); }
private void ImageStrDecInit() { InitializeStrDec(); a0MBbuffer = new PointerArray(16 * 16 * cmbWidth, 0); a1MBbuffer = new PointerArray(16 * 16 * cmbWidth, 0); StrIODecInit(); StrDecInit(); decompressedBits = new short[cWidth,cHeight]; }
private void InitMRPtr() { // assuming only one image plane p0MBbuffer = new PointerArray(a0MBbuffer, 0); p1MBbuffer = new PointerArray(a1MBbuffer, 0); }
internal void AdaptDiscriminant() { var bChange = false; if (!m_bInitialize) { m_bInitialize = true; m_iDiscriminant = m_iDiscriminant1 = 0; m_iTableIndex = Constant.gSecondDisc[m_iNSymbols]; } int dL, dH; dL = dH = m_iDiscriminant; if (Constant.gSecondDisc[m_iNSymbols] != 0) { dH = m_iDiscriminant1; } if (dL < m_iLowerBound) { m_iTableIndex--; bChange = true; } else if (dH > m_iUpperBound) { m_iTableIndex++; bChange = true; } if (bChange) { /** if initialization is fixed, we can exit on !bChange **/ m_iDiscriminant = 0; m_iDiscriminant1 = 0; } if (m_iDiscriminant < -Constant.THRESHOLD * Constant.MEMORY) { m_iDiscriminant = -Constant.THRESHOLD * Constant.MEMORY; } else if (m_iDiscriminant > Constant.THRESHOLD * Constant.MEMORY) { m_iDiscriminant = Constant.THRESHOLD * Constant.MEMORY; } if (m_iDiscriminant1 < -Constant.THRESHOLD * Constant.MEMORY) { m_iDiscriminant1 = -Constant.THRESHOLD * Constant.MEMORY; } else if (m_iDiscriminant1 > Constant.THRESHOLD * Constant.MEMORY) { m_iDiscriminant1 = Constant.THRESHOLD * Constant.MEMORY; } var t = m_iTableIndex; Debug.Assert(t >= 0); Debug.Assert(t < Constant.gMaxTables[m_iNSymbols]); m_iLowerBound = (t == 0) ? (-1 << 31) : -Constant.THRESHOLD; m_iUpperBound = (t == Constant.gMaxTables[m_iNSymbols] - 1) ? (1 << 30) : Constant.THRESHOLD; switch (m_iNSymbols) { case 4: m_pHuffman.m_hufDecTable = Constant.g4HuffLookupTable; break; case 5: m_pDelta = new PointerArray(Constant.g5DeltaTable,0); m_pHuffman.m_hufDecTable = Constant.g5HuffLookupTable[t]; break; case 6: m_pDelta1 = new PointerArray(Constant.g6DeltaTable, m_iNSymbols * (t - ((t + 1) == Constant.gMaxTables[m_iNSymbols] ? 1 : 0))); m_pDelta = new PointerArray(Constant.g6DeltaTable, (t - 1 + ((t == 0) ? 1 : 0)) * m_iNSymbols); m_pHuffman.m_hufDecTable = Constant.g6HuffLookupTable[t]; break; case 7: m_pDelta = new PointerArray(Constant.g7DeltaTable, 0); m_pHuffman.m_hufDecTable = Constant.g7HuffLookupTable[t]; break; case 8: m_pHuffman.m_hufDecTable = Constant.g8HuffLookupTable[0]; break; case 9: m_pDelta = new PointerArray(Constant.g9DeltaTable, 0); m_pHuffman.m_hufDecTable = Constant.g9HuffLookupTable[t]; break; case 12: m_pDelta1 = new PointerArray(Constant.g12DeltaTable, m_iNSymbols * (t - ((t + 1) == Constant.gMaxTables[m_iNSymbols] ? 1 : 0))); m_pDelta = new PointerArray(Constant.g12DeltaTable, (t - 1 + ((t == 0) ? 1 : 0)) * m_iNSymbols); m_pHuffman.m_hufDecTable = Constant.g12HuffLookupTable[t]; break; default: throw new ArgumentOutOfRangeException("Undefined fixed length table in AdaptDiscriminant()"); } }
/************************************************************************* Initialize an adaptive huffman table *************************************************************************/ internal void InitializeAH(int iNSymbols) { if (iNSymbols > 255 || iNSymbols <= 0) { throw new ArgumentOutOfRangeException("iNSymbols", "iNSymbols = " + iNSymbols); } m_iNSymbols = iNSymbols; m_pDelta = null; m_iDiscriminant = m_iUpperBound = m_iLowerBound = 0; m_pHuffman = new Huffman(); }
internal void AdaptDiscriminant() { bool bChange = false; if (!m_bInitialize) { m_bInitialize = true; m_iDiscriminant = m_iDiscriminant1 = 0; m_iTableIndex = Constant.gSecondDisc[m_iNSymbols]; } int dL, dH; dL = dH = m_iDiscriminant; if (Constant.gSecondDisc[m_iNSymbols] != 0) { dH = m_iDiscriminant1; } if (dL < m_iLowerBound) { m_iTableIndex--; bChange = true; } else if (dH > m_iUpperBound) { m_iTableIndex++; bChange = true; } if (bChange) { /** if initialization is fixed, we can exit on !bChange **/ m_iDiscriminant = 0; m_iDiscriminant1 = 0; } if (m_iDiscriminant < -Constant.THRESHOLD * Constant.MEMORY) { m_iDiscriminant = -Constant.THRESHOLD * Constant.MEMORY; } else if (m_iDiscriminant > Constant.THRESHOLD * Constant.MEMORY) { m_iDiscriminant = Constant.THRESHOLD * Constant.MEMORY; } if (m_iDiscriminant1 < -Constant.THRESHOLD * Constant.MEMORY) { m_iDiscriminant1 = -Constant.THRESHOLD * Constant.MEMORY; } else if (m_iDiscriminant1 > Constant.THRESHOLD * Constant.MEMORY) { m_iDiscriminant1 = Constant.THRESHOLD * Constant.MEMORY; } int t = m_iTableIndex; System.Diagnostics.Debug.Assert(t >= 0); System.Diagnostics.Debug.Assert(t < Constant.gMaxTables[m_iNSymbols]); m_iLowerBound = (t == 0) ? (-1 << 31) : -Constant.THRESHOLD; m_iUpperBound = (t == Constant.gMaxTables[m_iNSymbols] - 1) ? (1 << 30) : Constant.THRESHOLD; switch (m_iNSymbols) { case 4: m_pHuffman.m_hufDecTable = Constant.g4HuffLookupTable; break; case 5: m_pDelta = new PointerArray(Constant.g5DeltaTable, 0); m_pHuffman.m_hufDecTable = Constant.g5HuffLookupTable[t]; break; case 6: m_pDelta1 = new PointerArray(Constant.g6DeltaTable, m_iNSymbols * (t - ((t + 1) == Constant.gMaxTables[m_iNSymbols] ? 1 : 0))); m_pDelta = new PointerArray(Constant.g6DeltaTable, (t - 1 + ((t == 0) ? 1 : 0)) * m_iNSymbols); m_pHuffman.m_hufDecTable = Constant.g6HuffLookupTable[t]; break; case 7: m_pDelta = new PointerArray(Constant.g7DeltaTable, 0); m_pHuffman.m_hufDecTable = Constant.g7HuffLookupTable[t]; break; case 8: m_pHuffman.m_hufDecTable = Constant.g8HuffLookupTable[0]; break; case 9: m_pDelta = new PointerArray(Constant.g9DeltaTable, 0); m_pHuffman.m_hufDecTable = Constant.g9HuffLookupTable[t]; break; case 12: m_pDelta1 = new PointerArray(Constant.g12DeltaTable, m_iNSymbols * (t - ((t + 1) == Constant.gMaxTables[m_iNSymbols] ? 1 : 0))); m_pDelta = new PointerArray(Constant.g12DeltaTable, (t - 1 + ((t == 0) ? 1 : 0)) * m_iNSymbols); m_pHuffman.m_hufDecTable = Constant.g12HuffLookupTable[t]; break; default: throw new ArgumentOutOfRangeException("Undefined fixed length table in AdaptDiscriminant()"); } }