Path: blob/master/libs/jxr/image/decode/strPredQuantDec.c
4393 views
//*@@@+++@@@@******************************************************************1//2// Copyright © Microsoft Corp.3// All rights reserved.4//5// Redistribution and use in source and binary forms, with or without6// modification, are permitted provided that the following conditions are met:7//8// • Redistributions of source code must retain the above copyright notice,9// this list of conditions and the following disclaimer.10// • Redistributions in binary form must reproduce the above copyright notice,11// this list of conditions and the following disclaimer in the documentation12// and/or other materials provided with the distribution.13//14// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"15// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE16// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE17// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE18// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR19// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF20// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS21// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN22// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)23// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE24// POSSIBILITY OF SUCH DAMAGE.25//26//*@@@---@@@@******************************************************************2728#include "strcodec.h"2930#define DEQUANT(iRaw, iQP) ((iRaw) * (iQP))3132Void dequantizeBlock4x4(PixelI * pRec, Int * pOrg, const Int * pIndex, Int iQPLP)33{34Int i;3536for(i = 1; i < 16; i ++)37pRec[pIndex[i]] = DEQUANT(pOrg[i], iQPLP);38}3940Void dequantizeBlock2x2(PixelI * pRec, Int * pOrg, Int iQPLP)41{42pRec[32] = DEQUANT(pOrg[1], iQPLP);43pRec[16] = DEQUANT(pOrg[2], iQPLP);44pRec[48] = DEQUANT(pOrg[3], iQPLP);45}4647Void dequantizeBlock4x2(PixelI * pRec, Int * pOrg, Int iQPLP)48{49pRec[ 64] = DEQUANT(pOrg[1], iQPLP);50pRec[ 16] = DEQUANT(pOrg[2], iQPLP);51pRec[ 80] = DEQUANT(pOrg[3], iQPLP);52pRec[ 32] = DEQUANT(pOrg[4], iQPLP);53pRec[ 96] = DEQUANT(pOrg[5], iQPLP);54pRec[ 48] = DEQUANT(pOrg[6], iQPLP);55pRec[112] = DEQUANT(pOrg[7], iQPLP);56}575859Int dequantizeMacroblock(CWMImageStrCodec * pSC)60{61const COLORFORMAT cf = pSC->m_param.cfColorFormat;62CWMIMBInfo *pMBInfo = &pSC->MBInfo;63CWMITile * pTile = pSC->pTile + pSC->cTileColumn;64const size_t iChannels = pSC->m_param.cNumChannels;65size_t i;6667for(i = 0; i < iChannels; i ++){68//dequantize DC69pSC->p1MBbuffer[i][0] = DEQUANT(pMBInfo->iBlockDC[i][0], pTile->pQuantizerDC[i]->iQP);7071// dequantize LP72if(pSC->WMISCP.sbSubband != SB_DC_ONLY) {73if(i == 0 || (cf != YUV_422 && cf != YUV_420))74dequantizeBlock4x4(pSC->p1MBbuffer[i] , pMBInfo->iBlockDC[i], dctIndex[2], pTile->pQuantizerLP[i][pMBInfo->iQIndexLP].iQP);75else if(cf == YUV_422)76dequantizeBlock4x2(pSC->p1MBbuffer[i], pMBInfo->iBlockDC[i], pTile->pQuantizerLP[i][pMBInfo->iQIndexLP].iQP);77else // 42078dequantizeBlock2x2(pSC->p1MBbuffer[i], pMBInfo->iBlockDC[i], pTile->pQuantizerLP[i][pMBInfo->iQIndexLP].iQP);79}80}8182return ICERR_OK;83}8485/* frequency domain inverse DCAC prediction */86Void predDCACDec(CWMImageStrCodec * pSC)87{88const COLORFORMAT cf = pSC->m_param.cfColorFormat;89const Int iChannels = (cf == YUV_420 || cf == YUV_422) ? 1 : (Int) pSC->m_param.cNumChannels;90CWMIMBInfo *pMBInfo = &(pSC->MBInfo);91size_t mbX = pSC->cColumn;// mbY = pSC->cRow;92Int iDCACPredMode = getDCACPredMode(pSC, mbX);93Int iDCPredMode = (iDCACPredMode & 0x3);94Int iADPredMode = (iDCACPredMode & 0xC);95PixelI * pOrg, * pRef;96Int ii;9798for(ii = 0; ii < iChannels; ii ++){99pOrg = pMBInfo->iBlockDC[ii];//[dcBlkIdx + (i >> 4)]; // current DC block100101/* DC prediction */102if(iDCPredMode == 1){ // predict DC from top103pOrg[0] += pSC->PredInfoPrevRow[ii][mbX].iDC;104}105else if(iDCPredMode == 0){ // predict DC from left106pOrg[0] += (pSC->PredInfo[ii] + mbX - 1)->iDC;107}108else if(iDCPredMode == 2){// predict DC from top&left109pOrg[0] += ((pSC->PredInfo[ii] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[ii] + mbX)->iDC) >> 1;110}111112/* AD prediction */113if(iADPredMode == 4){// predict AD from top114pRef = (pSC->PredInfoPrevRow[ii] + mbX)->piAD;115pOrg[4] += pRef[3], pOrg[8] += pRef[4], pOrg[12] += pRef[5];116}117else if(iADPredMode == 0){// predict AD from left118pRef = (pSC->PredInfo[ii] + mbX - 1)->piAD;119pOrg[1] += pRef[0], pOrg[2] += pRef[1], pOrg[3] += pRef[2];120}121}122123if(cf == YUV_420){124for(ii = 1; ii < 3; ii ++){125pOrg = pMBInfo->iBlockDC[ii];//dcBlkIdx + ii]; // current DC block126127/* DC prediction */128if(iDCPredMode == 1){ // predict DC from top129pOrg[0] += (pSC->PredInfoPrevRow[ii] + mbX)->iDC;130}131else if(iDCPredMode == 0){ // predict DC from left132pOrg[0] += (pSC->PredInfo[ii] + mbX - 1)->iDC;133}134else if(iDCPredMode == 2){ // predict DC from top&left135pOrg[0] += (((pSC->PredInfo[ii] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[ii] + mbX)->iDC + 1) >> 1);136}137138/* AD prediciton */139if(iADPredMode == 4){// predict AD from top140pOrg[2] += (pSC->PredInfoPrevRow[ii] + mbX)->piAD[1];141}142else if(iADPredMode == 0){// predict AD from left143pOrg[1] += (pSC->PredInfo[ii] + mbX - 1)->piAD[0];144}145}146}147else if(cf == YUV_422){148for(ii = 1; ii < 3; ii ++){149pOrg = pMBInfo->iBlockDC[ii];//[dcBlkIdx + ii]; // current DC block150151/* DC prediciton */152if(iDCPredMode == 1){ // predict DC from top153pOrg[0] += (pSC->PredInfoPrevRow[ii] + mbX)->iDC;154}155else if(iDCPredMode == 0){ // predict DC from left156pOrg[0] += (pSC->PredInfo[ii] + mbX - 1)->iDC;157}158else if(iDCPredMode == 2){ // predict DC from top&left159pOrg[0] += (((pSC->PredInfo[ii] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[ii] + mbX)->iDC + 1) >> 1);160}161162/* AD prediction */163if(iADPredMode == 4){// predict AD from top164pOrg[4] += (pSC->PredInfoPrevRow[ii] + mbX)->piAD[4]; // AC of HT !!!165pOrg[2] += (pSC->PredInfoPrevRow[ii] + mbX)->piAD[3];166pOrg[6] += pOrg[2];167}168else if(iADPredMode == 0){// predict AD from left169pOrg[4] += (pSC->PredInfo[ii] + mbX - 1)->piAD[4]; // AC of HT !!!170pOrg[1] += (pSC->PredInfo[ii] + mbX - 1)->piAD[0];171pOrg[5] += (pSC->PredInfo[ii] + mbX - 1)->piAD[2];172}173else if(iDCPredMode == 1){174pOrg[6] += pOrg[2];175}176}177}178179pMBInfo->iOrientation = 2 - getACPredMode(pMBInfo, cf);180}181182/*************************************************************************183Frequency domain inverse AC prediction184*************************************************************************/185Void predACDec(CWMImageStrCodec * pSC)186{187const COLORFORMAT cf = pSC->m_param.cfColorFormat;188const Int iChannels = (cf == YUV_420 || cf == YUV_422) ? 1 : (Int) pSC->m_param.cNumChannels;189// size_t mbX = pSC->cColumn, mbY = pSC->cRow;190CWMIMBInfo *pMBInfo = &pSC->MBInfo;191Int iACPredMode = 2 - pMBInfo->iOrientation;192PixelI * pOrg, * pRef;193Int i, j;194195/* AC prediction */196for(i = 0; i < iChannels; i++){197// prediction only happens inside MB198PixelI* pSrc = pSC->p1MBbuffer[i];//0 == i ? pSC->pY1 : (1 == i ? pSC->pU1 : pSC->pV1);199200switch (iACPredMode)201{202case 1:203{204// predict from top205static U8 blkIdx[] = {1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15};206207for (j = 0; j < sizeof(blkIdx) / sizeof(*blkIdx); ++j)208{209pOrg = pSrc + 16 * blkIdx[j];210pRef = pOrg - 16;211212pOrg[ 2] += pRef[ 2];213pOrg[10] += pRef[10];214pOrg[ 9] += pRef[ 9];215}216break;217}218219case 0:220// predict from left221for (j = 64; j < 256; j += 16)222{223pOrg = pSrc + j;224pRef = pOrg - 64;225226pOrg[1] += pRef[1];227pOrg[5] += pRef[5];228pOrg[6] += pRef[6];229}230break;231232default:233// no prediction234break;235}236}237238if(cf == YUV_420){239for(i = 16; i <= 20; i += 4){240PixelI* pSrc = pSC->p1MBbuffer[(i >> 2) - 3];//16 == i ? pSC->pU1 : pSC->pV1;241242switch (iACPredMode)243{244case 1:245{246// predict from top247for (j = 1; j <= 3; j += 2)248{249pOrg = pSrc + 16 * j;250pRef = pOrg - 16;251252pOrg[ 2] += pRef[ 2];253pOrg[10] += pRef[10];254pOrg[ 9] += pRef[ 9];255}256break;257}258259case 0:260// predict from left261for (j = 2; j <= 3; ++j)262{263pOrg = pSrc + 16 * j;264pRef = pOrg - 32;265266pOrg[1] += pRef[1];267pOrg[5] += pRef[5];268pOrg[6] += pRef[6];269}270break;271272default:273// no prediction274break;275}276}277}278else if(cf == YUV_422){279for(i = 16; i < 32; i += 8){280PixelI* pSrc = pSC->p1MBbuffer[(i >> 3) - 1];//16 == i ? pSC->pU1 : pSC->pV1;281282switch (iACPredMode)283{284case 1:285{286// predict from top287for (j = 2; j < 8; j ++)288{289pOrg = pSrc + blkOffsetUV_422[j];290pRef = pOrg - 16;291292pOrg[10] += pRef[10];293pOrg[ 2] += pRef[ 2];294pOrg[ 9] += pRef[ 9];295}296break;297}298299case 0:300// predict from left301for (j = 1; j < 8; j += 2)302{303pOrg = pSrc + blkOffsetUV_422[j];304pRef = pOrg - 64;305306pOrg[1] += pRef[1];307pOrg[5] += pRef[5];308pOrg[6] += pRef[6];309}310break;311312default:313// no prediction314break;315}316}317}318}319320/*************************************************************************321CBP322*************************************************************************/323static int NumOnes(int i)324{325int retval = 0;326static const int g_Count[] = { 0,1,1,2, 1,2,2,3, 1,2,2,3, 2,3,3,4 };327i = i & 0xffff;328while (i) {329retval += g_Count[i & 0xf];330i >>= 4;331}332return retval;333}334335#define SATURATE32(x) if((unsigned int)(x + 16) >= 32) { if (x < 0) x = -16; else x = 15; }336337/* CBP prediction for 16 x 16 MB */338/* block index */339/* 0 1 4 5 */340/* 2 3 6 7 */341/* 8 9 12 13 */342/* 10 11 14 15 */343static Int predCBPCDec(CWMImageStrCodec * pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)344{345Int iNOrig;346const int iNDiff = AVG_NDIFF;347size_t c1 = c ? 1 : 0;348349UNREFERENCED_PARAMETER( mbY );350351if (pModel->m_iState[c1] == 0) {352if(pSC->m_bCtxLeft) {353if (pSC->m_bCtxTop) {354iCBP ^= 1;355}356else {357Int iTopCBP = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;358iCBP ^= (iTopCBP >> 10) & 1; // left: top(10) => 0359}360}361else {362Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;363iCBP ^= ((iLeftCBP >> 5) & 1); // left(5) => 0364}365366iCBP ^= (0x02 & (iCBP << 1)); // 0 => 1367iCBP ^= (0x10 & (iCBP << 3)); // 1 => 4368iCBP ^= (0x20 & (iCBP << 1)); // 4 => 5369370iCBP ^= ((iCBP & 0x33) << 2);371iCBP ^= ((iCBP & 0xcc) << 6);372iCBP ^= ((iCBP & 0x3300) << 2);373374}375else if (pModel->m_iState[c1] == 2) {376iCBP ^= 0xffff;377}378379iNOrig = NumOnes(iCBP);380381pModel->m_iCount0[c1] += iNOrig - iNDiff;382SATURATE32(pModel->m_iCount0[c1]);383384pModel->m_iCount1[c1] += 16 - iNOrig - iNDiff;385SATURATE32(pModel->m_iCount1[c1]);386387if (pModel->m_iCount0[c1] < 0) {388if (pModel->m_iCount0[c1] < pModel->m_iCount1[c1]) {389pModel->m_iState[c1] = 1;390}391else {392pModel->m_iState[c1] = 2;393}394}395else if (pModel->m_iCount1[c1] < 0) {396pModel->m_iState[c1] = 2;397}398else {399pModel->m_iState[c1] = 0;400}401return iCBP;402}403404static Int predCBPC420Dec(CWMImageStrCodec * pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)405{406Int iNOrig;407const int iNDiff = AVG_NDIFF;408409UNREFERENCED_PARAMETER( mbY );410411if (pModel->m_iState[1] == 0) {412if(pSC->m_bCtxLeft) {413if (pSC->m_bCtxTop) {414iCBP ^= 1;415}416else {417Int iTopCBP = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;418iCBP ^= (iTopCBP >> 2) & 1; // left: top(2) => 0419}420}421else {422Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;423iCBP ^= ((iLeftCBP >> 1) & 1); // left(1) => 0424}425426iCBP ^= (0x02 & (iCBP << 1)); // 0 => 1427iCBP ^= ((iCBP & 0x3) << 2); // [0 1] -> [2 3]428}429else if (pModel->m_iState[1] == 2) {430iCBP ^= 0xf;431}432433iNOrig = NumOnes(iCBP) * 4;434435pModel->m_iCount0[1] += iNOrig - iNDiff;436SATURATE32(pModel->m_iCount0[1]);437438pModel->m_iCount1[1] += 16 - iNOrig - iNDiff;439SATURATE32(pModel->m_iCount1[1]);440441if (pModel->m_iCount0[1] < 0) {442if (pModel->m_iCount0[1] < pModel->m_iCount1[1]) {443pModel->m_iState[1] = 1;444}445else {446pModel->m_iState[1] = 2;447}448}449else if (pModel->m_iCount1[1] < 0) {450pModel->m_iState[1] = 2;451}452else {453pModel->m_iState[1] = 0;454}455456return iCBP;457}458459static Int predCBPC422Dec(CWMImageStrCodec * pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)460{461Int iNOrig;462const int iNDiff = AVG_NDIFF;463464UNREFERENCED_PARAMETER( mbY );465466if (pModel->m_iState[1] == 0) {467if(pSC->m_bCtxLeft) {468if (pSC->m_bCtxTop) {469iCBP ^= 1;470}471else {472Int iTopCBP = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;473iCBP ^= (iTopCBP >> 6) & 1; // left: top(6) => 0474}475}476else {477Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;478iCBP ^= ((iLeftCBP >> 1) & 1); // left(1) => 0479}480481iCBP ^= (iCBP & 0x1) << 1; // [0]->[1]482iCBP ^= (iCBP & 0x3) << 2; // [0 1]->[2 3]483iCBP ^= (iCBP & 0xc) << 2; // [2 3]->[4 5]484iCBP ^= (iCBP & 0x30) << 2; // [4 5]->[6 7]485}486else if (pModel->m_iState[1] == 2) {487iCBP ^= 0xff;488}489490iNOrig = NumOnes(iCBP) * 2;491492pModel->m_iCount0[1] += iNOrig - iNDiff;493SATURATE32(pModel->m_iCount0[1]);494495pModel->m_iCount1[1] += 16 - iNOrig - iNDiff;496SATURATE32(pModel->m_iCount1[1]);497498if (pModel->m_iCount0[1] < 0) {499if (pModel->m_iCount0[1] < pModel->m_iCount1[1]) {500pModel->m_iState[1] = 1;501}502else {503pModel->m_iState[1] = 2;504}505}506else if (pModel->m_iCount1[1] < 0) {507pModel->m_iState[1] = 2;508}509else {510pModel->m_iState[1] = 0;511}512513return iCBP;514}515516517/* Coded Block Pattern (CBP) prediction */518Void predCBPDec(CWMImageStrCodec *pSC, CCodingContext *pContext)519{520const COLORFORMAT cf = pSC->m_param.cfColorFormat;521const size_t iChannels = (cf == YUV_420 || cf == YUV_422) ? 1 : pSC->m_param.cNumChannels;522size_t i, mbX = pSC->cColumn, mbY = pSC->cRow;523CWMIMBInfo *pMBInfo = &(pSC->MBInfo);524525for (i = 0; i < iChannels; i++) {526(pSC->PredInfo[i] + mbX)->iCBP = pMBInfo->iCBP[i] = predCBPCDec(pSC, pMBInfo->iDiffCBP[i], mbX, mbY, i, &pContext->m_aCBPModel); // Y Channel527}528529if (cf == YUV_422){530(pSC->PredInfo[1] + mbX)->iCBP = pMBInfo->iCBP[1] = predCBPC422Dec(pSC, pMBInfo->iDiffCBP[1], mbX, mbY, 1, &pContext->m_aCBPModel);531(pSC->PredInfo[2] + mbX)->iCBP = pMBInfo->iCBP[2] = predCBPC422Dec(pSC, pMBInfo->iDiffCBP[2], mbX, mbY, 2, &pContext->m_aCBPModel);532}533else if (cf == YUV_420) {534(pSC->PredInfo[1] + mbX)->iCBP = pMBInfo->iCBP[1] = predCBPC420Dec(pSC, pMBInfo->iDiffCBP[1], mbX, mbY, 1, &pContext->m_aCBPModel);535(pSC->PredInfo[2] + mbX)->iCBP = pMBInfo->iCBP[2] = predCBPC420Dec(pSC, pMBInfo->iDiffCBP[2], mbX, mbY, 2, &pContext->m_aCBPModel);536}537//}538}539540541