Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/LibJXR/image/decode/strdec.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 "strcodec.h"
#include "decode.h"
#include "strTransform.h"
#include <math.h>
#include "perfTimer.h"
#ifdef MEM_TRACE
#define TRACE_MALLOC 1
#define TRACE_NEW 0
#define TRACE_HEAP 0
#include "memtrace.h"
#endif
#ifdef X86OPT_INLINE
#define _FORCEINLINE __forceinline
#else // X86OPT_INLINE
#define _FORCEINLINE
#endif // X86OPT_INLINE
#if defined(WMP_OPT_SSE2) || defined(WMP_OPT_CC_DEC) || defined(WMP_OPT_TRFM_DEC)
void StrDecOpt(CWMImageStrCodec* pSC);
#endif // OPT defined
Int processMacroblockDec(CWMImageStrCodec *);
U8 readQuantizerSB(U8 pQPIndex[MAX_CHANNELS], SimpleBitIO * pIO, size_t cChannel)
{
U8 cChMode = 0;
if(cChannel >= MAX_CHANNELS)
return 0;
if(cChannel > 1)
cChMode = (U8)getBit32_SB(pIO, 2); // Channel mode
pQPIndex[0] = (U8)getBit32_SB(pIO, 8); // Y
if(cChMode == 1) // MIXED
pQPIndex[1] = (U8)getBit32_SB(pIO, 8); // UV
else if(cChMode > 0){ // INDEPENDENT
size_t i;
for(i = 1; i < cChannel; i ++)
#pragma prefast(suppress: __WARNING_UNRELATED_LOOP_TERMINATION_NO_SIZEEXPR, "PREfast false alarm: 1 <= i < MAX_CHANNELS, no buffer over/underrun!")
pQPIndex[i] = (U8)getBit32_SB(pIO, 8); // UV
}
return cChMode;
}
U8 readQuantizer(CWMIQuantizer * pQuantizer[MAX_CHANNELS], BitIOInfo * pIO, size_t cChannel, size_t iPos)
{
U8 cChMode = 0;
if(cChannel > 1)
cChMode = (U8)getBit16(pIO, 2); // Channel mode
pQuantizer[0][iPos].iIndex = (U8)getBit16(pIO, 8); // Y
if(cChMode == 1) // MIXED
pQuantizer[1][iPos].iIndex = (U8)getBit16(pIO, 8); // UV
else if(cChMode > 0){ // INDEPENDENT
size_t i;
for(i = 1; i < cChannel; i ++)
pQuantizer[i][iPos].iIndex = (U8)getBit16(pIO, 8); // UV
}
return cChMode;
}
// packet header: 00000000 00000000 00000001 ?????xxx
// xxx: 000(spatial) 001(DC) 010(AD) 011(AC) 100(FL) 101-111(reserved)
// ?????: (iTileY * cNumOfSliceV + iTileX) % 32
Int readPacketHeader(BitIOInfo * pIO, U8 ptPacketType, U8 pID)
{
UNREFERENCED_PARAMETER( ptPacketType );
UNREFERENCED_PARAMETER( pID );
if(getBit16(pIO, 8) != 0 || getBit16(pIO, 8) != 0 || getBit16(pIO, 8) != 1)
return ICERR_ERROR;
getBit16(pIO, 8);
return ICERR_OK;
}
src/Source/LibJXR/image/decode/strdec.c view on Meta::CPAN
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;
}
/* inverse transform and overlap possible part of a macroblock */
Int processMacroblockDec(CWMImageStrCodec * pSC)
{
const OVERLAP olOverlap = pSC->WMISCP.olOverlap;
// const Bool left = (pSC->cColumn == 0);
const Bool /*top = (pSC->cRow == 0),*/ bottom = (pSC->cRow == pSC->cmbHeight);
const Bool bottomORright = (bottom || pSC->cColumn == pSC->cmbWidth);
// const size_t mbWidth = pSC->cmbWidth, mbX = pSC->cColumn;
// Int iQIndex = 0;
ERR_CODE result = ICERR_OK;
size_t j, jend = (pSC->m_pNextSC != NULL);
for (j = 0; j <= jend; j++) {
if(!bottomORright){
CCodingContext *pContext;
getTilePos(pSC, pSC->cColumn, pSC->cRow);
if(jend){
pSC->m_pNextSC->cTileColumn = pSC->cTileColumn;
pSC->m_pNextSC->cTileRow = pSC->cTileRow;
}
pContext = &pSC->m_pCodingContext[pSC->cTileColumn];
if(readPackets(pSC) != ICERR_OK)
return ICERR_ERROR;
// check if we need to do entropy decode
if(!pSC->m_Dparam->bDecodeFullFrame){
if(pSC->cColumn == pSC->WMISCP.uiTileX[pSC->cTileColumn]){ // switching to a new tile
size_t rLeft = pSC->m_Dparam->cROILeftX, rRight = pSC->m_Dparam->cROIRightX;
size_t rTop = pSC->m_Dparam->cROITopY, rBottom = pSC->m_Dparam->cROIBottomY;
size_t rExt = (olOverlap == OL_NONE ? 0 : olOverlap == OL_ONE ? 2 : 10);
size_t tLeft = pSC->cColumn * 16, tTop = pSC->WMISCP.uiTileY[pSC->cTileRow] * 16;
size_t tRight = (pSC->cTileColumn != pSC->WMISCP.cNumOfSliceMinus1V ? pSC->WMISCP.uiTileX[pSC->cTileColumn + 1] : pSC->cmbWidth) * 16;
size_t tBottom = (pSC->cTileRow != pSC->WMISCP.cNumOfSliceMinus1H ? pSC->WMISCP.uiTileY[pSC->cTileRow + 1] : pSC->cmbHeight) * 16;
// tile overlaps with ROI?
pContext->m_bInROI = ((rLeft >= tRight + rExt || rTop >= tBottom + rExt || tLeft > rRight + rExt ||
tTop > rBottom + rExt || pSC->cRow * 16 > rBottom + rExt) ? FALSE : TRUE);
}
}
if(pSC->m_Dparam->bDecodeFullFrame || pContext->m_bInROI){
if ((result = DecodeMacroblockDC(pSC, pContext, (Int)pSC->cColumn, (Int)pSC->cRow)) != ICERR_OK)
return result;
if(pSC->m_Dparam->bDecodeLP){
if ((result = DecodeMacroblockLowpass(pSC, pContext, (Int)pSC->cColumn, (Int)pSC->cRow)) != ICERR_OK)
return result;
}
predDCACDec(pSC);
dequantizeMacroblock(pSC);
if(pSC->m_Dparam->bDecodeHP){
if ((result = DecodeMacroblockHighpass(pSC, pContext, (Int)pSC->cColumn, (Int)pSC->cRow)) != ICERR_OK)
return result;
predACDec(pSC);
}
/* keep necessary info for future prediction */
updatePredInfo(pSC, &pSC->MBInfo, (Int)pSC->cColumn, pSC->m_param.cfColorFormat);
}
}
if((!pSC->m_Dparam->bDecodeFullFrame) &&
((pSC->cColumn * 16 > pSC->m_Dparam->cROIRightX + 25) || (pSC->cColumn * 16 + 25 < pSC->m_Dparam->cROILeftX)
|| (pSC->cRow * 16 > pSC->m_Dparam->cROIBottomY + 25) || (pSC->cRow * 16 + 25 < pSC->m_Dparam->cROITopY)))
{
// do nothing
}
else {
pSC->Transform(pSC);
}
if (jend) {
pSC->m_pNextSC->cRow = pSC->cRow;
pSC->m_pNextSC->cColumn = pSC->cColumn;
pSC = pSC->m_pNextSC;
}
}
return result;
}
//================================================================
// Inverse Color Conversion
//#define _ICC1(r, g, b) (g^=b^=g^=b, r^=g^=r^=g, b += ((g) >> 1), r += ((g) >> 1), g -= (b+3*r+2) >> 2)
//#define _ICC(r, g, b) (g^=b^=g^=b, r^=g^=r^=g, b += ((g) >> 1), r += ((g) >> 1), g -= (b+3*r+2) >> 2)
//================================================================
//#define _ICC1(r, g, b) r -= (g >> 1), g += r, r -= ((b + 1) >> 1), b += r
//#define _ICC(r, g, b) r -= (g >> 1), g += r, r -= (b >> 1), b += r
#define _ICC(r, g, b) (g -= ((r + 0) >> 1), r -= ((b + 1) >> 1) - g, b += r)
#define _ICC_CMYK(c, m, y, k) (k -= ((m + 1) >> 1), m -= (c >> 1) - k, c -= ((y + 1) >> 1) - m, y += c)
#define _CLIP2(l, v, h) ((v) < (l) ? (l) : ((h) < (v) ? (h) : (v)))
#define _CLIP8(v) ((U8)_CLIP2(0, v, 255))
#define _CLIP16(v) ((I16)_CLIP2(-32768, v, 32767))
#define _CLIPU16(v) ((U16)_CLIP2(0, v, 65535))
#define min(a,b) (((a) < (b)) ? (a) : (b))
//inverseConvert: Inverse conversion from float RGB to RGBE
static _FORCEINLINE void inverseConvert (PixelI iF, U8 *pRGB, U8 *pE)
{
if (iF <= 0) {
*pRGB = *pE = 0;
}
else if ((iF >> 7) > 1) {
/** normal form **/
*pE = (U8) (iF >> 7); //+ 1;
*pRGB = (iF & 0x7f) | 0x80;
}
else {
/** denormal form **/
src/Source/LibJXR/image/decode/strdec.c view on Meta::CPAN
if(cII.cfColorFormat == CF_RGBE)
pII->cfColorFormat = CF_RGBE;
// validate thumbnail parameters
if(pII->cThumbnailWidth == 0 || pII->cThumbnailWidth > pII->cWidth)
pII->cThumbnailWidth = pII->cWidth;
if(pII->cThumbnailHeight == 0 || pII->cThumbnailHeight > pII->cHeight)
pII->cThumbnailHeight = pII->cHeight;
if((pII->cWidth + pII->cThumbnailWidth - 1) / pII->cThumbnailWidth != (pII->cHeight + pII->cThumbnailHeight - 1) / pII->cThumbnailHeight) {
while((pII->cWidth + cScale - 1) / cScale > pII->cThumbnailWidth &&
(pII->cHeight + cScale - 1) / cScale > pII->cThumbnailHeight && (cScale << 1))
cScale <<= 1;
}
else {
cScale = (pII->cWidth + pII->cThumbnailWidth - 1) / pII->cThumbnailWidth;
if (cScale == 0)
cScale = 1;
}
pII->cThumbnailWidth = (pII->cWidth + cScale - 1) / cScale;
pII->cThumbnailHeight = (pII->cHeight + cScale - 1) / cScale;
// validate region decode parameters
if(pII->cROIHeight == 0 || pII->cROIWidth == 0){
pII->cROILeftX = pII->cROITopY = 0;
pII->cROIWidth = pII->cThumbnailWidth;
pII->cROIHeight = pII->cThumbnailHeight;
}
if(pII->cROILeftX >= pII->cThumbnailWidth)
pII->cROILeftX = 0;
if(pII->cROITopY >= pII->cThumbnailHeight)
pII->cROITopY = 0;
if(pII->cROILeftX + pII->cROIWidth > pII->cThumbnailWidth)
pII->cROIWidth = pII->cThumbnailWidth - pII->cROILeftX;
if(pII->cROITopY + pII->cROIHeight > pII->cThumbnailHeight)
pII->cROIHeight = pII->cThumbnailHeight - pII->cROITopY;
return ICERR_OK;
}
/*************************************************************************
Initialization of CWMImageStrCodec struct
*************************************************************************/
static Void InitializeStrDec(CWMImageStrCodec *pSC,
const CCoreParameters *pParams, const CWMImageStrCodec *pSCIn)
{
// copy core parameters
memcpy (&(pSC->m_param), pParams, sizeof (CCoreParameters));
pSC->cbStruct = sizeof(*pSC);
pSC->WMII = pSCIn->WMII;
pSC->WMISCP = pSCIn->WMISCP;
pSC->cRow = 0;
pSC->cColumn = 0;
pSC->cmbWidth = (pSC->WMII.cWidth + 15) / 16;
pSC->cmbHeight = (pSC->WMII.cHeight + 15) / 16;
pSC->Load = outputMBRow; // output decoding result (ICC, etc)
pSC->Transform = pParams->cSubVersion == CODEC_SUBVERSION ?
invTransformMacroblock : invTransformMacroblock_alteredOperators_hard;
pSC->TransformCenter = pSC->Transform;
pSC->ProcessTopLeft = processMacroblockDec;
pSC->ProcessTop = processMacroblockDec;
pSC->ProcessTopRight = processMacroblockDec;
pSC->ProcessLeft = processMacroblockDec;
pSC->ProcessCenter = processMacroblockDec;
pSC->ProcessRight = processMacroblockDec;
pSC->ProcessBottomLeft = processMacroblockDec;
pSC->ProcessBottom = processMacroblockDec;
pSC->ProcessBottomRight = processMacroblockDec;
pSC->m_pNextSC = NULL;
pSC->m_bSecondary = FALSE;
}
/*************************************************************************
ImageStrDecInit
*************************************************************************/
Int ImageStrDecInit(
CWMImageInfo* pII,
CWMIStrCodecParam *pSCP,
CTXSTRCODEC* pctxSC)
{
static size_t cbChannels[BD_MAX] = {2, 4};
ERR err = WMP_errSuccess;
size_t cbChannel = 0, cblkChroma = 0;
size_t cbMacBlockStride = 0, cbMacBlockChroma = 0, cMacBlock = 0;
CWMImageStrCodec SC = {0};
CWMImageStrCodec *pSC = NULL, *pNextSC = NULL;
char* pb = NULL;
size_t cb = 0, i;
Bool bLossyTranscoding = FALSE;
Bool bUseHardTileBoundaries = FALSE; //default is soft tile boundaries
Bool bLessThan64Bit = sizeof(void *) < 8;
*pctxSC = NULL;
if(WMPhotoValidate(pII, pSCP) != ICERR_OK)
return ICERR_ERROR;
if(pSCP->sbSubband == SB_ISOLATED) // can not do anything with isolated bitstream
return ICERR_ERROR;
//================================================
SC.WMISCP.pWStream = pSCP->pWStream;
if (ReadWMIHeader(&SC.WMII, &SC.WMISCP, &SC.m_param) != ICERR_OK) {
return ICERR_ERROR;
}
bUseHardTileBoundaries = SC.WMISCP.bUseHardTileBoundaries;
if(SC.WMII.cfColorFormat == CMYK && pII->cfColorFormat == CF_RGB)
bLossyTranscoding = TRUE;
if(pSCP->cfColorFormat != CMYK && (pII->cfColorFormat == CMYK))
return ICERR_ERROR;
//================================================
SC.WMISCP = *pSCP;
SC.WMII = *pII;
// original image size
SC.WMII.cWidth += SC.m_param.cExtraPixelsLeft + SC.m_param.cExtraPixelsRight;
SC.WMII.cHeight += SC.m_param.cExtraPixelsTop + SC.m_param.cExtraPixelsBottom;
pII->cROILeftX += SC.m_param.cExtraPixelsLeft;
pII->cROITopY += SC.m_param.cExtraPixelsTop;
//================================================
cbChannel = cbChannels[SC.WMISCP.bdBitDepth];
cblkChroma = cblkChromas[SC.m_param.cfColorFormat];
cbMacBlockStride = cbChannel * 16 * 16;
cbMacBlockChroma = cbChannel * 16 * cblkChroma;
cMacBlock = (SC.WMII.cWidth + 15) / 16;
//================================================
cb = sizeof(*pSC) + (128 - 1) + sizeof(CWMDecoderParameters);
cb += (PACKETLENGTH * 4 - 1) + (PACKETLENGTH * 2 ) + sizeof(*pSC->pIOHeader);
i = (cbMacBlockStride + cbMacBlockChroma * (SC.m_param.cNumChannels - 1)) * 2; // i <= 2^15
if (bLessThan64Bit && ((i * (cMacBlock >> 16)) & 0xffffc000)) {
/** potential overflow - 32 bit pointers insufficient to address cache **/
return ICERR_ERROR;
}
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;
}
Int ImageStrDecDecode(
CTXSTRCODEC ctxSC,
const CWMImageBufferInfo* pBI
#ifdef REENTRANT_MODE
, size_t *pcDecodedLines
#endif
)
{
CWMImageStrCodec* pSC = (CWMImageStrCodec*)ctxSC;
CWMImageStrCodec* pNextSC = pSC->m_pNextSC;
size_t cMBRow, k;
ImageDataProc ProcessLeft, ProcessCenter, ProcessRight;
ImageDataProc Transform = NULL;
const size_t iChromaElements = (pSC->m_param.cfColorFormat == YUV_420) ? 8 * 8
: ((pSC->m_param.cfColorFormat == YUV_422) ? 8 * 16 : 16 * 16);
if (sizeof(*pSC) != pSC->cbStruct)
{
src/Source/LibJXR/image/decode/strdec.c view on Meta::CPAN
#ifdef REENTRANT_MODE
if (0 == pSC->WMIBI.uiFirstMBRow)
{
setROI(pSC);
if (pNextSC) {
pNextSC->WMIBI = pSC->WMIBI;
setROI(pNextSC);
}
}
#else
setROI(pSC);
if (pNextSC) {
pNextSC->WMIBI = pSC->WMIBI;
setROI(pNextSC);
}
#endif // REENTRANT_MODE
// optimization flags can be defined only after ROI is set!
#if defined(WMP_OPT_SSE2) || defined(WMP_OPT_CC_DEC) || defined(WMP_OPT_TRFM_DEC)
StrDecOpt(pSC);
#endif // OPT defined
cMBRow = (pSC->m_Dparam->bDecodeFullFrame ? pSC->cmbHeight : ((pSC->m_Dparam->cROIBottomY + 16) >> 4));
#ifdef REENTRANT_MODE
if (0 == pSC->WMIBI.uiFirstMBRow)
{
if(initLookupTables(pSC) != ICERR_OK)
return ICERR_ERROR;
if (pNextSC && initLookupTables(pNextSC) != ICERR_OK)
return ICERR_ERROR;
}
#else
if(initLookupTables(pSC) != ICERR_OK)
return ICERR_ERROR;
if (pNextSC && initLookupTables(pNextSC) != ICERR_OK)
return ICERR_ERROR;
#endif // REENTRANT_MODE
#ifndef REENTRANT_MODE
if(pSC->WMII.bdBitDepth == BD_1){
size_t i;
for(i = 0; i < pSC->WMIBI.cLine; i ++)
memset(pSC->WMIBI.pv, 0, pSC->WMIBI.cbStride);
}
#endif
//================================
// top row
#ifdef REENTRANT_MODE
#else
pSC->cRow = 0;
ProcessLeft = pSC->ProcessTopLeft;
ProcessCenter = pSC->ProcessTop;
ProcessRight = pSC->ProcessTopRight;
Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ?
invTransformMacroblock : invTransformMacroblock_alteredOperators_hard;
#endif // REENTRANT_MODE
#ifdef REENTRANT_MODE
for (pSC->cRow = pSC->WMIBI.uiFirstMBRow; pSC->cRow <= pSC->WMIBI.uiLastMBRow; pSC->cRow++)
{
// const COLORFORMAT cfExt = (pSC->m_param.cfColorFormat == Y_ONLY ? Y_ONLY : pSC->WMII.cfColorFormat);
if (0 == pSC->cRow)
{
ProcessLeft = pSC->ProcessTopLeft;
ProcessCenter = pSC->ProcessTop;
ProcessRight = pSC->ProcessTopRight;
Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ?
invTransformMacroblock : invTransformMacroblock_alteredOperators_hard;
}
else if (cMBRow == pSC->cRow)
{
//================================
// bottom row
ProcessLeft = pSC->ProcessBottomLeft;
ProcessCenter = pSC->ProcessBottom;
ProcessRight = pSC->ProcessBottomRight;
Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ?
invTransformMacroblock : invTransformMacroblock_alteredOperators_hard;
}
else { // middle rows
ProcessLeft = pSC->ProcessLeft;
ProcessCenter = pSC->ProcessCenter;
ProcessRight = pSC->ProcessRight;
Transform = pSC->TransformCenter;
}
#else
//================================
// central rows
for(pSC->cRow = 0; pSC->cRow <= cMBRow; pSC->cRow++)
{
#endif // REENTRANT_MODE
pSC->cColumn = 0;
initMRPtr(pSC);
/** zero out the transform coefficients (pull this out to once per MB row) **/
memset(pSC->p1MBbuffer[0], 0, sizeof(PixelI) * 16 * 16 * pSC->cmbWidth);
for (k = 1; k < pSC->m_param.cNumChannels; k++) {
memset(pSC->p1MBbuffer[k], 0, sizeof(PixelI) * iChromaElements * pSC->cmbWidth);
}
if (pSC->m_pNextSC != NULL) { // alpha channel
memset(pSC->m_pNextSC->p1MBbuffer[0], 0, sizeof(PixelI) * 16 * 16 * pSC->m_pNextSC->cmbWidth);
}
if(ProcessLeft(pSC) != ICERR_OK)
return ICERR_ERROR;
advanceMRPtr(pSC);
pSC->Transform = Transform;
for (pSC->cColumn = 1; pSC->cColumn < pSC->cmbWidth; ++pSC->cColumn)
{
if(ProcessCenter(pSC) != ICERR_OK)
return ICERR_ERROR;
advanceMRPtr(pSC);
}
pSC->Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ?
invTransformMacroblock : invTransformMacroblock_alteredOperators_hard;
if(ProcessRight(pSC) != ICERR_OK)
return ICERR_ERROR;
if (pSC->cRow) {
if(pSC->m_Dparam->cThumbnailScale < 2 && (pSC->m_Dparam->bDecodeFullFrame ||
((pSC->cRow * 16 > pSC->m_Dparam->cROITopY) && (pSC->cRow * 16 <= pSC->m_Dparam->cROIBottomY + 16)))) {
if( pSC->Load(pSC) != ICERR_OK ) // bypass CC for thumbnail decode
return ICERR_ERROR;
}
if(pSC->m_Dparam->cThumbnailScale >= 2) // decode thumbnail
decodeThumbnail(pSC);
}
advanceOneMBRow(pSC);
swapMRPtr(pSC);
#ifdef REENTRANT_MODE
*pcDecodedLines = pSC->WMIBI.cLinesDecoded;
#else
if (pSC->cRow == cMBRow - 1) {
//================================
// bottom row
ProcessLeft = pSC->ProcessBottomLeft;
ProcessCenter = pSC->ProcessBottom;
ProcessRight = pSC->ProcessBottomRight;
Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ?
invTransformMacroblock : invTransformMacroblock_alteredOperators_hard;
}
else {
ProcessLeft = pSC->ProcessLeft;
ProcessCenter = pSC->ProcessCenter;
ProcessRight = pSC->ProcessRight;
Transform = pSC->TransformCenter;
}
#endif // REENTRANT_MODE
}
#ifndef REENTRANT_MODE
fixup_Y_ONLY_to_Others(pSC, pBI);
#endif // REENTRANT_MODE
PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
return ICERR_OK;
}
Int ImageStrDecTerm(
CTXSTRCODEC ctxSC)
{
CWMImageStrCodec* pSC = (CWMImageStrCodec*)ctxSC;
if (NULL == pSC)
{
return ICERR_OK;
}
if (sizeof(*pSC) != pSC->cbStruct)
{
return ICERR_ERROR;
}
PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
StrDecTerm(pSC);
PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
PERFTIMER_REPORT(pSC->m_fMeasurePerf, pSC);
PERFTIMER_DELETE(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
PERFTIMER_DELETE(pSC->m_fMeasurePerf, pSC->m_ptEndToEndPerf);
free(pSC);
return ICERR_OK;
}
( run in 0.640 second using v1.01-cache-2.11-cpan-0bd6704ced7 )