Alien-FreeImage

 view release on metacpan or  search on metacpan

src/Source/LibJXR/image/encode/segenc.c  view on Meta::CPAN

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

src/Source/LibJXR/image/encode/segenc.c  view on Meta::CPAN

            }
        }
        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];

src/Source/LibJXR/image/encode/segenc.c  view on Meta::CPAN

                    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;
}



( run in 0.608 second using v1.01-cache-2.11-cpan-0bd6704ced7 )