Alien-FreeImage

 view release on metacpan or  search on metacpan

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

    PixelI * pFrameBuf = NULL, * pFrameBufAlpha = NULL;
    CWMIMBInfo * pMBInfo = NULL, * pMBInfoAlpha = NULL;
    CWMImageStrCodec * pSCDec, * pSCEnc, * pSC;
    CWMDecoderParameters aDecoderParam = {0};
    U8 * pIOHeaderDec, * pIOHeaderEnc;
    CCodingContext * pContext;
    CTileQPInfo * pTileQPInfo = NULL;
    ORIENTATION oO = pParam->oOrientation;
    size_t iAlphaPos = 0;
    size_t cUnit;
    size_t i, j, mbLeft, mbRight, mbTop, mbBottom, mbWidth, mbHeight;

    if(pStreamIn == NULL || pStreamOut == NULL || pParam == NULL)
        return ICERR_ERROR;

    // initialize decoder
    if((pSCDec = (CWMImageStrCodec *)malloc(sizeof(CWMImageStrCodec))) == NULL)
        return ICERR_ERROR;
    memset(pSCDec, 0, sizeof(CWMImageStrCodec));

    pSCDec->WMISCP.pWStream = pStreamIn;
    if(ReadWMIHeader(&pSCDec->WMII, &pSCDec->WMISCP, &pSCDec->m_param) != ICERR_OK)
        return ICERR_ERROR;

    if(pSCDec->WMISCP.cfColorFormat == YUV_422 && oO >= O_RCW)
        pParam->oOrientation = oO = O_NONE; // Can not rotate 422 in compressed domain!

    pSCDec->cmbWidth = (pSCDec->WMII.cWidth + pSCDec->m_param.cExtraPixelsLeft + pSCDec->m_param.cExtraPixelsRight + 15) / 16;
    pSCDec->cmbHeight = (pSCDec->WMII.cHeight + pSCDec->m_param.cExtraPixelsTop + pSCDec->m_param.cExtraPixelsBottom + 15) / 16;
    pSCDec->m_param.cNumChannels = pSCDec->WMISCP.cChannel;
    pSCDec->m_Dparam = &aDecoderParam;
    pSCDec->m_Dparam->bSkipFlexbits = (pSCDec->WMISCP.sbSubband == SB_NO_FLEXBITS);
    pSCDec->m_param.bTranscode = TRUE;

    pParam->bIgnoreOverlap = isTileExtraction(pSCDec, pParam);

    cUnit = (pSCDec->m_param.cfColorFormat == YUV_420 ? 384 : (pSCDec->m_param.cfColorFormat == YUV_422 ? 512 : 256 * pSCDec->m_param.cNumChannels));
    if(cUnit > 256 * MAX_CHANNELS)
        return ICERR_ERROR;
    pSCDec->p1MBbuffer[0] = pMBBuf = (PixelI *)malloc(cUnit * sizeof(PixelI));
    if(pMBBuf == NULL)
        return ICERR_ERROR;
    pSCDec->p1MBbuffer[1] = pSCDec->p1MBbuffer[0] + 256;
    for(i = 2; i < pSCDec->m_param.cNumChannels; i ++)
        pSCDec->p1MBbuffer[i] = pSCDec->p1MBbuffer[i - 1] + (pSCDec->m_param.cfColorFormat == YUV_420 ? 64 : (pSCDec->m_param.cfColorFormat == YUV_422 ? 128 : 256));

    if(pSCDec->m_param.bAlphaChannel){ // alpha channel
        SimpleBitIO SB = {0};

        iAlphaPos = pSCDec->m_param.cNumChannels;
        if((pSCDec->m_pNextSC = (CWMImageStrCodec *)malloc(sizeof(CWMImageStrCodec))) == NULL)
            return ICERR_ERROR;
        *pSCDec->m_pNextSC = *pSCDec;
        pSCDec->m_pNextSC->p1MBbuffer[0] = MBBufAlpha;
        pSCDec->m_pNextSC->WMISCP.cfColorFormat = pSCDec->m_pNextSC->WMII.cfColorFormat = pSCDec->m_pNextSC->m_param.cfColorFormat = Y_ONLY;
        pSCDec->m_pNextSC->WMISCP.cChannel  = pSCDec->m_pNextSC->m_param.cNumChannels = 1;
        pSCDec->m_pNextSC->m_bSecondary = TRUE;
        pSCDec->m_pNextSC->m_pNextSC = pSCDec;
 
        // read plane header of second image plane
        if(attach_SB(&SB, pSCDec->WMISCP.pWStream) != ICERR_OK)
            return ICERR_ERROR;
        ReadImagePlaneHeader(&pSCDec->m_pNextSC->WMII, &pSCDec->m_pNextSC->WMISCP, &pSCDec->m_pNextSC->m_param, &SB);
        detach_SB(&SB);

        if(StrDecInit(pSCDec->m_pNextSC) != ICERR_OK)
            return ICERR_ERROR;
    }
    else
        pParam->uAlphaMode = 0;

    pIOHeaderDec = (U8 *)malloc((PACKETLENGTH * 4 - 1) + PACKETLENGTH * 4 + sizeof(BitIOInfo));
    if(pIOHeaderDec == NULL)
        return ICERR_ERROR;
    memset(pIOHeaderDec, 0, (PACKETLENGTH * 4 - 1) + PACKETLENGTH * 4 + sizeof(BitIOInfo));
    pSCDec->pIOHeader = (BitIOInfo *)((U8 *)ALIGNUP(pIOHeaderDec, PACKETLENGTH * 4) + PACKETLENGTH * 2);
    
    if(StrIODecInit(pSCDec) != ICERR_OK)
        return ICERR_ERROR;

    if(StrDecInit(pSCDec) != ICERR_OK)
        return ICERR_ERROR;

    if(pSCDec->m_param.bAlphaChannel){ // alpha channel
        if(StrDecInit(pSCDec->m_pNextSC) != ICERR_OK)
            return ICERR_ERROR;
    }

    // initialize encoder
    if((pSCEnc = (CWMImageStrCodec *)malloc(sizeof(CWMImageStrCodec))) == NULL)
        return ICERR_ERROR;
    memset(pSCEnc, 0, sizeof(CWMImageStrCodec));

    pSCEnc->WMII = pSCDec->WMII;
    pSCEnc->WMISCP = pSCDec->WMISCP;
    pSCEnc->m_param = pSCDec->m_param;
    pSCEnc->WMISCP.pWStream = pStreamOut;
    pSCEnc->WMISCP.bfBitstreamFormat = pParam->bfBitstreamFormat;
//    pSCEnc->m_param.cfColorFormat = pSCEnc->WMISCP.cfColorFormat = pParam->cfColorFormat;
    pSCEnc->m_param.cfColorFormat = pSCEnc->WMISCP.cfColorFormat;
    pSCEnc->m_param.cNumChannels = (pSCEnc->WMISCP.cfColorFormat == Y_ONLY ? 1 : (pSCEnc->WMISCP.cfColorFormat == YUV_444 ? 3 : pSCEnc->WMISCP.cChannel));
    pSCEnc->m_param.bAlphaChannel = (pParam->uAlphaMode > 0);
    pSCEnc->m_param.bTranscode = TRUE;
    if(pParam->sbSubband >= SB_MAX)
        pParam->sbSubband = SB_ALL;
    if(pParam->sbSubband > pSCEnc->WMISCP.sbSubband)
        pSCEnc->WMISCP.sbSubband = pParam->sbSubband;
    pSCEnc->m_bSecondary = FALSE;

    pIOHeaderEnc = (U8 *)malloc((PACKETLENGTH * 4 - 1) + PACKETLENGTH * 4 + sizeof(BitIOInfo));
    if(pIOHeaderEnc == NULL)
        return ICERR_ERROR;
    memset(pIOHeaderEnc, 0, (PACKETLENGTH * 4 - 1) + PACKETLENGTH * 4 + sizeof(BitIOInfo));
    pSCEnc->pIOHeader = (BitIOInfo *)((U8 *)ALIGNUP(pIOHeaderEnc, PACKETLENGTH * 4) + PACKETLENGTH * 2);
    
    for(i = 0; i < pSCEnc->m_param.cNumChannels; i ++)
        pSCEnc->pPlane[i] = pSCDec->p1MBbuffer[i];
    
    for(i = 1; i < pSCDec->cNumBitIO * (pSCDec->WMISCP.cNumOfSliceMinus1H + 1); i ++){
        if(pSCDec->pIndexTable[i] == 0 && i + 1 != pSCDec->cNumBitIO * (pSCDec->WMISCP.cNumOfSliceMinus1H + 1)) // empty packet
            pSCDec->pIndexTable[i] = pSCDec->pIndexTable[i + 1];
        if(pSCDec->pIndexTable[i] != 0 && pSCDec->pIndexTable[i] < pSCDec->pIndexTable[i - 1]) // out of order bitstream, can not do fast tile extraction!
            pParam->bIgnoreOverlap = FALSE;
    }

    if(getROI(&pSCEnc->WMII, &pSCEnc->m_param, &pSCEnc->WMISCP, pParam) != ICERR_OK)
        return ICERR_ERROR;

    mbLeft = (pParam->cLeftX >> 4);
    mbRight = ((pParam->cLeftX + pParam->cWidth + 15) >> 4);
    mbTop = (pParam->cTopY >> 4);
    mbBottom = ((pParam->cTopY + pParam->cHeight + 15) >> 4);

    if(pSCDec->WMISCP.uiTileX[pSCDec->WMISCP.cNumOfSliceMinus1V] >= mbLeft && pSCDec->WMISCP.uiTileX[pSCDec->WMISCP.cNumOfSliceMinus1V] <= mbRight &&
        pSCDec->WMISCP.uiTileY[pSCDec->WMISCP.cNumOfSliceMinus1H] >= mbTop && pSCDec->WMISCP.uiTileY[pSCDec->WMISCP.cNumOfSliceMinus1H] <= mbBottom)
        pParam->bIgnoreOverlap = FALSE;

    pSCEnc->bTileExtraction = pParam->bIgnoreOverlap;

    mbWidth = pSCEnc->cmbWidth = mbRight - mbLeft;
    mbHeight = pSCEnc->cmbHeight = mbBottom - mbTop;
    if(oO >= O_RCW){
        SWAP(pSCEnc->WMII.cWidth, pSCEnc->WMII.cHeight);
        SWAP(pSCEnc->cmbWidth, pSCEnc->cmbHeight);
    }

    if(oO != O_NONE){
        pFrameBuf = (PixelI *)malloc(pSCEnc->cmbWidth * pSCEnc->cmbHeight * cUnit * sizeof(PixelI));
        if(pFrameBuf == NULL || (pSCEnc->cmbWidth * pSCEnc->cmbHeight * cUnit * sizeof(PixelI) < pSCEnc->cmbWidth * pSCEnc->cmbHeight * cUnit))
            return ICERR_ERROR;
        pMBInfo = (CWMIMBInfo *)malloc(pSCEnc->cmbWidth * pSCEnc->cmbHeight * sizeof(CWMIMBInfo));
        if(pMBInfo == NULL || (pSCEnc->cmbWidth * pSCEnc->cmbHeight * sizeof(CWMIMBInfo) < pSCEnc->cmbWidth * pSCEnc->cmbHeight))
            return ICERR_ERROR;
        if(pParam->uAlphaMode > 0){ // alpha channel
            pFrameBufAlpha = (PixelI *)malloc(pSCEnc->cmbWidth * pSCEnc->cmbHeight * 256 * sizeof(PixelI));
            if(pFrameBufAlpha == NULL || (pSCEnc->cmbWidth * pSCEnc->cmbHeight * 256 * sizeof(PixelI) < pSCEnc->cmbWidth * pSCEnc->cmbHeight * 256))
                return ICERR_ERROR;
            pMBInfoAlpha = (CWMIMBInfo *)malloc(pSCEnc->cmbWidth * pSCEnc->cmbHeight * sizeof(CWMIMBInfo));
            if(pMBInfoAlpha == NULL || (pSCEnc->cmbWidth * pSCEnc->cmbHeight * sizeof(CWMIMBInfo) < pSCEnc->cmbWidth * pSCEnc->cmbHeight))
                return ICERR_ERROR;
        }
    }

    if(oO < O_RCW && pSCEnc->WMII.oOrientation < O_RCW)
        pSCEnc->WMII.oOrientation ^= oO;
    else if(oO >= O_RCW && pSCEnc->WMII.oOrientation >= O_RCW){
        pSCEnc->WMII.oOrientation ^= oO;
        pSCEnc->WMII.oOrientation = (pSCEnc->WMII.oOrientation & 1) * 2 + (pSCEnc->WMII.oOrientation >> 1);
    }
    else if(oO >= O_RCW && pSCEnc->WMII.oOrientation < O_RCW)
        pSCEnc->WMII.oOrientation = oO ^ ((pSCEnc->WMII.oOrientation & 1) * 2 + (pSCEnc->WMII.oOrientation >> 1));
    else
        pSCEnc->WMII.oOrientation ^= ((oO & 1) * 2 + (oO >> 1));
    
//    pSCEnc->WMISCP.nExpBias += 128;

    if(pParam->bIgnoreOverlap == TRUE){
        attachISWrite(pSCEnc->pIOHeader, pSCEnc->WMISCP.pWStream);
        pSCEnc->pTile = pSCDec->pTile;
        if(pSCEnc->WMISCP.cNumOfSliceMinus1H + pSCEnc->WMISCP.cNumOfSliceMinus1V == 0 && pSCEnc->WMISCP.bfBitstreamFormat == SPATIAL)
            pSCEnc->m_param.bIndexTable = FALSE;
        WriteWMIHeader(pSCEnc);
    }
    else{
        pTileQPInfo = (CTileQPInfo *)malloc((oO == O_NONE ? 1 : (pSCEnc->WMISCP.cNumOfSliceMinus1H + 1) * (pSCEnc->WMISCP.cNumOfSliceMinus1V + 1)) * sizeof( CTileQPInfo));
        if(pTileQPInfo == NULL || ((oO == O_NONE ? 1 : (pSCEnc->WMISCP.cNumOfSliceMinus1H + 1) * (pSCEnc->WMISCP.cNumOfSliceMinus1V + 1)) * sizeof( CTileQPInfo) < (oO == O_NONE ? 1 : (pSCEnc->WMISCP.cNumOfSliceMinus1H + 1) * (pSCEnc->WMISCP.cNumOfSli...
            return ICERR_ERROR;
        
        if(StrEncInit(pSCEnc) != ICERR_OK)
            return ICERR_ERROR;
    }

    if(pParam->uAlphaMode > 0){ // alpha channel
//        pSCEnc->WMISCP.nExpBias -= 128;
        if((pSCEnc->m_pNextSC = (CWMImageStrCodec *)malloc(sizeof(CWMImageStrCodec))) == NULL)
            return ICERR_ERROR;
        *pSCEnc->m_pNextSC = *pSCEnc;
        pSCEnc->m_pNextSC->pPlane[0] = pSCDec->m_pNextSC->p1MBbuffer[0];
        pSCEnc->m_pNextSC->WMISCP.cfColorFormat = pSCEnc->m_pNextSC->WMII.cfColorFormat = pSCEnc->m_pNextSC->m_param.cfColorFormat = Y_ONLY;
        pSCEnc->m_pNextSC->WMISCP.cChannel  = pSCEnc->m_pNextSC->m_param.cNumChannels = 1;
        pSCEnc->m_pNextSC->m_bSecondary = TRUE;
        pSCEnc->m_pNextSC->m_pNextSC = pSCEnc;
        pSCEnc->m_pNextSC->m_param = pSCDec->m_pNextSC->m_param;
        pSCEnc->m_param.bAlphaChannel = TRUE;

        if(pParam->bIgnoreOverlap == TRUE)
            pSCEnc->m_pNextSC->pTile = pSCDec->m_pNextSC->pTile;
        else if(StrEncInit(pSCEnc->m_pNextSC) != ICERR_OK)
                return ICERR_ERROR;

        WriteImagePlaneHeader(pSCEnc->m_pNextSC);
    }

    if(pParam->bIgnoreOverlap == TRUE){
        SUBBAND sbEnc = pSCEnc->WMISCP.sbSubband, sbDec = pSCDec->WMISCP.sbSubband;
        size_t cfEnc = ((pSCEnc->WMISCP.bfBitstreamFormat == SPATIAL || sbEnc == SB_DC_ONLY) ? 1 : (sbEnc == SB_NO_HIGHPASS ? 2 : (sbEnc == SB_NO_FLEXBITS ? 3 : 4)));
        size_t cfDec = ((pSCDec->WMISCP.bfBitstreamFormat == SPATIAL || sbDec == SB_DC_ONLY) ? 1 : (sbDec == SB_NO_HIGHPASS ? 2 : (sbDec == SB_NO_FLEXBITS ? 3 : 4)));
        size_t k, l = 0;

        pSCEnc->pIndexTable = (size_t *)malloc(sizeof(size_t) * (pSCEnc->WMISCP.cNumOfSliceMinus1H + 1) * (pSCEnc->WMISCP.cNumOfSliceMinus1V + 1) * cfEnc);

        if(pSCEnc->pIndexTable == NULL || cfEnc > cfDec)
            return ICERR_ERROR;

        pSCEnc->cNumBitIO = cfEnc * (pSCEnc->WMISCP.cNumOfSliceMinus1V + 1);
        
        for(j = 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 ++, 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;



( run in 1.565 second using v1.01-cache-2.11-cpan-4991d5b9bd9 )