private int PredCBPCDec(int iCBP, CCodingContext.CCBPModel pModel) { int iNOrig; const int iNDiff = Constant.AVG_NDIFF; if (pModel.m_iState[0] == 0) { if(m_bCtxLeft) { if (m_bCtxTop) { iCBP ^= 1; } else { int iTopCBP = PredInfoPrevRow[cColumn].iCBP; iCBP ^= (iTopCBP >> 10) & 1; // left: top(10) => 0 } } else { int iLeftCBP = PredInfo[cColumn - 1].iCBP; iCBP ^= ((iLeftCBP >> 5) & 1); // left(5) => 0 } iCBP ^= (0x02 & (iCBP << 1)); // 0 => 1 iCBP ^= (0x10 & (iCBP << 3)); // 1 => 4 iCBP ^= (0x20 & (iCBP << 1)); // 4 => 5 iCBP ^= ((iCBP & 0x33) << 2); iCBP ^= ((iCBP & 0xcc) << 6); iCBP ^= ((iCBP & 0x3300) << 2); } else if (pModel.m_iState[0] == 2) { iCBP ^= 0xffff; } iNOrig = NumOnes(iCBP); pModel.m_iCount0[0] += iNOrig - iNDiff; pModel.m_iCount0[0] = Saturate32(pModel.m_iCount0[0]); pModel.m_iCount1[0] += 16 - iNOrig - iNDiff; pModel.m_iCount1[0] = Saturate32(pModel.m_iCount1[0]); if (pModel.m_iCount0[0] < 0) { if (pModel.m_iCount0[0] < pModel.m_iCount1[0]) { pModel.m_iState[0] = 1; } else { pModel.m_iState[0] = 2; } } else if (pModel.m_iCount1[0] < 0) { pModel.m_iState[0] = 2; } else { pModel.m_iState[0] = 0; } return iCBP; }
/************************************************************************* 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; }
/************************************************************************* 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; }
private void AllocateCodingContextDec() { m_pCodingContext = new CCodingContext(); m_pCodingContext.m_pAHexpt = new CAdaptiveHuffman[Constant.NUMVLCTABLES]; int iCBPSize = (cfColorFormat == COLORFORMAT.Y_ONLY || cfColorFormat == COLORFORMAT.N_CHANNEL || cfColorFormat == COLORFORMAT.CMYK) ? 5 : 9; /** allocate adaptive Huffman encoder **/ m_pCodingContext.m_pAdaptHuffCBPCY = new CAdaptiveHuffman(); m_pCodingContext.m_pAdaptHuffCBPCY.InitializeAH(iCBPSize); m_pCodingContext.m_pAdaptHuffCBPCY1 = new CAdaptiveHuffman(); m_pCodingContext.m_pAdaptHuffCBPCY1.InitializeAH(5); for (int k = 0; k < Constant.NUMVLCTABLES; k++) { m_pCodingContext.m_pAHexpt[k] = new CAdaptiveHuffman(); m_pCodingContext.m_pAHexpt[k].InitializeAH((int)Constant.aAlphabet[k]); } ResetCodingContextDec(); }