1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186 |
- //*@@@+++@@@@******************************************************************
- //
- // Copyright © Microsoft Corp.
- // All rights reserved.
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions are met:
- //
- // • Redistributions of source code must retain the above copyright notice,
- // this list of conditions and the following disclaimer.
- // • Redistributions in binary form must reproduce the above copyright notice,
- // this list of conditions and the following disclaimer in the documentation
- // and/or other materials provided with the distribution.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- // POSSIBILITY OF SUCH DAMAGE.
- //
- //*@@@---@@@@******************************************************************
- #include <stdio.h>
- #include <stdlib.h>
- #include "strcodec.h"
- #include "encode.h"
- #ifdef MEM_TRACE
- #define TRACE_MALLOC 1
- #define TRACE_NEW 0
- #define TRACE_HEAP 0
- #include "memtrace.h"
- #endif
- /** local function definitions **/
- #ifdef X86OPT_INLINE
- __forceinline
- #endif
- static Int EncodeBlock (Bool bChroma, const Int *aLocalCoef, Int iNumNonzero,
- struct CAdaptiveHuffman **pAHexpt,
- Int iContextOffset, BitIOInfo* pOut, UInt iLocation);
- /*************************************************************************
- EncodeSignificantAbsLevel
- *************************************************************************/
- #ifdef X86OPT_INLINE
- //__forceinline
- #endif
- static Void EncodeSignificantAbsLevel (UInt iAbsLevel, struct CAdaptiveHuffman *pAHexpt, BitIOInfo* pOut)
- {
- Int iIndex, iFixed, aIndex[] = { 0,1,2,2, 3,3,3,3, 4,4,4,4, 5,5,5,5 };
- Int aFixedLength[] = { 0, 0, 1, 2, 2, 2 };
- assert(iAbsLevel > 0);
- iAbsLevel--;
- if (iAbsLevel >= 16) {
- Int i = iAbsLevel;
- iIndex = 6;
- /** find leftmost bit **/
- i >>= 5;
- iFixed = 4;
- while (i) { /** caution - infinite loop if not careful **/
- iFixed++;
- assert (iFixed < 30);
- i >>= 1;
- }
-
- pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex];
- putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1], pAHexpt->m_pTable[iIndex * 2 + 2]);
- if (iFixed > 18) {
- putBit16z (pOut, 15, 4);
- if (iFixed > 21) {
- putBit16z (pOut, 3, 2);
- putBit16 (pOut, iFixed - 22, 3); // 22 - 29
- }
- else
- putBit16z (pOut, iFixed - 19, 2); // 19 20 21
- }
- else {
- putBit16z(pOut, (iFixed - 4), 4);
- }
- putBit32(pOut, iAbsLevel, iFixed);
- }
- else {
- iIndex = aIndex[iAbsLevel];
- iFixed = aFixedLength[iIndex];
- pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex];
- putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1], pAHexpt->m_pTable[iIndex * 2 + 2]);
- putBit32(pOut, iAbsLevel, iFixed);
- }
- }
- /*************************************************************************
- EncodeMacroblockDC
- *************************************************************************/
- Void encodeQPIndex(BitIOInfo* pIO, U8 iIndex,U8 cBits)
- {
- if(iIndex == 0)
- putBit16z(pIO, 0, 1);
- else{
- putBit16z(pIO, 1, 1);
- putBit16z(pIO, iIndex - 1, cBits);
- }
- }
- Int EncodeMacroblockDC (CWMImageStrCodec *pSC, CCodingContext *pContext, Int iMBX, Int iMBY)
- {
- CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
- BitIOInfo* pIO = pContext->m_pIODC;
- CWMIMBInfo *pMBInfo = &pSC->MBInfo;
- Int iIndex, j = 0;
- struct CAdaptiveHuffman *pAH;
- Int aLaplacianMean[2] = { 0, 0}, *pLM = aLaplacianMean;
- Int iModelBits = pContext->m_aModelDC.m_iFlcBits[0];
- COLORFORMAT cf = pSC->m_param.cfColorFormat;
- const Int iChannels = (Int) pSC->m_param.cNumChannels;
- UNREFERENCED_PARAMETER( iMBX );
- UNREFERENCED_PARAMETER( iMBY );
- writeIS_L1(pSC, pIO);
- if(pSC->m_param.bTranscode == FALSE){
- pMBInfo->iQIndexLP = (U8)(pTile->cNumQPLP > 1 ? (rand() % pTile->cNumQPLP) : 0);
- pMBInfo->iQIndexHP = (U8)(pTile->cNumQPHP > 1 ? (rand() % pTile->cNumQPHP) : 0);
- }
- if(pTile->cBitsHP == 0 && pTile->cNumQPHP > 1) // use LP QP
- pMBInfo->iQIndexHP = pMBInfo->iQIndexLP;
- if(pSC->WMISCP.bfBitstreamFormat == SPATIAL && pSC->WMISCP.sbSubband != SB_DC_ONLY){
- if(pTile->cBitsLP > 0) // MB-based LP QP index
- encodeQPIndex(pIO, pMBInfo->iQIndexLP, pTile->cBitsLP);
- if( pSC->WMISCP.sbSubband != SB_NO_HIGHPASS && pTile->cBitsHP > 0) // MB-based HP QP index
- encodeQPIndex(pIO, pMBInfo->iQIndexHP, pTile->cBitsHP);
- }
- if(pSC->m_param.bTranscode == FALSE)
- pSC->Quantize(pSC);
- predMacroblockEnc(pSC);
- /** code path for Y_ONLY, CMYK and N_CHANNEL DC **/
- if(cf == Y_ONLY || cf == CMYK || cf == NCOMPONENT) {
- Int iQDC, iDC, iSign;
- for (j = 0; j < iChannels; j++) {
- iDC = pMBInfo->iBlockDC[j][0];
- iSign = (iDC < 0);
- iDC = abs(iDC);
- iQDC = iDC >> iModelBits;
- /** send luminance DC **/
- if (iQDC) {
- putBit16z(pIO, 1, 1);
- EncodeSignificantAbsLevel((UInt) iQDC, pContext->m_pAHexpt[3], pIO);
- *pLM += 1;
- }
- else {
- putBit16z(pIO, 0, 1);
- }
- putBit16(pIO, iDC, iModelBits);
- if (iDC) {
- putBit16z(pIO, iSign, 1);
- }
- pLM = aLaplacianMean + 1;
- iModelBits = pContext->m_aModelDC.m_iFlcBits[1];
- }
- }
- else { /** code path for YUV DC **/
- Int iDCY, iDCU, iDCV, iQDCY, iQDCU, iQDCV;
- pAH = pContext->m_pAHexpt[2];
- iQDCY = abs(iDCY = pMBInfo->iBlockDC[0][0]);
- iQDCU = abs(iDCU = pMBInfo->iBlockDC[1][0]);
- iQDCV = abs(iDCV = pMBInfo->iBlockDC[2][0]);
- if (iModelBits) {
- iQDCY >>= iModelBits;
- }
- iModelBits = pContext->m_aModelDC.m_iFlcBits[1];
- if (iModelBits) {
- iQDCU >>= iModelBits;
- iQDCV >>= iModelBits;
- }
- iModelBits = pContext->m_aModelDC.m_iFlcBits[0];
- iIndex = (iQDCY != 0) * 4 + (iQDCU != 0) * 2 + (iQDCV != 0);
- putBit16z(pIO, pAH->m_pTable[iIndex * 2 + 1], pAH->m_pTable[iIndex * 2 + 2]);
- /** send luminance DC **/
- if (iQDCY) {
- EncodeSignificantAbsLevel((UInt) iQDCY, pContext->m_pAHexpt[3], pIO);
- *pLM += 1;
- }
- putBit16(pIO, abs(iDCY), iModelBits);
- if (iDCY) {
- putBit16z(pIO, (iDCY < 0), 1);
- }
- /** send chroma DC **/
- pLM = aLaplacianMean + 1;
- iModelBits = pContext->m_aModelDC.m_iFlcBits[1];
- if (iQDCU) {
- EncodeSignificantAbsLevel((UInt) iQDCU, pContext->m_pAHexpt[4], pIO);
- *pLM += 1;
- }
- putBit16(pIO, abs(iDCU), iModelBits);
- if (iDCU) {
- putBit16z(pIO, (iDCU < 0), 1);
- }
- if (iQDCV) {
- EncodeSignificantAbsLevel((UInt) iQDCV, pContext->m_pAHexpt[4], pIO);
- *pLM += 1;
- }
- putBit16(pIO, abs(iDCV), iModelBits);
- if (iDCV) {
- putBit16z(pIO, (iDCV < 0), 1);
- }
- }
- UpdateModelMB (cf, iChannels, aLaplacianMean, &(pContext->m_aModelDC));
- if (pSC->m_bResetContext && pSC->WMISCP.sbSubband == SB_DC_ONLY) {
- AdaptDiscriminant(pContext->m_pAHexpt[2]);
- AdaptDiscriminant(pContext->m_pAHexpt[3]);
- AdaptDiscriminant(pContext->m_pAHexpt[4]);
- }
- return ICERR_OK;
- }
- /*************************************************************************
- Scan block with zero model bits
- *************************************************************************/
- #ifdef X86OPT_INLINE
- __forceinline
- #endif
- static Int AdaptiveScanZero (const PixelI *pCoeffs, CAdaptiveScan *pScan,
- Int *pRLCoeffs, const Int iCount)
- {
- Int k, iRun = 1, iLevel, iNumNonzero = 0;
- iLevel = pCoeffs[pScan[1].uScan];
- if (iLevel) {
- pScan[1].uTotal++;
- pRLCoeffs[iNumNonzero * 2] = 0;
- pRLCoeffs[iNumNonzero * 2 + 1] = iLevel;
- iNumNonzero++;
- iRun = 0;
- }
- for (k = 2; k < iCount; k++) {
- iLevel = pCoeffs[pScan[k].uScan];
- iRun++;
- if (iLevel) {
- pScan[k].uTotal++;
- if (pScan[k].uTotal > pScan[k - 1].uTotal) {
- CAdaptiveScan cTemp = pScan[k];
- pScan[k] = pScan[k - 1];
- pScan[k - 1] = cTemp;
- }
- pRLCoeffs[iNumNonzero * 2] = iRun - 1;
- pRLCoeffs[iNumNonzero * 2 + 1] = iLevel;
- iNumNonzero++;
- iRun = 0;
- }
- }
- return iNumNonzero;
- }
- /*************************************************************************
- Scan block with nonzero model bits, all trimmed
- *************************************************************************/
- #ifdef X86OPT_INLINE
- __forceinline
- #endif
- static Int AdaptiveScanTrim (const PixelI *pCoeffs, CAdaptiveScan *pScan,
- const Int iModelBits, Int *pRLCoeffs, const Int iCount)
- {
- Int k, iRun = 1, iLevel, iNumNonzero = 0;
- Int iTemp;
- unsigned int iThOff = (1 << iModelBits) - 1, iTh = iThOff * 2 + 1;
- iLevel = pCoeffs[pScan[1].uScan];
- if ((unsigned int)(iLevel + iThOff) >= iTh) {
- iTemp = abs (iLevel) >> iModelBits;
- pScan[1].uTotal++;
- pRLCoeffs[iNumNonzero * 2] = 0;
- pRLCoeffs[iNumNonzero * 2 + 1] = (iLevel < 0) ? -iTemp : iTemp;
- iNumNonzero++;
- iRun = 0;
- }
- for (k = 2; k < iCount; k++) {
- iRun++;
- iLevel = pCoeffs[pScan[k].uScan];
- if ((unsigned int)(iLevel + iThOff) >= iTh) {
- iTemp = abs (iLevel) >> iModelBits;
- pScan[k].uTotal++;
- if (pScan[k].uTotal > pScan[k - 1].uTotal) {
- CAdaptiveScan cTemp = pScan[k];
- pScan[k] = pScan[k - 1];
- pScan[k - 1] = cTemp;
- }
- pRLCoeffs[iNumNonzero * 2] = iRun - 1;
- pRLCoeffs[iNumNonzero * 2 + 1] = (iLevel < 0) ? -iTemp : iTemp;
- iNumNonzero++;
- iRun = 0;
- }
- }
- return iNumNonzero;
- }
- /*************************************************************************
- Scan block with nonzero model bits
- *************************************************************************/
- /** saves around 1.5% at QP=1 (no SIMD opt) **/
- #define USE_GRES_LUT
- #ifdef USE_GRES_LUT
- static const Int gRes[] = {
- 65*2+1, 63*2+1, 61*2+1, 59*2+1, 57*2+1, 55*2+1, 53*2+1, 51*2+1, 49*2+1, 47*2+1, 45*2+1, 43*2+1, 41*2+1,
- 39*2+1, 37*2+1, 35*2+1, 33*2+1, 31*2+1, 29*2+1, 27*2+1, 25*2+1, 23*2+1, 21*2+1, 19*2+1, 17*2+1, 15*2+1,
- 13*2+1, 11*2+1, 9*2+1, 7*2+1, 5*2+1, 3*2+1,
- 0,
- 2*2+1, 4*2+1, 6*2+1, 8*2+1, 10*2+1, 12*2+1, 14*2+1, 16*2+1, 18*2+1, 20*2+1, 22*2+1, 24*2+1,
- 26*2+1, 28*2+1, 30*2+1, 32*2+1, 34*2+1, 36*2+1, 38*2+1, 40*2+1, 42*2+1, 44*2+1, 46*2+1, 48*2+1, 50*2+1,
- 52*2+1, 54*2+1, 56*2+1, 58*2+1, 60*2+1, 62*2+1, 64*2+1 };
- #endif // USE_GRES_LUT
- #ifdef X86OPT_INLINE
- //__forceinline
- #endif
- static Int AdaptiveScan (const PixelI *pCoeffs, Int *pResidual,
- CAdaptiveScan *pScan,
- const Int iModelBits, const Int iTrimBits,
- Int *pRLCoeffs, const Int iCount)
- {
- if (iModelBits == 0) {
- return AdaptiveScanZero (pCoeffs, pScan, pRLCoeffs, iCount);
- }
- else if (iModelBits <= iTrimBits) {
- return AdaptiveScanTrim (pCoeffs, pScan, iModelBits, pRLCoeffs, iCount);
- }
- else if (iTrimBits == 0
- #ifdef USE_GRES_LUT
- && iModelBits < 6
- #endif // USE_GRES_LUT
- ) {
- Int k, iRun = 0, iLevel, iNumNonzero = 0;
- Int iTemp, iTemp1;
- const unsigned int iThOff = (1 << iModelBits) - 1, iTh = iThOff * 2 + 1;
- iLevel = pCoeffs[pScan[1].uScan];
- if ((unsigned int)(iLevel + iThOff) >= iTh) {
- iTemp1 = abs (iLevel);
- iTemp = iTemp1 >> iModelBits;
- pResidual[pScan[1].uScan] = (iTemp1 & iThOff) * 2;
- pScan[1].uTotal++;
- pRLCoeffs[iNumNonzero * 2] = iRun;
- pRLCoeffs[iNumNonzero * 2 + 1] = (iLevel < 0) ? -iTemp : iTemp;
- iNumNonzero++;
- iRun = 0;
- }
- else {
- iRun++;
- #ifdef USE_GRES_LUT
- pResidual[pScan[1].uScan] = gRes[(iLevel + 32)];
- #else // USE_GRES_LUT
- iTemp = -(iLevel < 0);
- pResidual[pScan[1].uScan] = (iLevel ^ iTemp) * 4 + (6 & iTemp) + (iLevel != 0);
- #endif // USE_GRES_LUT
- }
- for (k = 2; k < iCount; k++) {
- const Int sk = pScan[k].uScan;
- //pResidual++;
- iLevel = pCoeffs[sk];
- if ((unsigned int)(iLevel + iThOff) >= iTh) {
- const Int iSign = -(iLevel < 0);
- iTemp1 = (iSign ^ iLevel) - iSign;
- iTemp = iTemp1 >> iModelBits;
- pResidual[sk] = (iTemp1 & iThOff) * 2;
- pScan[k].uTotal++;
- if (pScan[k].uTotal > pScan[k - 1].uTotal) {
- CAdaptiveScan cTemp = pScan[k];
- pScan[k] = pScan[k - 1];
- pScan[k - 1] = cTemp;
- }
- pRLCoeffs[iNumNonzero * 2] = iRun;
- pRLCoeffs[iNumNonzero * 2 + 1] = (iTemp ^ iSign) - iSign;
- iNumNonzero++;
- iRun = 0;
- }
- else {
- iRun++;
- #ifdef USE_GRES_LUT
- pResidual[sk] = gRes[(iLevel + 32)];
- #else // USE_GRES_LUT
- iTemp = -(iLevel < 0);
- pResidual[sk] = (iLevel ^ iTemp) * 4 + (6 & iTemp) + (iLevel != 0);
- #endif // USE_GRES_LUT
- ////(abs(iLevel) * 4) + ((iLevel < 0) * 2) + (iLevel != 0);
- }
- }
- return iNumNonzero;
- }
- else {
- Int k, iRun = 0, iLevel, iNumNonzero = 0;
- Int iTemp, iTemp1;
- const unsigned int iThOff = (1 << iModelBits) - 1, iTh = iThOff * 2 + 1;
- iLevel = pCoeffs[pScan[1].uScan];
- //pResidual++;
- if ((unsigned int)(iLevel + iThOff) >= iTh) {
- iTemp1 = abs (iLevel);
- iTemp = iTemp1 >> iModelBits;
- pResidual[pScan[1].uScan] = ((iTemp1 & iThOff) >> iTrimBits) * 2;
- pScan[1].uTotal++;
- pRLCoeffs[iNumNonzero * 2] = iRun;
- pRLCoeffs[iNumNonzero * 2 + 1] = (iLevel < 0) ? -iTemp : iTemp;
- iNumNonzero++;
- iRun = 0;
- }
- else {
- iRun++;
- iTemp = -(iLevel < 0);
- iLevel = ((iLevel + iTemp) >> iTrimBits) - iTemp; // round towards zero
- iTemp = -(iLevel < 0);
- pResidual[pScan[1].uScan] = (iLevel ^ iTemp) * 4 + (6 & iTemp) + (iLevel != 0);
- }
- for (k = 2; k < iCount; k++) {
- const Int sk = pScan[k].uScan;
- //pResidual++;
- iLevel = pCoeffs[sk];
- if ((unsigned int)(iLevel + iThOff) >= iTh) {
- iTemp1 = abs (iLevel);
- iTemp = iTemp1 >> iModelBits;
- pResidual[sk] = ((iTemp1 & iThOff) >> iTrimBits) * 2;
- pScan[k].uTotal++;
- if (pScan[k].uTotal > pScan[k - 1].uTotal) {
- CAdaptiveScan cTemp = pScan[k];
- pScan[k] = pScan[k - 1];
- pScan[k - 1] = cTemp;
- }
- pRLCoeffs[iNumNonzero * 2] = iRun;
- pRLCoeffs[iNumNonzero * 2 + 1] = (iLevel < 0) ? -iTemp : iTemp;
- iNumNonzero++;
- iRun = 0;
- }
- else {
- iRun++;
- iTemp = -(iLevel < 0);
- iLevel = ((iLevel + iTemp) >> iTrimBits) - iTemp; // round towards zero
- iTemp = -(iLevel < 0);
- pResidual[sk] = (iLevel ^ iTemp) * 4 + (6 & iTemp) + (iLevel != 0);
- }
- }
- return iNumNonzero;
- }
- }
- /*************************************************************************
- EncodeMacroblockLowpass
- *************************************************************************/
- Int EncodeMacroblockLowpass (CWMImageStrCodec *pSC, CCodingContext *pContext, Int iMBX, Int iMBY)
- {
- const COLORFORMAT cf = pSC->m_param.cfColorFormat;
- const Int iChannels = (Int) pSC->m_param.cNumChannels;
- Int iFullChannels = (cf == YUV_420 || cf == YUV_422) ? 1 : iChannels;
- CWMIMBInfo *pMBInfo = &pSC->MBInfo;
- BitIOInfo* pIO = pContext->m_pIOLP;
- CAdaptiveScan *pScan = pContext->m_aScanLowpass;
- Int k, /*iPrevRun = -1,*/ iRun = 0;// iLastIndex = 0;
- Int iModelBits = pContext->m_aModelLP.m_iFlcBits[0];
- PixelI aBuf[2][8];
- Int aLaplacianMean[2] = {0, 0}, *pLM = aLaplacianMean;
- Int iChannel, iVal;
- Int aRLCoeffs[MAX_CHANNELS][32], iNumCoeffs[MAX_CHANNELS];
- const I32 *aDC[MAX_CHANNELS];
- Int aResidual[MAX_CHANNELS][16];
- Void (*putBits)(BitIOInfo* pIO, U32 uiBits, U32 cBits) = putBit16;
- UNREFERENCED_PARAMETER( iMBX );
- UNREFERENCED_PARAMETER( iMBY );
- if (iChannels > MAX_CHANNELS)
- return ICERR_ERROR;
- if((pSC->WMISCP.bfBitstreamFormat != SPATIAL) && (pSC->pTile[pSC->cTileColumn].cBitsLP > 0)) // MB-based LP QP index
- encodeQPIndex(pIO, pMBInfo->iQIndexLP, pSC->pTile[pSC->cTileColumn].cBitsLP);
- // set arrays
- for (k = 0; k < iChannels; k++) {
- aDC[k] = pMBInfo->iBlockDC[k];
- }
- /** reset adaptive scan totals **/
- if (pSC->m_bResetRGITotals) {
- int iScale = 2;
- int iWeight = iScale * 16;
- pScan[0].uTotal = MAXTOTAL;
- for (k = 1; k < 16; k++) {
- pScan[k].uTotal = iWeight;
- iWeight -= iScale;
- }
- }
- /** scan 4x4 transform **/
- for (iChannel = 0; iChannel < iFullChannels; iChannel++) {
- iNumCoeffs[iChannel] = AdaptiveScan (aDC[iChannel], aResidual[iChannel],
- pScan, iModelBits, 0, aRLCoeffs[iChannel], 16);
- iModelBits = pContext->m_aModelLP.m_iFlcBits[1];
- }
- if (cf == YUV_420 || cf == YUV_422) { /** interleave U and V **/
- static const Int aRemap[] = { 4, 1,2,3, 5,6,7 };
- const Int *pRemap = aRemap + (cf == YUV_420);
- const Int iCount = (cf == YUV_420) ? 6 : 14;
- Int iCoef = 0;
- iRun = 0;
- iModelBits = pContext->m_aModelLP.m_iFlcBits[1];
- for (k = 0; k < iCount; k++) {
- Int iIndex = pRemap[k >> 1];
- Int iDC = aDC[(k & 1) + 1][iIndex];
- aBuf[k & 1][iIndex] = iVal = abs (iDC) >> iModelBits;
- if (iVal) {
- aRLCoeffs[1][iCoef * 2] = iRun;
- aRLCoeffs[1][iCoef * 2 + 1] = (iDC < 0) ? -iVal : iVal;
- iCoef++;
- iRun = 0;
- }
- else {
- iRun++;
- }
- }
- iNumCoeffs[1] = iCoef;
- }
- /** in raw mode, this can take 6% of the bits in the extreme low rate case!!! **/
- if (cf == YUV_420 || cf == YUV_422)
- iFullChannels = 2;
- if (cf == YUV_420 || cf == YUV_422 || cf == YUV_444) {
- int iCBP, iMax = iFullChannels * 4 - 5; /* actually (1 << iNChannels) - 1 **/
- int iCountM = pContext->m_iCBPCountMax, iCountZ = pContext->m_iCBPCountZero;
- iCBP = (iNumCoeffs[0] > 0) + (iNumCoeffs[1] > 0) * 2;
- if (iFullChannels == 3)
- iCBP += (iNumCoeffs[2] > 0) * 4;
- if (iCountZ <= 0 || iCountM < 0) {
- iVal = iCBP;
- if (iCountM < iCountZ) {
- iVal = iMax - iCBP;
- }
- if (iVal == 0)
- putBit16z(pIO, 0, 1);
- else if (iVal == 1)
- putBit16z(pIO, (iFullChannels + 1) & 0x6, iFullChannels); // 2 or 4
- else
- putBit16z(pIO, iVal + iMax + 1, iFullChannels + 1); // cbp + 4 or cbp + 8
- }
- else {
- putBit16z(pIO, iCBP, iFullChannels);
- }
- iCountM += 1 - 4 * (iCBP == iMax);//(b + c - 2*a);
- iCountZ += 1 - 4 * (iCBP == 0);//(a + b - 2*c);
- if (iCountM < -8)
- iCountM = -8;
- else if (iCountM > 7)
- iCountM = 7;
- pContext->m_iCBPCountMax = iCountM;
- if (iCountZ < -8)
- iCountZ = -8;
- else if (iCountZ > 7)
- iCountZ = 7;
- pContext->m_iCBPCountZero = iCountZ;
- }
- else { /** 1 or N channel **/
- for (iChannel = 0; iChannel < iChannels; iChannel++) {
- putBit16z(pIO, (iNumCoeffs[iChannel] > 0), 1);
- }
- }
- // set appropriate function pointer
- if (pContext->m_aModelLP.m_iFlcBits[0] > 14 || pContext->m_aModelLP.m_iFlcBits[1] > 14) {
- putBits = putBit32;
- }
- iModelBits = pContext->m_aModelLP.m_iFlcBits[0];
- for (iChannel = 0; iChannel < iFullChannels; iChannel++) {
- const Int *pRL = aRLCoeffs[iChannel];
- Int iCoef = iNumCoeffs[iChannel];
- if (iCoef) {
- (*pLM) += iCoef;
- if(EncodeBlock (iChannel > 0, pRL, iCoef, pContext->m_pAHexpt, CTDC,
- pIO, 1 + 9 * ((cf == YUV_420) && (iChannel == 1)) + ((cf == YUV_422) && (iChannel == 1))) != ICERR_OK)
- return ICERR_ERROR;
- }
- if (iModelBits) {
- if ((cf == YUV_420 || cf == YUV_422) && iChannel) { // 420/422 chroma
- for (k = 1; k < ((cf == YUV_420) ? 4 : 8); k++) {
- putBits(pIO, abs(aDC[1][k]), iModelBits);
- if (aBuf[0][k] == 0 && aDC[1][k]) {
- putBit16z(pIO, (aDC[1][k] < 0), 1);
- }
- putBits(pIO, abs(aDC[2][k]), iModelBits);
- if (aBuf[1][k] == 0 && aDC[2][k]) {
- putBit16z(pIO, (aDC[2][k] < 0), 1);
- }
- }
- }
- else { // normal case
- for (k = 1; k < 16; k++) {
- putBit16z(pIO, aResidual[iChannel][k] >> 1, iModelBits + (aResidual[iChannel][k] & 1));
- }
- }
- }
- pLM = aLaplacianMean + 1;
- iModelBits = pContext->m_aModelLP.m_iFlcBits[1];
- }
- writeIS_L1(pSC, pIO);
- UpdateModelMB (cf, iChannels, aLaplacianMean, &pContext->m_aModelLP);
- if (pSC->m_bResetContext) {
- AdaptLowpassEnc(pContext);
- }
- return ICERR_OK;
- }
- /*************************************************************************
- Adapt
- *************************************************************************/
- Void AdaptLowpassEnc(CCodingContext *pSC)
- {
- Int kk;
- for (kk = 0; kk < CONTEXTX + CTDC; kk++) { /** adapt fixed code (index 0 and 1) as well **/
- AdaptDiscriminant (pSC->m_pAHexpt[kk]);
- }
- }
- Void AdaptHighpassEnc(CCodingContext *pSC)
- {
- Int kk;
- //Adapt (pSC->m_pAdaptHuffCBPCY, FALSE);
- AdaptDiscriminant (pSC->m_pAdaptHuffCBPCY);
- AdaptDiscriminant (pSC->m_pAdaptHuffCBPCY1);
- for (kk = 0; kk < CONTEXTX; kk++) { /** adapt fixed code **/
- AdaptDiscriminant (pSC->m_pAHexpt[kk + CONTEXTX + CTDC]);
- }
- }
- /*************************************************************************
- Experimental code -- encodeBlock
- SR = <0 1 2> == <last, nonsignificant, significant run>
- alphabet 12:
- pAHexpt[0] == <SR', SL, SR | first symbol>
- alphabet 6:
- pAHexpt[1] == <SR', SL | continuous>
- pAHexpt[2] == <SR', SL | continuous>
- alphabet 4:
- pAHexpt[3] == <SR', SL | 1 free slot> (SR may be last or insignificant only)
- alphabet f(run) (this can be extended to 6 contexts - SL and SR')
- pAHexpt[4] == <run | continuous>
- alphabet f(lev) (this can be extended to 9 contexts)
- pAHexpt[5-6] == <lev | continuous> first symbol
- pAHexpt[7-8] == <lev | continuous> condition on SRn no use
- *************************************************************************/
- #ifdef X86OPT_INLINE
- __forceinline
- #endif
- static Void EncodeSignificantRun (Int iRun, Int iMaxRun, struct CAdaptiveHuffman *pAHexpt, BitIOInfo* pOut)
- {
- Int iIndex, iFLC, iBin;
- static const Int aIndex[] = {
- 0,1,2,2,3,3,4,4,4,4,4,4,4,4,
- 0,1,2,2,3,3,4,4,4,4,0,0,0,0,
- 0,1,2,3,4,4
- };
- if (iMaxRun < 5) {
- //if (iMaxRun == 4) {
- //static const Int gCode[] = { 0, 1, 1, 1 };
- static const Int gLen[] = { 3, 3, 2, 1 };
- if (iMaxRun > 1)
- putBit16z(pOut, (iMaxRun != iRun), gLen[iMaxRun - iRun] - (4 - iMaxRun));
- //}
- //else if (iMaxRun == 3) {
- // if (iRun == 1) {
- // putBit16z(pOut, 1, 1);
- // }
- // else {
- // putBit16z(pOut, 3 ^ iRun, 2);
- // }
- //}
- //else if (iMaxRun == 2) {
- // putBit16z(pOut, 2 - iRun, 1);
- //}
- return;
- }
- iBin = gSignificantRunBin[iMaxRun];
- iIndex = aIndex[iRun + iBin * 14 - 1];
- iFLC = gSignificantRunFixedLength[iIndex + iBin * 5];
- putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1], pAHexpt->m_pTable[iIndex * 2 + 2]);
- //this always uses table 0
- //pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex];
- putBit16(pOut, iRun + 1, iFLC);
- }
- #ifdef X86OPT_INLINE
- __forceinline
- #endif
- static Void EncodeFirstIndex (Bool bChroma, Int iLoc, Int iCont, Int iIndex, Int iSign,
- struct CAdaptiveHuffman **ppAHexpt, BitIOInfo* pOut)
- {
- // Int iContext = iCont + 1 + bChroma * 3;
- struct CAdaptiveHuffman *pAHexpt = ppAHexpt[bChroma * 3];
- UNREFERENCED_PARAMETER( iLoc );
- UNREFERENCED_PARAMETER( iCont );
- pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex];
- pAHexpt->m_iDiscriminant1 += pAHexpt->m_pDelta1[iIndex];
- putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1] * 2 + iSign, pAHexpt->m_pTable[iIndex * 2 + 2] + 1);
- return;
- }
- #ifdef X86OPT_INLINE
- __forceinline
- #endif
- static Void EncodeIndex (Bool bChroma, Int iLoc, Int iCont, Int iIndex, Int iSign,
- struct CAdaptiveHuffman **ppAHexpt, BitIOInfo* pOut)
- {
- Int iContext = iCont + 1 + bChroma * 3;
- if (iLoc < 15) {
- struct CAdaptiveHuffman *pAHexpt = ppAHexpt[iContext];
- pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex];
- pAHexpt->m_iDiscriminant1 += pAHexpt->m_pDelta1[iIndex];
- putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1] * 2 + iSign, pAHexpt->m_pTable[iIndex * 2 + 2] + 1);
- }
- else if (iLoc == 15) {
- static const U32 gCode[] = { 0, 6, 2, 7 };
- static const U32 gLen[] = { 1, 3, 2, 3 };
- putBit16z(pOut, gCode[iIndex] * 2 + iSign, gLen[iIndex] + 1);
- return;
- }
- else {//if (iLoc == 16) {
- putBit16z(pOut, iIndex * 2 + iSign, 1 + 1);
- return;
- }
- }
- #ifdef X86OPT_INLINE
- __forceinline
- #endif
- static Int EncodeBlock (Bool bChroma, const Int *aLocalCoef, Int iNumNonzero,
- struct CAdaptiveHuffman **pAHexpt, Int iContextOffset,
- BitIOInfo* pOut, UInt iLocation)
- {
- Int iSR, iSL, iSRn, iIndex, k, iCont, iLev;
- /** first symbol **/
- iLev = aLocalCoef[1];
- iSR = (aLocalCoef[0] == 0);
- iSL = ((unsigned int) (iLev + 1) > 2U);
- iSRn = 1;
- if (iNumNonzero == 1) {
- iSRn = 0;
- }
- else if (aLocalCoef[2] > 0) {
- iSRn = 2;
- }
- iIndex = iSRn * 4 + iSL * 2 + iSR;
- EncodeFirstIndex (bChroma, iLocation, 0, iIndex, (iLev < 0), pAHexpt + iContextOffset, pOut);
- iCont = iSR & iSRn;
- if (iSL) {
- EncodeSignificantAbsLevel ((UInt)(abs(iLev) - 1), pAHexpt[6 + iContextOffset + iCont], pOut);
- }
- if (iSR == 0) {
- EncodeSignificantRun (aLocalCoef[0], 15 - iLocation, pAHexpt[0], pOut);
- }
- iLocation += aLocalCoef[0] + 1;
- for (k = 1; k < iNumNonzero; k++) {
- if (iSRn == 2) {
- EncodeSignificantRun (aLocalCoef[k * 2], 15 - iLocation, pAHexpt[0], pOut);
- }
- iLocation += aLocalCoef[k * 2] + 1;
- iSRn = 1;
- if (k == iNumNonzero - 1) {
- iSRn = 0;
- }
- else if (aLocalCoef[k * 2 + 2] > 0) {
- iSRn = 2;
- }
- //iSL = (abs(aLocalCoef[k * 2 + 1]) > 1);
- iLev = aLocalCoef[k * 2 + 1];
- iSL = ((unsigned int) (iLev + 1) > 2U);
- iIndex = iSRn * 2 + iSL;
- EncodeIndex (bChroma, iLocation, iCont, iIndex, (iLev < 0), pAHexpt + iContextOffset, pOut);
- iCont &= iSRn; /** big difference! **/
- if (iSL) {
- EncodeSignificantAbsLevel ((UInt)(abs(iLev) - 1), pAHexpt[6 + iContextOffset + iCont], pOut);
- }
- //else {
- // putBit16z(pOut, (iLev < 0), 1);
- //}
- }
- return ICERR_OK;
- }
- /*************************************************************************
- CodeCoeffs
- *************************************************************************/
- #ifdef X86OPT_INLINE
- __forceinline
- #endif
- static Int CodeCoeffs (CWMImageStrCodec * pSC, CCodingContext *pContext,
- Int iMBX, Int iMBY, BitIOInfo* pIO, BitIOInfo* pIOFL)
- {
- const COLORFORMAT cf = pSC->m_param.cfColorFormat;
- const Int iChannels = (Int) pSC->m_param.cNumChannels;
- const Int iPlanes = (cf == YUV_420 || cf == YUV_422) ? 1 : iChannels;
- CWMIMBInfo * pMBInfo = &pSC->MBInfo;
- CAdaptiveScan *pScan;
- Int iBlock, iNBlocks = 4;
- Int iSubblock, iIndex = 0;
- Int i, k;
- const Int iNumCoeffs = 16;
- Int iModelBits = pContext->m_aModelAC.m_iFlcBits[0], iFlex = 0, iTrim = 0, iMask = 0;
- Int aLaplacianMean[2] = { 0, 0}, *pLM = aLaplacianMean;
- Bool bChroma = FALSE;
- UNREFERENCED_PARAMETER( iMBX );
- UNREFERENCED_PARAMETER( iMBY );
- assert (iModelBits < 16);
- if (pContext->m_iTrimFlexBits <= iModelBits && pSC->WMISCP.sbSubband != SB_NO_FLEXBITS) {
- iTrim = pContext->m_iTrimFlexBits;
- iFlex = iModelBits - pContext->m_iTrimFlexBits;
- iMask = (1 << iFlex) - 1;
- }
- if(pSC->WMISCP.sbSubband != SB_NO_FLEXBITS)
- writeIS_L1(pSC, pIOFL);
- /** set scan arrays **/
- if (pMBInfo->iOrientation == 1) {
- pScan = pContext->m_aScanVert;
- }
- else {
- pScan = pContext->m_aScanHoriz;
- }
- /** write out coefficients **/
- for (i = 0; i < iPlanes; i++) {
- Int iPattern = pMBInfo->iCBP[i];
- if (cf == YUV_420) {
- iNBlocks = 6;
- iPattern += (pMBInfo->iCBP[1] << 16) + (pMBInfo->iCBP[2] << 20);
- }
- else if (cf == YUV_422) {
- iNBlocks = 8;
- iPattern += (pMBInfo->iCBP[1] << 16) + (pMBInfo->iCBP[2] << 24);
- }
- for (iBlock = iIndex = 0; iBlock < iNBlocks; iBlock++) {
- writeIS_L2(pSC, pIO);
- if (pIO != pIOFL)
- writeIS_L2(pSC, pIOFL);
-
- for (iSubblock = 0; iSubblock < 4; iSubblock++, iPattern >>= 1, iIndex ++) {
- const PixelI *pCoeffs = NULL;
- if(iBlock < 4){
- pCoeffs = pSC->pPlane[i] + blkOffset[iIndex];
- }
- else if(cf == YUV_420){
- pCoeffs = pSC->pPlane[iBlock - 3] + blkOffsetUV[iSubblock];
- }
- else if(cf == YUV_422){
- pCoeffs = pSC->pPlane[1 + ((iBlock - 4) >> 1)] + blkOffsetUV_422[(iBlock & 1) * 4 + iSubblock];
- }
- /** put AC bits **/
- if ((iPattern & 1) == 0) {
- if (iFlex) {
- /** FLC only, all else is skipped **/
- for (k = 1; k < iNumCoeffs; k++) {
- Int data = pCoeffs[dctIndex[0][k]];
- Int atdata = (abs(data) >> iTrim);
- Int word = atdata & iMask, len = iFlex;
- if (atdata) {
- word += word + (data < 0);
- len++;
- }
- putBit16z(pIOFL, word, len);
- }
- }
- }
- else {
- // WARNING!!! interaction between lowpass coefficients and highpass scan ordering - may lead to break in decoding when model bits is nonzero!
- // Fix is to use same scan order in model bits transmission, and defer update of scan order to end of block
- /** collect coefficients **/
- Int aLocalCoef[32], iNumNonzero = 0;
- Int aResidual[16];
- iNumNonzero = AdaptiveScan (pCoeffs, aResidual,
- pScan, iModelBits, iTrim, aLocalCoef, 16);
- (*pLM) += iNumNonzero;
- EncodeBlock (bChroma, aLocalCoef, iNumNonzero, pContext->m_pAHexpt, CTDC + CONTEXTX, pIO, 1);
- if (iFlex) {
- for (k = 1; k < iNumCoeffs; k++) {
- putBit16z(pIOFL, aResidual[dctIndex[0][k]] >> 1, iFlex + (aResidual[dctIndex[0][k]] & 1));
- }
- }
- }
- }
- if (iBlock == 3) {
- iModelBits = pContext->m_aModelAC.m_iFlcBits[1];
- assert (iModelBits < 16);
- pLM = aLaplacianMean + 1;
- bChroma = TRUE;
- iTrim = iFlex = iMask = 0;
- if (pContext->m_iTrimFlexBits <= iModelBits && pSC->WMISCP.sbSubband != SB_NO_FLEXBITS) {
- iTrim = pContext->m_iTrimFlexBits;
- iFlex = iModelBits - iTrim;
- iMask = (1 << iFlex) - 1;
- }
- }
- }
- }
- /** update model at end of MB **/
- UpdateModelMB (cf, iChannels, aLaplacianMean, &pContext->m_aModelAC);
- return ICERR_OK;
- }
- /*************************************************************************
- CodeCBP
- *************************************************************************/
- static Void CodeCBP (CWMImageStrCodec * pSC, CCodingContext *pContext,
- Int iMBX, Int iMBY, BitIOInfo *pIO)
- {
- const COLORFORMAT cf = pSC->m_param.cfColorFormat;
- const Int iChannel = (cf == NCOMPONENT || cf == CMYK) ? (Int) pSC->m_param.cNumChannels : 1;
- Int iDiffCBPCY, iDiffCBPCU = 0, iDiffCBPCV = 0, iDY;
- Int iBlock, i, k;
- static const Int aNumOnes[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
- static const Int aTabLen[] = { 0, 2, 2, 2, 2, 2, 3, 2, 2, 3, 3, 2, 3, 2, 2, 0 };
- static const Int aTabCode[] = { 0, 0, 1, 0, 2, 1, 4, 3, 3, 5, 6, 2, 7, 1, 0, 0 };
- CAdaptiveHuffman *pAH;
- Int iCount, iPattern, iCode, iCodeU = 0, iCodeV = 0;
- UNREFERENCED_PARAMETER( iMBX );
- UNREFERENCED_PARAMETER( iMBY );
- predCBPEnc(pSC, pContext);
- writeIS_L1(pSC, pIO);
- iDiffCBPCU = pSC->MBInfo.iDiffCBP[1];
- iDiffCBPCV = pSC->MBInfo.iDiffCBP[2];
- for (i = 0; i < iChannel; i++) {
- iDiffCBPCY = pSC->MBInfo.iDiffCBP[i];
- if(cf == YUV_420){ // PackCBP420
- iDiffCBPCY = (iDiffCBPCY & 0xf) + ((iDiffCBPCU & 1) << 4) + ((iDiffCBPCV & 1) << 5) +
- ((iDiffCBPCY & 0x00f0) << 2) + ((iDiffCBPCU & 2) << 9) + ((iDiffCBPCV & 2) << 10) +
- ((iDiffCBPCY & 0x0f00) << 4) + ((iDiffCBPCU & 4) << 14) + ((iDiffCBPCV & 4) << 15) +
- ((iDiffCBPCY & 0xf000) << 6) + ((iDiffCBPCU & 8) << 19) + ((iDiffCBPCV & 8) << 20);
- }
- else if(cf == YUV_422){// PackCBP422
- iDiffCBPCY = (iDiffCBPCY & 0xf) + ((iDiffCBPCU & 1) << 4) + ((iDiffCBPCU & 4) << 3) +
- ((iDiffCBPCV & 1) << 6) + ((iDiffCBPCV & 4) << 5) +
- ((iDiffCBPCY & 0x00f0) << 4) + ((iDiffCBPCU & 2) << 11) + ((iDiffCBPCU & 8) << 10) +
- ((iDiffCBPCV & 2) << 13) + ((iDiffCBPCV & 8) << 12) +
- ((iDiffCBPCY & 0x0f00) << 8) + ((iDiffCBPCU & 16) << 16) + ((iDiffCBPCU & 64) << 15) +
- ((iDiffCBPCV & 16) << 18) + ((iDiffCBPCV & 64) << 17) +
- ((iDiffCBPCY & 0xf000) << 12) + ((iDiffCBPCU & 32) << 23) + ((iDiffCBPCU & 128) << 22) +
- ((iDiffCBPCV & 32) << 25) + ((iDiffCBPCV & 128) << 24);
- }
- /** send CBPCY **/
- iPattern = 0;
- iDY = iDiffCBPCY;
- if (cf == YUV_444) {
- iDY |= (iDiffCBPCU | iDiffCBPCV);
- }
- for (iBlock = 0; iBlock < 4; iBlock++) {
- if(cf == YUV_422) {
- iPattern |= ((iDY & 0xff) != 0) * 0x10;
- iDY >>= 8;
- }
- else if (cf == YUV_420) {
- iPattern |= ((iDY & 0x3f) != 0) * 0x10;
- iDY >>= 6;
- }
- else {
- iPattern |= ((iDY & 0xf) != 0) * 0x10;
- iDY >>= 4;
- }
- iPattern >>= 1;
- }
- pAH = pContext->m_pAdaptHuffCBPCY1;
- iCount = aNumOnes[iPattern];
- putBit16z(pIO, pAH->m_pTable[iCount * 2 + 1], pAH->m_pTable[iCount * 2 + 2]);
- pAH->m_iDiscriminant += pAH->m_pDelta[iCount];
- if (aTabLen[iPattern]) {
- putBit16z(pIO, aTabCode[iPattern], aTabLen[iPattern]);
- }
- for (iBlock = 0; iBlock < 4; iBlock++) {
- switch (cf) {
- case YUV_444:
- iCode = iDiffCBPCY & 0xf;
- iCodeU = iDiffCBPCU & 0xf;
- iCodeV = iDiffCBPCV & 0xf;
- iCode |= ((iCodeU != 0) << 4);
- iCode |= ((iCodeV != 0) << 5);
- iDiffCBPCY >>= 4;
- iDiffCBPCU >>= 4;
- iDiffCBPCV >>= 4;
- break;
- case YUV_422:
- iCode = iDiffCBPCY & 0xff;
- iDiffCBPCY >>= 8;
- break;
- case YUV_420:
- iCode = iDiffCBPCY & 0x3f;
- iDiffCBPCY >>= 6;
- break;
- default:
- iCode = iDiffCBPCY & 0xf;
- iDiffCBPCY >>= 4;
- }
- if (iCode) {
- static const Int gTab0[16] = { 0,1,1,2, 1,3,3,4, 1,3,3,4, 2,4,4,5 };
- static const Int gFL0[16] = { 0,2,2,1, 2,2,2,2, 2,2,2,2, 1,2,2,0 };
- static const Int gCode0[16] = { 0,0,1,0, 2,0,1,0, 3,2,3,1, 1,2,3,0 };
- int val, iChroma = (iCode >> 4);
- iCode &= 0xf;
-
- if(cf == YUV_422) {
- iCodeU = (iChroma & 3);
- iCodeV = ((iChroma >> 2) & 3);
- iChroma = (iCodeU == 0 ? 0 : 1);
- if(iCodeV != 0) {
- iChroma += 2;
- }
- }
- if (iChroma) {
- if (gTab0[iCode] > 2) {
- val = 8;
- }
- else {
- val = gTab0[iCode] + 6 - 1;
- }
- }
- else {
- val = gTab0[iCode] - 1;
- }
- pAH = pContext->m_pAdaptHuffCBPCY;
- putBit16z(pIO, pAH->m_pTable[val * 2 + 1], pAH->m_pTable[val * 2 + 2]);
- pAH->m_iDiscriminant += pAH->m_pDelta[val];
- if (iChroma) {
- if (iChroma == 1)
- putBit16z(pIO, 1, 1);
- else
- putBit16z(pIO, 3 - iChroma, 2);
- }
- if (val == 8) {
- if (gTab0[iCode] == 3) {
- putBit16z(pIO, 1, 1);
- }
- else {
- putBit16z(pIO, 5 - gTab0[iCode], 2);
- }
- }
- if (gFL0[iCode]) {
- putBit16z(pIO, gCode0[iCode], gFL0[iCode]);
- }
- if (cf == YUV_444) {
- pAH = pContext->m_pAHexpt[1];
- iPattern = iCodeU;
- for (k = 0; k < 2; k++) {
- if (iPattern) {
- iCount = aNumOnes[iPattern];
- iCount--;
- putBit16z(pIO, pAH->m_pTable[iCount * 2 + 1], pAH->m_pTable[iCount * 2 + 2]);
- if (aTabLen[iPattern]) {
- putBit16z(pIO, aTabCode[iPattern], aTabLen[iPattern]);
- }
- }
- iPattern = iCodeV;
- }
- }
- else if (cf == YUV_422){
- iPattern = iCodeU;
- for(k = 0; k < 2; k ++) {
- if(iPattern) {
- if (iPattern == 1)
- putBit16z(pIO, 1, 1);
- else {
- putBit16z(pIO, 3 - iPattern, 2);
- }
- }
- iPattern = iCodeV;
- }
- }
- }
- }
- }
- }
- /*************************************************************************
- macroblock encode function using 4x4 transforms
- *************************************************************************/
- Int EncodeMacroblockHighpass(CWMImageStrCodec * pSC, CCodingContext *pContext, Int iMBX, Int iMBY)
- {
- BitIOInfo* pIO = pContext->m_pIOAC;
- BitIOInfo* pIOFL = pContext->m_pIOFL;
- if((pSC->WMISCP.bfBitstreamFormat != SPATIAL) && (pSC->pTile[pSC->cTileColumn].cBitsHP > 0)) // MB-based HP QP index
- encodeQPIndex(pIO, pSC->MBInfo.iQIndexHP, pSC->pTile[pSC->cTileColumn].cBitsHP);
- /** reset adaptive scan totals **/
- if (pSC->m_bResetRGITotals) {
- Int iScale = 2;
- Int iWeight = iScale * 16;
- Int k;
- pContext->m_aScanHoriz[0].uTotal = pContext->m_aScanVert[0].uTotal = MAXTOTAL;
- for (k = 1; k < 16; k++) {
- pContext->m_aScanHoriz[k].uTotal = pContext->m_aScanVert[k].uTotal = iWeight;
- iWeight -= iScale;
- }
- }
- CodeCBP(pSC, pContext, iMBX, iMBY, pIO);
- if(CodeCoeffs(pSC, pContext, iMBX, iMBY, pIO, pIOFL) != ICERR_OK)
- return ICERR_ERROR;
- if (pSC->m_bResetContext) {
- AdaptHighpassEnc(pContext);
- }
- return ICERR_OK;
- }
|