Alien-FreeImage

 view release on metacpan or  search on metacpan

src/Source/LibJXR/image/decode/JXRTranscode.c  view on Meta::CPAN

//*@@@+++@@@@******************************************************************
//
// 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 "windowsmediaphoto.h"
#include "strcodec.h"
#include "decode.h"

EXTERN_C Void freePredInfo(CWMImageStrCodec *);

EXTERN_C Int ReadWMIHeader(CWMImageInfo *, CWMIStrCodecParam *, CCoreParameters *);
EXTERN_C Int StrIODecInit(CWMImageStrCodec *);
EXTERN_C Int StrDecInit(CWMImageStrCodec *);
EXTERN_C Int readPackets(CWMImageStrCodec *);
EXTERN_C Int DecodeMacroblockDC(CWMImageStrCodec *, CCodingContext *, Int, Int);
EXTERN_C Int DecodeMacroblockLowpass(CWMImageStrCodec *, CCodingContext *, Int, Int);
EXTERN_C Int DecodeMacroblockHighpass(CWMImageStrCodec *, CCodingContext *, Int, Int);
EXTERN_C Void predDCACDec(CWMImageStrCodec *);
EXTERN_C Void predACDec(CWMImageStrCodec *);
EXTERN_C Void StrIODecTerm(CWMImageStrCodec *);
EXTERN_C Void FreeCodingContextDec(CWMImageStrCodec *);

EXTERN_C Int StrEncInit(CWMImageStrCodec *);
EXTERN_C Void StrIOEncTerm(CWMImageStrCodec *);
EXTERN_C Void FreeCodingContextEnc(CWMImageStrCodec *);
EXTERN_C Void encodeMB(CWMImageStrCodec *, Int, Int);
EXTERN_C Int  writeIndexTableNull(CWMImageStrCodec *);
EXTERN_C Void writePacketHeader(BitIOInfo *, U8, U8);

EXTERN_C Int WriteWMIHeader(CWMImageStrCodec *);
EXTERN_C Int ReadImagePlaneHeader(CWMImageInfo *, CWMIStrCodecParam *, CCoreParameters *, SimpleBitIO *);
EXTERN_C Int WriteImagePlaneHeader(CWMImageStrCodec *);
EXTERN_C Int writeIndexTable(CWMImageStrCodec *);
EXTERN_C Int copyTo(struct WMPStream *, struct WMPStream *, size_t);

const static Bool bFlipV[O_MAX] = {FALSE, TRUE , FALSE, TRUE, TRUE , TRUE, FALSE, FALSE};
const static Bool bFlipH[O_MAX] = {FALSE, FALSE, TRUE , TRUE, FALSE, TRUE, FALSE, TRUE};

typedef struct CTileQPInfo
{
    U8 dcMode;
    U8 dcIndex[MAX_CHANNELS];

    Bool bUseDC;
    U8 lpNum;
    Bool bUseDCAlpha;
    U8 lpNumAlpha;
    U8 lpMode[16];
    U8 lpIndex[16][MAX_CHANNELS];

    Bool bUseLP;
    U8 hpNum;
    Bool bUseLPAlpha;
    U8 hpNumAlpha;
    U8 hpMode[16];
    U8 hpIndex[16][MAX_CHANNELS];
} CTileQPInfo;

Void transcodeQuantizer(BitIOInfo * pIO, U8 cIndex[MAX_CHANNELS], U8 cChMode, size_t cChannel)
{
    if(cChMode > 2)
        cChMode = 2;

    if(cChannel > 1)
        putBit16(pIO, cChMode, 2); // Channel mode
    else
        cChMode = 0;

    putBit16(pIO, cIndex[0], 8); // Y

    if(cChMode == 1)  // MIXED
        putBit16(pIO, cIndex[1], 8); // UV
    else if(cChMode > 0){ // INDEPENDENT
        size_t i;

        for(i = 1; i < cChannel; i ++)
            putBit16(pIO, cIndex[i], 8); // UV

src/Source/LibJXR/image/decode/JXRTranscode.c  view on Meta::CPAN

            for(i = 0; i <= pSCDec->WMISCP.cNumOfSliceMinus1V; i ++)
                if(pSCDec->WMISCP.uiTileX[i] >= mbLeft && pSCDec->WMISCP.uiTileX[i] < mbRight && 
                    pSCDec->WMISCP.uiTileY[j] >= mbTop && pSCDec->WMISCP.uiTileY[j] < mbBottom){
                        for(k = 0; k < cfEnc; k ++, l ++)
                            pSCEnc->pIndexTable[l] = pSCDec->pIndexTable[(j * (pSCDec->WMISCP.cNumOfSliceMinus1V + 1) + i) * cfDec + k + 1] - pSCDec->pIndexTable[(j * (pSCDec->WMISCP.cNumOfSliceMinus1V + 1) + i) * cfDec + k];
                }
        }

        if(pSCEnc->WMISCP.cNumOfSliceMinus1H + pSCEnc->WMISCP.cNumOfSliceMinus1V == 0 && pSCEnc->WMISCP.bfBitstreamFormat == SPATIAL){
            pSCEnc->m_param.bIndexTable = FALSE;
            pSCEnc->cNumBitIO = 0;
            writeIndexTableNull(pSCEnc);
        }
        else
            writeIndexTable(pSCEnc);
                
        detachISWrite(pSCEnc, pSCEnc->pIOHeader);

        for(j = l = 0; j <= pSCDec->WMISCP.cNumOfSliceMinus1H; j ++){
            for(i = 0; i <= pSCDec->WMISCP.cNumOfSliceMinus1V; i ++)
                if(pSCDec->WMISCP.uiTileX[i] >= mbLeft && pSCDec->WMISCP.uiTileX[i] < mbRight && 
                    pSCDec->WMISCP.uiTileY[j] >= mbTop && pSCDec->WMISCP.uiTileY[j] < mbBottom){
                        for(k = 0; k < cfEnc; k ++){
                            pSCDec->WMISCP.pWStream->SetPos(pSCDec->WMISCP.pWStream, pSCDec->pIndexTable[(j * (pSCDec->WMISCP.cNumOfSliceMinus1V + 1) + i) * cfDec + k] + pSCDec->cHeaderSize);
                            copyTo(pSCDec->WMISCP.pWStream, pSCEnc->WMISCP.pWStream, pSCEnc->pIndexTable[l++]);
                        }
                }
        }

        free(pSCEnc->pIndexTable);
    }
    else
        writeIndexTableNull(pSCEnc);

    for(pSCDec->cRow = 0; pSCDec->cRow < mbBottom && pParam->bIgnoreOverlap == FALSE; pSCDec->cRow ++){
        for(pSCDec->cColumn = 0; pSCDec->cColumn < pSCDec->cmbWidth; pSCDec->cColumn ++){
            Int cRow = (Int)pSCDec->cRow, cColumn = (Int)pSCDec->cColumn;
            CWMITile * pTile;
            
            memset(pMBBuf, 0, sizeof(PixelI) * cUnit);
            if(pSCDec->m_param.bAlphaChannel){ // alpha channel
                memset(pSCDec->m_pNextSC->p1MBbuffer[0], 0, sizeof(PixelI) * 256);
                pSCDec->m_pNextSC->cRow = pSCDec->cRow;
                pSCDec->m_pNextSC->cColumn = pSCDec->cColumn;
            }

            // decode
            pSC = pSCDec;
            for(i = (pSCDec->m_param.bAlphaChannel ? 2 : 1); i > 0; i --){
                getTilePos(pSCDec, cColumn, cRow);
                if(i == 2){
                    pSCDec->m_pNextSC->cTileColumn = pSCDec->cTileColumn;
                    pSCDec->m_pNextSC->cTileRow = pSCDec->cTileRow;
                }
                
                if(readPackets(pSCDec) != ICERR_OK)
                    return ICERR_ERROR;

                pContext = &pSCDec->m_pCodingContext[pSCDec->cTileColumn];
                
                if(DecodeMacroblockDC(pSCDec, pContext, cColumn, cRow) != ICERR_OK)
                    return ICERR_ERROR;
                
                if(pSCDec->cSB > 1)
                    if(DecodeMacroblockLowpass(pSCDec, pContext, cColumn, cRow) != ICERR_OK)
                        return ICERR_ERROR;

                predDCACDec(pSCDec);

                if(pSCDec->cSB > 2)
                    if(DecodeMacroblockHighpass(pSCDec, pContext, cColumn, cRow) != ICERR_OK)
                        return ICERR_ERROR;

                predACDec(pSCDec);
                
                updatePredInfo(pSCDec, &pSCDec->MBInfo, cColumn, pSCDec->WMISCP.cfColorFormat);

                pSCDec = pSCDec->m_pNextSC;
            }
            pSCDec = pSC;

            if(pSCDec->cRow >= mbTop && pSCDec->cColumn >= mbLeft && pSCDec->cColumn < mbRight){
                cRow = (Int)(pSCDec->cRow - mbTop);
                if(bFlipV[oO])
                    cRow = (Int)mbHeight - cRow - 1;
                cColumn = (Int)(pSCDec->cColumn - mbLeft);
                if(bFlipH[oO])
                    cColumn = (Int)mbWidth - cColumn - 1;

                pSCEnc->m_bCtxLeft = pSCEnc->m_bCtxTop = FALSE;
                for(i = 0; i <= pSCEnc->WMISCP.cNumOfSliceMinus1H; i ++)
                    if(pSCEnc->WMISCP.uiTileY[i] == (U32)(oO < O_RCW ? cRow : cColumn)){
                        pSCEnc->cTileRow = i;
                        pSCEnc->m_bCtxTop = TRUE;
                        break;
                    }
                for(i = 0; i <= pSCEnc->WMISCP.cNumOfSliceMinus1V; i ++)
                    if(pSCEnc->WMISCP.uiTileX[i] == (U32)(oO < O_RCW ? cColumn : cRow)){
                        pSCEnc->cTileColumn = i;
                        pSCEnc->m_bCtxLeft = TRUE;
                        break;
                    }

                if(pSCEnc->m_bCtxLeft && pSCEnc->m_bCtxTop){ // a new tile, buffer tile DQuant info
                    CTileQPInfo * pTmp = pTileQPInfo;
                    
                    pTile = pSCDec->pTile + pSCDec->cTileColumn;
                    
                    if(oO != O_NONE)
                        pTmp += pSCEnc->cTileRow * (pSCEnc->WMISCP.cNumOfSliceMinus1V + 1) + pSCEnc->cTileColumn;
                    
                    pTmp->dcMode = pTile->cChModeDC;
                    for(i = 0; i < pSCEnc->WMISCP.cChannel; i ++)
                        pTmp->dcIndex[i] = pTile->pQuantizerDC[i][0].iIndex;
                    
                    if(pSCEnc->WMISCP.sbSubband != SB_DC_ONLY){
                        pTmp->bUseDC = pTile->bUseDC;
                        pTmp->lpNum = pTile->cNumQPLP;
                        if(pTmp->bUseDC == FALSE)
                            for(j = 0; j < pTmp->lpNum; j ++){
                                pTmp->lpMode[j] = pTile->cChModeLP[j];
                                for(i = 0; i < pSCEnc->WMISCP.cChannel; i ++)
                                    pTmp->lpIndex[j][i] = pTile->pQuantizerLP[i][j].iIndex;
                            }
                            
                            if(pSCEnc->WMISCP.sbSubband != SB_NO_HIGHPASS){
                                pTmp->bUseLP = pTile->bUseLP;
                                pTmp->hpNum = pTile->cNumQPHP;
                                if(pTmp->bUseLP == FALSE)
                                    for(j = 0; j < pTmp->hpNum; j ++){
                                        pTmp->hpMode[j] = pTile->cChModeHP[j];



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