Alien-FreeImage

 view release on metacpan or  search on metacpan

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

        if (pSC->cmbHeight * pSC->cmbWidth * pSC->WMISCP.cChannel >= MAX_MEMORY_SIZE_IN_WORDS) {
#ifdef _WINDOWS_
            pSC->ppTempFile = (TCHAR **)malloc(pSC->cNumBitIO * sizeof(TCHAR *));
            if(pSC->ppTempFile == NULL) return ICERR_ERROR;
            memset(pSC->ppTempFile, 0, pSC->cNumBitIO * sizeof(TCHAR *)); 
#else
            pSC->ppTempFile = (char **)malloc(pSC->cNumBitIO * sizeof(char *));
            if(pSC->ppTempFile == NULL) return ICERR_ERROR;
            memset(pSC->ppTempFile, 0, pSC->cNumBitIO * sizeof(char *));
#endif
        }

        for(i = 0; i < pSC->cNumBitIO; i ++){
            if (pSC->cmbHeight * pSC->cmbWidth * pSC->WMISCP.cChannel >= MAX_MEMORY_SIZE_IN_WORDS) {
#if defined(_WINDOWS_) || defined(UNDER_CE)  // tmpnam does not exist in VS2005 WinCE CRT              
                Bool bUnicode = sizeof(TCHAR) == 2;
                pSC->ppTempFile[i] = (TCHAR *)malloc(MAX_PATH * sizeof(TCHAR));
                if(pSC->ppTempFile[i] == NULL) return ICERR_ERROR;

                pFilename = (char *)pSC->ppTempFile[i];

                cSize = GetTempPath(MAX_PATH, szPath);
                if(cSize == 0 || cSize >= MAX_PATH)
                    return ICERR_ERROR;
                if(!GetTempFileName(szPath, TEXT("wdp"), 0, pSC->ppTempFile[i]))
                    return ICERR_ERROR;

                if(bUnicode){ // unicode file name
                    for(k = j = cSize = 0; cSize < MAX_PATH; cSize ++, j += 2){
                        if(pSC->ppTempFile[i][cSize] == '\0')
                            break;
                        if(pFilename[j] != '\0')
                            pFilename[k ++] = pFilename[j];
                        if(pFilename[j + 1] != '\0')
                            pFilename[k ++] = pFilename[j + 1];
                    }
                    pFilename[cSize] = '\0';
                }

#else //DPK needs to support ANSI 
                pSC->ppTempFile[i] = (char *)malloc(FILENAME_MAX * sizeof(char));
                if(pSC->ppTempFile[i] == NULL) return ICERR_ERROR;

                if ((pFilename = tmpnam(NULL)) == NULL)
                    return ICERR_ERROR;                
                strcpy(pSC->ppTempFile[i], pFilename);
#endif
                if(CreateWS_File(pSC->ppWStream + i, pFilename, "w+b") != ICERR_OK) return ICERR_ERROR;                

            }
            else {
                if(CreateWS_List(pSC->ppWStream + i) != ICERR_OK) return ICERR_ERROR;
            }
            attachISWrite(pSC->m_ppBitIO[i], pSC->ppWStream[i]);
        }
    }

    return ICERR_OK;
}

#define PUTBITS putBit16
/*************************************************************************
    Write variable length byte aligned integer
*************************************************************************/
static Void PutVLWordEsc(BitIOInfo* pIO, Int iEscape, size_t s)
{
    if (iEscape) {
        assert(iEscape <= 0xff && iEscape > 0xfc); // fd,fe,ff are the only valid escapes
        PUTBITS(pIO, iEscape, 8);
    }
    else if (s < 0xfb00) {
        PUTBITS(pIO, (U32) s, 16);
    }
    else {
        size_t t = s >> 16;
        if ((t >> 16) == 0) {
            PUTBITS(pIO, 0xfb, 8);
        }
        else {
            t >>= 16;
            PUTBITS(pIO, 0xfc, 8);
            PUTBITS(pIO, (U32)(t >> 16) & 0xffff, 16);
            PUTBITS(pIO, (U32) t & 0xffff, 16);
        }
        PUTBITS(pIO, (U32) t & 0xffff, 16);
        PUTBITS(pIO, (U32) s & 0xffff, 16);
    }
}

/*************************************************************************
    Write index table at start (null index table)
*************************************************************************/
Int writeIndexTableNull(CWMImageStrCodec * pSC)
{
    if(pSC->cNumBitIO == 0){
        BitIOInfo* pIO = pSC->pIOHeader;
        fillToByte(pIO);

        /* Profile / Level info */
        PutVLWordEsc(pIO, 0, 4);    // 4 bytes
        PUTBITS(pIO, 111, 8);       // default profile idc
        PUTBITS(pIO, 255, 8);       // default level idc
        PUTBITS(pIO, 1, 16);        // LAST_FLAG
    }

    return ICERR_OK;
}

/*************************************************************************
    Write index table
*************************************************************************/
Int writeIndexTable(CWMImageStrCodec * pSC)
{
    if(pSC->cNumBitIO > 0){
        BitIOInfo* pIO = pSC->pIOHeader;
        size_t *pTable = pSC->pIndexTable, iSize[4] = { 0 };
        I32 iEntry = (I32)pSC->cNumBitIO * (pSC->WMISCP.cNumOfSliceMinus1H + 1), i, k, l;
        
        // write index table header [0x0001] - 2 bytes
        PUTBITS(pIO, 1, 16);

        for(i = pSC->WMISCP.cNumOfSliceMinus1H; i>= 0 && pSC->bTileExtraction == FALSE; i --){
            for(k = 0; k < (int)pSC->cNumBitIO; ){
                for(l = 0; l < (pSC->WMISCP.bfBitstreamFormat == FREQUENCY && pSC->WMISCP.bProgressiveMode ? pSC->cSB : 1); l ++, k ++)
                {
                if (i > 0)
                pTable[pSC->cNumBitIO * i + k] -= pSC->pIndexTable[pSC->cNumBitIO * (i - 1) + k]; // packet length
                iSize[l] += pTable[pSC->cNumBitIO * i + k];
                }
            }
        }

        iSize[3] = iSize[2] + iSize[1] + iSize[0];
        iSize[2] = iSize[1] + iSize[0];
        iSize[1] = iSize[0];
        iSize[0] = 0;

        for(i = 0; i < iEntry; ){
        for(l = 0; l < (pSC->WMISCP.bfBitstreamFormat == FREQUENCY && pSC->WMISCP.bProgressiveMode ? pSC->cSB : 1); l ++, i ++)
        {
            writeIS_L1(pSC, pIO);
            PutVLWordEsc(pIO, (pTable[i] <= MINIMUM_PACKET_LENGTH) ? 0xff : 0, iSize[l]);
            iSize[l] += (pTable[i] <= MINIMUM_PACKET_LENGTH) ? 0 : pTable[i];
        }
        }

        writeIS_L1(pSC, pIO);
        PutVLWordEsc(pIO, 0xff, 0); // escape to end
        fillToByte(pIO);
    }

    return ICERR_OK;
}

Int copyTo(struct WMPStream * pSrc, struct WMPStream * pDst, size_t iBytes)
{
    char pData[PACKETLENGTH];

    if (iBytes <= MINIMUM_PACKET_LENGTH){
        pSrc->Read(pSrc, pData, iBytes);
        return ICERR_OK;
    }

    while(iBytes > PACKETLENGTH){
        pSrc->Read(pSrc, pData, PACKETLENGTH);
        pDst->Write(pDst, pData, PACKETLENGTH);
        iBytes -= PACKETLENGTH;
    }
    pSrc->Read(pSrc, pData, iBytes);
    pDst->Write(pDst, pData, iBytes);

    return ICERR_OK;
}

Int StrIOEncTerm(CWMImageStrCodec* pSC)
{
    BitIOInfo * pIO = pSC->pIOHeader;

    fillToByte(pIO);

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

					}
					else{
						copyTo(pSC->ppWStream[j * pSC->cSB + l], pDst, pTable[k]);
						k += pSC->cSB;
					}
				}
			}
        }

        if (pSC->cmbHeight * pSC->cmbWidth * pSC->WMISCP.cChannel >= MAX_MEMORY_SIZE_IN_WORDS){           
            for(i = 0; i < pSC->cNumBitIO; i ++){
                if(pSC->ppWStream && pSC->ppWStream[i]){
                    if((*(pSC->ppWStream + i))->state.file.pFile){
                        fclose((*(pSC->ppWStream + i))->state.file.pFile);
#ifdef _WINDOWS_
                        if(DeleteFileA((LPCSTR)pSC->ppTempFile[i]) == 0)
                            return ICERR_ERROR;
#else
                        if (remove(pSC->ppTempFile[i]) == -1)
                            return ICERR_ERROR;
#endif
                    }

                    if (*(pSC->ppWStream + i))
                        free(*(pSC->ppWStream + i));
                }
                if(pSC->ppTempFile){
                    if(pSC->ppTempFile[i])
                        free(pSC->ppTempFile[i]);
                }
            }

            if(pSC->ppTempFile)
                free(pSC->ppTempFile);
        }
        else{
            for(i = 0; i < pSC->cNumBitIO; i ++){
                if(pSC->ppWStream && pSC->ppWStream[i])
                    pSC->ppWStream[i]->Close(pSC->ppWStream + i);
            }
        }

        free(pSC->ppWStream);

        free(pSC->m_ppBitIO);
        free(pSC->pIndexTable);
    }

    return 0;
}

/*************************************************************************
    Write header of image plane
*************************************************************************/
Int WriteImagePlaneHeader(CWMImageStrCodec * pSC)
{
    CWMImageInfo * pII = &pSC->WMII;
    CWMIStrCodecParam * pSCP = &pSC->WMISCP;
    BitIOInfo* pIO = pSC->pIOHeader;

    PUTBITS(pIO, (Int) pSC->m_param.cfColorFormat, 3); // internal color format
    PUTBITS(pIO, (Int) pSC->m_param.bScaledArith, 1); // lossless mode

// subbands
    PUTBITS(pIO, (U32)pSCP->sbSubband, 4);

// color parameters
    switch (pSC->m_param.cfColorFormat) {
        case YUV_420:
        case YUV_422:
        case YUV_444:
            PUTBITS(pIO, 0, 4);
            PUTBITS(pIO, 0, 4);
            break;
        case NCOMPONENT:
            PUTBITS(pIO, (Int) pSC->m_param.cNumChannels - 1, 4);
            PUTBITS(pIO, 0, 4);
            break;
        default:
            break;
    }

// float and 32s additional parameters
    switch (pII->bdBitDepth) {
        case BD_16:
        case BD_16S:
            PUTBITS(pIO, pSCP->nLenMantissaOrShift, 8);
            break;
        case BD_32:
        case BD_32S:
            if(pSCP->nLenMantissaOrShift == 0)
                pSCP->nLenMantissaOrShift = 10;//default
            PUTBITS(pIO, pSCP->nLenMantissaOrShift, 8);
            break;
        case BD_32F:
            if(pSCP->nLenMantissaOrShift == 0)
                pSCP->nLenMantissaOrShift = 13;//default
            PUTBITS(pIO, pSCP->nLenMantissaOrShift, 8);//float conversion parameters
            PUTBITS(pIO, pSCP->nExpBias, 8);
            break;
        default:
            break;
    }

        // quantization
    PUTBITS(pIO, (pSC->m_param.uQPMode & 1) == 1 ? 0 : 1, 1); // DC frame uniform quantization?
    if((pSC->m_param.uQPMode & 1) == 0)
        writeQuantizer(pSC->pTile[0].pQuantizerDC, pIO, (pSC->m_param.uQPMode >> 3) & 3, pSC->m_param.cNumChannels, 0);
    if(pSC->WMISCP.sbSubband != SB_DC_ONLY){
        PUTBITS(pIO, (pSC->m_param.uQPMode & 0x200) == 0 ? 1 : 0, 1); // use DC quantization?
        if((pSC->m_param.uQPMode & 0x200) != 0){
            PUTBITS(pIO, (pSC->m_param.uQPMode & 2) == 2 ? 0 : 1, 1); // LP frame uniform quantization?
            if((pSC->m_param.uQPMode & 2) == 0)
                writeQuantizer(pSC->pTile[0].pQuantizerLP, pIO, (pSC->m_param.uQPMode >> 5) & 3,  pSC->m_param.cNumChannels, 0);
        }

        if(pSC->WMISCP.sbSubband != SB_NO_HIGHPASS){
            PUTBITS(pIO, (pSC->m_param.uQPMode & 0x400) == 0 ? 1 : 0, 1); // use LP quantization?
            if((pSC->m_param.uQPMode & 0x400) != 0){
                PUTBITS(pIO, (pSC->m_param.uQPMode & 4) == 4 ? 0 : 1, 1); // HP frame uniform quantization?
                if((pSC->m_param.uQPMode & 4) == 0)
                    writeQuantizer(pSC->pTile[0].pQuantizerHP, pIO, (pSC->m_param.uQPMode >> 7) & 3,  pSC->m_param.cNumChannels, 0);
            }
        }
    }

    fillToByte(pIO);  // remove this later
    return ICERR_OK;
}

/*************************************************************************
    Write header to buffer
*************************************************************************/
Int WriteWMIHeader(CWMImageStrCodec * pSC)
{
    CWMImageInfo * pII = &pSC->WMII;
    CWMIStrCodecParam * pSCP = &pSC->WMISCP;
    CCoreParameters * pCoreParam = &pSC->m_param;
    BitIOInfo* pIO = pSC->pIOHeader;
    U32 /*iSizeOfSize = 2,*/ i;
    // temporary assignments / reserved words
    // const Int HEADERSIZE = 0;
    Bool bInscribed = FALSE;
    Bool bAbbreviatedHeader = (((pII->cWidth + 15) / 16 > 255 || (pII->cHeight + 15) / 16 > 255) ? FALSE : TRUE);

    if(pCoreParam->bTranscode == FALSE)
        pCoreParam->cExtraPixelsTop = pCoreParam->cExtraPixelsLeft = pCoreParam->cExtraPixelsRight = pCoreParam->cExtraPixelsBottom = 0;

    // num of extra boundary pixels due to compressed domain processing
    bInscribed = (pCoreParam->cExtraPixelsTop || pCoreParam->cExtraPixelsLeft || pCoreParam->cExtraPixelsBottom || pCoreParam->cExtraPixelsRight);

// 0
    /** signature **/
    for (i = 0; i < 8; PUTBITS(pSC->pIOHeader, gGDISignature[i++], 8));

// 8
    /** codec version and subversion **/
    PUTBITS(pIO, CODEC_VERSION, 4);  // this should be changed to "profile" in RTM
    if (pSC->WMISCP.bUseHardTileBoundaries)
        PUTBITS(pIO, CODEC_SUBVERSION_NEWSCALING_HARD_TILES, 4);
    else
        PUTBITS(pIO, CODEC_SUBVERSION_NEWSCALING_SOFT_TILES, 4);

// 9 primary parameters
    PUTBITS(pIO, (pSCP->cNumOfSliceMinus1V || pSCP->cNumOfSliceMinus1H) ? 1 : 0, 1); // tiling present
    PUTBITS(pIO, (Int) pSCP->bfBitstreamFormat, 1); // bitstream layout
    PUTBITS(pIO, pII->oOrientation, 3);        // m_iRotateFlip
    PUTBITS(pIO, pSC->m_param.bIndexTable, 1); // index table present
    PUTBITS(pIO, pSCP->olOverlap, 2); // overlap

// 10
    PUTBITS(pIO, bAbbreviatedHeader, 1); // short words for size and tiles
    PUTBITS(pIO, 1, 1); // long word length (use intelligence later)
    PUTBITS(pIO, bInscribed, 1); // windowing
    PUTBITS(pIO, pSC->m_param.bTrimFlexbitsFlag, 1); // trim flexbits flag sent
    PUTBITS(pIO, 0, 1); // tile stretching parameters (not enabled)
    PUTBITS(pIO, 0, 2); // reserved bits
    PUTBITS(pIO, (Int) pSC->m_param.bAlphaChannel, 1); // alpha channel present

// 11 - informational
    PUTBITS(pIO, (Int) pII->cfColorFormat, 4); // source color format
    if(BD_1 == pII->bdBitDepth && pSCP->bBlackWhite)
        PUTBITS(pIO, (Int) BD_1alt, 4); // source bit depth
    else 
        PUTBITS(pIO, (Int) pII->bdBitDepth, 4); // source bit depth

// 12 - Variable length fields
// size
    putBit32(pIO, (U32)(pII->cWidth - 1), bAbbreviatedHeader ? 16 : 32);
    putBit32(pIO, (U32)(pII->cHeight - 1), bAbbreviatedHeader ? 16 : 32);

// tiling
    if (pSCP->cNumOfSliceMinus1V || pSCP->cNumOfSliceMinus1H) {
        PUTBITS(pIO, pSCP->cNumOfSliceMinus1V, LOG_MAX_TILES); // # of vertical slices
        PUTBITS(pIO, pSCP->cNumOfSliceMinus1H, LOG_MAX_TILES); // # of horizontal slices
    }

// tile sizes
    for(i = 0; i < pSCP->cNumOfSliceMinus1V; i ++){ // width in MB of vertical slices, not needed for last slice!
        PUTBITS(pIO, pSCP->uiTileX[i + 1] - pSCP->uiTileX[i], bAbbreviatedHeader ? 8 : 16);
    }
    for(i = 0; i < pSCP->cNumOfSliceMinus1H; i ++){ // width in MB of horizontal slices, not needed for last slice!
        PUTBITS(pIO, pSCP->uiTileY[i + 1] - pSCP->uiTileY[i], bAbbreviatedHeader ? 8 : 16);
    }

// window due to compressed domain processing
    if (bInscribed) {
        PUTBITS(pIO, (U32)pCoreParam->cExtraPixelsTop, 6);
        PUTBITS(pIO, (U32)pCoreParam->cExtraPixelsLeft, 6);
        PUTBITS(pIO, (U32)pCoreParam->cExtraPixelsBottom, 6);
        PUTBITS(pIO, (U32)pCoreParam->cExtraPixelsRight, 6);
    }    
    fillToByte(pIO);  // redundant

    // write image plane headers
    WriteImagePlaneHeader(pSC);

    return ICERR_OK;
}

// streaming codec init/term
Int StrEncInit(CWMImageStrCodec* pSC)
{
    COLORFORMAT cf = pSC->m_param.cfColorFormat;
    COLORFORMAT cfE = pSC->WMII.cfColorFormat;
    U16 iQPIndexY = 0, iQPIndexYLP = 0, iQPIndexYHP = 0;
	U16 iQPIndexU = 0, iQPIndexULP = 0, iQPIndexUHP = 0;
    U16 iQPIndexV = 0, iQPIndexVLP = 0, iQPIndexVHP = 0; 
    size_t i;
    Bool b32bit = sizeof(size_t) == 4;

    /** color transcoding with resolution change **/
    pSC->m_bUVResolutionChange = (((cfE == CF_RGB || cfE == YUV_444 || cfE == CMYK || cfE == CF_RGBE) && 
								   (cf == YUV_422 || cf == YUV_420))
								  || (cfE == YUV_422 && cf == YUV_420)) && !pSC->WMISCP.bYUVData;

    if(pSC->m_bUVResolutionChange){
        size_t cSize = ((cfE == YUV_422 ? 128 : 256) + (cf == YUV_420 ? 32 : 0)) * pSC->cmbWidth + 256;

        if(b32bit){ // integer overlow/underflow check for 32-bit system
            if(((pSC->cmbWidth >> 16) * ((cfE == YUV_422 ? 128 : 256) + (cf == YUV_420 ? 32 : 0))) & 0xffff0000)
                return ICERR_ERROR;
            if(cSize >= 0x3fffffff)
                return ICERR_ERROR;
        }
        pSC->pResU = (PixelI *)malloc(cSize * sizeof(PixelI));
        pSC->pResV = (PixelI *)malloc(cSize * sizeof(PixelI));
        if(pSC->pResU == NULL || pSC->pResV == NULL){
            return ICERR_ERROR;
        }
    }

    pSC->cTileColumn = pSC->cTileRow = 0;

    if(allocateTileInfo(pSC) != ICERR_OK)
        return ICERR_ERROR;

    if(pSC->m_param.bTranscode == FALSE){
        pSC->m_param.uQPMode = 0x150;   // 101010 000
                                        // 000    == uniform (not per tile) DC, LP, HP
                                        // 101010 == cChMode == 2 == independent (not same) DC, LP, HP

        /** lossless or Y component lossless condition: all subbands present, uniform quantization with QPIndex 1 **/
        pSC->m_param.bScaledArith = !((pSC->m_param.uQPMode & 7) == 0 && 
									  1 == pSC->WMISCP.uiDefaultQPIndex <= 1 && 
									  pSC->WMISCP.sbSubband == SB_ALL && 
									  pSC->m_bUVResolutionChange == FALSE) &&
                                     !pSC->WMISCP.bUnscaledArith;
        if (BD_32 == pSC->WMII.bdBitDepth || BD_32S == pSC->WMII.bdBitDepth || BD_32F == pSC->WMII.bdBitDepth) {
            pSC->m_param.bScaledArith = FALSE;
        }



( run in 0.997 second using v1.01-cache-2.11-cpan-119454b85a5 )