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 )