Alien-FreeImage

 view release on metacpan or  search on metacpan

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

Int readTileHeaderHP(CWMImageStrCodec * pSC, BitIOInfo * pIO)
{
    if(pSC->WMISCP.sbSubband != SB_DC_ONLY && pSC->WMISCP.sbSubband != SB_NO_HIGHPASS && (pSC->m_param.uQPMode & 4) != 0){ // not HP uniform
        CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
        U8 i;

        pTile->bUseLP = (getBit16(pIO, 1) == 1 ? TRUE : FALSE);
        pTile->cBitsHP = 0;
        pTile->cNumQPHP = 1;

        if(pSC->cTileRow > 0)
            freeQuantizer(pTile->pQuantizerHP);
        
        if(pTile->bUseLP == TRUE){
            pTile->cNumQPHP = pTile->cNumQPLP;
            if(allocateQuantizer(pTile->pQuantizerHP, pSC->m_param.cNumChannels, pTile->cNumQPHP) != ICERR_OK)
                return ICERR_ERROR;
            useLPQuantizer(pSC, pTile->cNumQPHP, pSC->cTileColumn);
        }
        else{
            pTile->cNumQPHP = (U8)getBit16(pIO, 4) + 1;
            pTile->cBitsHP = dquantBits(pTile->cNumQPHP);

            if(allocateQuantizer(pTile->pQuantizerHP, pSC->m_param.cNumChannels, pTile->cNumQPHP) != ICERR_OK)
                return ICERR_ERROR;

            for(i = 0; i < pTile->cNumQPHP; i ++){
                pTile->cChModeHP[i] = readQuantizer(pTile->pQuantizerHP, pIO, pSC->m_param.cNumChannels, i);
                formatQuantizer(pTile->pQuantizerHP, pTile->cChModeHP[i], pSC->m_param.cNumChannels, i, FALSE, pSC->m_param.bScaledArith);
            }
        }
    }

    return ICERR_OK;
}

Int readPackets(CWMImageStrCodec * pSC)
{
    if(pSC->cColumn == 0 && pSC->cRow == pSC->WMISCP.uiTileY[pSC->cTileRow]){ // start of a new horizontal slice
        size_t k;
        
        if (pSC->m_bSecondary) {
             if(pSC->cNumBitIO > 0){
                for(k = 0; k <= pSC->WMISCP.cNumOfSliceMinus1V; k ++){
                    // reset coding contexts
                    ResetCodingContextDec(&pSC->m_pCodingContext[k]);
                }
            }
            else{ // for multiple decoding calls!
                ResetCodingContextDec(&pSC->m_pCodingContext[0]);
            }
        }
        else {
            // get sizes of each packet and update index table
            for(k = 0; k < pSC->cNumBitIO; k ++){
                if(pSC->ppWStream != NULL){ // new API
                    unsigned cBands = (pSC->WMISCP.bfBitstreamFormat == SPATIAL ? 1 : pSC->cSB);
                    struct WMPStream ** ppWS = pSC->ppWStream + (pSC->WMISCP.cNumOfSliceMinus1V + 1) * pSC->cTileRow * cBands
                        + k / cBands * cBands + (k % cBands);

                    if(pSC->cTileRow > 0 && pSC->m_ppBitIO[k]->pWS != NULL)     // attached to the same packet of the tile on top
                        detachISRead(pSC, pSC->m_ppBitIO[k]);    // detach it
                    
                    if(ppWS[0] != NULL)
                        attachISRead(pSC->m_ppBitIO[k], ppWS[0], pSC); // need to attach it
                }
                else{
                    if(pSC->cTileRow > 0)
                        detachISRead(pSC, pSC->m_ppBitIO[k]);
                    pSC->WMISCP.pWStream->SetPos(pSC->WMISCP.pWStream, pSC->pIndexTable[pSC->cNumBitIO * pSC->cTileRow + k] + pSC->cHeaderSize);
                    attachISRead(pSC->m_ppBitIO[k], pSC->WMISCP.pWStream, pSC);
                }
            }
            
            if(pSC->cNumBitIO == 0){
                detachISRead(pSC, pSC->pIOHeader);
                if(pSC->ppWStream != NULL){// new API
                    attachISRead(pSC->pIOHeader, pSC->ppWStream[0], pSC); // need to attach it
                }
                else{
                    pSC->WMISCP.pWStream->SetPos(pSC->WMISCP.pWStream, pSC->cHeaderSize);
                    attachISRead(pSC->pIOHeader, pSC->WMISCP.pWStream, pSC);
                }
            }
            
            for(k = 0; k <= pSC->WMISCP.cNumOfSliceMinus1V; k ++){
                U8 pID = (U8)((pSC->cTileRow * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + k) & 0x1F);
                
                // read packet header
                if(pSC->WMISCP.bfBitstreamFormat == SPATIAL){
                    BitIOInfo * pIO = (pSC->cNumBitIO == 0 ? pSC->pIOHeader : pSC->m_ppBitIO[k]);

                    if(pIO->pWS == NULL || readPacketHeader(pIO, 0, pID) != ICERR_OK)
                        return ICERR_ERROR;
                    pSC->m_pCodingContext[k].m_iTrimFlexBits = (pSC->m_param.bTrimFlexbitsFlag) ? getBit16(pIO, 4) : 0;
                }
                else{
                    if(pSC->m_ppBitIO[k * pSC->cSB + 0] == NULL || readPacketHeader(pSC->m_ppBitIO[k * pSC->cSB + 0], 1, pID) != ICERR_OK)
                        return ICERR_ERROR;
                    if(pSC->cSB > 1){
                        if(pSC->m_ppBitIO[k * pSC->cSB + 1] == NULL || readPacketHeader(pSC->m_ppBitIO[k * pSC->cSB + 1], 2, pID) != ICERR_OK)
                            return ICERR_ERROR;
                    }
                    if(pSC->cSB > 2){
                        if(pSC->m_ppBitIO[k * pSC->cSB + 2] == NULL || readPacketHeader(pSC->m_ppBitIO[k * pSC->cSB + 2], 3, pID) != ICERR_OK)
                            return ICERR_ERROR;
//                        readTileHeaderHP(pSC, pSC->m_ppBitIO[k * pSC->cSB + 2]);
                    }
                    if(pSC->cSB > 3){
                        if(pSC->m_ppBitIO[k * pSC->cSB + 3] == NULL)
                            return ICERR_ERROR;
                        readPacketHeader(pSC->m_ppBitIO[k * pSC->cSB + 3], 4, pID);  // bad flexbits packet doesn't generate an error
                        pSC->m_pCodingContext[k].m_iTrimFlexBits = (pSC->m_param.bTrimFlexbitsFlag) ? getBit16(pSC->m_ppBitIO[k * pSC->cSB + 3], 4) : 0;
                    }
                }

                // reset coding contexts
                ResetCodingContextDec(&pSC->m_pCodingContext[k]);
            }
        }
    }
    
    if(pSC->m_bCtxLeft && pSC->m_bCtxTop && pSC->m_bSecondary == FALSE){
        CCodingContext *pContext = &pSC->m_pCodingContext[pSC->cTileColumn];
        
        readTileHeaderDC(pSC, pContext->m_pIODC);
        if(pSC->m_pNextSC != NULL)
            readTileHeaderDC(pSC->m_pNextSC, pContext->m_pIODC);
        if(pSC->cSB > 1){
            readTileHeaderLP(pSC, pContext->m_pIOLP);
            if(pSC->m_pNextSC != NULL)
                readTileHeaderLP(pSC->m_pNextSC, pContext->m_pIOLP);
        }
        if(pSC->cSB > 2){
            readTileHeaderHP(pSC, pContext->m_pIOAC);
            if(pSC->m_pNextSC != NULL)
                readTileHeaderHP(pSC->m_pNextSC, pContext->m_pIOAC);
        }
    }

    return ICERR_OK;
}

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

    if (iEscape)
        *iEscape = 0;

    s = getBit32(pIO, 8);
    if (s == 0xfd || s == 0xfe || s == 0xff) {
        if (iEscape)
            *iEscape = (Int) s;
        s = 0;
    }
    else if (s < 0xfb) {
        s = (s << 8) | getBit32(pIO, 8);
    }
    else {
        s -= 0xfb;
        if (s) {
            s = getBit32(pIO, 16) << 16;
            s = (s | getBit32(pIO, 16)) << 16;
            s <<= 16;
        }
        s |= (getBit32(pIO, 16) << 16);
        s |= getBit32(pIO, 16);
    }
    return s;
}

//================================================================
Int readIndexTable(CWMImageStrCodec * pSC)
{
    BitIOInfo* pIO = pSC->pIOHeader;
    readIS_L1(pSC, pIO);

    if(pSC->cNumBitIO > 0){
        size_t *pTable = pSC->pIndexTable;
        U32 iEntry = (U32)pSC->cNumBitIO * (pSC->WMISCP.cNumOfSliceMinus1H + 1), i;

        // read index table header [0x0001] - 2 bytes
        if (getBit32(pIO, 16) != 1)
            return ICERR_ERROR;

        //iBits = getBit16(pIO, 5) + 1; // how many bits per entry
        for(i = 0; i < iEntry; i ++){
            readIS_L1(pSC, pIO);
            pTable[i] = GetVLWordEsc(pIO, NULL);  // escape handling is not important since the respective band is not accessed
        }
    }

    pSC->cHeaderSize = GetVLWordEsc(pIO, NULL);  // escape handling is not important
    flushToByte(pIO);    
    
    pSC->cHeaderSize += getPosRead(pSC->pIOHeader); // get header length

    return ICERR_OK;
}

Int StrIODecInit(CWMImageStrCodec* pSC)
{
    if(allocateBitIOInfo(pSC) != ICERR_OK){
        return ICERR_ERROR;
    }
    
    attachISRead(pSC->pIOHeader, pSC->WMISCP.pWStream, pSC);

    readIndexTable(pSC);

    if(pSC->WMISCP.bVerbose){
        U32 i, j;

        printf("\n%d horizontal tiles:\n", pSC->WMISCP.cNumOfSliceMinus1H + 1);
        for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1H; i ++){
            printf("    offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileY[i]);
        }

        printf("\n%d vertical tiles:\n", pSC->WMISCP.cNumOfSliceMinus1V + 1);
        for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i ++){
            printf("    offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileX[i]);
        }

        if(pSC->WMISCP.bfBitstreamFormat == SPATIAL){
            printf("\nSpatial order bitstream\n");
        }
        else{
            printf("\nFrequency order bitstream\n");
        }

        if(!pSC->m_param.bIndexTable){
            printf("\nstreaming mode, no index table.\n");
        }
        else if(pSC->WMISCP.bfBitstreamFormat == SPATIAL){
            for(j = 0; j <= pSC->WMISCP.cNumOfSliceMinus1H; j ++){
                for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i ++){
                    size_t * p = &pSC->pIndexTable[j * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + i];
                    if(i + j != pSC->WMISCP.cNumOfSliceMinus1H + pSC->WMISCP.cNumOfSliceMinus1V){
                        printf("bitstream size for tile (%d, %d): %d.\n", j, i, (int) (p[1] - p[0]));
                    }
                    else{
                        printf("bitstream size for tile (%d, %d): unknown.\n", j, i);
                    }
                }
            }
        }
        else{
            for(j = 0; j <= pSC->WMISCP.cNumOfSliceMinus1H; j ++){
                for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i ++){
                    size_t * p = &pSC->pIndexTable[(j * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + i) * 4];
                    if(i + j != pSC->WMISCP.cNumOfSliceMinus1H + pSC->WMISCP.cNumOfSliceMinus1V){
                        printf("bitstream size of (DC, LP, AC, FL) for tile (%d, %d): %d %d %d %d.\n", j, i,
                            (int) (p[1] - p[0]), (int) (p[2] - p[1]), (int) (p[3] - p[2]), (int) (p[4] - p[3]));
                    }
                    else{
                        printf("bitstream size of (DC, LP, AC, FL) for tile (%d, %d): %d %d %d unknown.\n", j, i,
                            (int) (p[1] - p[0]), (int) (p[2] - p[1]), (int) (p[3] - p[2]));
                    }
                }
            }
        }
    }

    return 0;
}

Int StrIODecTerm(CWMImageStrCodec* pSC)

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

        }
        else
            pSC->uQPMode += ((pSC->uQPMode & 1) << 1) + ((pSC->uQPMode & 0x18) << 2);

        if(pSCP->sbSubband != SB_NO_HIGHPASS){
            if(getBit32_SB(pSB, 1) == 0){ // don't use LP QP
                pSC->uQPMode += 0x400;
                if(getBit32_SB(pSB, 1) == 1) // HP uniform
                    pSC->uQPMode += (readQuantizerSB(pSC->uiQPIndexHP, pSB, pSC->cNumChannels) << 7);
                else
                    pSC->uQPMode += 4;
            }
            else
                pSC->uQPMode += ((pSC->uQPMode & 2) << 1) + ((pSC->uQPMode & 0x60) << 2);
        }
    }

    if(pSCP->sbSubband == SB_DC_ONLY)
        pSC->uQPMode |= 0x200;
    else if(pSCP->sbSubband == SB_NO_HIGHPASS)
        pSC->uQPMode |= 0x400;
    

    FailIf((pSC->uQPMode & 0x600) == 0, WMP_errInvalidParameter); // frame level QPs must be specified independently!

    flushToByte_SB(pSB);  // remove this later

Cleanup:
    return WMP_errSuccess == err ? ICERR_OK : ICERR_ERROR;
}

/*************************************************************************
    Read header of image, and header of FIRST PLANE only
*************************************************************************/
Int ReadWMIHeader(
    CWMImageInfo* pII,
    CWMIStrCodecParam *pSCP,
    CCoreParameters *pSC)
{
    U32 i;
    ERR err = WMP_errSuccess;
    Bool bTilingPresent, bInscribed, bTileStretch, bAbbreviatedHeader;
    struct WMPStream* pWS = pSCP->pWStream;

    SimpleBitIO SB = {0};
    SimpleBitIO* pSB = &SB;

    U8 szMS[8] = {0};
    U32 cbStream = 0;

    // U32 bits = 0;
    // Int HEADERSIZE = 0;

    assert(pSC != NULL);
    //================================
// 0
    /** signature **/
    Call(pWS->Read(pWS, szMS, sizeof(szMS)));
    FailIf(szMS != (U8 *) strstr((char *) szMS, "WMPHOTO"), WMP_errUnsupportedFormat);
    //================================
    Call(attach_SB(pSB, pWS));

// 8
    /** codec version and subversion **/
    i = getBit32_SB(pSB, 4);
    FailIf((i != CODEC_VERSION), WMP_errIncorrectCodecVersion);
    pSC->cVersion = i;
    i = getBit32_SB(pSB, 4); // subversion
    FailIf((i != CODEC_SUBVERSION &&
        i != CODEC_SUBVERSION_NEWSCALING_SOFT_TILES && i != CODEC_SUBVERSION_NEWSCALING_HARD_TILES),
        WMP_errIncorrectCodecSubVersion);
    pSC->cSubVersion = i;

    pSC->bUseHardTileBoundaries = FALSE;
    if (pSC->cSubVersion == CODEC_SUBVERSION_NEWSCALING_HARD_TILES) 
        pSC->bUseHardTileBoundaries = TRUE;

    pSCP->bUseHardTileBoundaries = pSC->bUseHardTileBoundaries;

// 9 primary parameters
    bTilingPresent = (Bool) getBit32_SB(pSB, 1); // tiling present
    pSCP->bfBitstreamFormat = getBit32_SB(pSB, 1); // bitstream layout
    pII->oOrientation = (ORIENTATION)getBit32_SB(pSB, 3); // presentation orientation
    pSC->bIndexTable = getBit32_SB(pSB, 1);
    i = getBit32_SB(pSB, 2); // overlap
    FailIf((i == 3), WMP_errInvalidParameter);
    pSCP->olOverlap = i;

// 11 some other parameters
    bAbbreviatedHeader = (Bool) getBit32_SB(pSB, 1); // short words for size and tiles
    pSCP->bdBitDepth = (BITDEPTH) getBit32_SB(pSB, 1); // long word
pSCP->bdBitDepth = BD_LONG; // remove when optimization is done
    bInscribed = (Bool) getBit32_SB(pSB, 1); // windowing
    pSC->bTrimFlexbitsFlag = (Bool) getBit32_SB(pSB, 1); // trim flexbits flag
    bTileStretch = (Bool) getBit32_SB(pSB, 1); // tile stretching flag
    pSC->bRBSwapped = (Bool) getBit32_SB(pSB, 1); // red-blue swap flag
    getBit32_SB(pSB, 1);  // padding / reserved bit
    pSC->bAlphaChannel = (Bool) getBit32_SB(pSB, 1); // alpha channel present

// 10 - informational
    pII->cfColorFormat = getBit32_SB(pSB, 4); // source color format
    pII->bdBitDepth = getBit32_SB(pSB, 4); // source bit depth

    if(BD_1alt == pII->bdBitDepth)
    {
        pII->bdBitDepth = BD_1;
        pSCP->bBlackWhite = 1;
    }

// 12 - Variable length fields
// size
    pII->cWidth = getBit32_SB(pSB, bAbbreviatedHeader ? 16 : 32) + 1;
    pII->cHeight = getBit32_SB(pSB, bAbbreviatedHeader ? 16 : 32) + 1;
    pSC->cExtraPixelsTop = pSC->cExtraPixelsLeft = pSC->cExtraPixelsBottom = pSC->cExtraPixelsRight = 0;
    if (bInscribed == FALSE && (pII->cWidth & 0xf) != 0)
        pSC->cExtraPixelsRight = 0x10 - (pII->cWidth & 0xF);
    if (bInscribed == FALSE && (pII->cHeight & 0xf) != 0)
        pSC->cExtraPixelsBottom = 0x10 - (pII->cHeight & 0xF);

// tiling
    pSCP->cNumOfSliceMinus1V = pSCP->cNumOfSliceMinus1H = 0;

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

    }
    cb += i * cMacBlock;

    pb = malloc(cb);
    if(pb == NULL)
        return WMP_errOutOfMemory;
    memset(pb, 0, cb);

    //================================================
    pSC = (CWMImageStrCodec*)pb; pb += sizeof(*pSC);
    if(pSC == NULL)
        return ICERR_ERROR;

    // Set up perf timers
    PERFTIMER_ONLY(pSC->m_fMeasurePerf = pSCP->fMeasurePerf);
    PERFTIMER_NEW(pSC->m_fMeasurePerf, &pSC->m_ptEndToEndPerf);
    PERFTIMER_NEW(pSC->m_fMeasurePerf, &pSC->m_ptEncDecPerf);
    PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEndToEndPerf);
    PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
    PERFTIMER_COPYSTARTTIME(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf, pSC->m_ptEndToEndPerf);

    pSC->m_Dparam = (CWMDecoderParameters*)pb; pb += sizeof(CWMDecoderParameters);
    pSC->cbChannel = cbChannel;
    //pSC->cNumChannels = SC.WMISCP.cChannel;
    pSC->bUseHardTileBoundaries = bUseHardTileBoundaries;

    //================================================
    InitializeStrDec(pSC, &SC.m_param, &SC);

    //================================================
    // 2 Macro Row buffers for each channel
    pb = ALIGNUP(pb, 128);
    for (i = 0; i < pSC->m_param.cNumChannels; i++) {
        pSC->a0MBbuffer[i] = (PixelI*)pb; pb += cbMacBlockStride * pSC->cmbWidth;
        pSC->a1MBbuffer[i] = (PixelI*)pb; pb += cbMacBlockStride * pSC->cmbWidth;
        cbMacBlockStride = cbMacBlockChroma;
    }

    //================================================
    // lay 2 aligned IO buffers just below pIO struct
    pb = (char*)ALIGNUP(pb, PACKETLENGTH * 4) + PACKETLENGTH * 2;
    pSC->pIOHeader = (BitIOInfo*)pb; pb += sizeof(*pSC->pIOHeader);

    // if interleaved alpha is needed
    if (pSC->m_param.bAlphaChannel) {
        SimpleBitIO SB = {0};
        cbMacBlockStride = cbChannel * 16 * 16;

        // 1. allocate new pNextSC info
        //================================================
        cb = sizeof(*pNextSC) + (128 - 1) + cbMacBlockStride * cMacBlock * 2;
        // if primary image is safe to allocate, alpha channel is certainly safe
        pb = malloc(cb);
        if(pb == NULL)
            return WMP_errOutOfMemory;
        memset(pb, 0, cb);
        //================================================
        pNextSC = (CWMImageStrCodec*)pb; pb += sizeof(*pNextSC);

        // read plane header of second image plane
        Call(attach_SB(&SB, pSCP->pWStream));
        InitializeStrDec(pNextSC, &SC.m_param, &SC);
        ReadImagePlaneHeader(&pNextSC->WMII, &pNextSC->WMISCP, &pNextSC->m_param, &SB);
        detach_SB(&SB);

        // 2. initialize pNextSC
        if(pNextSC == NULL)
            return ICERR_ERROR;
        pNextSC->m_Dparam = pSC->m_Dparam;
        pNextSC->cbChannel = cbChannel;
        //================================================

        // 3. initialize arrays
//        InitializeStrDec(pNextSC, &SC.m_param, &SC);
        pNextSC->m_param.cfColorFormat = Y_ONLY;
        pNextSC->m_param.cNumChannels = 1;
        pNextSC->m_param.bAlphaChannel = TRUE;
        //================================================

        // 2 Macro Row buffers for each channel
        pb = ALIGNUP(pb, 128);
        pNextSC->a0MBbuffer[0] = (PixelI*)pb; pb += cbMacBlockStride * pNextSC->cmbWidth;
        pNextSC->a1MBbuffer[0] = (PixelI*)pb;
        //================================================
        pNextSC->pIOHeader = pSC->pIOHeader;
        //================================================

        // 4. link pSC->pNextSC = pNextSC
        pNextSC->m_pNextSC = pSC;
        pNextSC->m_bSecondary = TRUE;

    }
    else
        pSC->WMISCP.uAlphaMode = 0;

    //================================================
    FailIf((StrIODecInit(pSC) != ICERR_OK), WMP_errOutOfMemory);
    FailIf((StrDecInit(pSC) != ICERR_OK), WMP_errOutOfMemory);
    if (pNextSC) {
        // 5. StrEncInit
        FailIf((StrDecInit(pNextSC) != ICERR_OK), WMP_errOutOfMemory);
    }

    pSC->m_pNextSC = pNextSC;
    //================================================
    *pII = pSC->WMII;
    *pSCP = pSC->WMISCP;
    *pctxSC = (CTXSTRCODEC)pSC;

    if(pSC->WMII.cPostProcStrength){
        initPostProc(pSC->pPostProcInfo, pSC->cmbWidth, pSC->m_param.cNumChannels);
        if (pSC->m_param.bAlphaChannel) 
            initPostProc(pNextSC->pPostProcInfo, pNextSC->cmbWidth, pNextSC->m_param.cNumChannels);
    }

    PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);

Cleanup:
    return WMP_errSuccess == err ? ICERR_OK : ICERR_ERROR;
}



( run in 0.384 second using v1.01-cache-2.11-cpan-3d66aa2751a )