libs: Import upstream code from jxrlib 1.1.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
9f0cdd2a6a
commit
cfc8f154e5
|
@ -707,6 +707,8 @@ PNG_PE_LIBS
|
|||
PNG_PE_CFLAGS
|
||||
LCMS2_PE_LIBS
|
||||
LCMS2_PE_CFLAGS
|
||||
JXR_PE_LIBS
|
||||
JXR_PE_CFLAGS
|
||||
JPEG_PE_LIBS
|
||||
JPEG_PE_CFLAGS
|
||||
GSM_PE_LIBS
|
||||
|
@ -1784,6 +1786,7 @@ enable_dxerr9
|
|||
enable_dxguid
|
||||
enable_gsm
|
||||
enable_jpeg
|
||||
enable_jxr
|
||||
enable_lcms2
|
||||
enable_mfuuid
|
||||
enable_png
|
||||
|
@ -1930,6 +1933,8 @@ GSM_PE_CFLAGS
|
|||
GSM_PE_LIBS
|
||||
JPEG_PE_CFLAGS
|
||||
JPEG_PE_LIBS
|
||||
JXR_PE_CFLAGS
|
||||
JXR_PE_LIBS
|
||||
LCMS2_PE_CFLAGS
|
||||
LCMS2_PE_LIBS
|
||||
PNG_PE_CFLAGS
|
||||
|
@ -2717,6 +2722,9 @@ Some influential environment variables:
|
|||
C compiler flags for the PE jpeg, overriding the bundled version
|
||||
JPEG_PE_LIBS
|
||||
Linker flags for the PE jpeg, overriding the bundled version
|
||||
JXR_PE_CFLAGS
|
||||
C compiler flags for the PE jxr, overriding the bundled version
|
||||
JXR_PE_LIBS Linker flags for the PE jxr, overriding the bundled version
|
||||
LCMS2_PE_CFLAGS
|
||||
C compiler flags for the PE lcms2, overriding the bundled
|
||||
version
|
||||
|
@ -10718,6 +10726,19 @@ fi
|
|||
$as_echo "$as_me:${as_lineno-$LINENO}: jpeg cflags: $JPEG_PE_CFLAGS" >&5
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: jpeg libs: $JPEG_PE_LIBS" >&5
|
||||
|
||||
if ${JXR_PE_CFLAGS:+false} :; then :
|
||||
JXR_PE_CFLAGS="-I\$(top_srcdir)/libs/jxr/jxrgluelib -I\$(top_srcdir)/libs/jxr/image/sys"
|
||||
else
|
||||
enable_jxr=no
|
||||
fi
|
||||
if ${JXR_PE_LIBS:+false} :; then :
|
||||
JXR_PE_LIBS=jxr
|
||||
else
|
||||
enable_jxr=no
|
||||
fi
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: jxr cflags: $JXR_PE_CFLAGS" >&5
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: jxr libs: $JXR_PE_LIBS" >&5
|
||||
|
||||
if ${LCMS2_PE_CFLAGS:+false} :; then :
|
||||
LCMS2_PE_CFLAGS="-I\$(top_srcdir)/libs/lcms2/include"
|
||||
else
|
||||
|
@ -18942,6 +18963,8 @@ GSM_PE_CFLAGS = $GSM_PE_CFLAGS
|
|||
GSM_PE_LIBS = $GSM_PE_LIBS
|
||||
JPEG_PE_CFLAGS = $JPEG_PE_CFLAGS
|
||||
JPEG_PE_LIBS = $JPEG_PE_LIBS
|
||||
JXR_PE_CFLAGS = $JXR_PE_CFLAGS
|
||||
JXR_PE_LIBS = $JXR_PE_LIBS
|
||||
LCMS2_PE_CFLAGS = $LCMS2_PE_CFLAGS
|
||||
LCMS2_PE_LIBS = $LCMS2_PE_LIBS
|
||||
PNG_PE_CFLAGS = $PNG_PE_CFLAGS
|
||||
|
@ -20238,6 +20261,7 @@ wine_fn_config_makefile libs/dxerr9 enable_dxerr9
|
|||
wine_fn_config_makefile libs/dxguid enable_dxguid
|
||||
wine_fn_config_makefile libs/gsm enable_gsm
|
||||
wine_fn_config_makefile libs/jpeg enable_jpeg
|
||||
wine_fn_config_makefile libs/jxr enable_jxr
|
||||
wine_fn_config_makefile libs/lcms2 enable_lcms2
|
||||
wine_fn_config_makefile libs/mfuuid enable_mfuuid
|
||||
wine_fn_config_makefile libs/png enable_png
|
||||
|
|
|
@ -1056,6 +1056,7 @@ dnl **** External libraries ****
|
|||
|
||||
WINE_EXTLIB_FLAGS(GSM, gsm, gsm, "-I\$(top_srcdir)/libs/gsm/inc")
|
||||
WINE_EXTLIB_FLAGS(JPEG, jpeg, jpeg, "-I\$(top_srcdir)/libs/jpeg")
|
||||
WINE_EXTLIB_FLAGS(JXR, jxr, jxr, "-I\$(top_srcdir)/libs/jxr/jxrgluelib -I\$(top_srcdir)/libs/jxr/image/sys")
|
||||
WINE_EXTLIB_FLAGS(LCMS2, lcms2, lcms2, "-I\$(top_srcdir)/libs/lcms2/include")
|
||||
WINE_EXTLIB_FLAGS(PNG, png, "png \$(ZLIB_PE_LIBS)", "-I\$(top_srcdir)/libs/png")
|
||||
WINE_EXTLIB_FLAGS(TIFF, tiff, tiff, "-I\$(top_srcdir)/libs/tiff/libtiff")
|
||||
|
@ -3705,6 +3706,7 @@ WINE_CONFIG_MAKEFILE(libs/dxerr9)
|
|||
WINE_CONFIG_MAKEFILE(libs/dxguid)
|
||||
WINE_CONFIG_MAKEFILE(libs/gsm)
|
||||
WINE_CONFIG_MAKEFILE(libs/jpeg)
|
||||
WINE_CONFIG_MAKEFILE(libs/jxr)
|
||||
WINE_CONFIG_MAKEFILE(libs/lcms2)
|
||||
WINE_CONFIG_MAKEFILE(libs/mfuuid)
|
||||
WINE_CONFIG_MAKEFILE(libs/png)
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
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.
|
|
@ -0,0 +1,25 @@
|
|||
EXTLIB = libjxr.a
|
||||
EXTRAINCL = -I$(srcdir)/jxrgluelib -I$(srcdir)/image/sys -DDISABLE_PERF_MEASUREMENT
|
||||
|
||||
C_SRCS = \
|
||||
image/decode/JXRTranscode.c \
|
||||
image/decode/decode.c \
|
||||
image/decode/postprocess.c \
|
||||
image/decode/segdec.c \
|
||||
image/decode/strInvTransform.c \
|
||||
image/decode/strPredQuantDec.c \
|
||||
image/decode/strdec.c \
|
||||
image/encode/encode.c \
|
||||
image/encode/segenc.c \
|
||||
image/encode/strFwdTransform.c \
|
||||
image/encode/strPredQuantEnc.c \
|
||||
image/encode/strenc.c \
|
||||
image/sys/adapthuff.c \
|
||||
image/sys/image.c \
|
||||
image/sys/strPredQuant.c \
|
||||
image/sys/strTransform.c \
|
||||
image/sys/strcodec.c \
|
||||
jxrgluelib/JXRGlue.c \
|
||||
jxrgluelib/JXRGlueJxr.c \
|
||||
jxrgluelib/JXRGluePFC.c \
|
||||
jxrgluelib/JXRMeta.c
|
|
@ -0,0 +1,991 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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 "windowsmediaphoto.h"
|
||||
#include "strcodec.h"
|
||||
#include "decode.h"
|
||||
|
||||
EXTERN_C Void freePredInfo(CWMImageStrCodec *);
|
||||
|
||||
EXTERN_C Int ReadWMIHeader(CWMImageInfo *, CWMIStrCodecParam *, CCoreParameters *);
|
||||
EXTERN_C Int StrIODecInit(CWMImageStrCodec *);
|
||||
EXTERN_C Int StrDecInit(CWMImageStrCodec *);
|
||||
EXTERN_C Int readPackets(CWMImageStrCodec *);
|
||||
EXTERN_C Int DecodeMacroblockDC(CWMImageStrCodec *, CCodingContext *, Int, Int);
|
||||
EXTERN_C Int DecodeMacroblockLowpass(CWMImageStrCodec *, CCodingContext *, Int, Int);
|
||||
EXTERN_C Int DecodeMacroblockHighpass(CWMImageStrCodec *, CCodingContext *, Int, Int);
|
||||
EXTERN_C Void predDCACDec(CWMImageStrCodec *);
|
||||
EXTERN_C Void predACDec(CWMImageStrCodec *);
|
||||
EXTERN_C Void StrIODecTerm(CWMImageStrCodec *);
|
||||
EXTERN_C Void FreeCodingContextDec(CWMImageStrCodec *);
|
||||
|
||||
EXTERN_C Int StrEncInit(CWMImageStrCodec *);
|
||||
EXTERN_C Void StrIOEncTerm(CWMImageStrCodec *);
|
||||
EXTERN_C Void FreeCodingContextEnc(CWMImageStrCodec *);
|
||||
EXTERN_C Int encodeMB(CWMImageStrCodec *, Int, Int);
|
||||
EXTERN_C Int writeIndexTableNull(CWMImageStrCodec *);
|
||||
EXTERN_C Void writePacketHeader(BitIOInfo *, U8, U8);
|
||||
|
||||
EXTERN_C Int WriteWMIHeader(CWMImageStrCodec *);
|
||||
EXTERN_C Int ReadImagePlaneHeader(CWMImageInfo *, CWMIStrCodecParam *, CCoreParameters *, SimpleBitIO *);
|
||||
EXTERN_C Int WriteImagePlaneHeader(CWMImageStrCodec *);
|
||||
EXTERN_C Int writeIndexTable(CWMImageStrCodec *);
|
||||
EXTERN_C Int copyTo(struct WMPStream *, struct WMPStream *, size_t);
|
||||
|
||||
const static Bool bFlipV[O_MAX] = {FALSE, TRUE , FALSE, TRUE, TRUE , TRUE, FALSE, FALSE};
|
||||
const static Bool bFlipH[O_MAX] = {FALSE, FALSE, TRUE , TRUE, FALSE, TRUE, FALSE, TRUE};
|
||||
|
||||
typedef struct CTileQPInfo
|
||||
{
|
||||
U8 dcMode;
|
||||
U8 dcIndex[MAX_CHANNELS];
|
||||
|
||||
Bool bUseDC;
|
||||
U8 lpNum;
|
||||
Bool bUseDCAlpha;
|
||||
U8 lpNumAlpha;
|
||||
U8 lpMode[16];
|
||||
U8 lpIndex[16][MAX_CHANNELS];
|
||||
|
||||
Bool bUseLP;
|
||||
U8 hpNum;
|
||||
Bool bUseLPAlpha;
|
||||
U8 hpNumAlpha;
|
||||
U8 hpMode[16];
|
||||
U8 hpIndex[16][MAX_CHANNELS];
|
||||
} CTileQPInfo;
|
||||
|
||||
Void transcodeQuantizer(BitIOInfo * pIO, U8 cIndex[MAX_CHANNELS], U8 cChMode, size_t cChannel)
|
||||
{
|
||||
if(cChMode > 2)
|
||||
cChMode = 2;
|
||||
|
||||
if(cChannel > 1)
|
||||
putBit16(pIO, cChMode, 2); // Channel mode
|
||||
else
|
||||
cChMode = 0;
|
||||
|
||||
putBit16(pIO, cIndex[0], 8); // Y
|
||||
|
||||
if(cChMode == 1) // MIXED
|
||||
putBit16(pIO, cIndex[1], 8); // UV
|
||||
else if(cChMode > 0){ // INDEPENDENT
|
||||
size_t i;
|
||||
|
||||
for(i = 1; i < cChannel; i ++)
|
||||
putBit16(pIO, cIndex[i], 8); // UV
|
||||
}
|
||||
}
|
||||
|
||||
Void transcodeQuantizers(BitIOInfo * pIO, U8 cIndex[16][MAX_CHANNELS], U8 cChMode[16], U32 cNum, size_t cChannel, Bool bCopy)
|
||||
{
|
||||
putBit16(pIO, bCopy == TRUE ? 1 : 0, 1);
|
||||
if(bCopy == FALSE){
|
||||
U32 i;
|
||||
|
||||
putBit16(pIO, cNum - 1, 4);
|
||||
|
||||
for(i = 0; i < cNum; i ++)
|
||||
transcodeQuantizer(pIO, cIndex[i], cChMode[i], cChannel);
|
||||
}
|
||||
}
|
||||
|
||||
Void transcodeQuantizersAlpha(BitIOInfo * pIO, U8 cIndex[16][MAX_CHANNELS], U32 cNum, size_t iChannel, Bool bCopy)
|
||||
{
|
||||
putBit16(pIO, bCopy == TRUE ? 1 : 0, 1);
|
||||
if(bCopy == FALSE){
|
||||
U32 i;
|
||||
|
||||
putBit16(pIO, cNum - 1, 4);
|
||||
|
||||
for(i = 0; i < cNum; i ++)
|
||||
putBit16(pIO, cIndex[i][iChannel], 8);
|
||||
}
|
||||
}
|
||||
|
||||
Void transcodeTileHeader(CWMImageStrCodec * pSC, CTileQPInfo * pTileQPInfo)
|
||||
{
|
||||
if(pSC->m_bCtxLeft && pSC->m_bCtxTop && pSC->m_bSecondary == FALSE){ // write packet headers
|
||||
CCodingContext * pContext = &pSC->m_pCodingContext[pSC->cTileColumn];
|
||||
CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
|
||||
U8 pID = (U8)((pSC->cTileRow * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + pSC->cTileColumn) & 0x1F);
|
||||
CWMImageStrCodec * pSCAlpha = (pSC->m_param.bAlphaChannel ? pSC->m_pNextSC : NULL);
|
||||
const size_t iAlphaPos = pSC->m_param.cNumChannels;
|
||||
|
||||
writePacketHeader(pContext->m_pIODC, pSC->WMISCP.bfBitstreamFormat == SPATIAL ? 0 : 1, pID);
|
||||
if (pSC->m_param.bTrimFlexbitsFlag && pSC->WMISCP.bfBitstreamFormat == SPATIAL)
|
||||
putBit16(pContext->m_pIODC, pContext->m_iTrimFlexBits, 4);
|
||||
|
||||
if((pSC->m_param.uQPMode & 1) != 0) // not DC uniform
|
||||
transcodeQuantizer(pContext->m_pIODC, pTileQPInfo->dcIndex, pTileQPInfo->dcMode, pSC->WMISCP.cChannel);
|
||||
if(pSCAlpha != NULL && (pSCAlpha->m_param.uQPMode & 1) != 0) // not DC uniform
|
||||
putBit16(pContext->m_pIODC, pTileQPInfo->dcIndex[iAlphaPos], 8);
|
||||
|
||||
if(pSC->WMISCP.bfBitstreamFormat == SPATIAL) {
|
||||
if(pSC->WMISCP.sbSubband != SB_DC_ONLY){
|
||||
if((pSC->m_param.uQPMode & 2) != 0) // not LP uniform
|
||||
transcodeQuantizers(pContext->m_pIODC, pTileQPInfo->lpIndex, pTileQPInfo->lpMode, pTileQPInfo->lpNum, pSC->WMISCP.cChannel, pTileQPInfo->bUseDC);
|
||||
if(pSCAlpha != NULL && (pSCAlpha->m_param.uQPMode & 2) != 0) // not LP uniform
|
||||
transcodeQuantizersAlpha(pContext->m_pIODC, pTileQPInfo->lpIndex, pTileQPInfo->lpNumAlpha, iAlphaPos, pTileQPInfo->bUseDCAlpha);
|
||||
if(pSC->WMISCP.sbSubband != SB_NO_HIGHPASS){
|
||||
if((pSC->m_param.uQPMode & 4) != 0) // not HP uniform
|
||||
transcodeQuantizers(pContext->m_pIODC, pTileQPInfo->hpIndex, pTileQPInfo->hpMode, pTileQPInfo->hpNum, pSC->WMISCP.cChannel, pTileQPInfo->bUseLP);
|
||||
if(pSCAlpha != NULL && (pSCAlpha->m_param.uQPMode & 4) != 0) // not HP uniform
|
||||
transcodeQuantizersAlpha(pContext->m_pIODC, pTileQPInfo->hpIndex, pTileQPInfo->hpNumAlpha, iAlphaPos, pTileQPInfo->bUseLPAlpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(pSC->WMISCP.sbSubband != SB_DC_ONLY){
|
||||
writePacketHeader(pContext->m_pIOLP, 2, pID);
|
||||
if((pSC->m_param.uQPMode & 2) != 0) // not LP uniform
|
||||
transcodeQuantizers(pContext->m_pIOLP, pTileQPInfo->lpIndex, pTileQPInfo->lpMode, pTileQPInfo->lpNum, pSC->WMISCP.cChannel, pTileQPInfo->bUseDC);
|
||||
if(pSCAlpha != NULL && (pSCAlpha->m_param.uQPMode & 2) != 0) // not LP uniform
|
||||
transcodeQuantizersAlpha(pContext->m_pIOLP, pTileQPInfo->lpIndex, pTileQPInfo->lpNumAlpha, iAlphaPos, pTileQPInfo->bUseDCAlpha);
|
||||
|
||||
if(pSC->WMISCP.sbSubband != SB_NO_HIGHPASS){
|
||||
writePacketHeader(pContext->m_pIOAC, 3, pID);
|
||||
if((pSC->m_param.uQPMode & 4) != 0) // not HP uniform
|
||||
transcodeQuantizers(pContext->m_pIOAC, pTileQPInfo->hpIndex, pTileQPInfo->hpMode, pTileQPInfo->hpNum, pSC->WMISCP.cChannel, pTileQPInfo->bUseLP);
|
||||
if(pSCAlpha != NULL && (pSCAlpha->m_param.uQPMode & 4) != 0) // not HP uniform
|
||||
transcodeQuantizersAlpha(pContext->m_pIOAC, pTileQPInfo->hpIndex, pTileQPInfo->hpNumAlpha, iAlphaPos, pTileQPInfo->bUseLPAlpha);
|
||||
|
||||
if(pSC->WMISCP.sbSubband != SB_NO_FLEXBITS){
|
||||
writePacketHeader(pContext->m_pIOFL, 4, pID);
|
||||
if (pSC->m_param.bTrimFlexbitsFlag)
|
||||
putBit16(pContext->m_pIOFL, pContext->m_iTrimFlexBits, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pTile->cBitsLP = (pTileQPInfo->bUseDC ? 0 : dquantBits(pTileQPInfo->lpNum));
|
||||
pTile->cBitsHP = (pTileQPInfo->bUseLP ? 0 : dquantBits(pTileQPInfo->hpNum));
|
||||
if(pSCAlpha != NULL){
|
||||
pTile = pSCAlpha->pTile + pSC->cTileColumn;
|
||||
pTile->cBitsLP = (pTileQPInfo->bUseDCAlpha ? 0 : dquantBits(pTileQPInfo->lpNumAlpha));
|
||||
pTile->cBitsHP = (pTileQPInfo->bUseLPAlpha ? 0 : dquantBits(pTileQPInfo->hpNumAlpha));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Void transformDCBlock(PixelI * pOrg, PixelI * pDst, ORIENTATION oOrientation)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if(bFlipV[oOrientation])
|
||||
for(i = 0; i < 16; i += 4)
|
||||
pOrg[i + 1] = -pOrg[i + 1], pOrg[i + 3] = -pOrg[i + 3];
|
||||
|
||||
if(bFlipH[oOrientation])
|
||||
for(i = 0; i < 4; i ++)
|
||||
pOrg[i + 4] = -pOrg[i + 4], pOrg[i + 12] = -pOrg[i + 12];
|
||||
|
||||
if(oOrientation < O_RCW)
|
||||
memcpy(pDst, pOrg, 16 * sizeof(PixelI));
|
||||
else
|
||||
for(i = 0; i < 16; i ++)
|
||||
pDst[i] = pOrg[(i >> 2) + ((i & 3) << 2)];
|
||||
}
|
||||
|
||||
Void transformDCBlock422(PixelI * pOrg, PixelI * pDst, ORIENTATION oOrientation)
|
||||
{
|
||||
assert(oOrientation < O_RCW);
|
||||
|
||||
if(bFlipV[oOrientation])
|
||||
pOrg[1] = -pOrg[1], pOrg[3] = -pOrg[3], pOrg[4] = -pOrg[4], pOrg[5] = -pOrg[5], pOrg[7] = -pOrg[7];
|
||||
|
||||
if(bFlipH[oOrientation])
|
||||
pOrg[2] = -pOrg[2], pOrg[3] = -pOrg[3], pOrg[6] = -pOrg[6], pOrg[7] = -pOrg[7];
|
||||
|
||||
if(bFlipV[oOrientation])
|
||||
pDst[0] = pOrg[0], pDst[1] = pOrg[5], pDst[2] = pOrg[6], pDst[3] = pOrg[7], pDst[4] = pOrg[4], pDst[5] = pOrg[1], pDst[6] = pOrg[2], pDst[7] = pOrg[3];
|
||||
else
|
||||
memcpy(pDst, pOrg, 8 * sizeof(PixelI));
|
||||
}
|
||||
|
||||
Void transformDCBlock420(PixelI * pOrg, PixelI * pDst, ORIENTATION oOrientation)
|
||||
{
|
||||
if(bFlipV[oOrientation])
|
||||
pOrg[1] = -pOrg[1], pOrg[3] = -pOrg[3];
|
||||
|
||||
if(bFlipH[oOrientation])
|
||||
pOrg[2] = -pOrg[2], pOrg[3] = -pOrg[3];
|
||||
|
||||
pDst[0] = pOrg[0], pDst[3] = pOrg[3];
|
||||
if(oOrientation < O_RCW)
|
||||
pDst[1] = pOrg[1], pDst[2] = pOrg[2];
|
||||
else
|
||||
pDst[1] = pOrg[2], pDst[2] = pOrg[1];
|
||||
}
|
||||
|
||||
Void transformACBlocks(PixelI * pOrg, PixelI * pDst, ORIENTATION oOrientation)
|
||||
{
|
||||
PixelI * pO, * pD;
|
||||
const Int * pT = dctIndex[0];
|
||||
size_t i, j, k;
|
||||
|
||||
for(j = 0, pO = pOrg; j < 16; j ++, pO += 16){
|
||||
if(bFlipV[oOrientation])
|
||||
for(i = 0; i < 16; i += 4)
|
||||
pO[pT[i + 1]] = -pO[pT[i + 1]], pO[pT[i + 3]] = -pO[pT[i + 3]];
|
||||
|
||||
if(bFlipH[oOrientation])
|
||||
for(i = 0; i < 4; i ++)
|
||||
pO[pT[i + 4]] = -pO[pT[i + 4]], pO[pT[i + 12]] = -pO[pT[i + 12]];
|
||||
}
|
||||
|
||||
for(j = 0; j < 4; j ++)
|
||||
for(i = 0; i < 4; i ++){
|
||||
size_t ii = (bFlipV[oOrientation] ? 3 - i : i);
|
||||
size_t jj = (bFlipH[oOrientation] ? 3 - j : j);
|
||||
|
||||
if(oOrientation < O_RCW)
|
||||
memcpy(pDst + (jj * 4 + ii) * 16, pOrg + (j * 4 + i) * 16, 16 * sizeof(PixelI));
|
||||
else{
|
||||
pO = pOrg + (j * 4 + i) * 16;
|
||||
pD = pDst + (ii * 4 + jj) * 16;
|
||||
for(k = 1; k < 16; k ++)
|
||||
pD[pT[k]] = pO[pT[(k >> 2) + ((k & 3) << 2)]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Void transformACBlocks422(PixelI * pOrg, PixelI * pDst, ORIENTATION oOrientation)
|
||||
{
|
||||
PixelI * pO;
|
||||
const Int * pT = dctIndex[0];
|
||||
size_t i, j;
|
||||
|
||||
assert(oOrientation < O_RCW);
|
||||
|
||||
for(j = 0, pO = pOrg; j < 8; j ++, pO += 16){
|
||||
if(bFlipV[oOrientation])
|
||||
for(i = 0; i < 16; i += 4)
|
||||
pO[pT[i + 1]] = -pO[pT[i + 1]], pO[pT[i + 3]] = -pO[pT[i + 3]];
|
||||
|
||||
if(bFlipH[oOrientation])
|
||||
for(i = 0; i < 4; i ++)
|
||||
pO[pT[i + 4]] = -pO[pT[i + 4]], pO[pT[i + 12]] = -pO[pT[i + 12]];
|
||||
}
|
||||
|
||||
for(j = 0; j < 2; j ++)
|
||||
for(i = 0; i < 4; i ++){
|
||||
size_t ii = (bFlipV[oOrientation] ? 3 - i : i);
|
||||
size_t jj = (bFlipH[oOrientation] ? 1 - j : j);
|
||||
|
||||
memcpy(pDst + (jj * 4 + ii) * 16, pOrg + (j * 4 + i) * 16, 16 * sizeof(PixelI));
|
||||
}
|
||||
}
|
||||
|
||||
Void transformACBlocks420(PixelI * pOrg, PixelI * pDst, ORIENTATION oOrientation)
|
||||
{
|
||||
PixelI * pO, * pD;
|
||||
const Int * pT = dctIndex[0];
|
||||
size_t i, j, k;
|
||||
|
||||
for(j = 0, pO = pOrg; j < 4; j ++, pO += 16){
|
||||
if(bFlipV[oOrientation])
|
||||
for(i = 0; i < 16; i += 4)
|
||||
pO[pT[i + 1]] = -pO[pT[i + 1]], pO[pT[i + 3]] = -pO[pT[i + 3]];
|
||||
|
||||
if(bFlipH[oOrientation])
|
||||
for(i = 0; i < 4; i ++)
|
||||
pO[pT[i + 4]] = -pO[pT[i + 4]], pO[pT[i + 12]] = -pO[pT[i + 12]];
|
||||
}
|
||||
|
||||
for(j = 0; j < 2; j ++)
|
||||
for(i = 0; i < 2; i ++){
|
||||
size_t ii = (bFlipV[oOrientation] ? 1 - i : i);
|
||||
size_t jj = (bFlipH[oOrientation] ? 1 - j : j);
|
||||
|
||||
if(oOrientation < O_RCW)
|
||||
memcpy(pDst + (jj * 2 + ii) * 16, pOrg + (j * 2 + i) * 16, 16 * sizeof(PixelI));
|
||||
else{
|
||||
pO = pOrg + (j * 2 + i) * 16;
|
||||
pD = pDst + (ii * 2 + jj) * 16;
|
||||
for(k = 1; k < 16; k ++)
|
||||
pD[pT[k]] = pO[pT[(k >> 2) + ((k & 3) << 2)]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Int getROI(CWMImageInfo * pII, CCoreParameters * pCore, CWMIStrCodecParam * pSCP, CWMTranscodingParam * pParam)
|
||||
{
|
||||
const ORIENTATION oO = pParam->oOrientation;
|
||||
size_t iLeft, iTop, cWidth, cHeight, i, j;
|
||||
size_t mbLeft, mbRight, mbTop, mbBottom;
|
||||
size_t * iTile = (size_t *)malloc(MAX_TILES * sizeof(size_t));
|
||||
|
||||
if(iTile == NULL)
|
||||
return ICERR_ERROR;
|
||||
|
||||
if(pParam->cLeftX + pParam->cWidth > pII->cWidth || pParam->cTopY + pParam->cHeight > pII->cHeight) // invalid region
|
||||
return ICERR_ERROR;
|
||||
|
||||
cWidth = pParam->cWidth, cHeight = pParam->cHeight;
|
||||
iLeft = pParam->cLeftX + pCore->cExtraPixelsLeft, iTop = pParam->cTopY + pCore->cExtraPixelsTop;
|
||||
if(pSCP->olOverlap != OL_NONE && pParam->bIgnoreOverlap == FALSE){ // include pixels borrowed
|
||||
size_t cBlurred = (pSCP->olOverlap == OL_TWO ? 10 : 2);
|
||||
|
||||
if(iLeft > cBlurred)
|
||||
iLeft -= cBlurred, cWidth += cBlurred;
|
||||
else
|
||||
cWidth += iLeft, iLeft = 0;
|
||||
if(iTop > cBlurred)
|
||||
iTop -= cBlurred, cHeight += cBlurred;
|
||||
else
|
||||
cHeight += iTop, iTop = 0;
|
||||
cWidth += cBlurred, cHeight += cBlurred;
|
||||
if(iLeft + cWidth > pII->cWidth + pCore->cExtraPixelsLeft + pCore->cExtraPixelsRight)
|
||||
cWidth = pII->cWidth + pCore->cExtraPixelsLeft + pCore->cExtraPixelsRight - iLeft;
|
||||
if(iTop + cHeight > pII->cHeight + pCore->cExtraPixelsTop + pCore->cExtraPixelsBottom)
|
||||
cHeight = pII->cHeight + pCore->cExtraPixelsTop + pCore->cExtraPixelsBottom - iTop;
|
||||
}
|
||||
|
||||
mbTop = (iTop >> 4), mbLeft = (iLeft >> 4);
|
||||
mbBottom = (iTop + cHeight + 15) >> 4, mbRight = (iLeft + cWidth + 15) >> 4;
|
||||
pCore->cExtraPixelsLeft += pParam->cLeftX - (mbLeft << 4);
|
||||
pCore->cExtraPixelsRight = ((mbRight - mbLeft) << 4) - pParam->cWidth - pCore->cExtraPixelsLeft;
|
||||
pCore->cExtraPixelsTop += pParam->cTopY - (mbTop << 4);
|
||||
pCore->cExtraPixelsBottom = ((mbBottom - mbTop) << 4) - pParam->cHeight - pCore->cExtraPixelsTop;
|
||||
|
||||
pII->cWidth = ((mbRight - mbLeft) << 4) - pCore->cExtraPixelsLeft - pCore->cExtraPixelsRight;
|
||||
pII->cHeight = ((mbBottom - mbTop) << 4) - pCore->cExtraPixelsTop - pCore->cExtraPixelsBottom;
|
||||
pParam->cLeftX = iLeft, pParam->cTopY = iTop;
|
||||
pParam->cWidth = cWidth, pParam->cHeight = cHeight;
|
||||
|
||||
// extra pixels in transformed space
|
||||
#define SWAP(a, b) i = a, a = b, b = i
|
||||
if(oO == O_FLIPH || oO == O_FLIPVH || oO == O_RCW_FLIPV || oO == O_RCW_FLIPVH)
|
||||
SWAP(pCore->cExtraPixelsLeft, pCore->cExtraPixelsRight);
|
||||
if(oO == O_FLIPV || oO == O_FLIPVH || oO == O_RCW || oO == O_RCW_FLIPV)
|
||||
SWAP(pCore->cExtraPixelsTop, pCore->cExtraPixelsBottom);
|
||||
if(oO >= O_RCW){
|
||||
SWAP(pCore->cExtraPixelsLeft, pCore->cExtraPixelsTop);
|
||||
SWAP(pCore->cExtraPixelsRight, pCore->cExtraPixelsBottom);
|
||||
}
|
||||
|
||||
// adjust tiling
|
||||
for(i = 0, j = 0, iTile[0] = 0; i <= (size_t)pSCP->cNumOfSliceMinus1V; i ++)
|
||||
if((size_t)pSCP->uiTileX[i] >= mbLeft && (size_t)pSCP->uiTileX[i] < mbRight){
|
||||
if(j >= MAX_TILES)
|
||||
j = MAX_TILES - 1;
|
||||
iTile[j] = (size_t)pSCP->uiTileX[i] - mbLeft, j ++;
|
||||
}
|
||||
if(iTile[0] == 0)
|
||||
for(i = 0, pSCP->cNumOfSliceMinus1V = (j == 0 ? 0 : (U32)(j - 1)); i < j; i ++)
|
||||
pSCP->uiTileX[i] = (U32)iTile[i];
|
||||
else
|
||||
for(i = 1, pSCP->uiTileX[0] = 0, pSCP->cNumOfSliceMinus1V = (U32)j; i <= j; i ++)
|
||||
pSCP->uiTileX[i] = (U32)iTile[i - 1];
|
||||
if(oO == O_FLIPH || oO == O_FLIPVH || oO == O_RCW_FLIPV || oO == O_RCW_FLIPVH){ // reverse order
|
||||
for(i = 0; i <= (size_t)pSCP->cNumOfSliceMinus1V; i ++)
|
||||
iTile[i] = mbRight - mbLeft - (size_t)pSCP->uiTileX[i];
|
||||
for(i = 1, pSCP->uiTileX[0] = 0; i <= (size_t)pSCP->cNumOfSliceMinus1V; i ++)
|
||||
pSCP->uiTileX[i] = (U32)(iTile[(size_t)pSCP->cNumOfSliceMinus1V - i + 1]);
|
||||
}
|
||||
for(i = 0, j = 0, iTile[0] = 0; i <= (size_t)pSCP->cNumOfSliceMinus1H; i ++)
|
||||
if(pSCP->uiTileY[i] >= mbTop && pSCP->uiTileY[i] < mbBottom){
|
||||
if(j >= MAX_TILES)
|
||||
j = MAX_TILES - 1;
|
||||
iTile[j] = (size_t)pSCP->uiTileY[i] - mbTop, j ++;
|
||||
}
|
||||
if(iTile[0] == 0)
|
||||
for(i = 0, pSCP->cNumOfSliceMinus1H = (j == 0 ? 0 : (U32)(j - 1)); i < j; i ++)
|
||||
pSCP->uiTileY[i] = (U32)iTile[i];
|
||||
else
|
||||
for(i = 1, pSCP->uiTileY[0] = 0, pSCP->cNumOfSliceMinus1H = (U32)j; i <= j; i ++)
|
||||
pSCP->uiTileY[i] = (U32)iTile[i - 1];
|
||||
if(oO == O_FLIPV || oO == O_FLIPVH || oO == O_RCW || oO == O_RCW_FLIPV){ // reverse order
|
||||
for(i = 0; i <= (size_t)pSCP->cNumOfSliceMinus1H; i ++)
|
||||
iTile[i] = mbBottom - mbTop - (size_t)pSCP->uiTileY[i];
|
||||
for(i = 1, pSCP->uiTileY[0] = 0; i <= (size_t)pSCP->cNumOfSliceMinus1H; i ++)
|
||||
pSCP->uiTileY[i] = (U32)(iTile[(size_t)pSCP->cNumOfSliceMinus1H - i + 1]);
|
||||
}
|
||||
if(oO >= O_RCW){ // switch X & Y
|
||||
for(i = 0; i <= (size_t)pSCP->cNumOfSliceMinus1V; i ++)
|
||||
iTile[i] = (size_t)pSCP->uiTileX[i];
|
||||
for(i = 0; i <= (size_t)pSCP->cNumOfSliceMinus1H; i ++)
|
||||
pSCP->uiTileX[i] = pSCP->uiTileY[i];
|
||||
for(i = 0; i <= (size_t)pSCP->cNumOfSliceMinus1V; i ++)
|
||||
pSCP->uiTileY[i] = (U32)iTile[i];
|
||||
i = (size_t)pSCP->cNumOfSliceMinus1H, pSCP->cNumOfSliceMinus1H = pSCP->cNumOfSliceMinus1V, pSCP->cNumOfSliceMinus1V = (U32)i;
|
||||
}
|
||||
|
||||
free(iTile);
|
||||
|
||||
return ICERR_OK;
|
||||
}
|
||||
|
||||
Bool isTileBoundary(U32 * pTilePos, U32 cTiles, U32 cMBs, U32 iPos)
|
||||
{
|
||||
U32 i;
|
||||
|
||||
for(i = 0; i < cTiles; i ++)
|
||||
if(iPos == pTilePos[i] * 16)
|
||||
break;
|
||||
|
||||
return ((i < cTiles || (iPos + 15) / 16 >= cMBs) ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
Bool isTileExtraction(CWMImageStrCodec * pSC, CWMTranscodingParam * pParam)
|
||||
{
|
||||
if(pParam->bIgnoreOverlap == FALSE && pSC->WMISCP.olOverlap == OL_NONE)
|
||||
pParam->bIgnoreOverlap = TRUE;
|
||||
|
||||
if(pParam->bIgnoreOverlap == TRUE && pParam->oOrientation == O_NONE && pParam->bfBitstreamFormat == pSC->WMISCP.bfBitstreamFormat){
|
||||
if(pParam->bfBitstreamFormat == SPATIAL && pParam->sbSubband != pSC->WMISCP.sbSubband)
|
||||
return FALSE;
|
||||
|
||||
return (isTileBoundary(pSC->WMISCP.uiTileX, pSC->WMISCP.cNumOfSliceMinus1V + 1, (U32)pSC->cmbWidth, (U32)(pParam->cLeftX + pSC->m_param.cExtraPixelsLeft)) &&
|
||||
isTileBoundary(pSC->WMISCP.uiTileY, pSC->WMISCP.cNumOfSliceMinus1H + 1, (U32)pSC->cmbHeight, (U32)(pParam->cTopY + pSC->m_param.cExtraPixelsTop)) &&
|
||||
isTileBoundary(pSC->WMISCP.uiTileX, pSC->WMISCP.cNumOfSliceMinus1V + 1, (U32)pSC->cmbWidth, (U32)(pParam->cLeftX + pParam->cWidth + pSC->m_param.cExtraPixelsLeft)) &&
|
||||
isTileBoundary(pSC->WMISCP.uiTileY, pSC->WMISCP.cNumOfSliceMinus1H + 1, (U32)pSC->cmbHeight, (U32)(pParam->cTopY + pParam->cHeight + pSC->m_param.cExtraPixelsTop)));
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Int WMPhotoTranscode(struct WMPStream * pStreamIn, struct WMPStream * pStreamOut, CWMTranscodingParam * pParam)
|
||||
{
|
||||
PixelI * pMBBuf, MBBufAlpha[256]; // shared buffer, decoder <=> encoder bridge
|
||||
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.cNumOfSliceMinus1V + 1))))
|
||||
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;
|
||||
writeIndexTableNull(pSCEnc);
|
||||
}
|
||||
else
|
||||
writeIndexTable(pSCEnc);
|
||||
|
||||
detachISWrite(pSCEnc, pSCEnc->pIOHeader);
|
||||
|
||||
for(j = l = 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 ++){
|
||||
pSCDec->WMISCP.pWStream->SetPos(pSCDec->WMISCP.pWStream, pSCDec->pIndexTable[(j * (pSCDec->WMISCP.cNumOfSliceMinus1V + 1) + i) * cfDec + k] + pSCDec->cHeaderSize);
|
||||
copyTo(pSCDec->WMISCP.pWStream, pSCEnc->WMISCP.pWStream, pSCEnc->pIndexTable[l++]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(pSCEnc->pIndexTable);
|
||||
}
|
||||
else
|
||||
writeIndexTableNull(pSCEnc);
|
||||
|
||||
for(pSCDec->cRow = 0; pSCDec->cRow < mbBottom && pParam->bIgnoreOverlap == FALSE; pSCDec->cRow ++){
|
||||
for(pSCDec->cColumn = 0; pSCDec->cColumn < pSCDec->cmbWidth; pSCDec->cColumn ++){
|
||||
Int cRow = (Int)pSCDec->cRow, cColumn = (Int)pSCDec->cColumn;
|
||||
CWMITile * pTile;
|
||||
|
||||
memset(pMBBuf, 0, sizeof(PixelI) * cUnit);
|
||||
if(pSCDec->m_param.bAlphaChannel){ // alpha channel
|
||||
memset(pSCDec->m_pNextSC->p1MBbuffer[0], 0, sizeof(PixelI) * 256);
|
||||
pSCDec->m_pNextSC->cRow = pSCDec->cRow;
|
||||
pSCDec->m_pNextSC->cColumn = pSCDec->cColumn;
|
||||
}
|
||||
|
||||
// decode
|
||||
pSC = pSCDec;
|
||||
for(i = (pSCDec->m_param.bAlphaChannel ? 2 : 1); i > 0; i --){
|
||||
getTilePos(pSCDec, cColumn, cRow);
|
||||
if(i == 2){
|
||||
pSCDec->m_pNextSC->cTileColumn = pSCDec->cTileColumn;
|
||||
pSCDec->m_pNextSC->cTileRow = pSCDec->cTileRow;
|
||||
}
|
||||
|
||||
if(readPackets(pSCDec) != ICERR_OK)
|
||||
return ICERR_ERROR;
|
||||
|
||||
pContext = &pSCDec->m_pCodingContext[pSCDec->cTileColumn];
|
||||
|
||||
if(DecodeMacroblockDC(pSCDec, pContext, cColumn, cRow) != ICERR_OK)
|
||||
return ICERR_ERROR;
|
||||
|
||||
if(pSCDec->cSB > 1)
|
||||
if(DecodeMacroblockLowpass(pSCDec, pContext, cColumn, cRow) != ICERR_OK)
|
||||
return ICERR_ERROR;
|
||||
|
||||
predDCACDec(pSCDec);
|
||||
|
||||
if(pSCDec->cSB > 2)
|
||||
if(DecodeMacroblockHighpass(pSCDec, pContext, cColumn, cRow) != ICERR_OK)
|
||||
return ICERR_ERROR;
|
||||
|
||||
predACDec(pSCDec);
|
||||
|
||||
updatePredInfo(pSCDec, &pSCDec->MBInfo, cColumn, pSCDec->WMISCP.cfColorFormat);
|
||||
|
||||
pSCDec = pSCDec->m_pNextSC;
|
||||
}
|
||||
pSCDec = pSC;
|
||||
|
||||
if(pSCDec->cRow >= mbTop && pSCDec->cColumn >= mbLeft && pSCDec->cColumn < mbRight){
|
||||
cRow = (Int)(pSCDec->cRow - mbTop);
|
||||
if(bFlipV[oO])
|
||||
cRow = (Int)mbHeight - cRow - 1;
|
||||
cColumn = (Int)(pSCDec->cColumn - mbLeft);
|
||||
if(bFlipH[oO])
|
||||
cColumn = (Int)mbWidth - cColumn - 1;
|
||||
|
||||
pSCEnc->m_bCtxLeft = pSCEnc->m_bCtxTop = FALSE;
|
||||
for(i = 0; i <= pSCEnc->WMISCP.cNumOfSliceMinus1H; i ++)
|
||||
if(pSCEnc->WMISCP.uiTileY[i] == (U32)(oO < O_RCW ? cRow : cColumn)){
|
||||
pSCEnc->cTileRow = i;
|
||||
pSCEnc->m_bCtxTop = TRUE;
|
||||
break;
|
||||
}
|
||||
for(i = 0; i <= pSCEnc->WMISCP.cNumOfSliceMinus1V; i ++)
|
||||
if(pSCEnc->WMISCP.uiTileX[i] == (U32)(oO < O_RCW ? cColumn : cRow)){
|
||||
pSCEnc->cTileColumn = i;
|
||||
pSCEnc->m_bCtxLeft = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if(pSCEnc->m_bCtxLeft && pSCEnc->m_bCtxTop){ // a new tile, buffer tile DQuant info
|
||||
CTileQPInfo * pTmp = pTileQPInfo;
|
||||
|
||||
pTile = pSCDec->pTile + pSCDec->cTileColumn;
|
||||
|
||||
if(oO != O_NONE)
|
||||
pTmp += pSCEnc->cTileRow * (pSCEnc->WMISCP.cNumOfSliceMinus1V + 1) + pSCEnc->cTileColumn;
|
||||
|
||||
pTmp->dcMode = pTile->cChModeDC;
|
||||
for(i = 0; i < pSCEnc->WMISCP.cChannel; i ++)
|
||||
pTmp->dcIndex[i] = pTile->pQuantizerDC[i][0].iIndex;
|
||||
|
||||
if(pSCEnc->WMISCP.sbSubband != SB_DC_ONLY){
|
||||
pTmp->bUseDC = pTile->bUseDC;
|
||||
pTmp->lpNum = pTile->cNumQPLP;
|
||||
if(pTmp->bUseDC == FALSE)
|
||||
for(j = 0; j < pTmp->lpNum; j ++){
|
||||
pTmp->lpMode[j] = pTile->cChModeLP[j];
|
||||
for(i = 0; i < pSCEnc->WMISCP.cChannel; i ++)
|
||||
pTmp->lpIndex[j][i] = pTile->pQuantizerLP[i][j].iIndex;
|
||||
}
|
||||
|
||||
if(pSCEnc->WMISCP.sbSubband != SB_NO_HIGHPASS){
|
||||
pTmp->bUseLP = pTile->bUseLP;
|
||||
pTmp->hpNum = pTile->cNumQPHP;
|
||||
if(pTmp->bUseLP == FALSE)
|
||||
for(j = 0; j < pTmp->hpNum; j ++){
|
||||
pTmp->hpMode[j] = pTile->cChModeHP[j];
|
||||
for(i = 0; i < pSCEnc->WMISCP.cChannel; i ++)
|
||||
pTmp->hpIndex[j][i] = pTile->pQuantizerHP[i][j].iIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(pParam->uAlphaMode > 0){
|
||||
pTile = pSCDec->m_pNextSC->pTile + pSCDec->cTileColumn;
|
||||
|
||||
pTmp->dcIndex[iAlphaPos] = pTile->pQuantizerDC[0][0].iIndex;
|
||||
|
||||
if(pSCEnc->WMISCP.sbSubband != SB_DC_ONLY){
|
||||
pTmp->bUseDCAlpha = pTile->bUseDC;
|
||||
pTmp->lpNumAlpha = pTile->cNumQPLP;
|
||||
if(pTmp->bUseDCAlpha == FALSE)
|
||||
for(j = 0; j < pTmp->lpNumAlpha; j ++)
|
||||
pTmp->lpIndex[j][iAlphaPos] = pTile->pQuantizerLP[0][j].iIndex;
|
||||
if(pSCEnc->WMISCP.sbSubband != SB_NO_HIGHPASS){
|
||||
pTmp->bUseLPAlpha = pTile->bUseLP;
|
||||
pTmp->hpNumAlpha = pTile->cNumQPHP;
|
||||
if(pTmp->bUseLPAlpha == FALSE)
|
||||
for(j = 0; j < pTmp->hpNumAlpha; j ++)
|
||||
pTmp->hpIndex[j][iAlphaPos] = pTile->pQuantizerHP[0][j].iIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(oO == O_NONE){
|
||||
// encode
|
||||
pSCEnc->cColumn = pSCDec->cColumn - mbLeft + 1;
|
||||
pSCEnc->cRow = pSCDec->cRow + 1 - mbTop;
|
||||
pSCEnc->MBInfo = pSCDec->MBInfo;
|
||||
|
||||
getTilePos(pSCEnc, cColumn, cRow);
|
||||
|
||||
if(pSCEnc->m_bCtxLeft && pSCEnc->m_bCtxTop)
|
||||
transcodeTileHeader(pSCEnc, pTileQPInfo);
|
||||
|
||||
if(encodeMB(pSCEnc, cColumn, cRow) != ICERR_OK)
|
||||
return ICERR_ERROR;
|
||||
if(pParam->uAlphaMode > 0){
|
||||
pSCEnc->m_pNextSC->cColumn = pSCDec->cColumn - mbLeft + 1;
|
||||
pSCEnc->m_pNextSC->cRow = pSCDec->cRow + 1 - mbTop;
|
||||
getTilePos(pSCEnc->m_pNextSC, cColumn, cRow);
|
||||
pSCEnc->m_pNextSC->MBInfo = pSCDec->m_pNextSC->MBInfo;
|
||||
if(encodeMB(pSCEnc->m_pNextSC, cColumn, cRow) != ICERR_OK)
|
||||
return ICERR_ERROR;
|
||||
}
|
||||
}
|
||||
else{
|
||||
size_t cOff = (oO < O_RCW ? (size_t)cRow * mbWidth + (size_t)cColumn : (size_t)cRow + mbHeight * (size_t)cColumn);
|
||||
|
||||
pMBInfo[cOff] = pSCDec->MBInfo;
|
||||
|
||||
memcpy(&pFrameBuf[cOff * cUnit], pMBBuf, cUnit * sizeof(PixelI));
|
||||
|
||||
if(pParam->uAlphaMode > 0){
|
||||
pMBInfoAlpha[cOff] = pSCDec->m_pNextSC->MBInfo;
|
||||
|
||||
memcpy(&pFrameBufAlpha[cOff * 256], MBBufAlpha, 256 * sizeof(PixelI));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
advanceOneMBRow(pSCDec);
|
||||
|
||||
if(oO == O_NONE)
|
||||
advanceOneMBRow(pSCEnc);
|
||||
}
|
||||
|
||||
if(oO != O_NONE){
|
||||
for(pSCEnc->cRow = 1; pSCEnc->cRow <= pSCEnc->cmbHeight; pSCEnc->cRow ++){
|
||||
for(pSCEnc->cColumn = 1; pSCEnc->cColumn <= pSCEnc->cmbWidth; pSCEnc->cColumn ++){
|
||||
Int cRow, cColumn;
|
||||
size_t cOff = (pSCEnc->cRow - 1) * pSCEnc->cmbWidth + pSCEnc->cColumn - 1;
|
||||
|
||||
for(i = 0; i < ((pSCEnc->m_param.cfColorFormat == YUV_420 || pSCEnc->m_param.cfColorFormat == YUV_422) ? 1 : pSCEnc->m_param.cNumChannels); i ++){
|
||||
transformDCBlock(pMBInfo[cOff].iBlockDC[i], pSCEnc->MBInfo.iBlockDC[i], oO);
|
||||
transformACBlocks(pFrameBuf + cOff * cUnit + i * 256, pMBBuf + 256 * i, oO);
|
||||
}
|
||||
if(pSCEnc->WMISCP.cfColorFormat == YUV_420)
|
||||
for(i = 0; i < 2; i ++){
|
||||
transformDCBlock420(pMBInfo[cOff].iBlockDC[i + 1], pSCEnc->MBInfo.iBlockDC[i + 1], oO);
|
||||
transformACBlocks420(pFrameBuf + cOff * cUnit + 256 + i * 64, pMBBuf + 256 + i * 64, oO);
|
||||
}
|
||||
else if(pSCEnc->WMISCP.cfColorFormat == YUV_422)
|
||||
for(i = 0; i < 2; i ++){
|
||||
transformDCBlock422(pMBInfo[cOff].iBlockDC[i + 1], pSCEnc->MBInfo.iBlockDC[i + 1], oO);
|
||||
transformACBlocks422(pFrameBuf + cOff * cUnit + 256 + i * 128, pMBBuf + 256 + i * 128, oO);
|
||||
}
|
||||
|
||||
pSCEnc->MBInfo.iQIndexLP = pMBInfo[cOff].iQIndexLP;
|
||||
pSCEnc->MBInfo.iQIndexHP = pMBInfo[cOff].iQIndexHP;
|
||||
|
||||
cRow = (Int)pSCEnc->cRow - 1;
|
||||
cColumn = (Int)pSCEnc->cColumn - 1;
|
||||
getTilePos(pSCEnc, cColumn, cRow);
|
||||
|
||||
if(pSCEnc->m_bCtxLeft && pSCEnc->m_bCtxTop)
|
||||
transcodeTileHeader(pSCEnc, pTileQPInfo + pSCEnc->cTileRow * (pSCEnc->WMISCP.cNumOfSliceMinus1V + 1) + pSCEnc->cTileColumn);
|
||||
if(encodeMB(pSCEnc, cColumn, cRow) != ICERR_OK)
|
||||
return ICERR_ERROR;
|
||||
|
||||
if(pParam->uAlphaMode > 0){
|
||||
pSCEnc->m_pNextSC->cColumn = pSCEnc->cColumn;
|
||||
pSCEnc->m_pNextSC->cRow = pSCEnc->cRow;
|
||||
getTilePos(pSCEnc->m_pNextSC, cColumn, cRow);
|
||||
pSCEnc->m_pNextSC->MBInfo = pSCDec->m_pNextSC->MBInfo;
|
||||
|
||||
transformDCBlock(pMBInfoAlpha[cOff].iBlockDC[0], pSCEnc->m_pNextSC->MBInfo.iBlockDC[0], oO);
|
||||
transformACBlocks(pFrameBufAlpha + cOff * 256, MBBufAlpha, oO);
|
||||
|
||||
pSCEnc->m_pNextSC->MBInfo.iQIndexLP = pMBInfoAlpha[cOff].iQIndexLP;
|
||||
pSCEnc->m_pNextSC->MBInfo.iQIndexHP = pMBInfoAlpha[cOff].iQIndexHP;
|
||||
|
||||
if(encodeMB(pSCEnc->m_pNextSC, cColumn, cRow) != ICERR_OK)
|
||||
return ICERR_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
advanceOneMBRow(pSCEnc);
|
||||
}
|
||||
}
|
||||
|
||||
free(pMBBuf);
|
||||
if(oO != O_NONE){
|
||||
free(pFrameBuf);
|
||||
free(pMBInfo);
|
||||
if(pParam->uAlphaMode > 0){ // alpha channel
|
||||
free(pFrameBufAlpha);
|
||||
free(pMBInfoAlpha);
|
||||
}
|
||||
}
|
||||
|
||||
freePredInfo(pSCDec);
|
||||
freeTileInfo(pSCDec);
|
||||
StrIODecTerm(pSCDec);
|
||||
FreeCodingContextDec(pSCDec);
|
||||
if(pSCDec->m_param.bAlphaChannel)
|
||||
free(pSCDec->m_pNextSC);
|
||||
free(pSCDec);
|
||||
free(pIOHeaderDec);
|
||||
|
||||
if(pParam->bIgnoreOverlap == FALSE){
|
||||
freePredInfo(pSCEnc);
|
||||
freeTileInfo(pSCEnc);
|
||||
StrIOEncTerm(pSCEnc);
|
||||
free(pTileQPInfo);
|
||||
FreeCodingContextEnc(pSCEnc);
|
||||
}
|
||||
free(pSCEnc);
|
||||
free(pIOHeaderEnc);
|
||||
|
||||
return ICERR_OK;
|
||||
}
|
|
@ -0,0 +1,200 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//*@@@---@@@@******************************************************************
|
||||
/******************************************************************************
|
||||
|
||||
Module Name:
|
||||
decode.c
|
||||
|
||||
Abstract:
|
||||
Defines the entry point for the console application.
|
||||
|
||||
Author:
|
||||
|
||||
Revision History:
|
||||
*******************************************************************************/
|
||||
#include "strcodec.h"
|
||||
#include "decode.h"
|
||||
|
||||
#ifdef MEM_TRACE
|
||||
#define TRACE_MALLOC 1
|
||||
#define TRACE_NEW 0
|
||||
#define TRACE_HEAP 0
|
||||
#include "memtrace.h"
|
||||
#endif
|
||||
|
||||
/******************************************************************
|
||||
Free Adaptive Huffman Table
|
||||
******************************************************************/
|
||||
static Void CleanAH(CAdaptiveHuffman **ppAdHuff)
|
||||
{
|
||||
CAdaptiveHuffman *pAdHuff;
|
||||
|
||||
if (NULL != ppAdHuff) {
|
||||
pAdHuff = *ppAdHuff;
|
||||
if (NULL != pAdHuff) {
|
||||
free(pAdHuff);
|
||||
}
|
||||
*ppAdHuff = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static Void CleanAHDec(CCodingContext * pSC)
|
||||
{
|
||||
Int kk;
|
||||
|
||||
for (kk = 0; kk < NUMVLCTABLES; kk++) {
|
||||
CleanAH(&(pSC->m_pAHexpt[kk]));
|
||||
}
|
||||
CleanAH(&(pSC->m_pAdaptHuffCBPCY));
|
||||
CleanAH(&(pSC->m_pAdaptHuffCBPCY1));
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Initialize an adaptive huffman table
|
||||
*************************************************************************/
|
||||
static Int InitializeAH(CAdaptiveHuffman **ppAdHuff, Int iSym)
|
||||
{
|
||||
Int iMemStatus = 0;
|
||||
|
||||
CAdaptiveHuffman *pAdHuff = Allocate(iSym, DECODER);
|
||||
if (pAdHuff == NULL) {
|
||||
iMemStatus = -1; // out of memory
|
||||
goto ErrorExit;
|
||||
}
|
||||
|
||||
//Adapt(pAdHuff, bFixedTables);
|
||||
//InitHuffman(pAdHuff->m_pHuffman);
|
||||
//if (ICERR_OK != initHuff(pAdHuff->m_pHuffman, 1, pAdHuff->m_pTable, NULL)) {
|
||||
// goto ErrorExit;
|
||||
//}
|
||||
*ppAdHuff = pAdHuff;
|
||||
return ICERR_OK;
|
||||
|
||||
ErrorExit:
|
||||
if (pAdHuff) {
|
||||
free(pAdHuff);
|
||||
}
|
||||
*ppAdHuff = NULL;
|
||||
if (-1 == iMemStatus) {
|
||||
printf("Insufficient memory to init decoder.\n");
|
||||
}
|
||||
return ICERR_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Context allocation
|
||||
*************************************************************************/
|
||||
Int AllocateCodingContextDec(CWMImageStrCodec *pSC, Int iNumContexts)
|
||||
{
|
||||
Int i, iCBPSize, k;
|
||||
static const Int aAlphabet[] = {5,4,8,7,7, 12,6,6,12,6,6,7,7, 12,6,6,12,6,6,7,7};
|
||||
|
||||
if (iNumContexts > MAX_TILES || iNumContexts < 1) // only between 1 and MAX_TILES allowed
|
||||
return ICERR_ERROR;
|
||||
|
||||
if (pSC == NULL)
|
||||
return ICERR_ERROR;
|
||||
|
||||
pSC->m_pCodingContext = malloc (iNumContexts * sizeof (CCodingContext));
|
||||
if (pSC->m_pCodingContext == NULL) {
|
||||
pSC->cNumCodingContext = 0;
|
||||
return ICERR_ERROR;
|
||||
}
|
||||
memset (pSC->m_pCodingContext, 0, iNumContexts * sizeof (CCodingContext));
|
||||
|
||||
pSC->cNumCodingContext = iNumContexts;
|
||||
iCBPSize = (pSC->m_param.cfColorFormat == Y_ONLY || pSC->m_param.cfColorFormat == NCOMPONENT
|
||||
|| pSC->m_param.cfColorFormat == CMYK) ? 5 : 9;
|
||||
|
||||
/** allocate / initialize members **/
|
||||
for (i = 0; i < iNumContexts; i++) {
|
||||
CCodingContext *pContext = &(pSC->m_pCodingContext[i]);
|
||||
|
||||
/** allocate adaptive Huffman encoder **/
|
||||
if (InitializeAH(&pContext->m_pAdaptHuffCBPCY, iCBPSize) != ICERR_OK) {
|
||||
return ICERR_ERROR;
|
||||
}
|
||||
if (InitializeAH(&pContext->m_pAdaptHuffCBPCY1, 5) != ICERR_OK) {
|
||||
return ICERR_ERROR;
|
||||
}
|
||||
|
||||
for(k = 0; k < NUMVLCTABLES; k ++){
|
||||
if (InitializeAH(&pContext->m_pAHexpt[k], aAlphabet[k]) != ICERR_OK) {
|
||||
return ICERR_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
ResetCodingContextDec(pContext);
|
||||
}
|
||||
|
||||
return ICERR_OK;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Context reset on encoder
|
||||
*************************************************************************/
|
||||
Void ResetCodingContextDec(CCodingContext *pContext)
|
||||
{
|
||||
Int k;
|
||||
/** set flags **/
|
||||
pContext->m_pAdaptHuffCBPCY->m_bInitialize = FALSE;
|
||||
pContext->m_pAdaptHuffCBPCY1->m_bInitialize = FALSE;
|
||||
for(k = 0; k < NUMVLCTABLES; k ++)
|
||||
pContext->m_pAHexpt[k]->m_bInitialize = FALSE;
|
||||
|
||||
// reset VLC tables
|
||||
AdaptLowpassDec (pContext);
|
||||
AdaptHighpassDec (pContext);
|
||||
|
||||
// reset zigzag patterns, totals
|
||||
InitZigzagScan(pContext);
|
||||
// reset bit reduction and cbp models
|
||||
ResetCodingContext(pContext);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Context deletion
|
||||
*************************************************************************/
|
||||
Void FreeCodingContextDec(CWMImageStrCodec *pSC)
|
||||
{
|
||||
Int iContexts = (Int)(pSC->cNumCodingContext), i, k;
|
||||
|
||||
if (iContexts > 0 && pSC->m_pCodingContext) {
|
||||
|
||||
for (i = 0; i < iContexts; i++) {
|
||||
CCodingContext *pContext = &(pSC->m_pCodingContext[i]);
|
||||
CleanAH (&pContext->m_pAdaptHuffCBPCY);
|
||||
CleanAH (&pContext->m_pAdaptHuffCBPCY1);
|
||||
for (k = 0; k < NUMVLCTABLES; k++)
|
||||
CleanAH (&pContext->m_pAHexpt[k]);
|
||||
}
|
||||
free (pSC->m_pCodingContext);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//*@@@---@@@@******************************************************************
|
||||
|
||||
#ifndef WMI_DECODE_H
|
||||
#define WMI_DECODE_H
|
||||
|
||||
typedef struct CWMDecoderParameters {
|
||||
/** ROI decode **/
|
||||
Bool bDecodeFullFrame;
|
||||
Bool bDecodeFullWidth;
|
||||
|
||||
/** thumbnail decode **/
|
||||
Bool bSkipFlexbits;
|
||||
size_t cThumbnailScale; // 1: cThumbnailScale thumbnail, only supports cThumbnailScale = 2^m for now
|
||||
Bool bDecodeHP;
|
||||
Bool bDecodeLP;
|
||||
|
||||
// Region of interest decoding
|
||||
size_t cROILeftX;
|
||||
size_t cROIRightX;
|
||||
size_t cROITopY;
|
||||
size_t cROIBottomY;
|
||||
|
||||
// table lookups for rotation and flip
|
||||
size_t * pOffsetX;
|
||||
size_t * pOffsetY;
|
||||
} CWMDecoderParameters;
|
||||
|
||||
Void predCBPDec(CWMImageStrCodec *, CCodingContext *);
|
||||
Void predDCACDec(CWMImageStrCodec *);
|
||||
Void predACDec(CWMImageStrCodec *);
|
||||
|
||||
Int dequantizeMacroblock(CWMImageStrCodec *);
|
||||
Int invTransformMacroblock(CWMImageStrCodec * pSC);
|
||||
Int invTransformMacroblock_alteredOperators_hard(CWMImageStrCodec * pSC);
|
||||
|
||||
Int DecodeMacroblockDC(CWMImageStrCodec * pSC, CCodingContext *pContext, Int iMBX, Int iMBY);
|
||||
Int DecodeMacroblockLowpass(CWMImageStrCodec * pSC, CCodingContext *pContext, Int iMBX, Int iMBY);
|
||||
Int DecodeMacroblockHighpass(CWMImageStrCodec * pSC, CCodingContext *pContext, Int iMBX, Int iMBY);
|
||||
|
||||
Int AdaptLowpassDec(struct CCodingContext *);
|
||||
Int AdaptHighpassDec(struct CCodingContext *);
|
||||
|
||||
Void ResetCodingContextDec(CCodingContext *pContext);
|
||||
Void FreeCodingContextDec(struct CWMImageStrCodec *pSC);
|
||||
|
||||
/*************************************************************************/
|
||||
// Inverse transform functions
|
||||
// 2-point post filter for boundaries (only used in 420 UV DC subband)
|
||||
Void strPost2(PixelI *, PixelI *);
|
||||
|
||||
// 2x2 post filter (only used in 420 UV DC subband)
|
||||
Void strPost2x2(PixelI *, PixelI *, PixelI *, PixelI *);
|
||||
|
||||
/** 4-point post filter for boundaries **/
|
||||
Void strPost4(PixelI *, PixelI *, PixelI *, PixelI *);
|
||||
|
||||
/** data allocation in working buffer (first stage) **/
|
||||
|
||||
/** Y, 444 U and V **/
|
||||
/** 0 1 2 3 **/
|
||||
/** 32 33 34 35 **/
|
||||
/** 64 65 66 67 **/
|
||||
/** 96 97 98 99 **/
|
||||
|
||||
/** 420 U and V **/
|
||||
/** 0 2 4 6 **/
|
||||
/** 64 66 68 70 **/
|
||||
/** 128 130 132 134 **/
|
||||
/** 192 194 196 198 **/
|
||||
|
||||
/** 4x4 inverse DCT for first stage **/
|
||||
Void strIDCT4x4FirstStage(PixelI *);
|
||||
Void strIDCT4x4Stage1(PixelI*);
|
||||
Void strIDCT4x4FirstStage420UV(PixelI *);
|
||||
|
||||
/** 4x4 post filter for first stage **/
|
||||
Void strPost4x4FirstStage(PixelI *);
|
||||
Void strPost4x4Stage1Split(PixelI*, PixelI*, Int, Int, Bool);
|
||||
Void strPost4x4Stage1(PixelI*, Int, Int, Bool);
|
||||
Void strPost4x4Stage1Split_alternate(PixelI*, PixelI*, Int);
|
||||
Void strPost4x4Stage1_alternate(PixelI*, Int);
|
||||
//Void strPost4x4Stage1Split_420(PixelI*, PixelI*);
|
||||
//Void strPost4x4Stage1_420(PixelI*);
|
||||
|
||||
Void strPost4x4FirstStage420UV(PixelI *);
|
||||
|
||||
/** data allocation in working buffer (second stage)**/
|
||||
|
||||
/** Y, 444 U and V **/
|
||||
/** 0 4 8 12 **/
|
||||
/** 128 132 136 140 **/
|
||||
/** 256 260 264 268 **/
|
||||
/** 384 388 392 396 **/
|
||||
|
||||
/** 420 U and V **/
|
||||
/** 0 8 **/
|
||||
/** 256 264 **/
|
||||
|
||||
/** 4x4 invesr DCT for second stage **/
|
||||
//Void strIDCT4x4SecondStage(PixelI *);
|
||||
Void strIDCT4x4Stage2(PixelI*);
|
||||
Void strNormalizeDec(PixelI*, Bool);
|
||||
Void strDCT2x2dnDec(PixelI *, PixelI *, PixelI *, PixelI *);
|
||||
|
||||
/** 4x4 post filter for second stage **/
|
||||
Void strPost4x4SecondStage(PixelI *);
|
||||
Void strPost4x4Stage2Split(PixelI*, PixelI*);
|
||||
Void strPost4x4Stage2Split_alternate(PixelI*, PixelI*);
|
||||
|
||||
/** Huffman decode related defines **/
|
||||
#define HUFFMAN_DECODE_ROOT_BITS_LOG 3
|
||||
#define HUFFMAN_DECODE_ROOT_BITS (5)
|
||||
|
||||
Int getHuff(const short *pDecodeTable, BitIOInfo* pIO);
|
||||
|
||||
#endif // WMI_DECODE_H
|
||||
|
|
@ -0,0 +1,288 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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 "windowsmediaphoto.h"
|
||||
#include "strcodec.h"
|
||||
|
||||
Void smoothMB(PixelI * p1, PixelI * p0, PixelI * q0, PixelI * q1)
|
||||
{
|
||||
// p1 p0 | q0 q1
|
||||
PixelI delta = ((((*q0 - *p0) << 2) + (*p1 - *q1)) >> 3);
|
||||
|
||||
*q0 -= delta;
|
||||
*p0 += delta;
|
||||
}
|
||||
|
||||
Void smooth(PixelI * p2, PixelI * p1, PixelI * p0, PixelI * q0, PixelI * q1, PixelI * q2)
|
||||
{
|
||||
// p2 p1 p0 | q0 q1 q2
|
||||
PixelI delta = ((((*q0 - *p0) << 2) + (*p1 - *q1)) >> 3);
|
||||
|
||||
*q0 -= delta;
|
||||
*p0 += delta;
|
||||
|
||||
*p1 = (*p1 >> 1) + ((*p0 + *p2) >> 2);
|
||||
*q1 = (*q1 >> 1) + ((*q0 + *q2) >> 2);
|
||||
}
|
||||
|
||||
Int initPostProc(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], size_t mbWidth, size_t iNumChannels)
|
||||
{
|
||||
size_t i, j, k, l;
|
||||
Bool b32bit = sizeof(int) == 4;
|
||||
|
||||
for(j = 0; j < iNumChannels; j ++){
|
||||
for(i = 0; i < 2; i ++){
|
||||
// 2 more are allocated to avoid boundary check
|
||||
if(b32bit) // integer overlow/underflow check for 32-bit system
|
||||
if((((mbWidth + 2) >> 16) * sizeof(struct tagPostProcInfo)) & 0xffff0000)
|
||||
return ICERR_ERROR;
|
||||
strPostProcInfo[j][i] = (struct tagPostProcInfo *)malloc((mbWidth + 2) * sizeof(struct tagPostProcInfo));
|
||||
assert(strPostProcInfo[j][i] != NULL);
|
||||
if(strPostProcInfo[j][i] == NULL){
|
||||
return ICERR_ERROR;
|
||||
}
|
||||
strPostProcInfo[j][i] ++;
|
||||
|
||||
// initialize out-of-bound MBs as bumpy (no post at all) to avoid boundary check
|
||||
// left boundary
|
||||
strPostProcInfo[j][i][-1].ucMBTexture = 3;
|
||||
for(l = 0; l < 4; l ++){
|
||||
for(k = 0; k < 4; k ++){
|
||||
strPostProcInfo[j][i][-1].ucBlockTexture[l][k] = 3;
|
||||
}
|
||||
}
|
||||
// right boundary
|
||||
strPostProcInfo[j][i][mbWidth] = strPostProcInfo[j][i][-1];
|
||||
}
|
||||
}
|
||||
|
||||
return ICERR_OK;
|
||||
}
|
||||
|
||||
Void termPostProc(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], size_t iNumChannels)
|
||||
{
|
||||
size_t i, j;
|
||||
|
||||
for(j = 0; j < iNumChannels; j ++){
|
||||
for(i = 0; i < 2; i ++){
|
||||
if(strPostProcInfo[j][i] != NULL){
|
||||
free(strPostProcInfo[j][i] - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Void slideOneMBRow(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], size_t iNumChannels, size_t mbWidth, Bool top, Bool bottom)
|
||||
{
|
||||
size_t i, j;
|
||||
struct tagPostProcInfo * bar;
|
||||
|
||||
for(i = 0; i < iNumChannels; i ++){
|
||||
// swap previous row and current row
|
||||
bar = strPostProcInfo[i][0];
|
||||
strPostProcInfo[i][0] = strPostProcInfo[i][1];
|
||||
strPostProcInfo[i][1] = bar;
|
||||
|
||||
if(top){ // if top row, previous row is out of boundary
|
||||
for(j = 0; j < mbWidth; j ++){
|
||||
strPostProcInfo[i][0][j] = strPostProcInfo[i][0][-1]; // set as bumpy
|
||||
}
|
||||
}
|
||||
|
||||
if(bottom){ // if bottom bottom row, set current row of MBs (out of boundary) as bumpy
|
||||
for(j = 0; j < mbWidth; j ++){
|
||||
strPostProcInfo[i][1][j] = strPostProcInfo[i][1][-1]; // set as bumpy
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get DC and texture infomation right before transform
|
||||
Void updatePostProcInfo(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], PixelI * pMB, size_t mbX, size_t cc)
|
||||
{
|
||||
size_t i, j;
|
||||
struct tagPostProcInfo * pMBInfo = strPostProcInfo[cc][1] + mbX;
|
||||
|
||||
// DC of MB
|
||||
pMBInfo->iMBDC = pMB[0];
|
||||
|
||||
// texture of MB
|
||||
pMBInfo->ucMBTexture = 0; // smooth
|
||||
for(i = 16; i < 256; i += 16){
|
||||
if(pMB[i] != 0){
|
||||
pMBInfo->ucMBTexture = 3; // bumpy
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// DCs of blocks not available yet, will collect after demacroblocking
|
||||
|
||||
// textures of blocks
|
||||
for(j = 0; j < 4; j ++)
|
||||
for(i = 0; i < 4; i ++){
|
||||
PixelI * p = pMB + i * 64 + j * 16;
|
||||
size_t k;
|
||||
|
||||
for(k = 1, pMBInfo->ucBlockTexture[j][i] = 0; k < 16; k ++){
|
||||
if(p[k] != 0){
|
||||
pMBInfo->ucBlockTexture[j][i] = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// demacroblock critirion: two MBs have same texture other than bumpy and DCs differ less than 1
|
||||
#define DMB(a, b) (a->ucMBTexture + b->ucMBTexture == 0) && (abs(a->iMBDC - b->iMBDC) <= threshold)
|
||||
|
||||
// demacroblock and get DCs of blocks
|
||||
Void postProcMB(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], PixelI * p0, PixelI * p1, size_t mbX, size_t cc, Int threshold)
|
||||
{
|
||||
/* 4 MBs involved, current MB is d, we have 4 2-pixel boundary segments */
|
||||
/* | */
|
||||
/* a | b */
|
||||
/* - - + + */
|
||||
/* c ! d */
|
||||
/* ! */
|
||||
struct tagPostProcInfo * pMBb = strPostProcInfo[cc][0] + mbX, * pMBa = pMBb - 1, * pMBd = strPostProcInfo[cc][1] + mbX, * pMBc = pMBd - 1;
|
||||
|
||||
// demacroblock segment --
|
||||
if(DMB(pMBa, pMBc)){
|
||||
smoothMB(p0 - 256 + 10 * 16, p0 - 256 + 11 * 16, p1 - 256 + 8 * 16, p1 - 256 + 9 * 16);
|
||||
smoothMB(p0 - 256 + 14 * 16, p0 - 256 + 15 * 16, p1 - 256 + 12 * 16, p1 - 256 + 13 * 16);
|
||||
}
|
||||
|
||||
// demacroblock segment ++
|
||||
if(DMB(pMBb, pMBd)){
|
||||
smoothMB(p0 + 2 * 16, p0 + 3 * 16, p1 + 0 * 16, p1 + 1 * 16);
|
||||
smoothMB(p0 + 6 * 16, p0 + 7 * 16, p1 + 4 * 16, p1 + 5 * 16);
|
||||
}
|
||||
|
||||
// demacroblock segment |
|
||||
if(DMB(pMBa, pMBb)){
|
||||
smoothMB(p0 - 256 + 10 * 16, p0 - 256 + 14 * 16, p0 + 2 * 16, p0 + 6 * 16);
|
||||
smoothMB(p0 - 256 + 11 * 16, p0 - 256 + 15 * 16, p0 + 3 * 16, p0 + 7 * 16);
|
||||
}
|
||||
|
||||
// demacroblock segment !
|
||||
if(DMB(pMBc, pMBd)){
|
||||
smoothMB(p1 - 256 + 8 * 16, p1 - 256 + 12 * 16, p1 + 0 * 16, p1 + 4 * 16);
|
||||
smoothMB(p1 - 256 + 9 * 16, p1 - 256 + 13 * 16, p1 + 1 * 16, p1 + 5 * 16);
|
||||
}
|
||||
|
||||
/* update DCs of blocks */
|
||||
// MB d
|
||||
pMBd->iBlockDC[0][0] = p1[0 * 16];
|
||||
pMBd->iBlockDC[0][1] = p1[4 * 16];
|
||||
pMBd->iBlockDC[1][0] = p1[1 * 16];
|
||||
pMBd->iBlockDC[1][1] = p1[5 * 16];
|
||||
|
||||
// MB b
|
||||
pMBb->iBlockDC[2][0] = p0[2 * 16];
|
||||
pMBb->iBlockDC[2][1] = p0[6 * 16];
|
||||
pMBb->iBlockDC[3][0] = p0[3 * 16];
|
||||
pMBb->iBlockDC[3][1] = p0[7 * 16];
|
||||
|
||||
// MB c
|
||||
pMBc->iBlockDC[0][2] = p1[ 8 * 16 - 256];
|
||||
pMBc->iBlockDC[0][3] = p1[12 * 16 - 256];
|
||||
pMBc->iBlockDC[1][2] = p1[ 9 * 16 - 256];
|
||||
pMBc->iBlockDC[1][3] = p1[13 * 16 - 256];
|
||||
|
||||
// MB a
|
||||
pMBa->iBlockDC[2][2] = p0[10 * 16 - 256];
|
||||
pMBa->iBlockDC[2][3] = p0[14 * 16 - 256];
|
||||
pMBa->iBlockDC[3][2] = p0[11 * 16 - 256];
|
||||
pMBa->iBlockDC[3][3] = p0[15 * 16 - 256];
|
||||
}
|
||||
|
||||
/* deblock and destair blocks */
|
||||
/* 4 MBs involved, need to process 16 blocks of a */
|
||||
/* | */
|
||||
/* a | b */
|
||||
/* - - - - */
|
||||
/* c | d */
|
||||
/* | */
|
||||
Void postProcBlock(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], PixelI * p0, PixelI * p1, size_t mbX, size_t cc, Int threshold)
|
||||
{
|
||||
size_t i, j, k;
|
||||
Int dc[5][5];
|
||||
U8 texture[5][5];
|
||||
struct tagPostProcInfo * pMBb = strPostProcInfo[cc][0] + mbX, * pMBa = pMBb - 1, * pMBd = strPostProcInfo[cc][1] + mbX, * pMBc = pMBd - 1;
|
||||
PixelI * pc, * pt;
|
||||
|
||||
/* copy DC and Texture info, can be optimized out */
|
||||
for(j = 0; j < 4; j ++){
|
||||
// from MB a
|
||||
for(i = 0; i < 4; i ++){
|
||||
dc[j][i] = pMBa->iBlockDC[j][i];
|
||||
texture[j][i] = pMBa->ucBlockTexture[j][i];
|
||||
}
|
||||
|
||||
// 4 blocks from MB c
|
||||
dc[4][j] = pMBc->iBlockDC[0][j];
|
||||
texture[4][j] = pMBc->ucBlockTexture[0][j];
|
||||
|
||||
// 4 blocks from MB b
|
||||
dc[j][4] = pMBb->iBlockDC[j][0];
|
||||
texture[j][4] = pMBb->ucBlockTexture[j][0];
|
||||
}
|
||||
// 1 block from MB d
|
||||
dc[4][4] = pMBd->iBlockDC[0][0];
|
||||
texture[4][4] = pMBd->ucBlockTexture[0][0];
|
||||
|
||||
/* block boundaries */
|
||||
/* | */
|
||||
/* | */
|
||||
/* --- */
|
||||
|
||||
for(j = 0; j < 4; j ++){
|
||||
for(i = 0; i < 4; i ++){
|
||||
pc = p0 - 256 + i * 64 + j * 16;
|
||||
|
||||
// deblock
|
||||
if(texture[j][i] + texture[j + 1][i] < 3 && abs(dc[j][i] - dc[j + 1][i]) <= threshold){
|
||||
// smooth horizontal boundary ----
|
||||
pt = (j < 3 ? pc + 16 : p1 - 256 + i * 64);
|
||||
for(k = 0; k < 4; k ++){
|
||||
smooth(pc + idxCC[1][k], pc + idxCC[2][k], pc + idxCC[3][k], pt + idxCC[0][k], pt + idxCC[1][k], pt + idxCC[2][k]);
|
||||
}
|
||||
}
|
||||
|
||||
// two horizontally adjacent blocks have same texture and similiar DCs
|
||||
if(texture[j][i] + texture[j][i + 1] < 3 && abs(dc[j][i] - dc[j][i + 1]) <= threshold){
|
||||
// smooth vertical boundary |
|
||||
pt = pc + 64;
|
||||
for(k = 0; k < 4; k ++){
|
||||
smooth(pc + idxCC[k][1], pc + idxCC[k][2], pc + idxCC[k][3], pt + idxCC[k][0], pt + idxCC[k][1], pt + idxCC[k][2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,539 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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"
|
||||
|
||||
#define DEQUANT(iRaw, iQP) ((iRaw) * (iQP))
|
||||
|
||||
Void dequantizeBlock4x4(PixelI * pRec, Int * pOrg, const Int * pIndex, Int iQPLP)
|
||||
{
|
||||
Int i;
|
||||
|
||||
for(i = 1; i < 16; i ++)
|
||||
pRec[pIndex[i]] = DEQUANT(pOrg[i], iQPLP);
|
||||
}
|
||||
|
||||
Void dequantizeBlock2x2(PixelI * pRec, Int * pOrg, Int iQPLP)
|
||||
{
|
||||
pRec[32] = DEQUANT(pOrg[1], iQPLP);
|
||||
pRec[16] = DEQUANT(pOrg[2], iQPLP);
|
||||
pRec[48] = DEQUANT(pOrg[3], iQPLP);
|
||||
}
|
||||
|
||||
Void dequantizeBlock4x2(PixelI * pRec, Int * pOrg, Int iQPLP)
|
||||
{
|
||||
pRec[ 64] = DEQUANT(pOrg[1], iQPLP);
|
||||
pRec[ 16] = DEQUANT(pOrg[2], iQPLP);
|
||||
pRec[ 80] = DEQUANT(pOrg[3], iQPLP);
|
||||
pRec[ 32] = DEQUANT(pOrg[4], iQPLP);
|
||||
pRec[ 96] = DEQUANT(pOrg[5], iQPLP);
|
||||
pRec[ 48] = DEQUANT(pOrg[6], iQPLP);
|
||||
pRec[112] = DEQUANT(pOrg[7], iQPLP);
|
||||
}
|
||||
|
||||
|
||||
Int dequantizeMacroblock(CWMImageStrCodec * pSC)
|
||||
{
|
||||
const COLORFORMAT cf = pSC->m_param.cfColorFormat;
|
||||
CWMIMBInfo *pMBInfo = &pSC->MBInfo;
|
||||
CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
|
||||
const size_t iChannels = pSC->m_param.cNumChannels;
|
||||
size_t i;
|
||||
|
||||
for(i = 0; i < iChannels; i ++){
|
||||
//dequantize DC
|
||||
pSC->p1MBbuffer[i][0] = DEQUANT(pMBInfo->iBlockDC[i][0], pTile->pQuantizerDC[i]->iQP);
|
||||
|
||||
// dequantize LP
|
||||
if(pSC->WMISCP.sbSubband != SB_DC_ONLY)
|
||||
if(i == 0 || (cf != YUV_422 && cf != YUV_420))
|
||||
dequantizeBlock4x4(pSC->p1MBbuffer[i] , pMBInfo->iBlockDC[i], dctIndex[2], pTile->pQuantizerLP[i][pMBInfo->iQIndexLP].iQP);
|
||||
else if(cf == YUV_422)
|
||||
dequantizeBlock4x2(pSC->p1MBbuffer[i], pMBInfo->iBlockDC[i], pTile->pQuantizerLP[i][pMBInfo->iQIndexLP].iQP);
|
||||
else // 420
|
||||
dequantizeBlock2x2(pSC->p1MBbuffer[i], pMBInfo->iBlockDC[i], pTile->pQuantizerLP[i][pMBInfo->iQIndexLP].iQP);
|
||||
}
|
||||
|
||||
return ICERR_OK;
|
||||
}
|
||||
|
||||
/* frequency domain inverse DCAC prediction */
|
||||
Void predDCACDec(CWMImageStrCodec * pSC)
|
||||
{
|
||||
const COLORFORMAT cf = pSC->m_param.cfColorFormat;
|
||||
const Int iChannels = (cf == YUV_420 || cf == YUV_422) ? 1 : (Int) pSC->m_param.cNumChannels;
|
||||
CWMIMBInfo *pMBInfo = &(pSC->MBInfo);
|
||||
size_t mbX = pSC->cColumn;// mbY = pSC->cRow;
|
||||
Int iDCACPredMode = getDCACPredMode(pSC, mbX);
|
||||
Int iDCPredMode = (iDCACPredMode & 0x3);
|
||||
Int iADPredMode = (iDCACPredMode & 0xC);
|
||||
PixelI * pOrg, * pRef;
|
||||
Int ii;
|
||||
|
||||
for(ii = 0; ii < iChannels; ii ++){
|
||||
pOrg = pMBInfo->iBlockDC[ii];//[dcBlkIdx + (i >> 4)]; // current DC block
|
||||
|
||||
/* DC prediction */
|
||||
if(iDCPredMode == 1){ // predict DC from top
|
||||
pOrg[0] += pSC->PredInfoPrevRow[ii][mbX].iDC;
|
||||
}
|
||||
else if(iDCPredMode == 0){ // predict DC from left
|
||||
pOrg[0] += (pSC->PredInfo[ii] + mbX - 1)->iDC;
|
||||
}
|
||||
else if(iDCPredMode == 2){// predict DC from top&left
|
||||
pOrg[0] += ((pSC->PredInfo[ii] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[ii] + mbX)->iDC) >> 1;
|
||||
}
|
||||
|
||||
/* AD prediction */
|
||||
if(iADPredMode == 4){// predict AD from top
|
||||
pRef = (pSC->PredInfoPrevRow[ii] + mbX)->piAD;
|
||||
pOrg[4] += pRef[3], pOrg[8] += pRef[4], pOrg[12] += pRef[5];
|
||||
}
|
||||
else if(iADPredMode == 0){// predict AD from left
|
||||
pRef = (pSC->PredInfo[ii] + mbX - 1)->piAD;
|
||||
pOrg[1] += pRef[0], pOrg[2] += pRef[1], pOrg[3] += pRef[2];
|
||||
}
|
||||
}
|
||||
|
||||
if(cf == YUV_420){
|
||||
for(ii = 1; ii < 3; ii ++){
|
||||
pOrg = pMBInfo->iBlockDC[ii];//dcBlkIdx + ii]; // current DC block
|
||||
|
||||
/* DC prediction */
|
||||
if(iDCPredMode == 1){ // predict DC from top
|
||||
pOrg[0] += (pSC->PredInfoPrevRow[ii] + mbX)->iDC;
|
||||
}
|
||||
else if(iDCPredMode == 0){ // predict DC from left
|
||||
pOrg[0] += (pSC->PredInfo[ii] + mbX - 1)->iDC;
|
||||
}
|
||||
else if(iDCPredMode == 2){ // predict DC from top&left
|
||||
pOrg[0] += (((pSC->PredInfo[ii] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[ii] + mbX)->iDC + 1) >> 1);
|
||||
}
|
||||
|
||||
/* AD prediciton */
|
||||
if(iADPredMode == 4){// predict AD from top
|
||||
pOrg[2] += (pSC->PredInfoPrevRow[ii] + mbX)->piAD[1];
|
||||
}
|
||||
else if(iADPredMode == 0){// predict AD from left
|
||||
pOrg[1] += (pSC->PredInfo[ii] + mbX - 1)->piAD[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(cf == YUV_422){
|
||||
for(ii = 1; ii < 3; ii ++){
|
||||
pOrg = pMBInfo->iBlockDC[ii];//[dcBlkIdx + ii]; // current DC block
|
||||
|
||||
/* DC prediciton */
|
||||
if(iDCPredMode == 1){ // predict DC from top
|
||||
pOrg[0] += (pSC->PredInfoPrevRow[ii] + mbX)->iDC;
|
||||
}
|
||||
else if(iDCPredMode == 0){ // predict DC from left
|
||||
pOrg[0] += (pSC->PredInfo[ii] + mbX - 1)->iDC;
|
||||
}
|
||||
else if(iDCPredMode == 2){ // predict DC from top&left
|
||||
pOrg[0] += (((pSC->PredInfo[ii] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[ii] + mbX)->iDC + 1) >> 1);
|
||||
}
|
||||
|
||||
/* AD prediction */
|
||||
if(iADPredMode == 4){// predict AD from top
|
||||
pOrg[4] += (pSC->PredInfoPrevRow[ii] + mbX)->piAD[4]; // AC of HT !!!
|
||||
pOrg[2] += (pSC->PredInfoPrevRow[ii] + mbX)->piAD[3];
|
||||
pOrg[6] += pOrg[2];
|
||||
}
|
||||
else if(iADPredMode == 0){// predict AD from left
|
||||
pOrg[4] += (pSC->PredInfo[ii] + mbX - 1)->piAD[4]; // AC of HT !!!
|
||||
pOrg[1] += (pSC->PredInfo[ii] + mbX - 1)->piAD[0];
|
||||
pOrg[5] += (pSC->PredInfo[ii] + mbX - 1)->piAD[2];
|
||||
}
|
||||
else if(iDCPredMode == 1){
|
||||
pOrg[6] += pOrg[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pMBInfo->iOrientation = 2 - getACPredMode(pMBInfo, cf);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Frequency domain inverse AC prediction
|
||||
*************************************************************************/
|
||||
Void predACDec(CWMImageStrCodec * pSC)
|
||||
{
|
||||
const COLORFORMAT cf = pSC->m_param.cfColorFormat;
|
||||
const Int iChannels = (cf == YUV_420 || cf == YUV_422) ? 1 : (Int) pSC->m_param.cNumChannels;
|
||||
// size_t mbX = pSC->cColumn, mbY = pSC->cRow;
|
||||
CWMIMBInfo *pMBInfo = &pSC->MBInfo;
|
||||
Int iACPredMode = 2 - pMBInfo->iOrientation;
|
||||
PixelI * pOrg, * pRef;
|
||||
Int i, j;
|
||||
|
||||
/* AC prediction */
|
||||
for(i = 0; i < iChannels; i++){
|
||||
// prediction only happens inside MB
|
||||
PixelI* pSrc = pSC->p1MBbuffer[i];//0 == i ? pSC->pY1 : (1 == i ? pSC->pU1 : pSC->pV1);
|
||||
|
||||
switch (iACPredMode)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
// predict from top
|
||||
static U8 blkIdx[] = {1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15};
|
||||
|
||||
for (j = 0; j < sizeof(blkIdx) / sizeof(*blkIdx); ++j)
|
||||
{
|
||||
pOrg = pSrc + 16 * blkIdx[j];
|
||||
pRef = pOrg - 16;
|
||||
|
||||
pOrg[ 2] += pRef[ 2];
|
||||
pOrg[10] += pRef[10];
|
||||
pOrg[ 9] += pRef[ 9];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 0:
|
||||
// predict from left
|
||||
for (j = 64; j < 256; j += 16)
|
||||
{
|
||||
pOrg = pSrc + j;
|
||||
pRef = pOrg - 64;
|
||||
|
||||
pOrg[1] += pRef[1];
|
||||
pOrg[5] += pRef[5];
|
||||
pOrg[6] += pRef[6];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// no prediction
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(cf == YUV_420){
|
||||
for(i = 16; i <= 20; i += 4){
|
||||
PixelI* pSrc = pSC->p1MBbuffer[(i >> 2) - 3];//16 == i ? pSC->pU1 : pSC->pV1;
|
||||
|
||||
switch (iACPredMode)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
// predict from top
|
||||
for (j = 1; j <= 3; j += 2)
|
||||
{
|
||||
pOrg = pSrc + 16 * j;
|
||||
pRef = pOrg - 16;
|
||||
|
||||
pOrg[ 2] += pRef[ 2];
|
||||
pOrg[10] += pRef[10];
|
||||
pOrg[ 9] += pRef[ 9];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 0:
|
||||
// predict from left
|
||||
for (j = 2; j <= 3; ++j)
|
||||
{
|
||||
pOrg = pSrc + 16 * j;
|
||||
pRef = pOrg - 32;
|
||||
|
||||
pOrg[1] += pRef[1];
|
||||
pOrg[5] += pRef[5];
|
||||
pOrg[6] += pRef[6];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// no prediction
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(cf == YUV_422){
|
||||
for(i = 16; i < 32; i += 8){
|
||||
PixelI* pSrc = pSC->p1MBbuffer[(i >> 3) - 1];//16 == i ? pSC->pU1 : pSC->pV1;
|
||||
|
||||
switch (iACPredMode)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
// predict from top
|
||||
for (j = 2; j < 8; j ++)
|
||||
{
|
||||
pOrg = pSrc + blkOffsetUV_422[j];
|
||||
pRef = pOrg - 16;
|
||||
|
||||
pOrg[10] += pRef[10];
|
||||
pOrg[ 2] += pRef[ 2];
|
||||
pOrg[ 9] += pRef[ 9];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 0:
|
||||
// predict from left
|
||||
for (j = 1; j < 8; j += 2)
|
||||
{
|
||||
pOrg = pSrc + blkOffsetUV_422[j];
|
||||
pRef = pOrg - 64;
|
||||
|
||||
pOrg[1] += pRef[1];
|
||||
pOrg[5] += pRef[5];
|
||||
pOrg[6] += pRef[6];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// no prediction
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
CBP
|
||||
*************************************************************************/
|
||||
static int NumOnes(int i)
|
||||
{
|
||||
int retval = 0;
|
||||
static const int g_Count[] = { 0,1,1,2, 1,2,2,3, 1,2,2,3, 2,3,3,4 };
|
||||
i = i & 0xffff;
|
||||
while (i) {
|
||||
retval += g_Count[i & 0xf];
|
||||
i >>= 4;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
#define SATURATE32(x) if((unsigned int)(x + 16) >= 32) { if (x < 0) x = -16; else x = 15; }
|
||||
|
||||
/* CBP prediction for 16 x 16 MB */
|
||||
/* block index */
|
||||
/* 0 1 4 5 */
|
||||
/* 2 3 6 7 */
|
||||
/* 8 9 12 13 */
|
||||
/* 10 11 14 15 */
|
||||
static Int predCBPCDec(CWMImageStrCodec * pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)
|
||||
{
|
||||
Int iNOrig;
|
||||
const int iNDiff = AVG_NDIFF;
|
||||
size_t c1 = c ? 1 : 0;
|
||||
|
||||
UNREFERENCED_PARAMETER( mbY );
|
||||
|
||||
if (pModel->m_iState[c1] == 0) {
|
||||
if(pSC->m_bCtxLeft) {
|
||||
if (pSC->m_bCtxTop) {
|
||||
iCBP ^= 1;
|
||||
}
|
||||
else {
|
||||
Int iTopCBP = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;
|
||||
iCBP ^= (iTopCBP >> 10) & 1; // left: top(10) => 0
|
||||
}
|
||||
}
|
||||
else {
|
||||
Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;
|
||||
iCBP ^= ((iLeftCBP >> 5) & 1); // left(5) => 0
|
||||
}
|
||||
|
||||
iCBP ^= (0x02 & (iCBP << 1)); // 0 => 1
|
||||
iCBP ^= (0x10 & (iCBP << 3)); // 1 => 4
|
||||
iCBP ^= (0x20 & (iCBP << 1)); // 4 => 5
|
||||
|
||||
iCBP ^= ((iCBP & 0x33) << 2);
|
||||
iCBP ^= ((iCBP & 0xcc) << 6);
|
||||
iCBP ^= ((iCBP & 0x3300) << 2);
|
||||
|
||||
}
|
||||
else if (pModel->m_iState[c1] == 2) {
|
||||
iCBP ^= 0xffff;
|
||||
}
|
||||
|
||||
iNOrig = NumOnes(iCBP);
|
||||
|
||||
pModel->m_iCount0[c1] += iNOrig - iNDiff;
|
||||
SATURATE32(pModel->m_iCount0[c1]);
|
||||
|
||||
pModel->m_iCount1[c1] += 16 - iNOrig - iNDiff;
|
||||
SATURATE32(pModel->m_iCount1[c1]);
|
||||
|
||||
if (pModel->m_iCount0[c1] < 0) {
|
||||
if (pModel->m_iCount0[c1] < pModel->m_iCount1[c1]) {
|
||||
pModel->m_iState[c1] = 1;
|
||||
}
|
||||
else {
|
||||
pModel->m_iState[c1] = 2;
|
||||
}
|
||||
}
|
||||
else if (pModel->m_iCount1[c1] < 0) {
|
||||
pModel->m_iState[c1] = 2;
|
||||
}
|
||||
else {
|
||||
pModel->m_iState[c1] = 0;
|
||||
}
|
||||
return iCBP;
|
||||
}
|
||||
|
||||
static Int predCBPC420Dec(CWMImageStrCodec * pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)
|
||||
{
|
||||
Int iNOrig;
|
||||
const int iNDiff = AVG_NDIFF;
|
||||
|
||||
UNREFERENCED_PARAMETER( mbY );
|
||||
|
||||
if (pModel->m_iState[1] == 0) {
|
||||
if(pSC->m_bCtxLeft) {
|
||||
if (pSC->m_bCtxTop) {
|
||||
iCBP ^= 1;
|
||||
}
|
||||
else {
|
||||
Int iTopCBP = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;
|
||||
iCBP ^= (iTopCBP >> 2) & 1; // left: top(2) => 0
|
||||
}
|
||||
}
|
||||
else {
|
||||
Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;
|
||||
iCBP ^= ((iLeftCBP >> 1) & 1); // left(1) => 0
|
||||
}
|
||||
|
||||
iCBP ^= (0x02 & (iCBP << 1)); // 0 => 1
|
||||
iCBP ^= ((iCBP & 0x3) << 2); // [0 1] -> [2 3]
|
||||
}
|
||||
else if (pModel->m_iState[1] == 2) {
|
||||
iCBP ^= 0xf;
|
||||
}
|
||||
|
||||
iNOrig = NumOnes(iCBP) * 4;
|
||||
|
||||
pModel->m_iCount0[1] += iNOrig - iNDiff;
|
||||
SATURATE32(pModel->m_iCount0[1]);
|
||||
|
||||
pModel->m_iCount1[1] += 16 - iNOrig - iNDiff;
|
||||
SATURATE32(pModel->m_iCount1[1]);
|
||||
|
||||
if (pModel->m_iCount0[1] < 0) {
|
||||
if (pModel->m_iCount0[1] < pModel->m_iCount1[1]) {
|
||||
pModel->m_iState[1] = 1;
|
||||
}
|
||||
else {
|
||||
pModel->m_iState[1] = 2;
|
||||
}
|
||||
}
|
||||
else if (pModel->m_iCount1[1] < 0) {
|
||||
pModel->m_iState[1] = 2;
|
||||
}
|
||||
else {
|
||||
pModel->m_iState[1] = 0;
|
||||
}
|
||||
|
||||
return iCBP;
|
||||
}
|
||||
|
||||
static Int predCBPC422Dec(CWMImageStrCodec * pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)
|
||||
{
|
||||
Int iNOrig;
|
||||
const int iNDiff = AVG_NDIFF;
|
||||
|
||||
UNREFERENCED_PARAMETER( mbY );
|
||||
|
||||
if (pModel->m_iState[1] == 0) {
|
||||
if(pSC->m_bCtxLeft) {
|
||||
if (pSC->m_bCtxTop) {
|
||||
iCBP ^= 1;
|
||||
}
|
||||
else {
|
||||
Int iTopCBP = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;
|
||||
iCBP ^= (iTopCBP >> 6) & 1; // left: top(6) => 0
|
||||
}
|
||||
}
|
||||
else {
|
||||
Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;
|
||||
iCBP ^= ((iLeftCBP >> 1) & 1); // left(1) => 0
|
||||
}
|
||||
|
||||
iCBP ^= (iCBP & 0x1) << 1; // [0]->[1]
|
||||
iCBP ^= (iCBP & 0x3) << 2; // [0 1]->[2 3]
|
||||
iCBP ^= (iCBP & 0xc) << 2; // [2 3]->[4 5]
|
||||
iCBP ^= (iCBP & 0x30) << 2; // [4 5]->[6 7]
|
||||
}
|
||||
else if (pModel->m_iState[1] == 2) {
|
||||
iCBP ^= 0xff;
|
||||
}
|
||||
|
||||
iNOrig = NumOnes(iCBP) * 2;
|
||||
|
||||
pModel->m_iCount0[1] += iNOrig - iNDiff;
|
||||
SATURATE32(pModel->m_iCount0[1]);
|
||||
|
||||
pModel->m_iCount1[1] += 16 - iNOrig - iNDiff;
|
||||
SATURATE32(pModel->m_iCount1[1]);
|
||||
|
||||
if (pModel->m_iCount0[1] < 0) {
|
||||
if (pModel->m_iCount0[1] < pModel->m_iCount1[1]) {
|
||||
pModel->m_iState[1] = 1;
|
||||
}
|
||||
else {
|
||||
pModel->m_iState[1] = 2;
|
||||
}
|
||||
}
|
||||
else if (pModel->m_iCount1[1] < 0) {
|
||||
pModel->m_iState[1] = 2;
|
||||
}
|
||||
else {
|
||||
pModel->m_iState[1] = 0;
|
||||
}
|
||||
|
||||
return iCBP;
|
||||
}
|
||||
|
||||
|
||||
/* Coded Block Pattern (CBP) prediction */
|
||||
Void predCBPDec(CWMImageStrCodec *pSC, CCodingContext *pContext)
|
||||
{
|
||||
const COLORFORMAT cf = pSC->m_param.cfColorFormat;
|
||||
const size_t iChannels = (cf == YUV_420 || cf == YUV_422) ? 1 : pSC->m_param.cNumChannels;
|
||||
size_t i, mbX = pSC->cColumn, mbY = pSC->cRow;
|
||||
CWMIMBInfo *pMBInfo = &(pSC->MBInfo);
|
||||
|
||||
for (i = 0; i < iChannels; i++) {
|
||||
(pSC->PredInfo[i] + mbX)->iCBP = pMBInfo->iCBP[i] = predCBPCDec(pSC, pMBInfo->iDiffCBP[i], mbX, mbY, i, &pContext->m_aCBPModel); // Y Channel
|
||||
}
|
||||
|
||||
if (cf == YUV_422){
|
||||
(pSC->PredInfo[1] + mbX)->iCBP = pMBInfo->iCBP[1] = predCBPC422Dec(pSC, pMBInfo->iDiffCBP[1], mbX, mbY, 1, &pContext->m_aCBPModel);
|
||||
(pSC->PredInfo[2] + mbX)->iCBP = pMBInfo->iCBP[2] = predCBPC422Dec(pSC, pMBInfo->iDiffCBP[2], mbX, mbY, 2, &pContext->m_aCBPModel);
|
||||
}
|
||||
else if (cf == YUV_420) {
|
||||
(pSC->PredInfo[1] + mbX)->iCBP = pMBInfo->iCBP[1] = predCBPC420Dec(pSC, pMBInfo->iDiffCBP[1], mbX, mbY, 1, &pContext->m_aCBPModel);
|
||||
(pSC->PredInfo[2] + mbX)->iCBP = pMBInfo->iCBP[2] = predCBPC420Dec(pSC, pMBInfo->iDiffCBP[2], mbX, mbY, 2, &pContext->m_aCBPModel);
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,144 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "encode.h"
|
||||
#include "strcodec.h"
|
||||
#include "common.h"
|
||||
|
||||
#ifdef MEM_TRACE
|
||||
#define TRACE_MALLOC 1
|
||||
#define TRACE_NEW 0
|
||||
#define TRACE_HEAP 0
|
||||
#include "memtrace.h"
|
||||
#endif
|
||||
|
||||
/*************************************************************************
|
||||
Context allocation
|
||||
In theory it is possible to independently set uiTrimFlexBits for
|
||||
each tile, but for now we assume only one user specified value is
|
||||
used for the entire image
|
||||
*************************************************************************/
|
||||
Int AllocateCodingContextEnc(CWMImageStrCodec *pSC, Int iNumContexts, Int iTrimFlexBits)
|
||||
{
|
||||
Int i, iCBPSize, k;
|
||||
static const Int aAlphabet[] = {5,4,8,7,7, 12,6,6,12,6,6,7,7, 12,6,6,12,6,6,7,7};
|
||||
|
||||
if (iTrimFlexBits < 0)
|
||||
iTrimFlexBits = 0;
|
||||
else if (iTrimFlexBits > 15)
|
||||
iTrimFlexBits = 15;
|
||||
pSC->m_param.bTrimFlexbitsFlag = (iTrimFlexBits > 0);
|
||||
|
||||
if (iNumContexts < 1 || iNumContexts > MAX_TILES) // only between 1 and 256 allowed
|
||||
return ICERR_ERROR;
|
||||
|
||||
if (pSC == NULL)
|
||||
return ICERR_ERROR;
|
||||
|
||||
pSC->m_pCodingContext = malloc (iNumContexts * sizeof (CCodingContext));
|
||||
if (pSC->m_pCodingContext == NULL) {
|
||||
pSC->cNumCodingContext = 0;
|
||||
return ICERR_ERROR;
|
||||
}
|
||||
memset (pSC->m_pCodingContext, 0, iNumContexts * sizeof (CCodingContext));
|
||||
|
||||
pSC->cNumCodingContext = iNumContexts;
|
||||
iCBPSize = (pSC->m_param.cfColorFormat == Y_ONLY || pSC->m_param.cfColorFormat == NCOMPONENT
|
||||
|| pSC->m_param.cfColorFormat == CMYK) ? 5 : 9;
|
||||
|
||||
/** allocate / initialize members **/
|
||||
for (i = 0; i < iNumContexts; i++) {
|
||||
CCodingContext *pContext = &(pSC->m_pCodingContext[i]);
|
||||
|
||||
/** allocate adaptive Huffman encoder **/
|
||||
pContext->m_pAdaptHuffCBPCY = Allocate (iCBPSize, ENCODER);
|
||||
if(pContext->m_pAdaptHuffCBPCY == NULL) {
|
||||
return ICERR_ERROR;
|
||||
}
|
||||
pContext->m_pAdaptHuffCBPCY1 = Allocate(5, ENCODER);
|
||||
if(pContext->m_pAdaptHuffCBPCY1 == NULL){
|
||||
return ICERR_ERROR;
|
||||
}
|
||||
|
||||
for(k = 0; k < NUMVLCTABLES; k ++){
|
||||
pContext->m_pAHexpt[k] = Allocate(aAlphabet[k], ENCODER);
|
||||
if(pContext->m_pAHexpt[k] == NULL){
|
||||
return ICERR_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
ResetCodingContextEnc(pContext);
|
||||
pContext->m_iTrimFlexBits = iTrimFlexBits;
|
||||
}
|
||||
|
||||
return ICERR_OK;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Context reset on encoder
|
||||
*************************************************************************/
|
||||
Void ResetCodingContextEnc(CCodingContext *pContext)
|
||||
{
|
||||
Int k;
|
||||
/** set flags **/
|
||||
pContext->m_pAdaptHuffCBPCY->m_bInitialize = FALSE;
|
||||
pContext->m_pAdaptHuffCBPCY1->m_bInitialize = FALSE;
|
||||
for(k = 0; k < NUMVLCTABLES; k ++)
|
||||
pContext->m_pAHexpt[k]->m_bInitialize = FALSE;
|
||||
|
||||
// reset VLC tables
|
||||
AdaptLowpassEnc (pContext);
|
||||
AdaptHighpassEnc (pContext);
|
||||
|
||||
// reset zigzag patterns, totals
|
||||
InitZigzagScan(pContext);
|
||||
// reset bit reduction and cbp models
|
||||
ResetCodingContext(pContext);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Context deletion
|
||||
*************************************************************************/
|
||||
Void FreeCodingContextEnc(CWMImageStrCodec *pSC)
|
||||
{
|
||||
Int iContexts = (Int)(pSC->cNumCodingContext), i, k;
|
||||
if (iContexts > 0 && pSC->m_pCodingContext) {
|
||||
|
||||
for (i = 0; i < iContexts; i++) {
|
||||
CCodingContext *pContext = &(pSC->m_pCodingContext[i]);
|
||||
Clean (pContext->m_pAdaptHuffCBPCY);
|
||||
Clean (pContext->m_pAdaptHuffCBPCY1);
|
||||
for (k = 0; k < NUMVLCTABLES; k++)
|
||||
Clean (pContext->m_pAHexpt[k]);
|
||||
}
|
||||
free (pSC->m_pCodingContext);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//*@@@---@@@@******************************************************************
|
||||
|
||||
#ifndef WMI_ENCODE_H
|
||||
#define WMI_ENCODE_H
|
||||
|
||||
#include "strcodec.h"
|
||||
|
||||
/*************************************************************************
|
||||
struct / class definitions
|
||||
*************************************************************************/
|
||||
|
||||
Int EncodeMacroblockDC(CWMImageStrCodec*, CCodingContext *, Int, Int);
|
||||
Int EncodeMacroblockLowpass(CWMImageStrCodec*, CCodingContext *, Int, Int);
|
||||
Int EncodeMacroblockHighpass(CWMImageStrCodec*, CCodingContext *, Int, Int);
|
||||
|
||||
Int quantizeMacroblock(CWMImageStrCodec *);
|
||||
Void transformMacroblock(CWMImageStrCodec *);
|
||||
Void predMacroblockEnc(CWMImageStrCodec *);
|
||||
|
||||
Void AdaptLowpassEnc(CCodingContext *pContext);
|
||||
Void AdaptHighpassEnc(CCodingContext *pContext);
|
||||
Void ResetCodingContextEnc(CCodingContext *pContext);
|
||||
Int AllocateCodingContextEnc(struct CWMImageStrCodec *pSC, Int iNumContexts, Int iTrimFlexBits);
|
||||
Void FreeCodingContextEnc(struct CWMImageStrCodec *pSC);
|
||||
Void predCBPEnc(CWMImageStrCodec *pSC, CCodingContext *pContext);
|
||||
|
||||
/*************************************************************************
|
||||
Forward transform definitions
|
||||
*************************************************************************/
|
||||
/** 2-point pre filter for boundaries (only used in 420 UV DC subband) **/
|
||||
Void strPre2(PixelI *, PixelI *);
|
||||
|
||||
/** 2x2 pre filter (only used in 420 UV DC subband) **/
|
||||
Void strPre2x2(PixelI *, PixelI *, PixelI *, PixelI *);
|
||||
|
||||
/** 4-point pre filter for boundaries **/
|
||||
Void strPre4(PixelI *, PixelI *, PixelI *, PixelI *);
|
||||
|
||||
/** data allocation in working buffer (first stage) **/
|
||||
|
||||
/** Y, 444 U and V **/
|
||||
/** 0 1 2 3 **/
|
||||
/** 32 33 34 35 **/
|
||||
/** 64 65 66 67 **/
|
||||
/** 96 97 98 99 **/
|
||||
|
||||
/** 420 U and V **/
|
||||
/** 0 2 4 6 **/
|
||||
/** 64 66 68 70 **/
|
||||
/** 128 130 132 134 **/
|
||||
/** 192 194 196 198 **/
|
||||
|
||||
/** 4x4 foward DCT for first stage **/
|
||||
Void strDCT4x4FirstStage(PixelI *);
|
||||
Void strDCT4x4FirstStage420UV(PixelI *);
|
||||
|
||||
Void strDCT4x4Stage1(PixelI*);
|
||||
|
||||
/** 4x4 pre filter for first stage **/
|
||||
Void strPre4x4FirstStage(PixelI *);
|
||||
Void strPre4x4FirstStage420UV(PixelI *);
|
||||
|
||||
Void strPre4x4Stage1Split(PixelI* p0, PixelI* p1, Int iOffset);
|
||||
Void strPre4x4Stage1(PixelI* p, Int iOffset);
|
||||
|
||||
/** data allocation in working buffer (second stage)**/
|
||||
|
||||
/** Y, 444 U and V **/
|
||||
/** 0 4 8 12 **/
|
||||
/** 128 132 136 140 **/
|
||||
/** 256 260 264 268 **/
|
||||
/** 384 388 392 396 **/
|
||||
|
||||
/** 420 U and V **/
|
||||
/** 0 8 **/
|
||||
/** 256 264 **/
|
||||
|
||||
/** 4x4 foward DCT for second stage **/
|
||||
Void strDCT4x4SecondStage(PixelI *);
|
||||
Void strNormalizeEnc(PixelI *, Bool);
|
||||
Void strDCT2x2dnEnc(PixelI *, PixelI *, PixelI *, PixelI *);
|
||||
|
||||
/** 4x4 pre filter for second stage **/
|
||||
Void strPre4x4Stage2Split(PixelI* p0, PixelI* p1);
|
||||
|
||||
#endif // ENCODE_H
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,511 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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 "encode.h"
|
||||
|
||||
I32 QUANT_Mulless(PixelI v, PixelI o, I32 r)
|
||||
{
|
||||
const I32 m = v >> 31;
|
||||
|
||||
assert(sizeof(PixelI) == sizeof(U32));
|
||||
return ((((v ^ m) - m + o) >> r) ^ m) - m;
|
||||
}
|
||||
|
||||
I32 MUL32HR(U32 a, U32 b, U32 r)
|
||||
{
|
||||
return (I32)((U32)((U64)a * b >> 32) >> r);
|
||||
}
|
||||
|
||||
I32 QUANT(PixelI v, PixelI o, I32 man, I32 exp)
|
||||
{
|
||||
const I32 m = v >> 31;
|
||||
|
||||
assert(sizeof(PixelI) == sizeof(U32));
|
||||
return (MUL32HR((v ^ m) - m + o, man, exp) ^ m) - m;
|
||||
}
|
||||
|
||||
Int quantizeMacroblock(CWMImageStrCodec* pSC)
|
||||
{
|
||||
CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
|
||||
CWMIMBInfo * pMBInfo = &pSC->MBInfo;
|
||||
const COLORFORMAT cf = pSC->m_param.cfColorFormat;
|
||||
int iChannel, i, j;
|
||||
|
||||
if(/*pSC->m_param.bScaledArith && */pSC->m_param.bTranscode == FALSE)
|
||||
for(iChannel = 0; iChannel < (int)pSC->m_param.cNumChannels; iChannel ++){
|
||||
const Bool bUV = (iChannel > 0 && (cf == YUV_444 || cf == YUV_422 || cf == YUV_420));
|
||||
const int iNumBlock = (bUV ? (cf == YUV_422 ? 8 : (cf == YUV_420 ? 4 : 16)) : 16);
|
||||
const int * pOffset = (iNumBlock == 4 ? blkOffsetUV : (iNumBlock == 8 ? blkOffsetUV_422 : blkOffset));
|
||||
CWMIQuantizer * pQPDC = pTile->pQuantizerDC[iChannel];
|
||||
CWMIQuantizer * pQPLP = pTile->pQuantizerLP[iChannel] + pMBInfo->iQIndexLP;
|
||||
CWMIQuantizer * pQPHP = pTile->pQuantizerHP[iChannel] + pMBInfo->iQIndexHP;
|
||||
|
||||
for(j = 0; j < iNumBlock; j ++){
|
||||
PixelI * pData = pSC->pPlane[iChannel] + pOffset[j];
|
||||
|
||||
if(j == 0) // DC
|
||||
pData[0] = (pQPDC->iMan == 0 ? QUANT_Mulless(pData[0], pQPDC->iOffset, pQPDC->iExp) : QUANT(pData[0], pQPDC->iOffset, pQPDC->iMan, pQPDC->iExp));
|
||||
else if(pSC->WMISCP.sbSubband != SB_DC_ONLY) // LP
|
||||
pData[0] = (pQPLP->iMan == 0 ? QUANT_Mulless(pData[0], pQPLP->iOffset, pQPLP->iExp) : QUANT(pData[0], pQPLP->iOffset, pQPLP->iMan, pQPLP->iExp));
|
||||
|
||||
// quantize HP
|
||||
if(pSC->WMISCP.sbSubband != SB_DC_ONLY && pSC->WMISCP.sbSubband != SB_NO_HIGHPASS)
|
||||
for(i = 1; i < 16; i ++)
|
||||
pData[i] = (pQPHP->iMan == 0 ? QUANT_Mulless(pData[i], pQPHP->iOffset, pQPHP->iExp) : QUANT(pData[i], pQPHP->iOffset, pQPHP->iMan, pQPHP->iExp));
|
||||
}
|
||||
}
|
||||
|
||||
for(iChannel = 0; iChannel < (int)pSC->m_param.cNumChannels; iChannel ++){
|
||||
I32 * pDC = pSC->MBInfo.iBlockDC[iChannel];
|
||||
PixelI * pData = pSC->pPlane[iChannel];
|
||||
|
||||
if(iChannel > 0 && cf == YUV_422){
|
||||
for(i = 0; i < 8; i ++){
|
||||
pDC[i] = pData[blkOffsetUV_422[i]];
|
||||
}
|
||||
}
|
||||
else if(iChannel > 0 && cf == YUV_420){
|
||||
for(i = 0; i < 4; i ++){
|
||||
pDC[i] = pData[blkOffsetUV[i]];
|
||||
}
|
||||
}
|
||||
else{
|
||||
for(i = 0; i < 16; i ++){
|
||||
pDC[i] = pData[dctIndex[2][i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* frequency domain prediction */
|
||||
Void predMacroblockEnc(CWMImageStrCodec * pSC)
|
||||
{
|
||||
const COLORFORMAT cf = pSC->m_param.cfColorFormat;
|
||||
const Int iChannels = (cf == YUV_420 || cf == YUV_422) ? 1 : (Int) pSC->m_param.cNumChannels;
|
||||
size_t mbX = pSC->cColumn - 1;// mbY = pSC->cRow - 1;
|
||||
CWMIMBInfo *pMBInfo = &(pSC->MBInfo);
|
||||
Int iDCACPredMode = getDCACPredMode(pSC, mbX);
|
||||
Int iDCPredMode = (iDCACPredMode & 0x3);
|
||||
Int iADPredMode = (iDCACPredMode & 0xC);
|
||||
Int iACPredMode = getACPredMode(pMBInfo, cf);
|
||||
PixelI * pOrg, * pRef;
|
||||
Int i, j, k;
|
||||
|
||||
pMBInfo->iOrientation = 2 - iACPredMode;
|
||||
|
||||
/* keep necessary info for future prediction */
|
||||
updatePredInfo(pSC, pMBInfo, mbX, cf);
|
||||
|
||||
for(i = 0; i < iChannels; i ++){
|
||||
pOrg = pMBInfo->iBlockDC[i]; // current DC block
|
||||
|
||||
/* DC prediction */
|
||||
if(iDCPredMode == 1){ // predict DC from top
|
||||
pOrg[0] -= (pSC->PredInfoPrevRow[i] + mbX)->iDC;
|
||||
}
|
||||
else if(iDCPredMode == 0){ // predict DC from left
|
||||
pOrg[0] -= (pSC->PredInfo[i] + mbX - 1)->iDC;
|
||||
}
|
||||
else if(iDCPredMode == 2){// predict DC from top&left
|
||||
pOrg[0] -= ((pSC->PredInfo[i] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[i] + mbX)->iDC) >> 1;
|
||||
}
|
||||
|
||||
/* AD prediction */
|
||||
if(iADPredMode == 4){// predict AD from top
|
||||
pRef = (pSC->PredInfoPrevRow[i] + mbX)->piAD;
|
||||
pOrg[4] -= pRef[3], pOrg[8] -= pRef[4], pOrg[12] -= pRef[5];
|
||||
}
|
||||
else if(iADPredMode == 0){// predict AD from left
|
||||
pRef = (pSC->PredInfo[i] + mbX - 1)->piAD;
|
||||
pOrg[1] -= pRef[0], pOrg[2] -= pRef[1], pOrg[3] -= pRef[2];
|
||||
}
|
||||
|
||||
pOrg = pSC->pPlane[i];
|
||||
/* AC prediction */
|
||||
if(iACPredMode == 1){ // predict from top
|
||||
for(k = 0; k <= 192; k += 64){
|
||||
/* inside macroblock, in reverse order */
|
||||
for(j = 48; j > 0; j -= 16){
|
||||
pOrg[k + j + 10] -= pOrg[k + j + 10 - 16];
|
||||
pOrg[k + j + 2] -= pOrg[k + j + 2 - 16];
|
||||
pOrg[k + j + 9] -= pOrg[k + j + 9 - 16];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(iACPredMode == 0){ // predict from left
|
||||
for(k = 0; k < 64; k += 16){
|
||||
/* inside macroblock, in reverse order */
|
||||
for(j = 192; j > 0; j -= 64){
|
||||
pOrg[k + j + 5] -= pOrg[k + j + 5 - 64];
|
||||
pOrg[k + j + 1] -= pOrg[k + j + 1 - 64];
|
||||
pOrg[k + j + 6] -= pOrg[k + j + 6 - 64];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(cf == YUV_420){
|
||||
for(i = 1; i < 3; i ++){
|
||||
pOrg = pMBInfo->iBlockDC[i]; // current DC block
|
||||
|
||||
/* DC prediciton */
|
||||
if(iDCPredMode == 1){ // predict DC from top
|
||||
pOrg[0] -= (pSC->PredInfoPrevRow[i] + mbX)->iDC;
|
||||
}
|
||||
else if(iDCPredMode == 0){ // predict DC from left
|
||||
pOrg[0] -= (pSC->PredInfo[i] + mbX - 1)->iDC;
|
||||
}
|
||||
else if(iDCPredMode == 2){ // predict DC from top&left
|
||||
pOrg[0] -= (((pSC->PredInfo[i] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[i] + mbX)->iDC + 1) >> 1);
|
||||
}
|
||||
|
||||
/* AD prediction */
|
||||
if(iADPredMode == 4){// predict AD from top
|
||||
pOrg[2] -= (pSC->PredInfoPrevRow[i] + mbX)->piAD[1];
|
||||
}
|
||||
else if(iADPredMode == 0){// predict AD from left
|
||||
pOrg[1] -= (pSC->PredInfo[i] + mbX - 1)->piAD[0];
|
||||
}
|
||||
|
||||
pOrg = pSC->pPlane[i];
|
||||
/* AC prediction */
|
||||
if(iACPredMode == 1){ // predict from top
|
||||
for(j = 16; j <= 48; j += 32){
|
||||
/* inside macroblock */
|
||||
pOrg[j + 10] -= pOrg[j + 10 - 16];
|
||||
pOrg[j + 2] -= pOrg[j + 2 - 16];
|
||||
pOrg[j + 9] -= pOrg[j + 9 - 16];
|
||||
}
|
||||
}
|
||||
else if(iACPredMode == 0){ // predict from left
|
||||
for(j = 32; j <= 48; j += 16){
|
||||
/* inside macroblock */
|
||||
pOrg[j + 5] -= pOrg[j + 5 - 32];
|
||||
pOrg[j + 1] -= pOrg[j + 1 - 32];
|
||||
pOrg[j + 6] -= pOrg[j + 6 - 32];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(cf == YUV_422){
|
||||
for(i = 1; i < 3; i ++){
|
||||
pOrg = pMBInfo->iBlockDC[i]; // current DC block
|
||||
|
||||
/* DC prediciton */
|
||||
if(iDCPredMode == 1){ // predict DC from top
|
||||
pOrg[0] -= (pSC->PredInfoPrevRow[i] + mbX)->iDC;
|
||||
}
|
||||
else if(iDCPredMode == 0){ // predict DC from left
|
||||
pOrg[0] -= (pSC->PredInfo[i] + mbX - 1)->iDC;
|
||||
}
|
||||
else if(iDCPredMode == 2){ // predict DC from top&left
|
||||
pOrg[0] -= (((pSC->PredInfo[i] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[i] + mbX)->iDC + 1) >> 1);
|
||||
}
|
||||
|
||||
/* AD prediction */
|
||||
if(iADPredMode == 4){// predict AD from top
|
||||
pOrg[4] -= (pSC->PredInfoPrevRow[i] + mbX)->piAD[4]; // AC of HT !!!
|
||||
pOrg[6] -= pOrg[2];
|
||||
pOrg[2] -= (pSC->PredInfoPrevRow[i] + mbX)->piAD[3];
|
||||
}
|
||||
else if(iADPredMode == 0){// predict AD from left
|
||||
pOrg[4] -= (pSC->PredInfo[i] + mbX - 1)->piAD[4]; // AC of HT !!!
|
||||
pOrg[1] -= (pSC->PredInfo[i] + mbX - 1)->piAD[0];
|
||||
pOrg[5] -= (pSC->PredInfo[i] + mbX - 1)->piAD[2];
|
||||
}
|
||||
else if(iDCPredMode == 1){
|
||||
pOrg[6] -= pOrg[2];
|
||||
}
|
||||
|
||||
pOrg = pSC->pPlane[i]; // current MB
|
||||
/* AC prediction */
|
||||
if(iACPredMode == 1){ // predict from top
|
||||
for(j = 48; j > 0; j -= 16){
|
||||
for(k = 0; k <= 64; k += 64){
|
||||
/* inside macroblock */
|
||||
pOrg[j + k + 10] -= pOrg[j + k + 10 - 16];
|
||||
pOrg[j + k + 2] -= pOrg[j + k + 2 - 16];
|
||||
pOrg[j + k + 9] -= pOrg[j + k + 9 - 16];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(iACPredMode == 0){ // predict from left
|
||||
for(j = 64; j <= 112; j += 16){
|
||||
/* inside macroblock */
|
||||
pOrg[j + 5] -= pOrg[j + 5 - 64];
|
||||
pOrg[j + 1] -= pOrg[j + 1 - 64];
|
||||
pOrg[j + 6] -= pOrg[j + 6 - 64];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* CBP prediction for 16 x 16 MB */
|
||||
/* block index */
|
||||
/* 0 1 4 5 */
|
||||
/* 2 3 6 7 */
|
||||
/* 8 9 12 13 */
|
||||
/* 10 11 14 15 */
|
||||
|
||||
static int NumOnes(int i)
|
||||
{
|
||||
int retval = 0;
|
||||
static const int g_Count[] = { 0,1,1,2, 1,2,2,3, 1,2,2,3, 2,3,3,4 };
|
||||
i = i & 0xffff;
|
||||
while (i) {
|
||||
retval += g_Count[i & 0xf];
|
||||
i >>= 4;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
#define SATURATE32(x) if((unsigned int)(x + 16) >= 32) { if (x < 0) x = -16; else x = 15; }
|
||||
|
||||
static Int predCBPCEnc(CWMImageStrCodec *pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)
|
||||
{
|
||||
Int iPredCBP = 0, iRetval = 0;
|
||||
Int iNOrig = NumOnes(iCBP), iNDiff = AVG_NDIFF;//NumOnes(iPredCBP ^ iCBP);
|
||||
|
||||
UNREFERENCED_PARAMETER( mbY );
|
||||
|
||||
/* only top left block pattern is predicted from neighbour */
|
||||
if(pSC->m_bCtxLeft) {
|
||||
if (pSC->m_bCtxTop) {
|
||||
iPredCBP = 1;
|
||||
}
|
||||
else {
|
||||
Int iTopCBP = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;
|
||||
iPredCBP = (iTopCBP >> 10) & 1; // left: top(10) => 0
|
||||
}
|
||||
}
|
||||
else {
|
||||
Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;
|
||||
iPredCBP = ((iLeftCBP >> 5) & 1); // left(5) => 0
|
||||
}
|
||||
|
||||
iPredCBP |= (iCBP & 0x3300) << 2; // [8 9 12 13]->[10 11 14 15]
|
||||
iPredCBP |= (iCBP & 0xcc) << 6; // [2 3 6 7]->[8 9 12 13]
|
||||
iPredCBP |= (iCBP & 0x33) << 2; // [0 1 4 5]->[2 3 6 7]
|
||||
iPredCBP |= (iCBP & 0x11) << 1; // [0 4]->[1 5]
|
||||
iPredCBP |= (iCBP & 0x2) << 3; // [1]->[4]
|
||||
|
||||
if (c) c = 1;
|
||||
if (pModel->m_iState[c] == 0) {
|
||||
iRetval = iPredCBP ^ iCBP;
|
||||
}
|
||||
else if (pModel->m_iState[c] == 1) {
|
||||
iRetval = iCBP;
|
||||
}
|
||||
else {
|
||||
iRetval = iCBP ^ 0xffff;
|
||||
}
|
||||
|
||||
pModel->m_iCount0[c] += iNOrig - iNDiff;
|
||||
SATURATE32(pModel->m_iCount0[c]);
|
||||
|
||||
pModel->m_iCount1[c] += 16 - iNOrig - iNDiff;
|
||||
SATURATE32(pModel->m_iCount1[c]);
|
||||
|
||||
if (pModel->m_iCount0[c] < 0) {
|
||||
if (pModel->m_iCount0[c] < pModel->m_iCount1[c]) {
|
||||
pModel->m_iState[c] = 1;
|
||||
}
|
||||
else {
|
||||
pModel->m_iState[c] = 2;
|
||||
}
|
||||
}
|
||||
else if (pModel->m_iCount1[c] < 0) {
|
||||
pModel->m_iState[c] = 2;
|
||||
}
|
||||
else {
|
||||
pModel->m_iState[c] = 0;
|
||||
}
|
||||
return iRetval;
|
||||
}
|
||||
|
||||
static Int predCBPC420Enc(CWMImageStrCodec *pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)
|
||||
{
|
||||
Int iPredCBP = 0, iRetval = 0;
|
||||
Int iNOrig = NumOnes(iCBP) * 4, iNDiff = AVG_NDIFF;//NumOnes(iPredCBP ^ iCBP);
|
||||
|
||||
UNREFERENCED_PARAMETER( mbY );
|
||||
|
||||
/* only top left block pattern is predicted from neighbour */
|
||||
if(pSC->m_bCtxLeft) {
|
||||
if (pSC->m_bCtxTop) {
|
||||
iPredCBP = 1;
|
||||
}
|
||||
else {
|
||||
Int iTopCBP = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;
|
||||
iPredCBP = (iTopCBP >> 2) & 1; // left: top(2) => 0
|
||||
}
|
||||
}
|
||||
else {
|
||||
Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;
|
||||
iPredCBP = ((iLeftCBP >> 1) & 1); // left(1) => 0
|
||||
}
|
||||
|
||||
iPredCBP |= (iCBP & 0x1) << 1; // [0]->[1]
|
||||
iPredCBP |= (iCBP & 0x3) << 2; // [0 1]->[2 3]
|
||||
|
||||
if (pModel->m_iState[1] == 0) {
|
||||
iRetval = iPredCBP ^ iCBP;
|
||||
}
|
||||
else if (pModel->m_iState[1] == 1) {
|
||||
iRetval = iCBP;
|
||||
}
|
||||
else {
|
||||
iRetval = iCBP ^ 0xf;
|
||||
}
|
||||
|
||||
pModel->m_iCount0[1] += iNOrig - iNDiff;
|
||||
SATURATE32(pModel->m_iCount0[1]);
|
||||
|
||||
pModel->m_iCount1[1] += 16 - iNOrig - iNDiff;
|
||||
SATURATE32(pModel->m_iCount1[1]);
|
||||
|
||||
if (pModel->m_iCount0[1] < 0) {
|
||||
if (pModel->m_iCount0[1] < pModel->m_iCount1[1]) {
|
||||
pModel->m_iState[1] = 1;
|
||||
}
|
||||
else {
|
||||
pModel->m_iState[1] = 2;
|
||||
}
|
||||
}
|
||||
else if (pModel->m_iCount1[1] < 0) {
|
||||
pModel->m_iState[1] = 2;
|
||||
}
|
||||
else {
|
||||
pModel->m_iState[1] = 0;
|
||||
}
|
||||
return iRetval;
|
||||
}
|
||||
|
||||
static Int predCBPC422Enc(CWMImageStrCodec *pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)
|
||||
{
|
||||
Int iPredCBP = 0, iRetval = 0;
|
||||
Int iNOrig = NumOnes(iCBP) * 2, iNDiff = AVG_NDIFF;//NumOnes(iPredCBP ^ iCBP);
|
||||
|
||||
UNREFERENCED_PARAMETER( mbY );
|
||||
|
||||
/* only top left block pattern is predicted from neighbour */
|
||||
if(pSC->m_bCtxLeft) {
|
||||
if (pSC->m_bCtxTop) {
|
||||
iPredCBP = 1;
|
||||
}
|
||||
else {
|
||||
Int iTopCBP = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;
|
||||
iPredCBP = (iTopCBP >> 6) & 1; // left: top(6) => 0
|
||||
}
|
||||
}
|
||||
else {
|
||||
Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;
|
||||
iPredCBP = ((iLeftCBP >> 1) & 1); // left(1) => 0
|
||||
}
|
||||
|
||||
iPredCBP |= (iCBP & 0x1) << 1; // [0]->[1]
|
||||
iPredCBP |= (iCBP & 0x3) << 2; // [0 1]->[2 3]
|
||||
iPredCBP |= (iCBP & 0xc) << 2; // [2 3]->[4 5]
|
||||
iPredCBP |= (iCBP & 0x30) << 2; // [4 5]->[6 7]
|
||||
|
||||
if (pModel->m_iState[1] == 0) {
|
||||
iRetval = iPredCBP ^ iCBP;
|
||||
}
|
||||
else if (pModel->m_iState[1] == 1) {
|
||||
iRetval = iCBP;
|
||||
}
|
||||
else {
|
||||
iRetval = iCBP ^ 0xff;
|
||||
}
|
||||
|
||||
pModel->m_iCount0[1] += iNOrig - iNDiff;
|
||||
SATURATE32(pModel->m_iCount0[1]);
|
||||
|
||||
pModel->m_iCount1[1] += 16 - iNOrig - iNDiff;
|
||||
SATURATE32(pModel->m_iCount1[1]);
|
||||
|
||||
if (pModel->m_iCount0[1] < 0) {
|
||||
if (pModel->m_iCount0[1] < pModel->m_iCount1[1]) {
|
||||
pModel->m_iState[1] = 1;
|
||||
}
|
||||
else {
|
||||
pModel->m_iState[1] = 2;
|
||||
}
|
||||
}
|
||||
else if (pModel->m_iCount1[1] < 0) {
|
||||
pModel->m_iState[1] = 2;
|
||||
}
|
||||
else {
|
||||
pModel->m_iState[1] = 0;
|
||||
}
|
||||
return iRetval;
|
||||
}
|
||||
|
||||
Void predCBPEnc(CWMImageStrCodec* pSC, CCodingContext *pContext)
|
||||
{
|
||||
size_t mbX = pSC->cColumn - 1, mbY = pSC->cRow - 1;
|
||||
CWMIMBInfo * pMBInfo = &(pSC->MBInfo);
|
||||
int iChannel, i, j;
|
||||
|
||||
for(iChannel = 0; iChannel < (int)pSC->m_param.cNumChannels; iChannel ++){
|
||||
const COLORFORMAT cf = pSC->m_param.cfColorFormat;
|
||||
const Bool bUV = (iChannel > 0);
|
||||
const int iNumBlock = (bUV ? (cf == YUV_422 ? 8 : (cf == YUV_420 ? 4 : 16)) : 16);
|
||||
const int * pOffset = (iNumBlock == 4 ? blkOffsetUV : (iNumBlock == 8 ? blkOffsetUV_422 : blkOffset));
|
||||
const Int threshold = (1 << pContext->m_aModelAC.m_iFlcBits[bUV ? 1 : 0]) - 1, threshold2 = threshold * 2 + 1;
|
||||
Int iCBP = 0;
|
||||
|
||||
for(j = 0; j < iNumBlock; j ++){
|
||||
PixelI * pData = pSC->pPlane[iChannel] + pOffset[j];
|
||||
for(i = 1; i < 16; i ++){
|
||||
if((unsigned int)(pData[i] + threshold) >= (unsigned int) threshold2){ // significant coeff
|
||||
iCBP |= (1 << j); // update CBP
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pMBInfo->iCBP[iChannel] = (pSC->PredInfo[iChannel] + mbX)->iCBP = iCBP;
|
||||
|
||||
if(iNumBlock == 16){
|
||||
pMBInfo->iDiffCBP[iChannel] = predCBPCEnc(pSC, pMBInfo->iCBP[iChannel], mbX, mbY, iChannel, &pContext->m_aCBPModel);
|
||||
}
|
||||
else if(iNumBlock == 8){
|
||||
pSC->MBInfo.iDiffCBP[iChannel] = predCBPC422Enc(pSC, pMBInfo->iCBP[iChannel], mbX, mbY, iChannel, &pContext->m_aCBPModel);
|
||||
}
|
||||
else{
|
||||
pSC->MBInfo.iDiffCBP[iChannel] = predCBPC420Enc(pSC, pMBInfo->iCBP[iChannel], mbX, mbY, iChannel, &pContext->m_aCBPModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,511 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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"
|
||||
|
||||
#ifdef MEM_TRACE
|
||||
#define TRACE_MALLOC 1
|
||||
#define TRACE_NEW 0
|
||||
#define TRACE_HEAP 0
|
||||
#include "memtrace.h"
|
||||
#endif
|
||||
|
||||
// Huffman lookup tables
|
||||
static const short g4HuffLookupTable[40] = {
|
||||
19,19,19,19,27,27,27,27,10,10,10,10,10,10,10,10,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
0,0,0,0,0,0,0,0 };
|
||||
|
||||
static const short g5HuffLookupTable[2][42] = {{
|
||||
28,28,36,36,19,19,19,19,10,10,10,10,10,10,10,10,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
0,0,0,0,0,0,0,0,0,0 },
|
||||
{
|
||||
11,11,11,11,19,19,19,19,27,27,27,27,35,35,35,35,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
0,0,0,0,0,0,0,0,0,0 }};
|
||||
|
||||
static const short g6HuffLookupTable[4][44] = {{
|
||||
13,29,44,44,19,19,19,19,34,34,34,34,34,34,34,34,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0 },
|
||||
{
|
||||
12,12,28,28,43,43,43,43,2,2,2,2,2,2,2,2,
|
||||
18,18,18,18,18,18,18,18,34,34,34,34,34,34,34,34,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0 },
|
||||
{
|
||||
4,4,12,12,43,43,43,43,18,18,18,18,18,18,18,18,
|
||||
26,26,26,26,26,26,26,26,34,34,34,34,34,34,34,34,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0 },
|
||||
{
|
||||
5,13,36,36,43,43,43,43,18,18,18,18,18,18,18,18,
|
||||
25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0 }};
|
||||
|
||||
static const short g7HuffLookupTable[2][46] = {{
|
||||
45,53,36,36,27,27,27,27,2,2,2,2,2,2,2,2,
|
||||
10,10,10,10,10,10,10,10,18,18,18,18,18,18,18,18,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
|
||||
{
|
||||
-32736,37,28,28,19,19,19,19,10,10,10,10,10,10,10,10,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
5,6,0,0,0,0,0,0,0,0,0,0,0,0 }};
|
||||
|
||||
static const short g8HuffLookupTable[2][48] = {{
|
||||
53,21,28,28,11,11,11,11,43,43,43,43,59,59,59,59,
|
||||
2,2,2,2,2,2,2,2,34,34,34,34,34,34,34,34,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
|
||||
{
|
||||
52,52,20,20,3,3,3,3,11,11,11,11,27,27,27,27,
|
||||
35,35,35,35,43,43,43,43,58,58,58,58,58,58,58,58,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }};
|
||||
|
||||
static const short g9HuffLookupTable[2][50] = {{
|
||||
13,29,37,61,20,20,68,68,3,3,3,3,51,51,51,51,
|
||||
41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0 },
|
||||
{
|
||||
-32736,53,28,28,11,11,11,11,19,19,19,19,43,43,43,43,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
-32734,4,7,8,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0 }};
|
||||
|
||||
static const short g12HuffLookupTable[5][56] = {{
|
||||
-32736,5,76,76,37,53,69,85,43,43,43,43,91,91,91,91,
|
||||
57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
|
||||
-32734,1,2,3,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0 },
|
||||
{
|
||||
-32736,85,13,53,4,4,36,36,43,43,43,43,67,67,67,67,
|
||||
75,75,75,75,91,91,91,91,58,58,58,58,58,58,58,58,
|
||||
2,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0 },
|
||||
{
|
||||
-32736,37,92,92,11,11,11,11,43,43,43,43,59,59,59,59,
|
||||
67,67,67,67,75,75,75,75,2,2,2,2,2,2,2,2,
|
||||
-32734,-32732,2,3,6,10,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0 },
|
||||
{
|
||||
-32736,29,37,69,3,3,3,3,43,43,43,43,59,59,59,59,
|
||||
75,75,75,75,91,91,91,91,10,10,10,10,10,10,10,10,
|
||||
-32734,10,2,6,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0 },
|
||||
{
|
||||
-32736,93,28,28,60,60,76,76,3,3,3,3,43,43,43,43,
|
||||
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
|
||||
-32734,-32732,-32730,2,4,8,6,10,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0 }};
|
||||
|
||||
/**********************************************************************
|
||||
Allocation and dellocation
|
||||
**********************************************************************/
|
||||
Void Clean (CAdaptiveHuffman *pAdHuff)
|
||||
{
|
||||
if (pAdHuff == NULL)
|
||||
return;
|
||||
free (pAdHuff);
|
||||
}
|
||||
|
||||
CAdaptiveHuffman *Allocate (Int iNSymbols, CODINGMODE cm)
|
||||
{
|
||||
CAdaptiveHuffman *pAdHuff = (CAdaptiveHuffman *) malloc (sizeof (CAdaptiveHuffman));
|
||||
|
||||
UNREFERENCED_PARAMETER(cm);
|
||||
|
||||
if (pAdHuff == NULL)
|
||||
return NULL;
|
||||
if (iNSymbols > 255 || iNSymbols <= 0)
|
||||
goto ErrorExit;
|
||||
|
||||
memset (pAdHuff, 0, sizeof (CAdaptiveHuffman));
|
||||
pAdHuff->m_iNSymbols = iNSymbols;
|
||||
|
||||
pAdHuff->m_pDelta = NULL;
|
||||
pAdHuff->m_iDiscriminant = pAdHuff->m_iUpperBound = pAdHuff->m_iLowerBound = 0;
|
||||
|
||||
return pAdHuff;
|
||||
|
||||
ErrorExit:
|
||||
Clean (pAdHuff);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Adapt Huffman table
|
||||
**********************************************************************/
|
||||
// Alphabet size = 4
|
||||
static const Int g_Index4Table[] = {
|
||||
1,2,3,3
|
||||
};
|
||||
static const Int g4CodeTable[] = {
|
||||
4,
|
||||
1, 1,
|
||||
1, 2,
|
||||
0, 3,
|
||||
1, 3
|
||||
};
|
||||
|
||||
// Alphabet size = 5
|
||||
static const Int g_Index5Table[] = {
|
||||
1,2,3,4,4,
|
||||
1,3,3,3,3
|
||||
};
|
||||
static const Int g5CodeTable[] = {
|
||||
5,
|
||||
1, 1,
|
||||
1, 2,
|
||||
1, 3,
|
||||
0, 4,
|
||||
1, 4,
|
||||
|
||||
5,
|
||||
1, 1,
|
||||
0, 3,
|
||||
1, 3,
|
||||
2, 3,
|
||||
3, 3,
|
||||
};
|
||||
static const Int g5DeltaTable[] = { 0,-1,0,1,1 };
|
||||
|
||||
// Alphabet size = 6
|
||||
static const Int g_Index6Table[] = {
|
||||
1,5,3,5,2,4,
|
||||
2,4,2,4,2,3,
|
||||
4,4,2,2,2,3,
|
||||
5,5,2,1,4,3,
|
||||
};
|
||||
static const Int g6CodeTable[] = {
|
||||
6,
|
||||
1, 1,
|
||||
0, 5,
|
||||
1, 3,
|
||||
1, 5,
|
||||
1, 2,
|
||||
1, 4,
|
||||
|
||||
6,
|
||||
1, 2,
|
||||
0, 4,
|
||||
2, 2,
|
||||
1, 4,
|
||||
3, 2,
|
||||
1, 3,
|
||||
|
||||
6,
|
||||
0, 4,
|
||||
1, 4,
|
||||
1, 2,
|
||||
2, 2,
|
||||
3, 2,
|
||||
1, 3,
|
||||
|
||||
6,
|
||||
0, 5,
|
||||
1, 5,
|
||||
1, 2,
|
||||
1, 1,
|
||||
1, 4,
|
||||
1, 3
|
||||
};
|
||||
static const Int g6DeltaTable[] = {
|
||||
-1, 1, 1, 1, 0, 1,
|
||||
-2, 0, 0, 2, 0, 0,
|
||||
-1,-1, 0, 1,-2, 0
|
||||
};
|
||||
|
||||
// Alphabet size = 7
|
||||
static const Int g_Index7Table[] = { 2,2,2,3,4,5,5,
|
||||
1,2,3,4,5,6,6 };
|
||||
static const Int g7CodeTable[] = {
|
||||
7,
|
||||
1, 2,
|
||||
2, 2,
|
||||
3, 2,
|
||||
1, 3,
|
||||
1, 4,
|
||||
0, 5,
|
||||
1, 5,
|
||||
|
||||
7,
|
||||
1, 1,
|
||||
1, 2,
|
||||
1, 3,
|
||||
1, 4,
|
||||
1, 5,
|
||||
0, 6,
|
||||
1, 6
|
||||
};
|
||||
static const Int g7DeltaTable[] = { 1,0,-1,-1,-1,-1,-1 };
|
||||
|
||||
// Alphabet size = 8
|
||||
static const Int g_Index8Table[] = { 2,3,5,4,2,3,5,3,
|
||||
3,3,4,3,3,3,4,2};
|
||||
static const Int g8CodeTable[] = {
|
||||
8,
|
||||
2, 2,
|
||||
1, 3,
|
||||
1, 5,
|
||||
1, 4,
|
||||
3, 2,
|
||||
2, 3,
|
||||
0, 5,
|
||||
3, 3,
|
||||
|
||||
8,
|
||||
1, 3,
|
||||
2, 3,
|
||||
1, 4,
|
||||
3, 3,
|
||||
4, 3,
|
||||
5, 3,
|
||||
0, 4,
|
||||
3, 2
|
||||
};
|
||||
static const Int g8DeltaTable[] = { -1,0,1,1,-1,0,1,1 };
|
||||
|
||||
static const Int g_Index9Table[] = {
|
||||
3,5,4,5,5,1,3,5,4,
|
||||
1,3,3,4,6,3,5,7,7,
|
||||
};
|
||||
static const Int g9CodeTable[] = {
|
||||
9,
|
||||
2, 3,
|
||||
0, 5,
|
||||
2, 4,
|
||||
1, 5,
|
||||
2, 5,
|
||||
1, 1,
|
||||
3, 3,
|
||||
3, 5,
|
||||
3, 4,
|
||||
|
||||
9,
|
||||
1, 1,
|
||||
1, 3,
|
||||
2, 3,
|
||||
1, 4,
|
||||
1, 6,
|
||||
3, 3,
|
||||
1, 5,
|
||||
0, 7,
|
||||
1, 7,
|
||||
};
|
||||
static const Int g9DeltaTable[] = { 2,2,1,1,-1,-2,-2,-2,-3 };
|
||||
|
||||
// Alphabet size = 12
|
||||
static const Int g_Index12Table[] = { // index12 is the most critical symbol
|
||||
5,6,7,7,5,3,5,1,5,4,5,3,
|
||||
4,5,6,6,4,3,5,2,3,3,5,3,
|
||||
2,3,7,7,5,3,7,3,3,3,7,4,
|
||||
3,2,7,5,5,3,7,3,5,3,6,3,
|
||||
3,1,7,4,7,3,8,4,7,4,8,5,
|
||||
};
|
||||
static const Int g12CodeTable[] = {
|
||||
12,
|
||||
1, 5,
|
||||
1, 6,
|
||||
0, 7,
|
||||
1, 7,
|
||||
4, 5,
|
||||
2, 3,
|
||||
5, 5,
|
||||
1, 1,
|
||||
6, 5,
|
||||
1, 4,
|
||||
7, 5,
|
||||
3, 3,
|
||||
|
||||
12,
|
||||
2, 4,
|
||||
2, 5,
|
||||
0, 6,
|
||||
1, 6,
|
||||
3, 4,
|
||||
2, 3,
|
||||
3, 5,
|
||||
3, 2,
|
||||
3, 3,
|
||||
4, 3,
|
||||
1, 5,
|
||||
5, 3,
|
||||
|
||||
12,
|
||||
3, 2,
|
||||
1, 3,
|
||||
0, 7,
|
||||
1, 7,
|
||||
1, 5,
|
||||
2, 3,
|
||||
2, 7,
|
||||
3, 3,
|
||||
4, 3,
|
||||
5, 3,
|
||||
3, 7,
|
||||
1, 4,
|
||||
|
||||
12,
|
||||
1, 3,
|
||||
3, 2,
|
||||
0, 7,
|
||||
1, 5,
|
||||
2, 5,
|
||||
2, 3,
|
||||
1, 7,
|
||||
3, 3,
|
||||
3, 5,
|
||||
4, 3,
|
||||
1, 6,
|
||||
5, 3,
|
||||
|
||||
12,
|
||||
2, 3,
|
||||
1, 1,
|
||||
1, 7,
|
||||
1, 4,
|
||||
2, 7,
|
||||
3, 3,
|
||||
0, 8,
|
||||
2, 4,
|
||||
3, 7,
|
||||
3, 4,
|
||||
1, 8,
|
||||
1, 5
|
||||
};
|
||||
static const Int g12DeltaTable[] = {
|
||||
1, 1, 1, 1, 1, 0, 0,-1, 2, 1, 0, 0,
|
||||
2, 2,-1,-1,-1, 0,-2,-1, 0, 0,-2,-1,
|
||||
-1, 1, 0, 2, 0, 0, 0, 0,-2, 0, 1, 1,
|
||||
0, 1, 0, 1,-2, 0,-1,-1,-2,-1,-2,-2
|
||||
};
|
||||
|
||||
/**********************************************************************
|
||||
Adapt fixed length codes based on discriminant
|
||||
**********************************************************************/
|
||||
static const Int THRESHOLD = 8;
|
||||
static const Int MEMORY = 8;
|
||||
|
||||
Void AdaptDiscriminant (CAdaptiveHuffman *pAdHuff)
|
||||
{
|
||||
Int iSym = pAdHuff->m_iNSymbols, t, dL, dH;
|
||||
const Int *pCodes, *pDelta = NULL;
|
||||
Bool bChange = FALSE;
|
||||
static const Int gMaxTables[] = { 0,0,0,0, 1,2, 4,2, 2,2, 0,0,5 };
|
||||
static const Int gSecondDisc[]= { 0,0,0,0, 0,0, 1,0, 0,0, 0,0,1 };
|
||||
|
||||
if (!pAdHuff->m_bInitialize) {
|
||||
pAdHuff->m_bInitialize = 1;
|
||||
pAdHuff->m_iDiscriminant = pAdHuff->m_iDiscriminant1 = 0;
|
||||
pAdHuff->m_iTableIndex = gSecondDisc[iSym];//(gMaxTables[iSym] - 1) >> 1;
|
||||
}
|
||||
|
||||
dL = dH = pAdHuff->m_iDiscriminant;
|
||||
if (gSecondDisc[iSym]) {
|
||||
dH = pAdHuff->m_iDiscriminant1;
|
||||
}
|
||||
|
||||
if (dL < pAdHuff->m_iLowerBound) {
|
||||
pAdHuff->m_iTableIndex--;
|
||||
bChange = TRUE;
|
||||
}
|
||||
else if (dH > pAdHuff->m_iUpperBound) {
|
||||
pAdHuff->m_iTableIndex++;
|
||||
bChange = TRUE;
|
||||
}
|
||||
if (bChange) {
|
||||
/** if initialization is fixed, we can exit on !bChange **/
|
||||
pAdHuff->m_iDiscriminant = 0;
|
||||
pAdHuff->m_iDiscriminant1 = 0;
|
||||
}
|
||||
{
|
||||
if (pAdHuff->m_iDiscriminant < -THRESHOLD * MEMORY)
|
||||
pAdHuff->m_iDiscriminant = -THRESHOLD * MEMORY;
|
||||
else if (pAdHuff->m_iDiscriminant > THRESHOLD * MEMORY)
|
||||
pAdHuff->m_iDiscriminant = THRESHOLD * MEMORY;
|
||||
|
||||
if (pAdHuff->m_iDiscriminant1 < -THRESHOLD * MEMORY)
|
||||
pAdHuff->m_iDiscriminant1 = -THRESHOLD * MEMORY;
|
||||
else if (pAdHuff->m_iDiscriminant1 > THRESHOLD * MEMORY)
|
||||
pAdHuff->m_iDiscriminant1 = THRESHOLD * MEMORY;
|
||||
}
|
||||
|
||||
t = pAdHuff->m_iTableIndex;
|
||||
assert (t >= 0);
|
||||
assert (t < gMaxTables[iSym]);
|
||||
|
||||
//pAdHuff->m_iDiscriminant >>= 1;
|
||||
pAdHuff->m_iLowerBound = (t == 0) ? (-1 << 31) : -THRESHOLD;
|
||||
pAdHuff->m_iUpperBound = (t == gMaxTables[iSym] - 1) ? (1 << 30) : THRESHOLD;
|
||||
|
||||
switch (iSym) {
|
||||
case 4:
|
||||
pCodes = g4CodeTable;
|
||||
pAdHuff->m_hufDecTable = (short *) g4HuffLookupTable;
|
||||
break;
|
||||
case 5:
|
||||
pCodes = g5CodeTable + (iSym * 2 + 1) * t;
|
||||
pDelta = g5DeltaTable;
|
||||
pAdHuff->m_hufDecTable = g5HuffLookupTable[t];
|
||||
break;
|
||||
case 6:
|
||||
pCodes = g6CodeTable + (iSym * 2 + 1) * t;
|
||||
pAdHuff->m_pDelta1 = g6DeltaTable + iSym * (t - (t + 1 == gMaxTables[iSym]));
|
||||
pDelta = g6DeltaTable + (t - 1 + (t == 0)) * iSym;
|
||||
pAdHuff->m_hufDecTable = g6HuffLookupTable[t];
|
||||
break;
|
||||
case 7:
|
||||
pCodes = g7CodeTable + (iSym * 2 + 1) * t;
|
||||
pDelta = g7DeltaTable;
|
||||
pAdHuff->m_hufDecTable = g7HuffLookupTable[t];
|
||||
break;
|
||||
case 8:
|
||||
//printf ("%d ", t);
|
||||
pCodes = g8CodeTable;// + (iSym * 2 + 1) * t;
|
||||
//pDelta = g8DeltaTable;
|
||||
pAdHuff->m_hufDecTable = g8HuffLookupTable[0];
|
||||
break;
|
||||
case 9:
|
||||
pCodes = g9CodeTable + (iSym * 2 + 1) * t;
|
||||
pDelta = g9DeltaTable;
|
||||
pAdHuff->m_hufDecTable = g9HuffLookupTable[t];
|
||||
break;
|
||||
case 12:
|
||||
pCodes = g12CodeTable + (iSym * 2 + 1) * t;
|
||||
pAdHuff->m_pDelta1 = g12DeltaTable + iSym * (t - (t + 1 == gMaxTables[iSym]));
|
||||
pDelta = g12DeltaTable + (t - 1 + (t == 0)) * iSym;
|
||||
pAdHuff->m_hufDecTable = g12HuffLookupTable[t];
|
||||
break;
|
||||
default:
|
||||
assert (0); // undefined fixed length table
|
||||
return;
|
||||
}
|
||||
|
||||
pAdHuff->m_pTable = pCodes;
|
||||
pAdHuff->m_pDelta = pDelta;
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//*@@@---@@@@******************************************************************
|
||||
#pragma once
|
||||
|
||||
//================================
|
||||
// bitio functions
|
||||
//================================
|
||||
#define PACKETLENGTH (1U<<12) // 4kB
|
||||
|
||||
#define readIS_L1(pSC, pIO) readIS(pSC, pIO)
|
||||
#define readIS_L2(pSC, pIO) (void)(pSC, pIO)
|
||||
|
||||
#define writeIS_L1(pSC, pIO) writeIS(pSC, pIO)
|
||||
#define writeIS_L2(pSC, pIO) (void)(pSC, pIO)
|
||||
|
||||
|
||||
//================================
|
||||
// common defines
|
||||
//================================
|
||||
#define FORCE_INLINE
|
||||
#define CDECL
|
||||
#if __LP64__
|
||||
#define UINTPTR_T unsigned long long
|
||||
#define INTPTR_T long long
|
||||
#else
|
||||
#define UINTPTR_T unsigned int
|
||||
#define INTPTR_T int
|
||||
#endif
|
||||
|
||||
|
||||
//================================
|
||||
// quantization optimization
|
||||
//================================
|
||||
//#define RECIP_QUANT_OPT
|
||||
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//*@@@---@@@@******************************************************************
|
||||
|
||||
#ifndef WMI_COMMON_H
|
||||
#define WMI_COMMON_H
|
||||
|
||||
/*************************************************************************
|
||||
// Common typedef's
|
||||
*************************************************************************/
|
||||
typedef enum { ENCODER = 0, DECODER = 1 } CODINGMODE;
|
||||
|
||||
typedef enum tagBand
|
||||
{
|
||||
BAND_HEADER = 0,
|
||||
BAND_DC = 1,
|
||||
BAND_LP = 2,
|
||||
BAND_AC = 3,
|
||||
BAND_FL = 4
|
||||
} BAND;
|
||||
|
||||
/*************************************************************************
|
||||
struct / class definitions
|
||||
*************************************************************************/
|
||||
//#define SIGNATURE_BYTES 8 // Bytes for GDI+ signature
|
||||
#define CODEC_VERSION 1
|
||||
#define CODEC_SUBVERSION 0
|
||||
#define CODEC_SUBVERSION_NEWSCALING_SOFT_TILES 1
|
||||
#define CODEC_SUBVERSION_NEWSCALING_HARD_TILES 9
|
||||
|
||||
#define CONTEXTX 8
|
||||
#define CTDC 5
|
||||
#define NUMVLCTABLES 21 // CONTEXTX * 2 + CTDC
|
||||
#define AVG_NDIFF 3
|
||||
|
||||
#define MAXTOTAL 32767 // 511 should be enough
|
||||
|
||||
/** Quantization related defines **/
|
||||
#define SHIFTZERO 1 /* >= 0 */
|
||||
#define QPFRACBITS 2 /* or 0 only supported */
|
||||
|
||||
/** adaptive huffman encoding / decoding struct **/
|
||||
typedef struct CAdaptiveHuffman
|
||||
{
|
||||
Int m_iNSymbols;
|
||||
const Int *m_pTable;
|
||||
const Int *m_pDelta, *m_pDelta1;
|
||||
Int m_iTableIndex;
|
||||
const short *m_hufDecTable;
|
||||
Bool m_bInitialize;
|
||||
//Char m_pLabel[8]; // for debugging - label attached to constructor
|
||||
|
||||
Int m_iDiscriminant, m_iDiscriminant1;
|
||||
Int m_iUpperBound;
|
||||
Int m_iLowerBound;
|
||||
} CAdaptiveHuffman;
|
||||
|
||||
|
||||
/************************************************************************************
|
||||
Context structures
|
||||
************************************************************************************/
|
||||
typedef struct CAdaptiveModel {
|
||||
Int m_iFlcState[2];
|
||||
Int m_iFlcBits[2];
|
||||
BAND m_band;
|
||||
} CAdaptiveModel;
|
||||
|
||||
typedef struct CCBPModel {
|
||||
Int m_iCount0[2];
|
||||
Int m_iCount1[2];
|
||||
Int m_iState[2];
|
||||
} CCBPModel;
|
||||
|
||||
/*************************************************************************
|
||||
globals
|
||||
*************************************************************************/
|
||||
extern Int grgiZigzagInv4x4_lowpass[];
|
||||
extern Int grgiZigzagInv4x4H[];
|
||||
extern Int grgiZigzagInv4x4V[];
|
||||
extern const Int gSignificantRunBin[];
|
||||
extern const Int gSignificantRunFixedLength[];
|
||||
static const Int cblkChromas[] = {0,4,8,16, 16,16,16, 0,0};
|
||||
/*************************************************************************
|
||||
function declarations
|
||||
*************************************************************************/
|
||||
// common utilities
|
||||
Void Clean (CAdaptiveHuffman *pAdHuff);
|
||||
CAdaptiveHuffman *Allocate (Int iNSymbols, CODINGMODE cm);
|
||||
|
||||
/* Timing functions */
|
||||
void reset_timing(double *time);
|
||||
void report_timing(const char *s, double time);
|
||||
// static double timeperclock;
|
||||
|
||||
/** adaptive model functions **/
|
||||
Void UpdateModelMB (COLORFORMAT cf, Int iChannels, Int iLaplacianMean[], CAdaptiveModel *m_pModel);
|
||||
|
||||
/** adaptive huffman encoder / decoder functions **/
|
||||
Void Adapt (CAdaptiveHuffman *pAdHuff, Bool bFixedTables);
|
||||
Void AdaptFixed (CAdaptiveHuffman *pAdHuff);
|
||||
Void AdaptDiscriminant (CAdaptiveHuffman *pAdHuff);
|
||||
|
||||
#ifndef _PREFAST_
|
||||
#pragma warning(disable:4068)
|
||||
#endif
|
||||
|
||||
#endif // WMI_COMMON_H
|
|
@ -0,0 +1,183 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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 "xplatform_image.h"
|
||||
|
||||
#ifdef MEM_TRACE
|
||||
#define TRACE_MALLOC 1
|
||||
#define TRACE_NEW 0
|
||||
#define TRACE_HEAP 0
|
||||
#include "memtrace.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !(defined(__ANSI__))
|
||||
// Desktop
|
||||
#include <windows.h>
|
||||
#else
|
||||
// ANSI
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
Int grgiZigzagInv4x4_lowpass [] = {
|
||||
0, 1, 4, 5, 2, 8, 6, 9,
|
||||
3, 12, 10, 7, 13, 11, 14, 15
|
||||
};
|
||||
|
||||
Int grgiZigzagInv4x4H [] = {
|
||||
0, 1, 4, 5, 2, 8, 6, 9,
|
||||
3, 12, 10, 7, 13, 11, 14, 15
|
||||
};
|
||||
Int grgiZigzagInv4x4V [] = {
|
||||
0, 4, 8, 5, 1, 12, 9, 6, 2, 13, 3, 15, 7, 10, 14, 11
|
||||
};
|
||||
|
||||
const Int gSignificantRunBin[] = {
|
||||
-1,-1,-1,-1,
|
||||
2,2,2,
|
||||
1,1,1,1,
|
||||
0,0,0,0
|
||||
};
|
||||
|
||||
const Int gSignificantRunFixedLength[] = {
|
||||
0,0,1,1,3,
|
||||
0,0,1,1,2,
|
||||
0,0,0,0,1,
|
||||
};
|
||||
|
||||
/*************************************************************************
|
||||
UpdateModelMB : update adaptive model at end of macroblock
|
||||
(for lowest resolution only)
|
||||
*************************************************************************/
|
||||
#define MODELWEIGHT 70//90
|
||||
|
||||
Void UpdateModelMB (COLORFORMAT cf, Int iChannels, Int iLaplacianMean[], CAdaptiveModel *pModel)
|
||||
{
|
||||
Int j;
|
||||
static const Int aWeight0[3] = { 240/*DC*/, 12/*LP*/, 1 };
|
||||
static const Int aWeight1[3][MAX_CHANNELS] = {
|
||||
{ 0,240,120,80, 60,48,40,34, 30,27,24,22, 20,18,17,16 },
|
||||
{ 0,12,6,4, 3,2,2,2, 2,1,1,1, 1,1,1,1 },
|
||||
{ 0,16,8,5, 4,3,3,2, 2,2,2,1, 1,1,1,1 }
|
||||
};
|
||||
static const Int aWeight2[6] = { 120,37,2,/*420*/ 120,18,1/*422*/ };
|
||||
|
||||
iLaplacianMean[0] *= aWeight0[pModel->m_band - BAND_DC];
|
||||
if (cf == YUV_420) {
|
||||
iLaplacianMean[1] *= aWeight2[pModel->m_band - BAND_DC];
|
||||
}
|
||||
else if (cf == YUV_422) {
|
||||
iLaplacianMean[1] *= aWeight2[3 + (pModel->m_band) - BAND_DC];
|
||||
}
|
||||
else {
|
||||
iLaplacianMean[1] *= aWeight1[pModel->m_band - BAND_DC][iChannels - 1];
|
||||
if (pModel->m_band == BAND_AC)
|
||||
iLaplacianMean[1] >>= 4;
|
||||
}
|
||||
|
||||
for (j = 0; j < 2; j++) {
|
||||
Int iLM = iLaplacianMean[j];
|
||||
Int iMS = pModel->m_iFlcState[j];
|
||||
Int iDelta = (iLM - MODELWEIGHT) >> 2;
|
||||
|
||||
if (iDelta <= -8) {
|
||||
iDelta += 4;
|
||||
if (iDelta < -16)
|
||||
iDelta = -16;
|
||||
iMS += iDelta;
|
||||
if (iMS < -8) {
|
||||
if (pModel->m_iFlcBits[j] == 0)
|
||||
iMS = -8;
|
||||
else {
|
||||
iMS = 0;
|
||||
pModel->m_iFlcBits[j]--;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (iDelta >= 8) {
|
||||
iDelta -= 4;
|
||||
if (iDelta > 15)
|
||||
iDelta = 15;
|
||||
iMS += iDelta;
|
||||
if (iMS > 8) {
|
||||
if (pModel->m_iFlcBits[j] >= 15) {
|
||||
pModel->m_iFlcBits[j] = 15;
|
||||
iMS = 8;
|
||||
}
|
||||
else {
|
||||
iMS = 0;
|
||||
pModel->m_iFlcBits[j]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
pModel->m_iFlcState[j] = iMS;
|
||||
if (cf == Y_ONLY)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Void ResetCodingContext(CCodingContext *pContext)
|
||||
{
|
||||
// reset bit reduction models
|
||||
memset (&(pContext->m_aModelAC), 0, sizeof(CAdaptiveModel));
|
||||
pContext->m_aModelAC.m_band = BAND_AC;
|
||||
|
||||
memset (&(pContext->m_aModelLP), 0, sizeof(CAdaptiveModel));
|
||||
pContext->m_aModelLP.m_band = BAND_LP;
|
||||
pContext->m_aModelLP.m_iFlcBits[0] = pContext->m_aModelLP.m_iFlcBits[1] = 4;
|
||||
|
||||
memset (&(pContext->m_aModelDC), 0, sizeof(CAdaptiveModel));
|
||||
pContext->m_aModelDC.m_band = BAND_DC;
|
||||
pContext->m_aModelDC.m_iFlcBits[0] = pContext->m_aModelDC.m_iFlcBits[1] = 8;
|
||||
|
||||
// reset CBP models
|
||||
pContext->m_iCBPCountMax = pContext->m_iCBPCountZero = 1;
|
||||
|
||||
pContext->m_aCBPModel.m_iCount0[0] = pContext->m_aCBPModel.m_iCount0[1] = -4;
|
||||
pContext->m_aCBPModel.m_iCount1[0] = pContext->m_aCBPModel.m_iCount1[1] = 4;
|
||||
pContext->m_aCBPModel.m_iState[0] = pContext->m_aCBPModel.m_iState[1] = 0;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Initialize zigzag scan parameters
|
||||
*************************************************************************/
|
||||
Void InitZigzagScan(CCodingContext * pContext)
|
||||
{
|
||||
if (NULL != pContext) {
|
||||
Int i;
|
||||
for (i=0; i<16; i++) {
|
||||
pContext->m_aScanLowpass[i].uScan = grgiZigzagInv4x4_lowpass[i];
|
||||
pContext->m_aScanHoriz[i].uScan = dctIndex[0][grgiZigzagInv4x4H[i]];
|
||||
pContext->m_aScanVert[i].uScan = dctIndex[0][grgiZigzagInv4x4V[i]];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//*@@@---@@@@******************************************************************
|
||||
|
||||
#ifndef __PERFTIMER_H_
|
||||
#define __PERFTIMER_H_
|
||||
|
||||
//***************************************************************************
|
||||
// Description
|
||||
//
|
||||
// Performance timer API used to measure codec performance. The underlying
|
||||
// implementation of this API may vary - from ANSI-C implementation via clock,
|
||||
// Win32 implementation via QueryPerformanceCounter or GetProcessTimes. At
|
||||
// present we only support one implementation of this PerfTimer "object".
|
||||
// You choose the implementation by choosing which one of the many files
|
||||
// to compile and link with your application.
|
||||
//***************************************************************************
|
||||
|
||||
#ifdef DISABLE_PERF_MEASUREMENT
|
||||
|
||||
#define PERFTIMER_ONLY(code)
|
||||
#define PERFTIMER_NEW(fPerf, ppPerfTimer)
|
||||
#define PERFTIMER_DELETE(fPerf, ppPerfTimer)
|
||||
#define PERFTIMER_START(fPerf, pPerfTimer)
|
||||
#define PERFTIMER_STOP(fPerf, pPerfTimer)
|
||||
#define PERFTIMER_GETRESULTS(fPerf, pPerfTimer, pResults)
|
||||
#define PERFTIMER_COPYSTARTTIME(fPerf, pDst, pSrc)
|
||||
#define PERFTIMER_REPORT(fPerf, pCodec)
|
||||
|
||||
#else // DISABLE_PERF_MEASUREMENT
|
||||
|
||||
#define PERFTIMER_ONLY(code) code
|
||||
#define PERFTIMER_NEW(fPerf, ppPerfTimer) if (fPerf) {Bool b = b = PerfTimerNew(ppPerfTimer); assert(b);};
|
||||
#define PERFTIMER_DELETE(fPerf, pPerfTimer) if (fPerf) {PerfTimerDelete(pPerfTimer);};
|
||||
#define PERFTIMER_START(fPerf, pPerfTimer) if (fPerf) {Bool b = b = PerfTimerStart(pPerfTimer); assert(b);};
|
||||
#define PERFTIMER_STOP(fPerf, pPerfTimer) if (fPerf) {Bool b = b = PerfTimerStop(pPerfTimer); assert(b);};
|
||||
#define PERFTIMER_GETRESULTS(fPerf, pPerfTimer, pResults) \
|
||||
if (fPerf) {Bool b = b = PerfTimerGetResults((pPerfTimer), (pResults)); assert(b);};
|
||||
#define PERFTIMER_COPYSTARTTIME(fPerf, pDst, pSrc) \
|
||||
if (fPerf) {Bool b = b = PerfTimerCopyStartTime((pDst), (pSrc)); assert(b);};
|
||||
#define PERFTIMER_REPORT(fPerf, pCodec) \
|
||||
if (fPerf) {OutputPerfTimerReport(pCodec);};
|
||||
#endif // DISABLE_PERF_MEASUREMENT
|
||||
|
||||
//***************************************************************************
|
||||
// Data Types
|
||||
//***************************************************************************
|
||||
typedef U64 PERFTIMERTIME;
|
||||
typedef struct PERFTIMERRESULTS
|
||||
{
|
||||
PERFTIMERTIME iElapsedTime; // In nanoseconds or CPU cycles
|
||||
PERFTIMERTIME iTicksPerSecond; // Number of ticks per second (clock frequency)
|
||||
PERFTIMERTIME iZeroTimeIntervals; // Number of zero-time intervals.
|
||||
// Presence of zero-time intervals may indicate insufficient clock precision
|
||||
} PERFTIMERRESULTS;
|
||||
|
||||
#define NANOSECONDS_PER_SECOND 1000000000
|
||||
|
||||
|
||||
//***************************************************************************
|
||||
// Data Declarations
|
||||
//***************************************************************************
|
||||
typedef enum
|
||||
{
|
||||
CS_UNINIT,
|
||||
CS_RUNNING,
|
||||
CS_STOPPED,
|
||||
} CLOCKSTATE;
|
||||
|
||||
typedef struct PERFTIMERSTATE
|
||||
{
|
||||
CLOCKSTATE eState;
|
||||
PERFTIMERTIME iElapsedTime;
|
||||
PERFTIMERTIME iPrevStartTime;
|
||||
PERFTIMERTIME iZeroTimeIntervals;
|
||||
} PERFTIMERSTATE;
|
||||
|
||||
|
||||
//***************************************************************************
|
||||
// Functions and Macros
|
||||
//***************************************************************************
|
||||
Bool PerfTimerNew(PERFTIMERSTATE **ppNewPerfTimer);
|
||||
void PerfTimerDelete(PERFTIMERSTATE *pThisPerfTimer);
|
||||
Bool PerfTimerStart(PERFTIMERSTATE *pThisPerfTimer);
|
||||
Bool PerfTimerStop(PERFTIMERSTATE *pThisPerfTimer);
|
||||
Bool PerfTimerGetResults(PERFTIMERSTATE *pThisPerfTimer,
|
||||
PERFTIMERRESULTS *pPerfTimerResults);
|
||||
Bool PerfTimerCopyStartTime(PERFTIMERSTATE *pDestPerfTimer,
|
||||
PERFTIMERSTATE *pSrcPerfTimer);
|
||||
|
||||
#endif // __PERFTIMER_H_
|
|
@ -0,0 +1,306 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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"
|
||||
|
||||
#define ORIENT_WEIGHT 4
|
||||
|
||||
/* reciprocal (pMantissa, exponent) lookup table */
|
||||
typedef struct tagQPManExp
|
||||
{
|
||||
int iMan;
|
||||
int iExp;
|
||||
} QPManExp;
|
||||
|
||||
static QPManExp gs_QPRecipTable[32] = {
|
||||
{0x0, 0}, // 0, invalid
|
||||
{0x0, 0}, // 1, lossless
|
||||
{0x0, 1}, // 2
|
||||
{0xaaaaaaab, 1},
|
||||
{0x0, 2}, // 4
|
||||
{0xcccccccd, 2},
|
||||
{0xaaaaaaab, 2},
|
||||
{0x92492493, 2},
|
||||
{0x0, 3}, // 8
|
||||
{0xe38e38e4, 3},
|
||||
{0xcccccccd, 3},
|
||||
{0xba2e8ba3, 3},
|
||||
{0xaaaaaaab, 3},
|
||||
{0x9d89d89e, 3},
|
||||
{0x92492493, 3},
|
||||
{0x88888889, 3},
|
||||
{0x0, 4}, // 16
|
||||
{0xf0f0f0f1, 4},
|
||||
{0xe38e38e4, 4},
|
||||
{0xd79435e6, 4},
|
||||
{0xcccccccd, 4},
|
||||
{0xc30c30c4, 4},
|
||||
{0xba2e8ba3, 4},
|
||||
{0xb21642c9, 4},
|
||||
{0xaaaaaaab, 4},
|
||||
{0xa3d70a3e, 4},
|
||||
{0x9d89d89e, 4},
|
||||
{0x97b425ee, 4},
|
||||
{0x92492493, 4},
|
||||
{0x8d3dcb09, 4},
|
||||
{0x88888889, 4},
|
||||
{0x84210843, 4},
|
||||
};
|
||||
|
||||
/*************************************************************************
|
||||
QPRemapping
|
||||
*************************************************************************/
|
||||
|
||||
Void remapQP(CWMIQuantizer * pQP, I32 iShift, Bool bScaledArith)
|
||||
{
|
||||
U8 uiQPIndex = pQP->iIndex;
|
||||
|
||||
if(uiQPIndex == 0) // Lossless mode!
|
||||
pQP->iQP = 1, pQP->iMan = pQP->iExp = pQP->iOffset = 0;
|
||||
else if (!bScaledArith) {
|
||||
I32 man = 0, exp = 0;
|
||||
const I32 ciShift = SHIFTZERO - (SHIFTZERO + QPFRACBITS); // == -QPFRACBITS
|
||||
|
||||
if (pQP->iIndex < 32)
|
||||
man = (pQP->iIndex + 3) >> 2, exp = ciShift + 2;
|
||||
else if (pQP->iIndex < 48)
|
||||
man = (16 + (pQP->iIndex & 0xf) + 1) >> 1, exp = ((pQP->iIndex >> 4) - 1) + 1 + ciShift;
|
||||
else
|
||||
man = 16 + (pQP->iIndex & 0xf), exp = ((pQP->iIndex >> 4) - 1) + ciShift;
|
||||
|
||||
pQP->iQP = man << exp;
|
||||
pQP->iMan = gs_QPRecipTable[man].iMan;
|
||||
pQP->iExp = gs_QPRecipTable[man].iExp + exp;
|
||||
pQP->iOffset = ((pQP->iQP * 3 + 1) >> 3);
|
||||
#if defined(WMP_OPT_QT)
|
||||
pQP->f1_QP = 1.0f / pQP->iQP;
|
||||
pQP->d1_QP = 1.0 / pQP->iQP;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
I32 man = 0, exp = 0;
|
||||
|
||||
if(pQP->iIndex < 16)
|
||||
man = pQP->iIndex, exp = iShift;
|
||||
else
|
||||
man = 16 + (pQP->iIndex & 0xf), exp = ((pQP->iIndex >> 4) - 1) + iShift;
|
||||
|
||||
pQP->iQP = man << exp;
|
||||
pQP->iMan = gs_QPRecipTable[man].iMan;
|
||||
pQP->iExp = gs_QPRecipTable[man].iExp + exp;
|
||||
pQP->iOffset = ((pQP->iQP * 3 + 1) >> 3);
|
||||
#if defined(WMP_OPT_QT)
|
||||
pQP->f1_QP = 1.0f / pQP->iQP;
|
||||
pQP->d1_QP = 1.0 / pQP->iQP;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* allocate PredInfo buffers */
|
||||
Int allocatePredInfo(CWMImageStrCodec *pSC)
|
||||
{
|
||||
size_t i, j;
|
||||
// COLORFORMAT cf = pSC->m_param.cfColorFormat;
|
||||
const size_t mbWidth = pSC->cmbWidth;
|
||||
const size_t iChannels = pSC->m_param.cNumChannels;
|
||||
CWMIPredInfo* pMemory;
|
||||
Bool b32Bit = sizeof(size_t) == 4;
|
||||
|
||||
if(b32Bit) // integer overlow/underflow check for 32-bit system
|
||||
if(((mbWidth >> 16) * iChannels * 2 * sizeof(CWMIPredInfo)) & 0xffff0000)
|
||||
return ICERR_ERROR;
|
||||
pMemory = (CWMIPredInfo *)malloc(mbWidth * iChannels * 2 * sizeof(CWMIPredInfo));
|
||||
if (pMemory == NULL)
|
||||
return ICERR_ERROR;
|
||||
|
||||
pSC->pPredInfoMemory = pMemory;
|
||||
for(i = 0; i < iChannels; i ++){
|
||||
pSC->PredInfo[i] = pMemory;
|
||||
pMemory += mbWidth;
|
||||
pSC->PredInfoPrevRow[i] = pMemory;
|
||||
pMemory += mbWidth;
|
||||
|
||||
for(j = 0; j < mbWidth; j ++){
|
||||
pSC->PredInfo[i][j].piAD = pSC->PredInfo[i][j].iAD;
|
||||
pSC->PredInfoPrevRow[i][j].piAD = pSC->PredInfoPrevRow[i][j].iAD;
|
||||
}
|
||||
}
|
||||
|
||||
return ICERR_OK;
|
||||
}
|
||||
|
||||
/* clear PredInfo buffers */
|
||||
Void freePredInfo(CWMImageStrCodec *pSC)
|
||||
{
|
||||
if (pSC->pPredInfoMemory)
|
||||
free (pSC->pPredInfoMemory);
|
||||
pSC->pPredInfoMemory = NULL;
|
||||
}
|
||||
|
||||
/* get AC prediction mode: 0(from left) 1(from top) 2(none) */
|
||||
Int getACPredMode(CWMIMBInfo * pMBInfo, COLORFORMAT cf)
|
||||
{
|
||||
//Int blkIdx = (cf == Y_ONLY ? 16 : (cf == YUV_420 ? 24 : (cf == YUV_422 ? 32 : 48)));
|
||||
PixelI * pCoeffs = pMBInfo->iBlockDC[0];
|
||||
Int StrH = abs(pCoeffs[1]) + abs(pCoeffs[2]) + abs(pCoeffs[3]);
|
||||
Int StrV = abs(pCoeffs[4]) + abs(pCoeffs[8]) + abs(pCoeffs[12]);
|
||||
|
||||
if(cf != Y_ONLY && cf != NCOMPONENT){
|
||||
PixelI * pCoeffsU = pMBInfo->iBlockDC[1];
|
||||
PixelI * pCoeffsV = pMBInfo->iBlockDC[2];
|
||||
|
||||
StrH += abs(pCoeffsU[1]) + abs(pCoeffsV[1]);
|
||||
if(cf == YUV_420){
|
||||
StrV += abs(pCoeffsU[2]) + abs(pCoeffsV[2]);
|
||||
}
|
||||
else if (cf == YUV_422){
|
||||
StrV += abs(pCoeffsU[2]) + abs(pCoeffsV[2]) + abs(pCoeffsU[6]) + abs(pCoeffsV[6]);
|
||||
StrH += abs(pCoeffsU[5]) + abs(pCoeffsV[5]);
|
||||
}
|
||||
else { // YUV_444 or CMYK
|
||||
StrV += abs(pCoeffsU[4]) + abs(pCoeffsV[4]);
|
||||
}
|
||||
}
|
||||
|
||||
return (StrH * ORIENT_WEIGHT < StrV ? 1 : (StrV * ORIENT_WEIGHT < StrH ? 0 : 2));
|
||||
}
|
||||
|
||||
/* get DCAC prediction mode: 0(from left) 1(from top) 2(none) */
|
||||
Int getDCACPredMode(CWMImageStrCodec *pSC, size_t mbX)
|
||||
{
|
||||
Int iDCMode, iADMode = 2; // DC: 0(left) 1(top) 2(mean) 3(no)
|
||||
// AD: 0(left) 1(top) 2(no)
|
||||
|
||||
if(pSC->m_bCtxLeft && pSC->m_bCtxTop){ // topleft corner, no prediction
|
||||
iDCMode = 3;
|
||||
}
|
||||
else if(pSC->m_bCtxLeft){
|
||||
iDCMode = 1; // left column, predict from top
|
||||
}
|
||||
else if(pSC->m_bCtxTop){
|
||||
iDCMode = 0; // top row, predict from left
|
||||
}
|
||||
else{
|
||||
COLORFORMAT cf = pSC->m_param.cfColorFormat;
|
||||
Int iL = pSC->PredInfo[0][mbX - 1].iDC, iT = pSC->PredInfoPrevRow[0][mbX].iDC, iTL = pSC->PredInfoPrevRow[0][mbX - 1].iDC;
|
||||
Int StrH, StrV;
|
||||
|
||||
if(cf == Y_ONLY || cf == NCOMPONENT){ // CMYK uses YUV metric
|
||||
StrH = abs(iTL - iL);
|
||||
StrV = abs(iTL - iT);
|
||||
}
|
||||
else{
|
||||
CWMIPredInfo * pTU = pSC->PredInfoPrevRow[1] + mbX, * pLU = pSC->PredInfo[1] + mbX - 1, * pTLU = pTU - 1;
|
||||
CWMIPredInfo * pTV = pSC->PredInfoPrevRow[2] + mbX, * pLV = pSC->PredInfo[2] + mbX - 1, * pTLV = pTV - 1;
|
||||
Int scale = (cf == YUV_420 ? 8 : (cf == YUV_422 ? 4 : 2));
|
||||
|
||||
StrH = abs(iTL - iL) * scale + abs(pTLU->iDC - pLU->iDC) + abs(pTLV->iDC - pLV->iDC);
|
||||
StrV = abs(iTL - iT) * scale + abs(pTLU->iDC - pTU->iDC) + abs(pTLV->iDC - pTV->iDC);
|
||||
}
|
||||
iDCMode = (StrH * ORIENT_WEIGHT < StrV ? 1 : (StrV * ORIENT_WEIGHT < StrH ? 0 : 2));
|
||||
}
|
||||
|
||||
if(iDCMode == 1 && pSC->MBInfo.iQIndexLP == pSC->PredInfoPrevRow[0][mbX].iQPIndex)
|
||||
iADMode = 1;
|
||||
if(iDCMode == 0 && pSC->MBInfo.iQIndexLP == pSC->PredInfo[0][mbX - 1].iQPIndex)
|
||||
iADMode = 0;
|
||||
|
||||
return (iDCMode + (iADMode << 2));
|
||||
}
|
||||
|
||||
Void copyAC(PixelI * src, PixelI * dst)
|
||||
{
|
||||
/* first row of ACs */
|
||||
dst[0] = src[1];
|
||||
dst[1] = src[2];
|
||||
dst[2] = src[3];
|
||||
|
||||
/* first column of ACs */
|
||||
dst[3] = src[4];
|
||||
dst[4] = src[8];
|
||||
dst[5] = src[12];
|
||||
}
|
||||
|
||||
/* info of current MB to be saved for future prediction */
|
||||
Void updatePredInfo(CWMImageStrCodec *pSC, CWMIMBInfo * pMBInfo, size_t mbX, COLORFORMAT cf)
|
||||
{
|
||||
CWMIPredInfo *pPredInfo;
|
||||
PixelI * p;
|
||||
Int i, iChannels = (cf == YUV_420 || cf == YUV_422) ? 1 : (Int) pSC->m_param.cNumChannels;
|
||||
|
||||
for(i = 0; i < iChannels; i ++){
|
||||
pPredInfo = pSC->PredInfo[i] + mbX;
|
||||
p = pMBInfo->iBlockDC[i];//[dcBlkIdx + i];
|
||||
|
||||
/* DC of DC block */
|
||||
pPredInfo->iDC = p[0];
|
||||
|
||||
/* QP Index */
|
||||
pPredInfo->iQPIndex = pMBInfo->iQIndexLP;
|
||||
|
||||
/* first row and first column of ACs of DC block */
|
||||
copyAC(p, pPredInfo->piAD);
|
||||
}
|
||||
|
||||
if(cf == YUV_420){ // 420 UV channels
|
||||
for(i = 1U; i < 3U; i ++){
|
||||
pPredInfo = pSC->PredInfo[i] + mbX;
|
||||
p = pMBInfo->iBlockDC[i];//[dcBlkIdx + i];
|
||||
|
||||
/* DC of DC block */
|
||||
pPredInfo->iDC = p[0];
|
||||
|
||||
/* QP Index */
|
||||
pPredInfo->iQPIndex = pMBInfo->iQIndexLP;
|
||||
/* first row and first column of ACs of DC block */
|
||||
pPredInfo->piAD[0] = p[1];
|
||||
pPredInfo->piAD[1] = p[2];
|
||||
}
|
||||
}
|
||||
else if(cf == YUV_422){ // 420 UV channels
|
||||
for(i = 1U; i < 3U; i ++){
|
||||
pPredInfo = pSC->PredInfo[i] + mbX;
|
||||
|
||||
/* QP Index */
|
||||
pPredInfo->iQPIndex = pMBInfo->iQIndexLP;
|
||||
|
||||
p = pMBInfo->iBlockDC[i];//[dcBlkIdx + i];
|
||||
|
||||
/* DC of DC block */
|
||||
pPredInfo->iDC = p[0];
|
||||
|
||||
/* first row and first column of ACs of first DC block */
|
||||
pPredInfo->piAD[0] = p[1];
|
||||
pPredInfo->piAD[1] = p[2];
|
||||
/* first row and first column of ACs of second DC block */
|
||||
pPredInfo->piAD[2] = p[5];
|
||||
pPredInfo->piAD[3] = p[6];
|
||||
pPredInfo->piAD[4] = p[4]; //AC of 1D HT!!!
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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 "strTransform.h"
|
||||
|
||||
/** need to swap b and c **/
|
||||
/** rounding behavior: [0 0 0 0] <-> [+ - - -]
|
||||
[+ + + +] <-> [+3/4 - - -]
|
||||
[- - - -] <-> [- - - -] **/
|
||||
Void strDCT2x2dn(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
|
||||
{
|
||||
PixelI a, b, c, d, C, t;
|
||||
a = *pa;
|
||||
b = *pb;
|
||||
C = *pc;
|
||||
d = *pd;
|
||||
|
||||
a += d;
|
||||
b -= C;
|
||||
t = ((a - b) >> 1);
|
||||
c = t - d;
|
||||
d = t - C;
|
||||
a -= d;
|
||||
b += c;
|
||||
|
||||
*pa = a;
|
||||
*pb = b;
|
||||
*pc = c;
|
||||
*pd = d;
|
||||
}
|
||||
|
||||
Void strDCT2x2up(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
|
||||
{
|
||||
PixelI a, b, c, d, C, t;
|
||||
a = *pa;
|
||||
b = *pb;
|
||||
C = *pc;
|
||||
d = *pd;
|
||||
|
||||
a += d;
|
||||
b -= C;
|
||||
t = ((a - b + 1) >> 1);
|
||||
c = t - d;
|
||||
d = t - C;
|
||||
a -= d;
|
||||
b += c;
|
||||
|
||||
*pa = a;
|
||||
*pb = b;
|
||||
*pc = c;
|
||||
*pd = d;
|
||||
}
|
||||
|
||||
Void FOURBUTTERFLY_HARDCODED1(PixelI *p)
|
||||
{
|
||||
strDCT2x2dn(&p[0], &p[4], &p[8], &p[12]);
|
||||
strDCT2x2dn(&p[1], &p[5], &p[9], &p[13]);
|
||||
strDCT2x2dn(&p[2], &p[6], &p[10], &p[14]);
|
||||
strDCT2x2dn(&p[3], &p[7], &p[11], &p[15]);
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//*@@@---@@@@******************************************************************
|
||||
|
||||
#ifndef WMI_STRTRANSFORM_H
|
||||
#define WMI_STRTRANSFORM_H
|
||||
|
||||
#include "windowsmediaphoto.h"
|
||||
|
||||
#define COMPUTE_CORNER_PRED_DIFF(a, b) (*(a) -= (b))
|
||||
#define COMPUTE_CORNER_PRED_ADD(a, b) (*(a) += (b))
|
||||
|
||||
/** 2x2 foward DCT == 2x2 inverse DCT **/
|
||||
Void strDCT2x2dn(PixelI *, PixelI *, PixelI *, PixelI *);
|
||||
Void strDCT2x2up(PixelI *, PixelI *, PixelI *, PixelI *);
|
||||
Void FOURBUTTERFLY_HARDCODED1(PixelI *p);
|
||||
|
||||
/** 2x2 dct of a group of 4**/
|
||||
#define FOURBUTTERFLY(p, i00, i01, i02, i03, i10, i11, i12, i13,\
|
||||
i20, i21, i22, i23, i30, i31, i32, i33) \
|
||||
strDCT2x2dn(&p[i00], &p[i01], &p[i02], &p[i03]); \
|
||||
strDCT2x2dn(&p[i10], &p[i11], &p[i12], &p[i13]); \
|
||||
strDCT2x2dn(&p[i20], &p[i21], &p[i22], &p[i23]); \
|
||||
strDCT2x2dn(&p[i30], &p[i31], &p[i32], &p[i33])
|
||||
|
||||
#endif // WMI_STRTRANSFORM_H
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,678 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//*@@@---@@@@******************************************************************
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "windowsmediaphoto.h"
|
||||
#include "common.h"
|
||||
// #include "xplatform_image.h"
|
||||
|
||||
// added for Xcode PK universal binary
|
||||
#ifdef __ppc__
|
||||
#define _BIG__ENDIAN_
|
||||
#endif
|
||||
|
||||
//================================================================
|
||||
#ifdef ENABLE_OPTIMIZATIONS
|
||||
#if defined(WIN32) && !defined(_WIN64)
|
||||
#define WMP_OPT_SSE2
|
||||
|
||||
#define WMP_OPT_CC_ENC
|
||||
//#define WMP_OPT_TRFM_ENC
|
||||
//#define WMP_OPT_QT
|
||||
|
||||
#define WMP_OPT_CC_DEC
|
||||
#define WMP_OPT_TRFM_DEC
|
||||
|
||||
#define X86OPT_INLINE
|
||||
|
||||
#endif
|
||||
#endif // ENABLE_OPTIMIZATIONS
|
||||
|
||||
//================================================================
|
||||
//#ifdef WIN32
|
||||
#if defined(WIN32) && !defined(UNDER_CE) // WIN32 seems to be defined always in VS2005 for ARM platform
|
||||
#define PLATFORM_X86
|
||||
#include "../x86/x86.h"
|
||||
#endif
|
||||
|
||||
#ifndef UNREFERENCED_PARAMETER
|
||||
#define UNREFERENCED_PARAMETER(P) { (P) = (P); }
|
||||
#endif
|
||||
|
||||
#ifdef UNDER_CE
|
||||
#define PLATFORM_WCE
|
||||
#include "arm.h"
|
||||
#endif
|
||||
|
||||
#ifdef __ANSI__
|
||||
#define PLATFORM_ANSI
|
||||
#include "ansi.h"
|
||||
#endif
|
||||
|
||||
//================================================================
|
||||
|
||||
#ifdef PLATFORM_ANSI
|
||||
typedef unsigned long long U64;
|
||||
#else // PLATFORM_ANSI
|
||||
typedef unsigned __int64 U64;
|
||||
#endif // PLATFORM_ANSI
|
||||
|
||||
//================================================================
|
||||
#define MARKERCOUNT (PACKETLENGTH * 2)
|
||||
|
||||
// The following macros depend on UINTPTR_T and INTPTR_T being properly defined
|
||||
// so that they are equal to pointer width. Confirm and fail if our assumptions are wrong.
|
||||
CT_ASSERT(sizeof(UINTPTR_T) == sizeof(void*), strcodec1);
|
||||
CT_ASSERT(sizeof(INTPTR_T) == sizeof(void*), strcodec2);
|
||||
|
||||
// wrap around pointer, s=pow(2,n), p wraps aligned to s
|
||||
#define WRAPPTR(p, s) ((void*)((UINTPTR_T)(p) & ~(UINTPTR_T)(s)))
|
||||
|
||||
// mask certain bit inside a pointer, simulate wrap around
|
||||
#define MASKPTR(p, m) ((void*)((UINTPTR_T)(p) & (INTPTR_T)(m)))
|
||||
|
||||
// test for more than 1 packet data
|
||||
#define PACKET1(ps, pc, s) (((INTPTR_T)(ps) ^ (INTPTR_T)(pc)) & ((UINTPTR_T)(s)))
|
||||
|
||||
// alternate pointer p between 2 values aligned to s, s=pow(2,n)
|
||||
//#define ALTPTR(p, s) ((void*)((uintptr_t)(p) ^ (s)))
|
||||
|
||||
// align point, s=pow(2,n), p aligns to s
|
||||
#define ALIGNUP(p, s) ((void*)(((UINTPTR_T)(p) + ((UINTPTR_T)(s) - 1)) & ~((UINTPTR_T)(s) - 1)))
|
||||
#define ALIGNDOWN(p, s) ((void*)((UINTPTR_T)(p) & ~((UINTPTR_T)(s) - 1)))
|
||||
|
||||
//================================================================
|
||||
// timer support
|
||||
//================================================================
|
||||
|
||||
#define TraceResult(a)
|
||||
|
||||
//================================================================
|
||||
typedef enum tagPacketType
|
||||
{
|
||||
PK_NULL = 0,
|
||||
PK_DC = 1, PK_AD, PK_AC, PK_CP,
|
||||
PK_MAX,
|
||||
} PACKETTYPE;
|
||||
|
||||
typedef struct tagIOContext
|
||||
{
|
||||
U8 P0[PACKETLENGTH]; // packet circular buffer 0
|
||||
U8 P1[PACKETLENGTH]; // packet circular buffer 1
|
||||
|
||||
union
|
||||
{
|
||||
U8 P2[PACKETLENGTH];
|
||||
struct
|
||||
{
|
||||
U32 uiShadow; // shadow of P0[0]-P0[3]
|
||||
|
||||
U32 uiAccumulator; // 32bit acc as bit field cache
|
||||
U32 cBitsUsed; // # of bits used of acc, [0,16)
|
||||
|
||||
U8* pbPacket; // packet pointer
|
||||
U8* pbCurrent; // current pointer
|
||||
|
||||
struct WMPStream* pWS; // pointer to WMPStream
|
||||
long offPacket; // byte offset into stream
|
||||
|
||||
//ULARGE_INTEGER u64Acc;
|
||||
|
||||
//========================================
|
||||
// index packet, used for packet retrieval
|
||||
//========================================
|
||||
U32 cIndex; // current index for index packet
|
||||
long offIndex; // byte offset into stream for index packet
|
||||
}State;
|
||||
}P2Info;
|
||||
U8 P3[PACKETLENGTH]; // index packet buffer
|
||||
} IOContext;
|
||||
|
||||
typedef struct tagMemReadState
|
||||
{
|
||||
U8* pbBuf;
|
||||
size_t cbBuf;
|
||||
size_t cbCur;
|
||||
} MemReadState;
|
||||
|
||||
typedef struct tagBitIOInfo
|
||||
{
|
||||
U32 uiShadow; // shadow of first 4B of circular buffer
|
||||
|
||||
U32 uiAccumulator; // 32bit acc as bit field cache
|
||||
U32 cBitsUsed; // # of bits used of acc, [0,16)
|
||||
#ifdef ARMOPT_BITIO
|
||||
U32 cBitsUnused; // # of bits remain unused in acc, [0,32]
|
||||
#endif
|
||||
|
||||
I32 iMask; // mask used simulate pointer wrap around
|
||||
|
||||
U8* pbStart; // start pointer
|
||||
#ifndef ARMOPT_BITIO
|
||||
U8* pbCurrent; // current pointer
|
||||
#else
|
||||
U32* pbCurrent; // current pointer
|
||||
#endif
|
||||
|
||||
struct WMPStream* pWS; // pointer to WMPStream
|
||||
size_t offRef; // reference offset on IStream,
|
||||
// for read, it moves along the stream
|
||||
// for write, it stays at the attach point
|
||||
} BitIOInfo;
|
||||
|
||||
//================================================================
|
||||
typedef struct tagCWMIQuantizer {
|
||||
U8 iIndex;
|
||||
I32 iQP;
|
||||
I32 iOffset;
|
||||
I32 iMan;
|
||||
I32 iExp;
|
||||
#if defined(WMP_OPT_QT)
|
||||
float f1_QP;
|
||||
double d1_QP;
|
||||
#endif
|
||||
} CWMIQuantizer;
|
||||
|
||||
/* temporary bridge between old APIs and streaming APIs */
|
||||
typedef struct tagCWMIMBInfo {
|
||||
I32 iBlockDC[MAX_CHANNELS][16];
|
||||
I32 iOrientation;
|
||||
Int iCBP[MAX_CHANNELS];
|
||||
Int iDiffCBP[MAX_CHANNELS];
|
||||
U8 iQIndexLP; // 0 - 15
|
||||
U8 iQIndexHP; // 0 - 15
|
||||
} CWMIMBInfo;
|
||||
|
||||
struct CWMImageStrCodec;
|
||||
|
||||
typedef Int (*ImageDataProc)(struct CWMImageStrCodec*);
|
||||
|
||||
/** scan model **/
|
||||
typedef struct CAdaptiveScan {
|
||||
U32 uTotal;
|
||||
U32 uScan;
|
||||
} CAdaptiveScan;
|
||||
|
||||
/** Adaptive context model **/
|
||||
typedef struct CCodingContext {
|
||||
BitIOInfo * m_pIODC;
|
||||
BitIOInfo * m_pIOLP;
|
||||
BitIOInfo * m_pIOAC;
|
||||
BitIOInfo * m_pIOFL;
|
||||
|
||||
/** adaptive huffman structs **/
|
||||
CAdaptiveHuffman *m_pAdaptHuffCBPCY;
|
||||
CAdaptiveHuffman *m_pAdaptHuffCBPCY1;
|
||||
CAdaptiveHuffman *m_pAHexpt[NUMVLCTABLES];
|
||||
|
||||
/** 4x4 zigzag patterns */
|
||||
CAdaptiveScan m_aScanLowpass[16];
|
||||
CAdaptiveScan m_aScanHoriz[16];
|
||||
CAdaptiveScan m_aScanVert[16];
|
||||
|
||||
/** Adaptive bit reduction model **/
|
||||
CAdaptiveModel m_aModelAC;
|
||||
CAdaptiveModel m_aModelLP;
|
||||
CAdaptiveModel m_aModelDC;
|
||||
|
||||
/** Adaptive lowpass CBP model **/
|
||||
Int m_iCBPCountZero;
|
||||
Int m_iCBPCountMax;
|
||||
|
||||
/** Adaptive AC CBP model **/
|
||||
CCBPModel m_aCBPModel;
|
||||
|
||||
/** Trim flex bits - externally set **/
|
||||
Int m_iTrimFlexBits;
|
||||
|
||||
Bool m_bInROI; // inside ROI (for region decode and compressed domain cropping)?
|
||||
} CCodingContext;
|
||||
|
||||
// Following stuff used to be in strPredQuant.h
|
||||
/* circulant buffer for 2 MB rows: current row and previous row */
|
||||
typedef struct tagCWMIPredInfo {
|
||||
Int iQPIndex; // QP Index
|
||||
Int iCBP; // coded block pattern
|
||||
PixelI iDC; // DC of MB
|
||||
PixelI iAD[6];
|
||||
PixelI * piAD; // AC of DC block: [2] 420UV [4] 422UV [6] elsewhere
|
||||
}CWMIPredInfo;
|
||||
|
||||
// the following is used on decode side while reading image info
|
||||
typedef struct CWMImageStrCodecParameters {
|
||||
size_t cVersion;
|
||||
size_t cSubVersion;
|
||||
COLORFORMAT cfColorFormat; // color format
|
||||
Bool bRBSwapped; // blue and red shall be swapped in BGR555,565,101010
|
||||
Bool bAlphaChannel; // alpha channel present
|
||||
Bool bScaledArith; // lossless mode
|
||||
Bool bIndexTable; // index table present
|
||||
Bool bTrimFlexbitsFlag; // trimmed flexbits indicated in packet header
|
||||
Bool bUseHardTileBoundaries; //default is soft tile boundaries
|
||||
size_t cNumChannels;
|
||||
size_t cExtraPixelsTop;
|
||||
size_t cExtraPixelsLeft;
|
||||
size_t cExtraPixelsBottom;
|
||||
size_t cExtraPixelsRight;
|
||||
Bool bTranscode; // transcoding flag
|
||||
U32 uQPMode; // 0/1: no dquant/with dquant, first bit for DC, second bit for LP, third bit for HP
|
||||
U8 uiQPIndexDC[MAX_CHANNELS];
|
||||
U8 uiQPIndexLP[MAX_CHANNELS];
|
||||
U8 uiQPIndexHP[MAX_CHANNELS];
|
||||
}CCoreParameters;
|
||||
|
||||
typedef struct CWMITile
|
||||
{
|
||||
CWMIQuantizer * pQuantizerDC[MAX_CHANNELS];
|
||||
CWMIQuantizer * pQuantizerLP[MAX_CHANNELS];
|
||||
CWMIQuantizer * pQuantizerHP[MAX_CHANNELS];
|
||||
U8 cNumQPLP;
|
||||
U8 cNumQPHP;
|
||||
U8 cBitsLP;
|
||||
U8 cBitsHP;
|
||||
|
||||
Bool bUseDC;
|
||||
Bool bUseLP;
|
||||
U8 cChModeDC;
|
||||
U8 cChModeLP[16];
|
||||
U8 cChModeHP[16];
|
||||
} CWMITile;
|
||||
|
||||
#ifdef ARMOPT_COLORCONVERSION_C
|
||||
#include "ARM_InvColorConversion.h"
|
||||
#endif
|
||||
|
||||
struct tagPostProcInfo{
|
||||
Int iMBDC; // DC of MB
|
||||
U8 ucMBTexture; // MB texture : 0(flat) 1(horizontal) 2(vertical) 3(bumpy)
|
||||
Int iBlockDC[4][4]; // DC of block
|
||||
U8 ucBlockTexture[4][4]; // block texture: 0(flat) 1(horizontal) 2(vertical) 3(bumpy)
|
||||
};
|
||||
|
||||
typedef struct CWMImageStrCodec {
|
||||
#ifdef ARMOPT_COLORCONVERSION_C
|
||||
CWMImageStrInvCCParam InvCCParam;
|
||||
#endif
|
||||
|
||||
size_t cbStruct;
|
||||
|
||||
CWMImageInfo WMII;
|
||||
CWMIStrCodecParam WMISCP;
|
||||
CWMImageBufferInfo WMIBI;
|
||||
CWMIMBInfo MBInfo;
|
||||
|
||||
/** core parameters **/
|
||||
CCoreParameters m_param;
|
||||
|
||||
struct CWMDecoderParameters *m_Dparam; // this is specified thru pointer because the same set of parameters may be used by multiple image planes
|
||||
|
||||
U8 cSB;
|
||||
|
||||
Bool m_bUVResolutionChange;
|
||||
|
||||
Bool bTileExtraction;
|
||||
|
||||
BitIOInfo * pIOHeader;
|
||||
|
||||
Bool bUseHardTileBoundaries; //default is soft tile boundaries
|
||||
|
||||
PixelI * pInterU;
|
||||
PixelI * pInterV;
|
||||
|
||||
//============== tile related info begins here ===========
|
||||
// index table
|
||||
size_t *pIndexTable;
|
||||
|
||||
// current tile position
|
||||
size_t cTileRow;
|
||||
size_t cTileColumn;
|
||||
|
||||
// tile boundary
|
||||
Bool m_bCtxLeft;
|
||||
Bool m_bCtxTop;
|
||||
|
||||
Bool m_bResetRGITotals;
|
||||
Bool m_bResetContext;
|
||||
|
||||
CWMITile * pTile;
|
||||
|
||||
// BitIOs
|
||||
BitIOInfo ** m_ppBitIO;
|
||||
size_t cNumBitIO;
|
||||
size_t cHeaderSize;
|
||||
|
||||
// coding contexts
|
||||
struct CCodingContext *m_pCodingContext;
|
||||
size_t cNumCodingContext;
|
||||
|
||||
//============== tile related info ends here ===========
|
||||
|
||||
size_t cNumOfQPIndex; // number of QP indexes
|
||||
U8 cBitsDQUANT; // number of bits to encode DQUANT
|
||||
|
||||
size_t cRow; // row for current macro block
|
||||
size_t cColumn; // column for current macro block
|
||||
|
||||
size_t cmbWidth; // macro block/image width
|
||||
size_t cmbHeight; // macro block/image height
|
||||
|
||||
size_t cbChannel; // byte/channel
|
||||
|
||||
size_t mbX, mbY;
|
||||
size_t tileX, tileY;
|
||||
Bool bVertTileBoundary, bHoriTileBoundary;
|
||||
Bool bOneMBLeftVertTB, bOneMBRightVertTB; //Macroblock to the left and to the right of tile boundaries
|
||||
|
||||
PixelI iPredBefore[2][2];
|
||||
PixelI iPredAfter[2][2];
|
||||
|
||||
//================================
|
||||
// input data into
|
||||
// macro block 3 of 2x2 working widow
|
||||
//================================
|
||||
ImageDataProc Load;
|
||||
//ImageDataProc Load2;
|
||||
ImageDataProc Transform;
|
||||
ImageDataProc TransformCenter;
|
||||
|
||||
//================================
|
||||
ImageDataProc Quantize;
|
||||
//ImageDataProc QuantizeLuma;
|
||||
//ImageDataProc QuantizeChroma;
|
||||
|
||||
//================================
|
||||
// process and store data from
|
||||
// macro block 0 of 2x2 working window
|
||||
//================================
|
||||
ImageDataProc ProcessTopLeft;
|
||||
ImageDataProc ProcessTop;
|
||||
ImageDataProc ProcessTopRight;
|
||||
ImageDataProc ProcessLeft;
|
||||
ImageDataProc ProcessCenter;
|
||||
ImageDataProc ProcessRight;
|
||||
ImageDataProc ProcessBottomLeft;
|
||||
ImageDataProc ProcessBottom;
|
||||
ImageDataProc ProcessBottomRight;
|
||||
|
||||
|
||||
//================================
|
||||
// 2 MB working window for encoder
|
||||
//================================
|
||||
PixelI *pPlane[MAX_CHANNELS];
|
||||
|
||||
//================================
|
||||
// 2 rows of MB buffer
|
||||
//================================
|
||||
PixelI *a0MBbuffer[MAX_CHANNELS]; // pointer to start of previous MB row
|
||||
PixelI *a1MBbuffer[MAX_CHANNELS]; // pointer to start of current MB row
|
||||
PixelI *p0MBbuffer[MAX_CHANNELS]; // working pointer to start of previous row MB
|
||||
PixelI *p1MBbuffer[MAX_CHANNELS]; // working pointer to start of current row MB
|
||||
|
||||
//================================
|
||||
// downsampling buffer for UV
|
||||
//================================
|
||||
PixelI * pResU;
|
||||
PixelI * pResV;
|
||||
|
||||
//================================
|
||||
// circular buffer for 2 MB rows: current row and previous row
|
||||
//================================
|
||||
CWMIPredInfo *PredInfo[MAX_CHANNELS];
|
||||
CWMIPredInfo *PredInfoPrevRow[MAX_CHANNELS];
|
||||
CWMIPredInfo *pPredInfoMemory;
|
||||
|
||||
struct WMPStream ** ppWStream;
|
||||
|
||||
#ifdef _WINDOWS_
|
||||
TCHAR **ppTempFile;
|
||||
#else
|
||||
char **ppTempFile;
|
||||
#endif
|
||||
|
||||
// interleaved alpha support - linked structure for Alpha channel
|
||||
struct CWMImageStrCodec *m_pNextSC;
|
||||
Bool m_bSecondary;
|
||||
|
||||
//================================
|
||||
// Perf Timers
|
||||
//================================
|
||||
#ifndef DISABLE_PERF_MEASUREMENT
|
||||
Bool m_fMeasurePerf;
|
||||
struct PERFTIMERSTATE *m_ptEndToEndPerf; // Measures from Init to Term, including I/O
|
||||
struct PERFTIMERSTATE *m_ptEncDecPerf; // Measures time spent in ImageStrEncEncode/ImageStrDecDecode, excluding I/O
|
||||
#endif // DISABLE_PERF_MEASUREMENT
|
||||
|
||||
// postproc information for 2 MB rows: 0(previous row) 1(current row)
|
||||
struct tagPostProcInfo * pPostProcInfo[MAX_CHANNELS][2];
|
||||
} CWMImageStrCodec;
|
||||
|
||||
|
||||
//================================================================
|
||||
ERR WMPAlloc(void** ppv, size_t cb);
|
||||
ERR WMPFree(void** ppv);
|
||||
|
||||
//================================================================
|
||||
Void initMRPtr(CWMImageStrCodec*);
|
||||
Void advanceMRPtr(CWMImageStrCodec*);
|
||||
Void swapMRPtr(CWMImageStrCodec*);
|
||||
|
||||
Int IDPEmpty(CWMImageStrCodec*);
|
||||
|
||||
//================================================================
|
||||
extern const int dctIndex[3][16];
|
||||
extern const int blkOffset[16];
|
||||
extern const int blkOffsetUV[4];
|
||||
extern const int blkOffsetUV_422[8];
|
||||
|
||||
extern const U8 idxCC[16][16];
|
||||
extern const U8 idxCC_420[8][8];
|
||||
|
||||
extern const Char gGDISignature[];
|
||||
|
||||
//================================================================
|
||||
Int allocatePredInfo(CWMImageStrCodec*);
|
||||
Void freePredInfo(CWMImageStrCodec*);
|
||||
Void advanceOneMBRow(CWMImageStrCodec*);
|
||||
|
||||
//================================================================
|
||||
// bit I/O
|
||||
//================================================================
|
||||
Int allocateBitIOInfo(CWMImageStrCodec*);
|
||||
Int setBitIOPointers(CWMImageStrCodec* pSC);
|
||||
|
||||
#ifndef ARMOPT_BITIO
|
||||
U32 peekBit16(BitIOInfo* pIO, U32 cBits);
|
||||
U32 flushBit16(BitIOInfo* pIO, U32 cBits);
|
||||
U32 getBit16(BitIOInfo* pIO, U32 cBits);
|
||||
U32 getBool16(BitIOInfo* pIO);
|
||||
I32 getBit16s(BitIOInfo* pIO, U32 cBits);
|
||||
U32 getBit32(BitIOInfo* pIO, U32 cBits);
|
||||
U32 flushToByte(BitIOInfo* pIO);
|
||||
#endif // ARMOPT_BITIO
|
||||
|
||||
Void putBit16z(BitIOInfo* pIO, U32 uiBits, U32 cBits);
|
||||
Void putBit16(BitIOInfo* pIO, U32 uiBits, U32 cBits);
|
||||
Void putBit32(BitIOInfo* pIO, U32 uiBits, U32 cBits);
|
||||
Void fillToByte(BitIOInfo* pIO);
|
||||
|
||||
U32 getSizeRead(BitIOInfo* pIO);
|
||||
U32 getSizeWrite(BitIOInfo* pIO);
|
||||
|
||||
U32 getPosRead(BitIOInfo* pIO);
|
||||
|
||||
// safe function, solely for the convenience of test code
|
||||
#ifndef ARMOPT_BITIO
|
||||
U32 getBit16_S(CWMImageStrCodec* pSC, BitIOInfo* pIO, U32 cBits);
|
||||
#endif // ARMOPT_BITIO
|
||||
|
||||
//================================================================
|
||||
// packet I/O
|
||||
//================================================================
|
||||
ERR attachISRead(BitIOInfo* pIO, struct WMPStream* pWS, CWMImageStrCodec* pSC);
|
||||
ERR readIS(CWMImageStrCodec* pSC, BitIOInfo* pIO);
|
||||
ERR detachISRead(CWMImageStrCodec* pSC, BitIOInfo* pIO);
|
||||
|
||||
ERR attachISWrite(BitIOInfo* pIO, struct WMPStream* pWS);
|
||||
ERR writeIS(CWMImageStrCodec* pSC, BitIOInfo* pIO);
|
||||
ERR detachISWrite(CWMImageStrCodec* pSC, BitIOInfo* pIO);
|
||||
|
||||
|
||||
//================================================================
|
||||
// post processing for decoder
|
||||
//================================================================
|
||||
Int initPostProc(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], size_t mbWidth, size_t iNumChannels);
|
||||
Void termPostProc(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], size_t iNumChannels);
|
||||
Void slideOneMBRow(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], size_t iNumChannels, size_t mbWidth, Bool top, Bool bottom);
|
||||
Void updatePostProcInfo(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], PixelI * p, size_t mbX, size_t cc);
|
||||
Void postProcMB(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], PixelI * p0, PixelI * p1, size_t mbX, size_t cc, Int threshold);
|
||||
Void postProcBlock(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], PixelI * p0, PixelI * p1, size_t mbX, size_t cc, Int threshold);
|
||||
|
||||
//================================================================
|
||||
// Simple BitIO access functions
|
||||
//================================================================
|
||||
typedef struct tagSimpleBitIO
|
||||
{
|
||||
struct WMPStream* pWS;
|
||||
U32 cbRead;
|
||||
U8 bAccumulator;
|
||||
U32 cBitLeft;
|
||||
} SimpleBitIO;
|
||||
|
||||
ERR attach_SB(SimpleBitIO* pSB, struct WMPStream* pWS);
|
||||
U32 getBit32_SB(SimpleBitIO* pSB, U32 cBits);
|
||||
Void flushToByte_SB(SimpleBitIO* pSB);
|
||||
U32 getByteRead_SB(SimpleBitIO* pSB);
|
||||
ERR detach_SB(SimpleBitIO* pSB);
|
||||
|
||||
//----------------------------------------------------------------
|
||||
EXTERN_C Bool EOSWS_File(struct WMPStream* pWS);
|
||||
|
||||
EXTERN_C ERR ReadWS_File(struct WMPStream* pWS, void* pv, size_t cb);
|
||||
EXTERN_C ERR WriteWS_File(struct WMPStream* pWS, const void* pv, size_t cb);
|
||||
//EXTERN_C ERR GetLineWS_File(struct WMPStream* pWS, void* pv, size_t cb);
|
||||
|
||||
EXTERN_C ERR SetPosWS_File(struct WMPStream* pWS, size_t offPos);
|
||||
EXTERN_C ERR GetPosWS_File(struct WMPStream* pWS, size_t* poffPos);
|
||||
|
||||
//----------------------------------------------------------------
|
||||
EXTERN_C Bool EOSWS_Memory(struct WMPStream* pWS);
|
||||
|
||||
EXTERN_C ERR ReadWS_Memory(struct WMPStream* pWS, void* pv, size_t cb);
|
||||
EXTERN_C ERR WriteWS_Memory(struct WMPStream* pWS, const void* pv, size_t cb);
|
||||
//EXTERN_C ERR GetLineWS_Memory(struct WMPStream* pWS, void* pv, size_t cb);
|
||||
|
||||
EXTERN_C ERR SetPosWS_Memory(struct WMPStream* pWS, size_t offPos);
|
||||
EXTERN_C ERR GetPosWS_Memory(struct WMPStream* pWS, size_t* poffPos);
|
||||
|
||||
//EXTERN_C ERR GetPtrWS_Memory(struct WMPStream* pWS, size_t align, U8** ppb);
|
||||
//----------------------------------------------------------------
|
||||
EXTERN_C Bool EOSWS_List(struct WMPStream* pWS);
|
||||
|
||||
EXTERN_C ERR ReadWS_List(struct WMPStream* pWS, void* pv, size_t cb);
|
||||
EXTERN_C ERR WriteWS_List(struct WMPStream* pWS, const void* pv, size_t cb);
|
||||
|
||||
EXTERN_C ERR SetPosWS_List(struct WMPStream* pWS, size_t offPos);
|
||||
EXTERN_C ERR GetPosWS_List(struct WMPStream* pWS, size_t* poffPos);
|
||||
|
||||
EXTERN_C ERR CreateWS_List(struct WMPStream** ppWS);
|
||||
EXTERN_C ERR CloseWS_List(struct WMPStream** ppWS);
|
||||
|
||||
/********************************************************************/
|
||||
// Stuff related to scale/spatial ordering
|
||||
typedef struct PacketInfo
|
||||
{
|
||||
BAND m_iBand;
|
||||
size_t m_iSize;
|
||||
size_t m_iOffset;
|
||||
struct PacketInfo *m_pNext;
|
||||
} PacketInfo;
|
||||
/********************************************************************/
|
||||
|
||||
/********************************************************************/
|
||||
const static Int blkIdxByRow[4][4] = {{0, 1, 4, 5}, {2, 3, 6, 7}, {8, 9, 12, 13}, {10, 11, 14, 15}};
|
||||
const static Int blkIdxByColumn[4][4] = {{0, 2, 8, 10}, {1, 3, 9, 11},{4, 6, 12, 14},{5, 7, 13, 15}};
|
||||
|
||||
Int getACPredMode(CWMIMBInfo *, COLORFORMAT);
|
||||
Int getDCACPredMode(CWMImageStrCodec *, size_t);
|
||||
Void updatePredInfo(CWMImageStrCodec* pSC, CWMIMBInfo *, size_t, COLORFORMAT);
|
||||
|
||||
Int AllocateCodingContextDec(struct CWMImageStrCodec *pSC, Int iNumContexts);
|
||||
Void ResetCodingContext(CCodingContext *pContext);
|
||||
Void getTilePos(CWMImageStrCodec* pSC, size_t mbX, size_t mbY);
|
||||
Void InitZigzagScan(CCodingContext * pSC);
|
||||
Int checkImageBuffer(CWMImageStrCodec *, size_t, size_t);
|
||||
|
||||
//U32 log2(U32);
|
||||
|
||||
//DQUANT stuff
|
||||
EXTERN_C Void remapQP(CWMIQuantizer *, I32, Bool);
|
||||
Int allocateTileInfo(CWMImageStrCodec *);
|
||||
Void freeTileInfo(CWMImageStrCodec *);
|
||||
Int allocateQuantizer(CWMIQuantizer * pQuantizer[MAX_CHANNELS], size_t, size_t);
|
||||
Void freeQuantizer(CWMIQuantizer * pQuantizer[MAX_CHANNELS]);
|
||||
Void setUniformQuantizer(CWMImageStrCodec *, size_t);
|
||||
Void useDCQuantizer(CWMImageStrCodec *, size_t);
|
||||
Void useLPQuantizer(CWMImageStrCodec *, size_t, size_t);
|
||||
Void formatQuantizer(CWMIQuantizer * pQuantizer[MAX_CHANNELS], U8, size_t, size_t, Bool, Bool);
|
||||
U8 dquantBits(U8);
|
||||
|
||||
#ifdef ARMOPT_BITIO
|
||||
#define peekBit16 peekBits
|
||||
#define flushBit16 flushBits
|
||||
#define getBit16 getBits
|
||||
#define getBit32 getBits
|
||||
#define getBit16s getBitsS
|
||||
#define getBool16(pIO) getBits(pIO, 1)
|
||||
|
||||
U32 peekBits(BitIOInfo* pIO, U32 cBits);
|
||||
void flushBits(BitIOInfo* pIO, U32 cBits);
|
||||
U32 getBits(BitIOInfo* pIO, U32 cBits);
|
||||
U32 getBitsS(BitIOInfo* pIO, U32 cBits);
|
||||
void flushToByte(BitIOInfo* pIO);
|
||||
#endif // ARMOPT_BITIO
|
||||
|
||||
/*************************************************************************
|
||||
Bitio defines
|
||||
*************************************************************************/
|
||||
#define PEEKBIT16(pIO, cBits) \
|
||||
assert(0 <= (I32)cBits && cBits <= 16);\
|
||||
return (pIO->uiAccumulator >> (32 - cBits/* - pIO->cBitsUsed*/));
|
||||
|
||||
#define FLUSHBIT16(pIO, cBits) \
|
||||
assert(0 <= (I32)cBits && cBits <= 16);\
|
||||
assert((pIO->iMask & 1) == 0);\
|
||||
pIO->cBitsUsed += cBits;\
|
||||
pIO->pbCurrent = MASKPTR(pIO->pbCurrent + ((pIO->cBitsUsed >> 3)/* & 2*/), pIO->iMask);\
|
||||
pIO->cBitsUsed &= 16 - 1;\
|
||||
pIO->uiAccumulator = LOAD16(pIO->pbCurrent) << pIO->cBitsUsed;\
|
||||
return 0;
|
||||
// pIO->uiAccumulator = LOAD16(pIO->pbCurrent) & ((U32)(-1) >> pIO->cBitsUsed);\
|
||||
|
||||
void OutputPerfTimerReport(CWMImageStrCodec *pState);
|
|
@ -0,0 +1,515 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//*@@@---@@@@******************************************************************
|
||||
|
||||
#ifndef WMI_WINDOWSMEDIAPHOTO_H
|
||||
#define WMI_WINDOWSMEDIAPHOTO_H
|
||||
|
||||
//================================================================
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(__cplusplus) && !defined(EXTERN_C)
|
||||
#define EXTERN_C extern "C"
|
||||
#elif !defined(EXTERN_C)// __cplusplus
|
||||
#define EXTERN_C extern
|
||||
#endif // __cplusplus
|
||||
|
||||
/********************************************************************************
|
||||
Type definitions
|
||||
********************************************************************************/
|
||||
typedef int Bool;
|
||||
typedef char Char;
|
||||
typedef double Double;
|
||||
typedef int Int;
|
||||
typedef signed char I8;
|
||||
typedef short I16; // 16 bit int
|
||||
typedef int I32;
|
||||
typedef long Long;
|
||||
typedef unsigned char PixelC;
|
||||
typedef int PixelI;
|
||||
typedef unsigned int UInt;
|
||||
typedef unsigned long ULong;
|
||||
typedef unsigned char U8; // 8 bit uint
|
||||
typedef unsigned short U16;
|
||||
typedef unsigned int U32; // 32 bit uint
|
||||
typedef void Void;
|
||||
|
||||
typedef void* CTXSTRCODEC;
|
||||
|
||||
|
||||
#define REENTRANT_MODE 1
|
||||
/*
|
||||
DESCRIPTION OF COMPILER FLAG REENTRANT_MODE:
|
||||
|
||||
//#define REENTRANT_MODE 1
|
||||
|
||||
This compiler flag is related to the capability of banded decode
|
||||
(decoding only one MB row of the source JPEG XR image at a time).
|
||||
|
||||
With REENTRANT_MODE defined, the decoder decodes one MB row on each call to
|
||||
ImageStrDecDecode().
|
||||
|
||||
The decoder acts as if it can only write to the single MBRow whose pointer was passed to it.
|
||||
This acts as a proof of concept that the API would work if you passed it a small buffer
|
||||
on each call to ImageStrDecDecode().
|
||||
|
||||
The REENTRANT_MODE flag only works when the output image is in Orientations 0, 1
|
||||
(vertically flipped) or 2 (horizontally flipped).
|
||||
|
||||
With REENTRANT_MODE defined, the function PKImageDecode_Copy_WMP()
|
||||
decodes only as far as the pRect parameter indicates. The width of the rectangle must be the width
|
||||
of the image, but on each call, this function will decode the image up to the end of the MB Row
|
||||
which contains the i-th pixel row, where i = pRect->Y.
|
||||
|
||||
A target use of this version would be to have PKImageDecode_Copy_WMP() called in a loop, once for
|
||||
each MB row. On each call, pRect would specify a 1-MB-Row-tall rectangle that is the width of the
|
||||
image. The decoder state is preserved until the Decoder finishes decoding the image.
|
||||
|
||||
If, at a certain point, a request is made for a rectangle _above_ the last row decoded, then the
|
||||
decoder instance is terminated and re-initiated, and decoding re-starts, going from the beginning
|
||||
of the image to the end of the current rectangle.
|
||||
|
||||
***
|
||||
|
||||
We've chosen to uncomment-out this definition in this header file. An alternate method would be
|
||||
to allow the user to define this in the PREPROCESSOR DEFINITIONS section of the properties page
|
||||
for each of the following projects: CommonLib, DecodeLib, JXRDecApp and JXRGlueLib.
|
||||
|
||||
*/
|
||||
/*************************************************************************
|
||||
enums
|
||||
*************************************************************************/
|
||||
typedef enum {
|
||||
ICERR_OK = 0, ICERR_ERROR = -1
|
||||
} ERR_CODE;
|
||||
|
||||
typedef enum BITDEPTH {
|
||||
BD_SHORT, BD_LONG,
|
||||
|
||||
/* add new BITDEPTH here */ BD_MAX
|
||||
} BITDEPTH;
|
||||
|
||||
typedef enum BITDEPTH_BITS {
|
||||
// regular ones
|
||||
BD_1, //White is foreground
|
||||
BD_8, BD_16, BD_16S, BD_16F, BD_32, BD_32S, BD_32F,
|
||||
|
||||
// irregular ones
|
||||
BD_5, BD_10, BD_565,
|
||||
|
||||
/* add new BITDEPTH_BITS here */ BDB_MAX,
|
||||
|
||||
BD_1alt = 0xf, //Black is foreground
|
||||
} BITDEPTH_BITS;
|
||||
|
||||
typedef enum OVERLAP {
|
||||
OL_NONE = 0, OL_ONE, OL_TWO,
|
||||
|
||||
/* add new OVERLAP here */ OL_MAX
|
||||
} OVERLAP;
|
||||
|
||||
typedef enum BITSTREAMFORMAT {
|
||||
SPATIAL = 0, // spatial order
|
||||
FREQUENCY, // frequency order
|
||||
} BITSTREAMFORMAT;
|
||||
|
||||
typedef enum COLORFORMAT {
|
||||
Y_ONLY = 0,
|
||||
YUV_420 = 1,
|
||||
YUV_422 = 2,
|
||||
YUV_444 = 3,
|
||||
CMYK = 4,
|
||||
//CMYKDIRECT = 5,
|
||||
NCOMPONENT = 6,
|
||||
|
||||
// these are external-only
|
||||
CF_RGB = 7,
|
||||
CF_RGBE = 8,
|
||||
|
||||
/* add new COLORFORMAT here */ CFT_MAX
|
||||
} COLORFORMAT;
|
||||
|
||||
// rotation and flip
|
||||
typedef enum ORIENTATION {
|
||||
// CRW: Clock Wise 90% Rotation; FlipH: Flip Horizontally; FlipV: Flip Vertically
|
||||
// Peform rotation FIRST!
|
||||
// CRW FlipH FlipV
|
||||
O_NONE = 0, // 0 0 0
|
||||
O_FLIPV, // 0 0 1
|
||||
O_FLIPH, // 0 1 0
|
||||
O_FLIPVH, // 0 1 1
|
||||
O_RCW, // 1 0 0
|
||||
O_RCW_FLIPV, // 1 0 1
|
||||
O_RCW_FLIPH, // 1 1 0
|
||||
O_RCW_FLIPVH, // 1 1 1
|
||||
/* add new ORIENTATION here */ O_MAX
|
||||
} ORIENTATION;
|
||||
|
||||
typedef enum SUBBAND {
|
||||
SB_ALL = 0, // keep all subbands
|
||||
SB_NO_FLEXBITS, // skip flex bits
|
||||
SB_NO_HIGHPASS, // skip highpass
|
||||
SB_DC_ONLY, // skip lowpass and highpass, DC only
|
||||
SB_ISOLATED, // not decodable
|
||||
/* add new SUBBAND here */ SB_MAX
|
||||
} SUBBAND;
|
||||
|
||||
enum { RAW = 0, BMP = 1, PPM = 2, TIF = 3, HDR = 4, IYUV = 5, YUV422 = 6, YUV444 = 7};
|
||||
|
||||
typedef enum {ERROR_FAIL = -1, SUCCESS_DONE, PRE_READ_HDR, PRE_SETUP, PRE_DECODE, POST_READ_HDR } WMIDecoderStatus;
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif // FALSE
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif // TRUE
|
||||
|
||||
#define MAX_CHANNELS 16
|
||||
#define LOG_MAX_TILES 12
|
||||
#define MAX_TILES (1 << LOG_MAX_TILES)
|
||||
|
||||
|
||||
//================================================================
|
||||
// Codec-specific constants
|
||||
#define MB_WIDTH_PIXEL 16
|
||||
#define MB_HEIGHT_PIXEL 16
|
||||
|
||||
#define BLK_WIDTH_PIXEL 4
|
||||
#define BLK_HEIGHT_PIXEL 4
|
||||
|
||||
#define MB_WIDTH_BLK 4
|
||||
#define MB_HEIGHT_BLK 4
|
||||
|
||||
// The codec operates most efficiently when the framebuffers for encoder input
|
||||
// and decoder output are: 1) aligned on a particular boundary, and 2) the stride
|
||||
// is also aligned to this boundary (so that each scanline is also aligned).
|
||||
// This boundary is defined below.
|
||||
#define FRAMEBUFFER_ALIGNMENT 128
|
||||
|
||||
|
||||
//================================================================
|
||||
#define WMP_errSuccess 0
|
||||
|
||||
#define WMP_errFail -1
|
||||
#define WMP_errNotYetImplemented -2
|
||||
#define WMP_errAbstractMethod -3
|
||||
|
||||
#define WMP_errOutOfMemory -101
|
||||
#define WMP_errFileIO -102
|
||||
#define WMP_errBufferOverflow -103
|
||||
#define WMP_errInvalidParameter -104
|
||||
#define WMP_errInvalidArgument -105
|
||||
#define WMP_errUnsupportedFormat -106
|
||||
#define WMP_errIncorrectCodecVersion -107
|
||||
#define WMP_errIndexNotFound -108
|
||||
#define WMP_errOutOfSequence -109
|
||||
#define WMP_errNotInitialized -110
|
||||
#define WMP_errMustBeMultipleOf16LinesUntilLastCall -111
|
||||
#define WMP_errPlanarAlphaBandedEncRequiresTempFile -112
|
||||
#define WMP_errAlphaModeCannotBeTranscoded -113
|
||||
#define WMP_errIncorrectCodecSubVersion -114
|
||||
|
||||
|
||||
//================================================================
|
||||
typedef long ERR;
|
||||
|
||||
#define Failed(err) ((err)<0)
|
||||
|
||||
#define CRLF "\r\n"
|
||||
|
||||
#define CT_ASSERT(exp, uniq) typedef char __CT_ASSERT__##uniq[(exp) ? 1 : -1] // Caller must provide a unique tag, or this fails to compile under GCC
|
||||
|
||||
#if defined(_DEBUG) || defined(DBG)
|
||||
#define Report(err, szExp, szFile, nLine) \
|
||||
fprintf(stderr, "FAILED: %ld=%s" CRLF, (err), (szExp)); \
|
||||
fprintf(stderr, " %s:%ld" CRLF, (szFile), (nLine)); \
|
||||
|
||||
#else
|
||||
#define Report(err, szExp, szFile, lLine) err = err
|
||||
#endif
|
||||
|
||||
#define Call(exp) \
|
||||
if (Failed(err = (exp))) \
|
||||
{ \
|
||||
Report(err, #exp, __FILE__, (long)__LINE__); \
|
||||
goto Cleanup; \
|
||||
} \
|
||||
else err = err
|
||||
|
||||
#define CallIgnoreError(errTmp, exp) \
|
||||
if (Failed(errTmp = (exp))) \
|
||||
{ \
|
||||
Report(errTmp, #exp, __FILE__, (long)__LINE__); \
|
||||
} \
|
||||
else errTmp = errTmp
|
||||
|
||||
|
||||
#define Test(exp, err) Call((exp) ? WMP_errSuccess : (err))
|
||||
#define FailIf(exp, err) Call((exp) ? (err) : WMP_errSuccess)
|
||||
|
||||
//================================================================
|
||||
// WMPStream interface
|
||||
//================================================================
|
||||
struct WMPStream
|
||||
{
|
||||
union
|
||||
{
|
||||
struct tagFile
|
||||
{
|
||||
FILE* pFile;
|
||||
} file;
|
||||
|
||||
struct tagBuf
|
||||
{
|
||||
U8* pbBuf;
|
||||
size_t cbBuf;
|
||||
size_t cbCur;
|
||||
size_t cbBufCount;
|
||||
} buf;
|
||||
|
||||
void* pvObj;
|
||||
} state;
|
||||
|
||||
Bool fMem;
|
||||
|
||||
ERR (*Close)(struct WMPStream** pme);
|
||||
|
||||
Bool (*EOS)(struct WMPStream* me);
|
||||
|
||||
ERR (*Read)(struct WMPStream* me, void* pv, size_t cb);
|
||||
ERR (*Write)(struct WMPStream* me, const void* pv, size_t cb);
|
||||
//ERR (*GetLine)(struct WMPStream* me, void* pv, size_t cb);
|
||||
|
||||
ERR (*SetPos)(struct WMPStream* me, size_t offPos);
|
||||
ERR (*GetPos)(struct WMPStream* me, size_t* poffPos);
|
||||
};
|
||||
|
||||
EXTERN_C ERR CreateWS_File(struct WMPStream** ppWS, const char* szFilename, const char* szMode);
|
||||
EXTERN_C ERR CloseWS_File(struct WMPStream** ppWS);
|
||||
|
||||
EXTERN_C ERR CreateWS_Memory(struct WMPStream** ppWS, void* pv, size_t cb);
|
||||
EXTERN_C ERR CloseWS_Memory(struct WMPStream** ppWS);
|
||||
|
||||
|
||||
//================================================================
|
||||
// Enc/Dec data structure
|
||||
//================================================================
|
||||
typedef struct tagCWMImageInfo {
|
||||
size_t cWidth;
|
||||
size_t cHeight;
|
||||
COLORFORMAT cfColorFormat;
|
||||
BITDEPTH_BITS bdBitDepth;
|
||||
size_t cBitsPerUnit;
|
||||
size_t cLeadingPadding; // number of leading padding
|
||||
Bool bRGB; // true: RGB; false: BGR
|
||||
U8 cChromaCenteringX; // Relative location of Chroma w.r.t Luma
|
||||
U8 cChromaCenteringY; // Relative location of Chroma w.r.t Luma
|
||||
|
||||
// Region of interest decoding
|
||||
size_t cROILeftX;
|
||||
size_t cROIWidth;
|
||||
size_t cROITopY;
|
||||
size_t cROIHeight;
|
||||
|
||||
// thumbnail decode
|
||||
Bool bSkipFlexbits;
|
||||
size_t cThumbnailWidth;
|
||||
size_t cThumbnailHeight;
|
||||
|
||||
// image orientation
|
||||
ORIENTATION oOrientation;
|
||||
|
||||
// post processing
|
||||
U8 cPostProcStrength; // 0(none) 1(light) 2(medium) 3(strong) 4(very strong)
|
||||
|
||||
// user buffer is always padded to whole MB
|
||||
Bool fPaddedUserBuffer;
|
||||
} CWMImageInfo;
|
||||
|
||||
typedef struct tagCWMIStrCodecParam {
|
||||
Bool bVerbose;
|
||||
|
||||
// for macroblock quantization (DQUANT)
|
||||
U8 uiDefaultQPIndex;
|
||||
U8 uiDefaultQPIndexYLP;
|
||||
U8 uiDefaultQPIndexYHP;
|
||||
U8 uiDefaultQPIndexU;
|
||||
U8 uiDefaultQPIndexULP;
|
||||
U8 uiDefaultQPIndexUHP;
|
||||
U8 uiDefaultQPIndexV;
|
||||
U8 uiDefaultQPIndexVLP;
|
||||
U8 uiDefaultQPIndexVHP;
|
||||
U8 uiDefaultQPIndexAlpha;
|
||||
|
||||
COLORFORMAT cfColorFormat;
|
||||
BITDEPTH bdBitDepth;
|
||||
OVERLAP olOverlap;
|
||||
BITSTREAMFORMAT bfBitstreamFormat;
|
||||
size_t cChannel; // number of color channels including alpha
|
||||
U8 uAlphaMode; // 0:no alpha 1: alpha only else: something + alpha
|
||||
SUBBAND sbSubband; // which subbands to keep
|
||||
U8 uiTrimFlexBits;
|
||||
|
||||
struct WMPStream* pWStream;
|
||||
size_t cbStream;
|
||||
|
||||
// tiling info
|
||||
U32 cNumOfSliceMinus1V; // # of vertical slices
|
||||
U32 uiTileX[MAX_TILES]; // width in MB of each veritical slice
|
||||
U32 cNumOfSliceMinus1H; // # of horizontal slices
|
||||
U32 uiTileY[MAX_TILES]; // height in MB of each horizontal slice
|
||||
|
||||
//32f and 32s conversion parameters
|
||||
U8 nLenMantissaOrShift;
|
||||
I8 nExpBias;
|
||||
|
||||
Bool bBlackWhite;
|
||||
|
||||
Bool bUseHardTileBoundaries; //default is soft tile boundaries
|
||||
|
||||
Bool bProgressiveMode; //default is sequential mode
|
||||
|
||||
Bool bYUVData; //default is cfColorFormat data
|
||||
|
||||
Bool bUnscaledArith; //force unscaled arithmetic
|
||||
|
||||
// Perf measurement
|
||||
Bool fMeasurePerf;
|
||||
} CWMIStrCodecParam;
|
||||
|
||||
typedef struct tagCWMImageBufferInfo {
|
||||
void* pv; // pointer to scanline buffer
|
||||
size_t cLine; // count of scanlines
|
||||
size_t cbStride; // count of BYTE for stride
|
||||
#ifdef REENTRANT_MODE
|
||||
unsigned int uiFirstMBRow; // Current First MB Row being decoded
|
||||
unsigned int uiLastMBRow; // Current Last MB Row being decoded
|
||||
size_t cLinesDecoded; // Number of lines decoded and returned in low-mem mode
|
||||
#endif // REENTRANT_MODE
|
||||
} CWMImageBufferInfo;
|
||||
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Encode API */
|
||||
/****************************************************************/
|
||||
EXTERN_C Int ImageStrEncInit(
|
||||
CWMImageInfo* pII,
|
||||
CWMIStrCodecParam *pSCP,
|
||||
CTXSTRCODEC* pctxSC);
|
||||
|
||||
EXTERN_C Int ImageStrEncEncode(
|
||||
CTXSTRCODEC ctxSC,
|
||||
const CWMImageBufferInfo* pBI);
|
||||
|
||||
EXTERN_C Int ImageStrEncTerm(
|
||||
CTXSTRCODEC ctxSC);
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Decode API */
|
||||
/****************************************************************/
|
||||
struct CWMImageStrCodec;
|
||||
|
||||
EXTERN_C Int ImageStrDecGetInfo(
|
||||
CWMImageInfo* pII,
|
||||
CWMIStrCodecParam *pSCP);
|
||||
|
||||
EXTERN_C Int ImageStrDecInit(
|
||||
CWMImageInfo* pII,
|
||||
CWMIStrCodecParam *pSCP,
|
||||
CTXSTRCODEC* pctxSC);
|
||||
|
||||
EXTERN_C Int ImageStrDecDecode(
|
||||
CTXSTRCODEC ctxSC,
|
||||
const CWMImageBufferInfo* pBI
|
||||
#ifdef REENTRANT_MODE
|
||||
, size_t *pcDecodedLines
|
||||
#endif
|
||||
);
|
||||
|
||||
EXTERN_C Int ImageStrDecTerm(
|
||||
CTXSTRCODEC ctxSC);
|
||||
|
||||
EXTERN_C Int WMPhotoValidate(
|
||||
CWMImageInfo * pII,
|
||||
CWMIStrCodecParam * pSCP);
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Transcoding API */
|
||||
/****************************************************************/
|
||||
typedef struct tagCWMTranscodingParam {
|
||||
size_t cLeftX;
|
||||
size_t cWidth;
|
||||
size_t cTopY;
|
||||
size_t cHeight; // interested region
|
||||
|
||||
BITSTREAMFORMAT bfBitstreamFormat; // desired bitstream format
|
||||
// COLORFORMAT cfColorFormat; // desired color format
|
||||
U8 uAlphaMode; // 0:no alpha 1: alpha only else: something + alpha
|
||||
SUBBAND sbSubband; // which subbands to keep
|
||||
ORIENTATION oOrientation; // flip / right angle rotation
|
||||
Bool bIgnoreOverlap;
|
||||
} CWMTranscodingParam;
|
||||
|
||||
EXTERN_C Int WMPhotoTranscode(
|
||||
struct WMPStream* pStreamDec, // input bitstrean
|
||||
struct WMPStream* pStreamEnc, // output bitstream
|
||||
CWMTranscodingParam* pParam // transcoding parameters
|
||||
);
|
||||
|
||||
typedef struct tagCWMDetilingParam {
|
||||
size_t cWidth;
|
||||
size_t cHeight; // image size
|
||||
size_t cChannel; // # of channels
|
||||
OVERLAP olOverlap; // overlap
|
||||
BITDEPTH_BITS bdBitdepth; // bit depth
|
||||
|
||||
// tiling info
|
||||
U32 cNumOfSliceMinus1V; // # of vertical slices
|
||||
U32 uiTileX[MAX_TILES]; // position in MB of each veritical slice
|
||||
U32 cNumOfSliceMinus1H; // # of horizontal slices
|
||||
U32 uiTileY[MAX_TILES]; // position in MB of each horizontal slice
|
||||
|
||||
// image info
|
||||
void * pImage;
|
||||
size_t cbStride;
|
||||
} CWMDetilingParam;
|
||||
|
||||
EXTERN_C Int WMPhotoDetile(
|
||||
CWMDetilingParam * pParam // detiling parameters
|
||||
);
|
||||
|
||||
#endif // WMI_WINDOWSMEDIAPHOTO_H
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//*@@@---@@@@******************************************************************
|
||||
|
||||
#ifndef XPLATFORM_IMAGE_H
|
||||
#define XPLATFORM_IMAGE_H
|
||||
|
||||
#ifdef __ANSI__
|
||||
// ANSI
|
||||
#define FORCE_INLINE
|
||||
#define CDECL
|
||||
#define UINTPTR_T unsigned int
|
||||
#define INTPTR_T int
|
||||
#define DECLSPEC_ALIGN(bytes)
|
||||
#endif // __ANSI__
|
||||
|
||||
|
||||
//#if defined(WIN32)
|
||||
#if defined(WIN32) && !defined(UNDER_CE) // WIN32 seems to be defined always in VS2005 for ARM platform
|
||||
// x86
|
||||
//#define CDECL __cdecl
|
||||
#define DECLSPEC_ALIGN(bytes) __declspec(align(bytes))
|
||||
#endif // x86
|
||||
|
||||
|
||||
#if defined(_ARM_) || defined(UNDER_CE)
|
||||
// ARM, WinCE
|
||||
#define FORCE_INLINE inline
|
||||
#define CDECL
|
||||
#define UINTPTR_T unsigned int
|
||||
#define INTPTR_T int
|
||||
#define DECLSPEC_ALIGN(bytes)
|
||||
|
||||
// parser
|
||||
#define FULL_PATH_CONFIG_FILE_ENCODE "\\ConfigFile_encode.txt"
|
||||
#define FULL_PATH_CONFIG_FILE_DECODE "\\ConfigFile_decode.txt"
|
||||
#define MAX_ARGC 14
|
||||
#define MaxCharReadCount 10
|
||||
#define MAX_FNAME 256
|
||||
#define DELIMITER "filelist:"
|
||||
#define CODEC_ENCODE "encode"
|
||||
#define CODEC_DECODE "decode"
|
||||
#define PHOTON "ptn"
|
||||
#define OUTRAW "raw"
|
||||
#define OUTBMP "bmp"
|
||||
#define OUTPPM "ppm"
|
||||
#define OUTTIF "tif"
|
||||
#define OUTHDR "hdr"
|
||||
#define OUTIYUV "iyuv"
|
||||
#define OUTYUV422 "yuv422"
|
||||
#define OUTYUV444 "yuv444"
|
||||
int XPLATparser(char *pcARGV[], char *pcCodec);
|
||||
void freeXPLATparser(int iARGC, char *pcARGV[]);
|
||||
|
||||
// WinCE intrinsic
|
||||
#include <Cmnintrin.h>
|
||||
#endif // ARM, WinCE
|
||||
|
||||
#endif // XPLATFORM_IMAGE_H
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//*@@@---@@@@******************************************************************
|
||||
#pragma once
|
||||
|
||||
#include <assert.h>
|
||||
#include <windows.h>
|
||||
|
||||
//================================
|
||||
// bitio functions
|
||||
//================================
|
||||
#define PACKETLENGTH (1U<<12) // 4kB
|
||||
|
||||
#define readIS_L1(pSC, pIO) readIS(pSC, pIO)
|
||||
#define readIS_L2(pSC, pIO) (void)(pSC, pIO)
|
||||
|
||||
#define writeIS_L1(pSC, pIO) writeIS(pSC, pIO)
|
||||
#define writeIS_L2(pSC, pIO) (void)(pSC, pIO)
|
||||
|
||||
|
||||
//================================
|
||||
// common defines
|
||||
//================================
|
||||
#define FORCE_INLINE __forceinline
|
||||
#define UINTPTR_T uintptr_t
|
||||
#define INTPTR_T intptr_t
|
||||
|
||||
|
||||
//================================
|
||||
// quantization optimization
|
||||
//================================
|
||||
#define RECIP_QUANT_OPT
|
||||
|
||||
|
|
@ -0,0 +1,930 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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 <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define INITGUID
|
||||
#include <JXRGlue.h>
|
||||
|
||||
//================================================================
|
||||
const PKIID IID_PKImageScanEncode = 1;
|
||||
const PKIID IID_PKImageFrameEncode = 2;
|
||||
|
||||
const PKIID IID_PKImageUnsupported = 100;
|
||||
const PKIID IID_PKImageWmpEncode = 101;
|
||||
|
||||
const PKIID IID_PKImageWmpDecode = 201;
|
||||
|
||||
//================================================================
|
||||
// Misc supporting functions
|
||||
//================================================================
|
||||
ERR PKAlloc(void** ppv, size_t cb)
|
||||
{
|
||||
*ppv = calloc(1, cb);
|
||||
return *ppv ? WMP_errSuccess : WMP_errOutOfMemory;
|
||||
}
|
||||
|
||||
|
||||
ERR PKFree(void** ppv)
|
||||
{
|
||||
if (ppv)
|
||||
{
|
||||
free(*ppv);
|
||||
*ppv = NULL;
|
||||
}
|
||||
|
||||
return WMP_errSuccess;
|
||||
}
|
||||
|
||||
ERR PKAllocAligned(void** ppv, size_t cb, size_t iAlign)
|
||||
{
|
||||
U8 *pOrigPtr;
|
||||
U8 *pReturnedPtr;
|
||||
size_t iAlignmentCorrection;
|
||||
const size_t c_cbBlockSize = cb + sizeof(void*) + iAlign - 1;
|
||||
|
||||
*ppv = NULL;
|
||||
pOrigPtr = calloc(1, c_cbBlockSize);
|
||||
if (NULL == pOrigPtr)
|
||||
return WMP_errOutOfMemory;
|
||||
|
||||
iAlignmentCorrection = iAlign - ((size_t)pOrigPtr % iAlign);
|
||||
if (iAlignmentCorrection < sizeof(void*))
|
||||
// Alignment correction won't leave us enough space to store pOrigPtr - advance to next block
|
||||
iAlignmentCorrection += iAlign;
|
||||
|
||||
assert(iAlignmentCorrection >= sizeof(void*)); // Alignment correction must have space for pOrigPtr
|
||||
assert(iAlignmentCorrection + cb <= c_cbBlockSize); // Don't exceed right edge of memory block
|
||||
|
||||
pReturnedPtr = pOrigPtr + iAlignmentCorrection;
|
||||
*(void**)(pReturnedPtr - sizeof(void*)) = pOrigPtr;
|
||||
|
||||
assert(0 == ((size_t)pReturnedPtr % iAlign)); // Are we in fact aligned?
|
||||
*ppv = pReturnedPtr;
|
||||
return WMP_errSuccess;
|
||||
}
|
||||
|
||||
ERR PKFreeAligned(void** ppv)
|
||||
{
|
||||
if (ppv && *ppv)
|
||||
{
|
||||
U8 **ppOrigPtr = (U8**)((U8*)(*ppv) - sizeof(void*));
|
||||
assert(*ppOrigPtr <= (U8*)ppOrigPtr); // Something's wrong if pOrigPtr points forward
|
||||
free(*ppOrigPtr);
|
||||
*ppv = NULL;
|
||||
}
|
||||
return WMP_errSuccess;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int PKStrnicmp(const char* s1, const char* s2, size_t c)
|
||||
{
|
||||
for(; tolower(*s1) == tolower(*s2) && *s1 && *s2 && c; ++s1, ++s2, --c);
|
||||
return c ? *s1 - *s2 : 0;
|
||||
}
|
||||
|
||||
static const PKPixelInfo pixelInfo[] =
|
||||
{
|
||||
{&GUID_PKPixelFormatDontCare, 1, Y_ONLY, BD_8, 8, PK_pixfmtNul, 0, 0, 0, 0},
|
||||
|
||||
// Gray
|
||||
//{&GUID_PKPixelFormat2bppGray, 1, Y_ONLY, BD_8, 2, PK_pixfmtNul},
|
||||
//{&GUID_PKPixelFormat4bppGray, 1, Y_ONLY, BD_8, 4, PK_pixfmtNul},
|
||||
|
||||
{&GUID_PKPixelFormatBlackWhite, 1, Y_ONLY, BD_1, 1, PK_pixfmtNul, 1, 1, 1, 1},//BlackIsZero is default for GUID_PKPixelFormatBlackWhite
|
||||
{&GUID_PKPixelFormatBlackWhite, 1, Y_ONLY, BD_1, 1, PK_pixfmtNul, 0, 1, 1, 1},//WhiteIsZero
|
||||
{&GUID_PKPixelFormat8bppGray, 1, Y_ONLY, BD_8, 8, PK_pixfmtNul, 1, 1, 8, 1},
|
||||
{&GUID_PKPixelFormat16bppGray, 1, Y_ONLY, BD_16, 16, PK_pixfmtNul, 1, 1, 16, 1},
|
||||
{&GUID_PKPixelFormat16bppGrayFixedPoint, 1, Y_ONLY, BD_16S, 16, PK_pixfmtNul, 1, 1, 16, 2},
|
||||
{&GUID_PKPixelFormat16bppGrayHalf, 1, Y_ONLY, BD_16F, 16, PK_pixfmtNul, 1, 1, 16, 3},
|
||||
//{&GUID_PKPixelFormat32bppGray, 1, Y_ONLY, BD_32, 32, PK_pixfmtNul, 1, 1, 32, 1},
|
||||
{&GUID_PKPixelFormat32bppGrayFixedPoint, 1, Y_ONLY, BD_32S, 32, PK_pixfmtNul, 1, 1, 32, 2},
|
||||
{&GUID_PKPixelFormat32bppGrayFloat, 1, Y_ONLY, BD_32F, 32, PK_pixfmtNul, 1, 1, 32, 3},
|
||||
|
||||
// RGB
|
||||
{&GUID_PKPixelFormat24bppRGB, 3, CF_RGB, BD_8, 24, PK_pixfmtNul, 2, 3, 8, 1},
|
||||
{&GUID_PKPixelFormat24bppBGR, 3, CF_RGB, BD_8, 24, PK_pixfmtBGR, 2, 3, 8, 1},
|
||||
{&GUID_PKPixelFormat32bppRGB, 3, CF_RGB, BD_8, 32, PK_pixfmtNul, 2, 3, 8, 1},
|
||||
{&GUID_PKPixelFormat32bppBGR, 3, CF_RGB, BD_8, 32, PK_pixfmtBGR, 2, 3, 8, 1},
|
||||
{&GUID_PKPixelFormat48bppRGB, 3, CF_RGB, BD_16, 48, PK_pixfmtNul, 2, 3, 16, 1},
|
||||
{&GUID_PKPixelFormat48bppRGBFixedPoint, 3, CF_RGB, BD_16S, 48, PK_pixfmtNul, 2, 3, 16, 2},
|
||||
{&GUID_PKPixelFormat48bppRGBHalf, 3, CF_RGB, BD_16F, 48, PK_pixfmtNul, 2, 3, 16, 3},
|
||||
{&GUID_PKPixelFormat64bppRGBFixedPoint, 3, CF_RGB, BD_16S, 64, PK_pixfmtNul, 2, 3, 16, 2},
|
||||
{&GUID_PKPixelFormat64bppRGBHalf, 3, CF_RGB, BD_16F, 64, PK_pixfmtNul, 2, 3, 16, 3},
|
||||
//{&GUID_PKPixelFormat96bppRGB, 3, CF_RGB, BD_32, 96, PK_pixfmtNul, 2, 3, 32, 1},
|
||||
{&GUID_PKPixelFormat96bppRGBFixedPoint, 3, CF_RGB, BD_32S, 96, PK_pixfmtNul, 2, 3, 32, 2},
|
||||
{&GUID_PKPixelFormat96bppRGBFloat, 3, CF_RGB, BD_32F, 96, PK_pixfmtNul, 2, 3, 32, 3},
|
||||
{&GUID_PKPixelFormat128bppRGBFixedPoint, 3, CF_RGB, BD_32S, 128, PK_pixfmtNul, 2, 3, 32, 2},
|
||||
{&GUID_PKPixelFormat128bppRGBFloat, 3, CF_RGB, BD_32F, 128, PK_pixfmtNul, 2, 3, 32, 3},
|
||||
|
||||
// RGBA
|
||||
{&GUID_PKPixelFormat32bppBGRA, 4, CF_RGB, BD_8, 32, PK_pixfmtHasAlpha | PK_pixfmtBGR, 2, 4, 8, 1},
|
||||
{&GUID_PKPixelFormat32bppRGBA, 4, CF_RGB, BD_8, 32, PK_pixfmtHasAlpha, 2, 4, 8, 1},
|
||||
{&GUID_PKPixelFormat64bppRGBA, 4, CF_RGB, BD_16, 64, PK_pixfmtHasAlpha, 2, 4, 16, 1},
|
||||
{&GUID_PKPixelFormat64bppRGBAFixedPoint, 4, CF_RGB, BD_16S, 64, PK_pixfmtHasAlpha, 2, 4, 16, 2},
|
||||
{&GUID_PKPixelFormat64bppRGBAHalf, 4, CF_RGB, BD_16F, 64, PK_pixfmtHasAlpha, 2, 4, 16, 3},
|
||||
//{&GUID_PKPixelFormat128bppRGBA, 4, CF_RGB, BD_32, 128, PK_pixfmtHasAlpha, 2, 4, 32, 1},
|
||||
{&GUID_PKPixelFormat128bppRGBAFixedPoint, 4, CF_RGB, BD_32S, 128, PK_pixfmtHasAlpha, 2, 4, 32, 2},
|
||||
{&GUID_PKPixelFormat128bppRGBAFloat, 4, CF_RGB, BD_32F, 128, PK_pixfmtHasAlpha, 2, 4, 32, 3},
|
||||
|
||||
// PRGBA
|
||||
{&GUID_PKPixelFormat32bppPBGRA, 4, CF_RGB, BD_8, 32, PK_pixfmtHasAlpha | PK_pixfmtPreMul | PK_pixfmtBGR, 2, 4, 8, 1},
|
||||
{&GUID_PKPixelFormat32bppPRGBA, 4, CF_RGB, BD_8, 32, PK_pixfmtHasAlpha | PK_pixfmtPreMul, 2, 4, 8, 1},
|
||||
{&GUID_PKPixelFormat64bppPRGBA, 4, CF_RGB, BD_16, 64, PK_pixfmtHasAlpha | PK_pixfmtPreMul, 2, 4, 16, 1},
|
||||
//{&GUID_PKPixelFormat64bppPRGBAFixedPoint, 4, CF_RGB, BD_16S, 64, PK_pixfmtHasAlpha, 2, 4, 16, 2},
|
||||
//{&GUID_PKPixelFormat64bppPRGBAHalf, 4, CF_RGB, BD_16F, 64, PK_pixfmtHasAlpha, 2, 4, 16, 3},
|
||||
//{&GUID_PKPixelFormat128bppPRGBAFixedPoint, 4, CF_RGB, BD_32S, 128, PK_pixfmtHasAlpha, 2, 4, 32, 2},
|
||||
{&GUID_PKPixelFormat128bppPRGBAFloat, 4, CF_RGB, BD_32F, 128, PK_pixfmtHasAlpha | PK_pixfmtPreMul, 2, 4, 32, 3},
|
||||
|
||||
// Packed formats
|
||||
{&GUID_PKPixelFormat16bppRGB555, 3, CF_RGB, BD_5, 16, PK_pixfmtNul, 2, 3, 5, 1},
|
||||
{&GUID_PKPixelFormat16bppRGB565, 3, CF_RGB, BD_565, 16, PK_pixfmtNul, 2, 3, 6, 1},
|
||||
{&GUID_PKPixelFormat32bppRGB101010, 3, CF_RGB, BD_10, 32, PK_pixfmtNul, 2, 3, 10, 1},
|
||||
|
||||
// CMYK
|
||||
{&GUID_PKPixelFormat32bppCMYK, 4, CMYK, BD_8, 32, PK_pixfmtNul, 5, 4, 8, 1},
|
||||
{&GUID_PKPixelFormat40bppCMYKAlpha, 5, CMYK, BD_8, 40, PK_pixfmtHasAlpha, 5, 5, 8, 1},
|
||||
|
||||
{&GUID_PKPixelFormat64bppCMYK, 4, CMYK, BD_16, 64, PK_pixfmtNul, 5, 4, 16, 1},
|
||||
{&GUID_PKPixelFormat80bppCMYKAlpha, 5, CMYK, BD_16, 80, PK_pixfmtHasAlpha, 5, 5, 16, 1},
|
||||
|
||||
// N_CHANNEL
|
||||
{&GUID_PKPixelFormat24bpp3Channels, 3, NCOMPONENT, BD_8, 24, PK_pixfmtNul, PK_PI_NCH, 3, 8, 1},//the N channel TIF by PS has PhotometricInterpretation of PK_PI_RGB
|
||||
{&GUID_PKPixelFormat32bpp4Channels, 4, NCOMPONENT, BD_8, 32, PK_pixfmtNul, PK_PI_NCH, 4, 8, 1},
|
||||
{&GUID_PKPixelFormat40bpp5Channels, 5, NCOMPONENT, BD_8, 40, PK_pixfmtNul, PK_PI_NCH, 5, 8, 1},
|
||||
{&GUID_PKPixelFormat48bpp6Channels, 6, NCOMPONENT, BD_8, 48, PK_pixfmtNul, PK_PI_NCH, 6, 8, 1},
|
||||
{&GUID_PKPixelFormat56bpp7Channels, 7, NCOMPONENT, BD_8, 56, PK_pixfmtNul, PK_PI_NCH, 7, 8, 1},
|
||||
{&GUID_PKPixelFormat64bpp8Channels, 8, NCOMPONENT, BD_8, 64, PK_pixfmtNul, PK_PI_NCH, 8, 8, 1},
|
||||
|
||||
{&GUID_PKPixelFormat32bpp3ChannelsAlpha, 4, NCOMPONENT, BD_8, 32, PK_pixfmtHasAlpha, PK_PI_NCH, 4, 8, 1},
|
||||
{&GUID_PKPixelFormat40bpp4ChannelsAlpha, 5, NCOMPONENT, BD_8, 40, PK_pixfmtHasAlpha, PK_PI_NCH, 5, 8, 1},
|
||||
{&GUID_PKPixelFormat48bpp5ChannelsAlpha, 6, NCOMPONENT, BD_8, 48, PK_pixfmtHasAlpha, PK_PI_NCH, 6, 8, 1},
|
||||
{&GUID_PKPixelFormat56bpp6ChannelsAlpha, 7, NCOMPONENT, BD_8, 56, PK_pixfmtHasAlpha, PK_PI_NCH, 7, 8, 1},
|
||||
{&GUID_PKPixelFormat64bpp7ChannelsAlpha, 8, NCOMPONENT, BD_8, 64, PK_pixfmtHasAlpha, PK_PI_NCH, 8, 8, 1},
|
||||
{&GUID_PKPixelFormat72bpp8ChannelsAlpha, 9, NCOMPONENT, BD_8, 72, PK_pixfmtHasAlpha, PK_PI_NCH, 9, 8, 1},
|
||||
|
||||
{&GUID_PKPixelFormat48bpp3Channels, 3, NCOMPONENT, BD_16, 48, PK_pixfmtNul, PK_PI_NCH, 3, 16, 1},
|
||||
{&GUID_PKPixelFormat64bpp4Channels, 4, NCOMPONENT, BD_16, 64, PK_pixfmtNul, PK_PI_NCH, 4, 16, 1},
|
||||
{&GUID_PKPixelFormat80bpp5Channels, 5, NCOMPONENT, BD_16, 80, PK_pixfmtNul, PK_PI_NCH, 5, 16, 1},
|
||||
{&GUID_PKPixelFormat96bpp6Channels, 6, NCOMPONENT, BD_16, 96, PK_pixfmtNul, PK_PI_NCH, 6, 16, 1},
|
||||
{&GUID_PKPixelFormat112bpp7Channels, 7, NCOMPONENT, BD_16, 112, PK_pixfmtNul, PK_PI_NCH, 7, 16, 1},
|
||||
{&GUID_PKPixelFormat128bpp8Channels, 8, NCOMPONENT, BD_16, 128, PK_pixfmtNul, PK_PI_NCH, 8, 16, 1},
|
||||
|
||||
{&GUID_PKPixelFormat64bpp3ChannelsAlpha, 4, NCOMPONENT, BD_16, 64, PK_pixfmtHasAlpha, PK_PI_NCH, 4, 16, 1},
|
||||
{&GUID_PKPixelFormat80bpp4ChannelsAlpha, 5, NCOMPONENT, BD_16, 80, PK_pixfmtHasAlpha, PK_PI_NCH, 5, 16, 1},
|
||||
{&GUID_PKPixelFormat96bpp5ChannelsAlpha, 6, NCOMPONENT, BD_16, 96, PK_pixfmtHasAlpha, PK_PI_NCH, 6, 16, 1},
|
||||
{&GUID_PKPixelFormat112bpp6ChannelsAlpha, 7, NCOMPONENT, BD_16, 112, PK_pixfmtHasAlpha, PK_PI_NCH, 7, 16, 1},
|
||||
{&GUID_PKPixelFormat128bpp7ChannelsAlpha, 8, NCOMPONENT, BD_16, 128, PK_pixfmtHasAlpha, PK_PI_NCH, 8, 16, 1},
|
||||
{&GUID_PKPixelFormat144bpp8ChannelsAlpha, 9, NCOMPONENT, BD_16, 144, PK_pixfmtHasAlpha, PK_PI_NCH, 9, 16, 1},
|
||||
|
||||
//RGBE
|
||||
{&GUID_PKPixelFormat32bppRGBE, 4, CF_RGBE, BD_8, 32, PK_pixfmtNul, PK_PI_RGBE, 4, 8, 1},
|
||||
|
||||
//YUV
|
||||
{&GUID_PKPixelFormat12bppYUV420, 3, YUV_420, BD_8, 48, PK_pixfmtNul},
|
||||
{&GUID_PKPixelFormat16bppYUV422, 3, YUV_422, BD_8, 32, PK_pixfmtNul},
|
||||
{&GUID_PKPixelFormat24bppYUV444, 3, YUV_444, BD_8, 24, PK_pixfmtNul},
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------
|
||||
//ERR GetPixelInfo(PKPixelFormatGUID enPixelFormat, const PKPixelInfo** ppPI)
|
||||
ERR PixelFormatLookup(PKPixelInfo* pPI, U8 uLookupType)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < sizeof2(pixelInfo); ++i)
|
||||
{
|
||||
if (LOOKUP_FORWARD == uLookupType)
|
||||
{
|
||||
if (IsEqualGUID(pPI->pGUIDPixFmt, pixelInfo[i].pGUIDPixFmt))
|
||||
{
|
||||
*pPI = pixelInfo[i];
|
||||
goto Cleanup;
|
||||
}
|
||||
}
|
||||
else if (LOOKUP_BACKWARD_TIF == uLookupType)
|
||||
{
|
||||
if (pPI->uSamplePerPixel == pixelInfo[i].uSamplePerPixel &&
|
||||
pPI->uBitsPerSample == pixelInfo[i].uBitsPerSample &&
|
||||
pPI->uSampleFormat == pixelInfo[i].uSampleFormat &&
|
||||
pPI->uInterpretation == pixelInfo[i].uInterpretation)
|
||||
{
|
||||
// match alpha & premult
|
||||
if ((pPI->grBit & (PK_pixfmtHasAlpha | PK_pixfmtPreMul)) ==
|
||||
(pixelInfo[i].grBit & (PK_pixfmtHasAlpha | PK_pixfmtPreMul)))
|
||||
{
|
||||
*pPI = pixelInfo[i];
|
||||
goto Cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Call(WMP_errUnsupportedFormat);
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
const PKPixelFormatGUID* GetPixelFormatFromHash(const U8 uPFHash)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof2(pixelInfo); i++)
|
||||
{
|
||||
if (pixelInfo[i].pGUIDPixFmt->Data4[7] == uPFHash)
|
||||
return pixelInfo[i].pGUIDPixFmt;
|
||||
}
|
||||
|
||||
// If we reached this point, we did not find anything which matched the hash
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
typedef struct tagPKIIDInfo
|
||||
{
|
||||
const char* szExt;
|
||||
const PKIID* pIIDEnc;
|
||||
const PKIID* pIIDDec;
|
||||
} PKIIDInfo;
|
||||
|
||||
static ERR GetIIDInfo(const char* szExt, const PKIIDInfo** ppInfo)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
static PKIIDInfo iidInfo[] = {
|
||||
{".jxr", &IID_PKImageWmpEncode, &IID_PKImageWmpDecode},
|
||||
{".wdp", &IID_PKImageUnsupported, &IID_PKImageWmpDecode},
|
||||
{".hdp", &IID_PKImageUnsupported, &IID_PKImageWmpDecode},
|
||||
};
|
||||
size_t i = 0;
|
||||
|
||||
*ppInfo = NULL;
|
||||
for (i = 0; i < sizeof2(iidInfo); ++i)
|
||||
{
|
||||
if (0 == PKStrnicmp(szExt, iidInfo[i].szExt, strlen(iidInfo[i].szExt)))
|
||||
{
|
||||
*ppInfo = &iidInfo[i];
|
||||
goto Cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
Call(WMP_errUnsupportedFormat);
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR GetImageEncodeIID(const char* szExt, const PKIID** ppIID)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
const PKIIDInfo* pInfo = NULL;
|
||||
|
||||
Call(GetIIDInfo(szExt, &pInfo));
|
||||
*ppIID = pInfo->pIIDEnc;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR GetImageDecodeIID(const char* szExt, const PKIID** ppIID)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
const PKIIDInfo* pInfo = NULL;
|
||||
|
||||
Call(GetIIDInfo(szExt, &pInfo));
|
||||
*ppIID = pInfo->pIIDDec;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
//================================================================
|
||||
// PKFactory
|
||||
//================================================================
|
||||
ERR PKCreateFactory_CreateStream(PKStream** ppStream)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
Call(PKAlloc((void **) ppStream, sizeof(**ppStream)));
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKCreateFactory_Release(PKFactory** ppFactory)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
Call(PKFree((void **) ppFactory));
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
ERR PKCreateFactory(PKFactory** ppFactory, U32 uVersion)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
PKFactory* pFactory = NULL;
|
||||
|
||||
UNREFERENCED_PARAMETER( uVersion );
|
||||
|
||||
Call(PKAlloc((void **) ppFactory, sizeof(**ppFactory)));
|
||||
pFactory = *ppFactory;
|
||||
|
||||
pFactory->CreateStream = PKCreateFactory_CreateStream;
|
||||
|
||||
pFactory->CreateStreamFromFilename = CreateWS_File;
|
||||
pFactory->CreateStreamFromMemory = CreateWS_Memory;
|
||||
|
||||
pFactory->Release = PKCreateFactory_Release;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
//================================================================
|
||||
// PKCodecFactory
|
||||
//================================================================
|
||||
ERR PKCodecFactory_CreateCodec(const PKIID* iid, void** ppv)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
if (IID_PKImageWmpEncode == *iid)
|
||||
{
|
||||
Call(PKImageEncode_Create_WMP((PKImageEncode**)ppv));
|
||||
}
|
||||
else if (IID_PKImageWmpDecode == *iid)
|
||||
{
|
||||
Call(PKImageDecode_Create_WMP((PKImageDecode**)ppv));
|
||||
}
|
||||
else
|
||||
{
|
||||
Call(WMP_errUnsupportedFormat);
|
||||
}
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKCodecFactory_CreateDecoderFromFile(const char* szFilename, PKImageDecode** ppDecoder)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
char *pExt = NULL;
|
||||
const PKIID* pIID = NULL;
|
||||
|
||||
struct WMPStream* pStream = NULL;
|
||||
PKImageDecode* pDecoder = NULL;
|
||||
|
||||
// get file extension
|
||||
pExt = strrchr(szFilename, '.');
|
||||
FailIf(NULL == pExt, WMP_errUnsupportedFormat);
|
||||
|
||||
// get decode PKIID
|
||||
Call(GetImageDecodeIID(pExt, &pIID));
|
||||
|
||||
// create stream
|
||||
Call(CreateWS_File(&pStream, szFilename, "rb"));
|
||||
|
||||
// Create decoder
|
||||
Call(PKCodecFactory_CreateCodec(pIID, (void **) ppDecoder));
|
||||
pDecoder = *ppDecoder;
|
||||
|
||||
// attach stream to decoder
|
||||
Call(pDecoder->Initialize(pDecoder, pStream));
|
||||
pDecoder->fStreamOwner = !0;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKCodecFactory_CreateFormatConverter(PKFormatConverter** ppFConverter)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
PKFormatConverter* pFC = NULL;
|
||||
|
||||
Call(PKAlloc((void **) ppFConverter, sizeof(**ppFConverter)));
|
||||
pFC = *ppFConverter;
|
||||
|
||||
pFC->Initialize = PKFormatConverter_Initialize;
|
||||
pFC->InitializeConvert = PKFormatConverter_InitializeConvert;
|
||||
pFC->GetPixelFormat = PKFormatConverter_GetPixelFormat;
|
||||
pFC->GetSourcePixelFormat = PKFormatConverter_GetSourcePixelFormat;
|
||||
pFC->GetSize = PKFormatConverter_GetSize;
|
||||
pFC->GetResolution = PKFormatConverter_GetResolution;
|
||||
pFC->Copy = PKFormatConverter_Copy;
|
||||
pFC->Convert = PKFormatConverter_Convert;
|
||||
pFC->Release = PKFormatConverter_Release;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKCreateCodecFactory_Release(PKCodecFactory** ppCFactory)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
Call(PKFree((void **) ppCFactory));
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKCreateCodecFactory(PKCodecFactory** ppCFactory, U32 uVersion)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
PKCodecFactory* pCFactory = NULL;
|
||||
|
||||
UNREFERENCED_PARAMETER( uVersion );
|
||||
|
||||
Call(PKAlloc((void **) ppCFactory, sizeof(**ppCFactory)));
|
||||
pCFactory = *ppCFactory;
|
||||
|
||||
pCFactory->CreateCodec = PKCodecFactory_CreateCodec;
|
||||
pCFactory->CreateDecoderFromFile = PKCodecFactory_CreateDecoderFromFile;
|
||||
pCFactory->CreateFormatConverter = PKCodecFactory_CreateFormatConverter;
|
||||
pCFactory->Release = PKCreateCodecFactory_Release;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
//================================================================
|
||||
// PKImageEncode
|
||||
//================================================================
|
||||
ERR PKImageEncode_Initialize(
|
||||
PKImageEncode* pIE,
|
||||
struct WMPStream* pStream,
|
||||
void* pvParam,
|
||||
size_t cbParam)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
UNREFERENCED_PARAMETER( pIE );
|
||||
UNREFERENCED_PARAMETER( pvParam );
|
||||
UNREFERENCED_PARAMETER( cbParam );
|
||||
|
||||
pIE->pStream = pStream;
|
||||
pIE->guidPixFormat = GUID_PKPixelFormatDontCare;
|
||||
pIE->fResX = 96;
|
||||
pIE->fResY = 96;
|
||||
pIE->cFrame = 1;
|
||||
|
||||
Call(pIE->pStream->GetPos(pIE->pStream, &pIE->offStart));
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageEncode_Terminate(
|
||||
PKImageEncode* pIE)
|
||||
{
|
||||
UNREFERENCED_PARAMETER( pIE );
|
||||
return WMP_errSuccess;
|
||||
}
|
||||
|
||||
ERR PKImageEncode_SetPixelFormat(
|
||||
PKImageEncode* pIE,
|
||||
PKPixelFormatGUID enPixelFormat)
|
||||
{
|
||||
pIE->guidPixFormat = enPixelFormat;
|
||||
|
||||
return WMP_errSuccess;
|
||||
}
|
||||
|
||||
ERR PKImageEncode_SetSize(
|
||||
PKImageEncode* pIE,
|
||||
I32 iWidth,
|
||||
I32 iHeight)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
pIE->uWidth = (U32)iWidth;
|
||||
pIE->uHeight = (U32)iHeight;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageEncode_SetResolution(
|
||||
PKImageEncode* pIE,
|
||||
Float fResX,
|
||||
Float fResY)
|
||||
{
|
||||
pIE->fResX = fResX;
|
||||
pIE->fResY = fResY;
|
||||
|
||||
return WMP_errSuccess;
|
||||
}
|
||||
|
||||
ERR PKImageEncode_SetColorContext(PKImageEncode *pIE,
|
||||
const U8 *pbColorContext,
|
||||
U32 cbColorContext)
|
||||
{
|
||||
UNREFERENCED_PARAMETER( pIE );
|
||||
UNREFERENCED_PARAMETER( pbColorContext );
|
||||
UNREFERENCED_PARAMETER( cbColorContext );
|
||||
return WMP_errNotYetImplemented;
|
||||
}
|
||||
|
||||
|
||||
ERR PKImageEncode_SetDescriptiveMetadata(PKImageEncode *pIE, const DESCRIPTIVEMETADATA *pDescMetadata)
|
||||
{
|
||||
UNREFERENCED_PARAMETER( pIE );
|
||||
UNREFERENCED_PARAMETER( pDescMetadata );
|
||||
return WMP_errNotYetImplemented;
|
||||
}
|
||||
|
||||
ERR PKImageEncode_WritePixels(
|
||||
PKImageEncode* pIE,
|
||||
U32 cLine,
|
||||
U8* pbPixels,
|
||||
U32 cbStride)
|
||||
{
|
||||
UNREFERENCED_PARAMETER( pIE );
|
||||
UNREFERENCED_PARAMETER( cLine );
|
||||
UNREFERENCED_PARAMETER( pbPixels );
|
||||
UNREFERENCED_PARAMETER( cbStride );
|
||||
return WMP_errAbstractMethod;
|
||||
}
|
||||
|
||||
ERR PKImageEncode_WriteSource(
|
||||
PKImageEncode* pIE,
|
||||
PKFormatConverter* pFC,
|
||||
PKRect* pRect)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
PKPixelFormatGUID enPFFrom = GUID_PKPixelFormatDontCare;
|
||||
PKPixelFormatGUID enPFTo = GUID_PKPixelFormatDontCare;
|
||||
|
||||
PKPixelInfo pPIFrom;
|
||||
PKPixelInfo pPITo;
|
||||
|
||||
U32 cbStrideTo = 0;
|
||||
U32 cbStrideFrom = 0;
|
||||
U32 cbStride = 0;
|
||||
|
||||
U8* pb = NULL;
|
||||
|
||||
// CWMTranscodingParam* pParam = NULL;
|
||||
|
||||
// get pixel format
|
||||
Call(pFC->GetSourcePixelFormat(pFC, &enPFFrom));
|
||||
Call(pFC->GetPixelFormat(pFC, &enPFTo));
|
||||
FailIf(!IsEqualGUID(&pIE->guidPixFormat, &enPFTo), WMP_errUnsupportedFormat);
|
||||
|
||||
// calc common stride
|
||||
// Call(GetPixelInfo(enPFFrom, &pPIFrom));
|
||||
pPIFrom.pGUIDPixFmt = &enPFFrom;
|
||||
PixelFormatLookup(&pPIFrom, LOOKUP_FORWARD);
|
||||
|
||||
// Call(GetPixelInfo(enPFTo, &pPITo));
|
||||
pPITo.pGUIDPixFmt = &enPFTo;
|
||||
PixelFormatLookup(&pPITo, LOOKUP_FORWARD);
|
||||
|
||||
// cbStrideFrom = (pPIFrom->cbPixel * pRect->Width + pPIFrom->cbPixelDenom - 1) / pPIFrom->cbPixelDenom;
|
||||
cbStrideFrom = (BD_1 == pPIFrom.bdBitDepth ? ((pPIFrom.cbitUnit * pRect->Width + 7) >> 3) : (((pPIFrom.cbitUnit + 7) >> 3) * pRect->Width));
|
||||
if (&GUID_PKPixelFormat12bppYUV420 == pPIFrom.pGUIDPixFmt
|
||||
|| &GUID_PKPixelFormat16bppYUV422 == pPIFrom.pGUIDPixFmt)
|
||||
cbStrideFrom >>= 1;
|
||||
|
||||
// cbStrideTo = (pPITo->cbPixel * pIE->uWidth + pPITo->cbPixelDenom - 1) / pPITo->cbPixelDenom;
|
||||
cbStrideTo = (BD_1 == pPITo.bdBitDepth ? ((pPITo.cbitUnit * pIE->uWidth + 7) >> 3) : (((pPITo.cbitUnit + 7) >> 3) * pIE->uWidth));
|
||||
if (&GUID_PKPixelFormat12bppYUV420 == pPITo.pGUIDPixFmt
|
||||
|| &GUID_PKPixelFormat16bppYUV422 == pPITo.pGUIDPixFmt)
|
||||
cbStrideTo >>= 1;
|
||||
|
||||
cbStride = max(cbStrideFrom, cbStrideTo);
|
||||
|
||||
// actual dec/enc with local buffer
|
||||
Call(PKAllocAligned((void **) &pb, cbStride * pRect->Height, 128));
|
||||
|
||||
Call(pFC->Copy(pFC, pRect, pb, cbStride));
|
||||
|
||||
Call(pIE->WritePixels(pIE, pRect->Height, pb, cbStride));
|
||||
|
||||
Cleanup:
|
||||
PKFreeAligned((void **) &pb);
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageEncode_WritePixelsBandedBegin(PKImageEncode* pEncoder, struct WMPStream *pPATempFile)
|
||||
{
|
||||
UNREFERENCED_PARAMETER( pEncoder );
|
||||
UNREFERENCED_PARAMETER( pPATempFile );
|
||||
return WMP_errAbstractMethod;
|
||||
}
|
||||
|
||||
ERR PKImageEncode_WritePixelsBanded(PKImageEncode* pEncoder, U32 cLines, U8* pbPixels, U32 cbStride, Bool fLastCall)
|
||||
{
|
||||
UNREFERENCED_PARAMETER( pEncoder );
|
||||
UNREFERENCED_PARAMETER( cLines );
|
||||
UNREFERENCED_PARAMETER( pbPixels );
|
||||
UNREFERENCED_PARAMETER( cbStride );
|
||||
UNREFERENCED_PARAMETER( fLastCall );
|
||||
return WMP_errAbstractMethod;
|
||||
}
|
||||
|
||||
ERR PKImageEncode_WritePixelsBandedEnd(PKImageEncode* pEncoder)
|
||||
{
|
||||
UNREFERENCED_PARAMETER( pEncoder );
|
||||
return WMP_errAbstractMethod;
|
||||
}
|
||||
|
||||
|
||||
ERR PKImageEncode_Transcode(
|
||||
PKImageEncode* pIE,
|
||||
PKFormatConverter* pFC,
|
||||
PKRect* pRect)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
PKPixelFormatGUID enPFFrom = GUID_PKPixelFormatDontCare;
|
||||
PKPixelFormatGUID enPFTo = GUID_PKPixelFormatDontCare;
|
||||
|
||||
PKPixelInfo pPIFrom;
|
||||
PKPixelInfo pPITo;
|
||||
|
||||
U32 cbStrideTo = 0;
|
||||
U32 cbStrideFrom = 0;
|
||||
U32 cbStride = 0;
|
||||
|
||||
U8* pb = NULL;
|
||||
|
||||
CWMTranscodingParam cParam = {0};
|
||||
|
||||
// get pixel format
|
||||
Call(pFC->GetSourcePixelFormat(pFC, &enPFFrom));
|
||||
Call(pFC->GetPixelFormat(pFC, &enPFTo));
|
||||
FailIf(!IsEqualGUID(&pIE->guidPixFormat, &enPFTo), WMP_errUnsupportedFormat);
|
||||
|
||||
// calc common stride
|
||||
// Call(GetPixelInfo(enPFFrom, &pPIFrom));
|
||||
pPIFrom.pGUIDPixFmt = &enPFFrom;
|
||||
PixelFormatLookup(&pPIFrom, LOOKUP_FORWARD);
|
||||
|
||||
// Call(GetPixelInfo(enPFTo, &pPITo));
|
||||
pPITo.pGUIDPixFmt = &enPFTo;
|
||||
PixelFormatLookup(&pPITo, LOOKUP_FORWARD);
|
||||
|
||||
// cbStrideFrom = (pPIFrom->cbPixel * pRect->Width + pPIFrom->cbPixelDenom - 1) / pPIFrom->cbPixelDenom;
|
||||
cbStrideFrom = (BD_1 == pPIFrom.bdBitDepth ? ((pPIFrom.cbitUnit * pRect->Width + 7) >> 3) : (((pPIFrom.cbitUnit + 7) >> 3) * pRect->Width));
|
||||
if (&GUID_PKPixelFormat12bppYUV420 == pPIFrom.pGUIDPixFmt
|
||||
|| &GUID_PKPixelFormat16bppYUV422 == pPIFrom.pGUIDPixFmt)
|
||||
cbStrideFrom >>= 1;
|
||||
|
||||
// cbStrideTo = (pPITo->cbPixel * pIE->uWidth + pPITo->cbPixelDenom - 1) / pPITo->cbPixelDenom;
|
||||
cbStrideTo = (BD_1 == pPITo.bdBitDepth ? ((pPITo.cbitUnit * pIE->uWidth + 7) >> 3) : (((pPITo.cbitUnit + 7) >> 3) * pIE->uWidth));
|
||||
if (&GUID_PKPixelFormat12bppYUV420 == pPITo.pGUIDPixFmt
|
||||
|| &GUID_PKPixelFormat16bppYUV422 == pPITo.pGUIDPixFmt)
|
||||
cbStrideTo >>= 1;
|
||||
|
||||
cbStride = max(cbStrideFrom, cbStrideTo);
|
||||
|
||||
if(pIE->bWMP){
|
||||
cParam.cLeftX = pFC->pDecoder->WMP.wmiI.cROILeftX;
|
||||
cParam.cTopY = pFC->pDecoder->WMP.wmiI.cROITopY;
|
||||
cParam.cWidth = pFC->pDecoder->WMP.wmiI.cROIWidth;
|
||||
cParam.cHeight = pFC->pDecoder->WMP.wmiI.cROIHeight;
|
||||
cParam.oOrientation = pFC->pDecoder->WMP.wmiI.oOrientation;
|
||||
// cParam.cfColorFormat = pFC->pDecoder->WMP.wmiI.cfColorFormat;
|
||||
cParam.uAlphaMode = pFC->pDecoder->WMP.wmiSCP.uAlphaMode;
|
||||
cParam.bfBitstreamFormat = pFC->pDecoder->WMP.wmiSCP.bfBitstreamFormat;
|
||||
cParam.sbSubband = pFC->pDecoder->WMP.wmiSCP.sbSubband;
|
||||
cParam.bIgnoreOverlap = pFC->pDecoder->WMP.bIgnoreOverlap;
|
||||
|
||||
Call(pIE->Transcode(pIE, pFC->pDecoder, &cParam));
|
||||
}
|
||||
else
|
||||
{
|
||||
// actual dec/enc with local buffer
|
||||
Call(PKAllocAligned((void **) &pb, cbStride * pRect->Height, 128));
|
||||
Call(pFC->Copy(pFC, pRect, pb, cbStride));
|
||||
Call(pIE->WritePixels(pIE, pRect->Height, pb, cbStride));
|
||||
}
|
||||
|
||||
Cleanup:
|
||||
PKFreeAligned((void **) &pb);
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PKImageEncode_CreateNewFrame(
|
||||
PKImageEncode* pIE,
|
||||
void* pvParam,
|
||||
size_t cbParam)
|
||||
{
|
||||
UNREFERENCED_PARAMETER( pIE );
|
||||
UNREFERENCED_PARAMETER( pvParam );
|
||||
UNREFERENCED_PARAMETER( cbParam );
|
||||
// NYI
|
||||
return WMP_errSuccess;
|
||||
}
|
||||
|
||||
ERR PKImageEncode_Release(
|
||||
PKImageEncode** ppIE)
|
||||
{
|
||||
PKImageEncode *pIE = *ppIE;
|
||||
pIE->pStream->Close(&pIE->pStream);
|
||||
|
||||
return PKFree((void **) ppIE);
|
||||
}
|
||||
|
||||
ERR PKImageEncode_Create(PKImageEncode** ppIE)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
PKImageEncode* pIE = NULL;
|
||||
|
||||
Call(PKAlloc((void **) ppIE, sizeof(**ppIE)));
|
||||
|
||||
pIE = *ppIE;
|
||||
pIE->Initialize = PKImageEncode_Initialize;
|
||||
pIE->Terminate = PKImageEncode_Terminate;
|
||||
pIE->SetPixelFormat = PKImageEncode_SetPixelFormat;
|
||||
pIE->SetSize = PKImageEncode_SetSize;
|
||||
pIE->SetResolution = PKImageEncode_SetResolution;
|
||||
pIE->SetColorContext = PKImageEncode_SetColorContext;
|
||||
pIE->SetDescriptiveMetadata = PKImageEncode_SetDescriptiveMetadata;
|
||||
pIE->WritePixels = PKImageEncode_WritePixels;
|
||||
// pIE->WriteSource = PKImageEncode_WriteSource;
|
||||
|
||||
pIE->WritePixelsBandedBegin = PKImageEncode_WritePixelsBandedBegin;
|
||||
pIE->WritePixelsBanded = PKImageEncode_WritePixelsBanded;
|
||||
pIE->WritePixelsBandedEnd = PKImageEncode_WritePixelsBandedEnd;
|
||||
|
||||
pIE->CreateNewFrame = PKImageEncode_CreateNewFrame;
|
||||
pIE->Release = PKImageEncode_Release;
|
||||
pIE->bWMP = FALSE;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
//================================================================
|
||||
// PKImageDecode
|
||||
//================================================================
|
||||
ERR PKImageDecode_Initialize(
|
||||
PKImageDecode* pID,
|
||||
struct WMPStream* pStream)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
|
||||
pID->pStream = pStream;
|
||||
pID->guidPixFormat = GUID_PKPixelFormatDontCare;
|
||||
pID->fResX = 96;
|
||||
pID->fResY = 96;
|
||||
pID->cFrame = 1;
|
||||
|
||||
Call(pID->pStream->GetPos(pID->pStream, &pID->offStart));
|
||||
|
||||
memset(&pID->WMP.wmiDEMisc, 0, sizeof(pID->WMP.wmiDEMisc));
|
||||
|
||||
Cleanup:
|
||||
return WMP_errSuccess;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_GetPixelFormat(
|
||||
PKImageDecode* pID,
|
||||
PKPixelFormatGUID* pPF)
|
||||
{
|
||||
*pPF = pID->guidPixFormat;
|
||||
|
||||
return WMP_errSuccess;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_GetSize(
|
||||
PKImageDecode* pID,
|
||||
I32* piWidth,
|
||||
I32* piHeight)
|
||||
{
|
||||
*piWidth = (I32)pID->uWidth;
|
||||
*piHeight = (I32)pID->uHeight;
|
||||
|
||||
return WMP_errSuccess;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_GetResolution(
|
||||
PKImageDecode* pID,
|
||||
Float* pfResX,
|
||||
Float* pfResY)
|
||||
{
|
||||
*pfResX = pID->fResX;
|
||||
*pfResY = pID->fResY;
|
||||
|
||||
return WMP_errSuccess;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_GetColorContext(PKImageDecode *pID, U8 *pbColorContext, U32 *pcbColorContext)
|
||||
{
|
||||
UNREFERENCED_PARAMETER( pID );
|
||||
UNREFERENCED_PARAMETER( pbColorContext );
|
||||
UNREFERENCED_PARAMETER( pcbColorContext );
|
||||
return WMP_errNotYetImplemented;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_GetDescriptiveMetadata(PKImageDecode *pIE, DESCRIPTIVEMETADATA *pDescMetadata)
|
||||
{
|
||||
UNREFERENCED_PARAMETER( pIE );
|
||||
UNREFERENCED_PARAMETER( pDescMetadata );
|
||||
return WMP_errNotYetImplemented;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_Copy(
|
||||
PKImageDecode* pID,
|
||||
const PKRect* pRect,
|
||||
U8* pb,
|
||||
U32 cbStride)
|
||||
{
|
||||
UNREFERENCED_PARAMETER( pID );
|
||||
UNREFERENCED_PARAMETER( pRect );
|
||||
UNREFERENCED_PARAMETER( pb );
|
||||
UNREFERENCED_PARAMETER( cbStride );
|
||||
return WMP_errAbstractMethod;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_GetFrameCount(
|
||||
PKImageDecode* pID,
|
||||
U32* puCount)
|
||||
{
|
||||
*puCount = pID->cFrame;
|
||||
|
||||
return WMP_errSuccess;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_SelectFrame(
|
||||
PKImageDecode* pID,
|
||||
U32 uFrame)
|
||||
{
|
||||
UNREFERENCED_PARAMETER( pID );
|
||||
UNREFERENCED_PARAMETER( uFrame );
|
||||
// NYI
|
||||
return WMP_errSuccess;
|
||||
}
|
||||
|
||||
ERR PKImageDecode_Release(
|
||||
PKImageDecode** ppID)
|
||||
{
|
||||
PKImageDecode* pID = *ppID;
|
||||
|
||||
pID->fStreamOwner && pID->pStream->Close(&pID->pStream);
|
||||
|
||||
return PKFree((void **) ppID);
|
||||
}
|
||||
|
||||
ERR PKImageDecode_Create(
|
||||
PKImageDecode** ppID)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
PKImageDecode* pID = NULL;
|
||||
|
||||
Call(PKAlloc((void **) ppID, sizeof(**ppID)));
|
||||
|
||||
pID = *ppID;
|
||||
pID->Initialize = PKImageDecode_Initialize;
|
||||
pID->GetPixelFormat = PKImageDecode_GetPixelFormat;
|
||||
pID->GetSize = PKImageDecode_GetSize;
|
||||
pID->GetResolution = PKImageDecode_GetResolution;
|
||||
pID->GetColorContext = PKImageDecode_GetColorContext;
|
||||
pID->GetDescriptiveMetadata = PKImageDecode_GetDescriptiveMetadata;
|
||||
pID->Copy = PKImageDecode_Copy;
|
||||
pID->GetFrameCount = PKImageDecode_GetFrameCount;
|
||||
pID->SelectFrame = PKImageDecode_SelectFrame;
|
||||
pID->Release = PKImageDecode_Release;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
|
@ -0,0 +1,642 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//*@@@---@@@@******************************************************************
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <JXRMeta.h>
|
||||
#include <guiddef.h>
|
||||
|
||||
//================================================================
|
||||
#define WMP_SDK_VERSION 0x0101
|
||||
#define PK_SDK_VERSION 0x0101
|
||||
|
||||
#define sizeof2(array) (sizeof(array)/sizeof(*(array)))
|
||||
#ifndef max
|
||||
#define max(a,b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef min
|
||||
#define min(b,a) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
#ifdef __ANSI__
|
||||
#define STRCPY_SAFE(pszDest, cbDest, pszSrc) (strncpy((pszDest), (pszSrc), (cbDest)) == (pszDest) ? 0 : 1)
|
||||
#else
|
||||
#define STRCPY_SAFE(pszDest, cbDest, pszSrc) (strcpy_s((pszDest), (cbDest), (pszSrc)))
|
||||
#endif // __ANSI__
|
||||
|
||||
//================================================================
|
||||
typedef struct tagPKRect
|
||||
{
|
||||
I32 X;
|
||||
I32 Y;
|
||||
I32 Width;
|
||||
I32 Height;
|
||||
} PKRect;
|
||||
|
||||
//================================================================
|
||||
typedef U32 PKIID;
|
||||
|
||||
EXTERN_C const PKIID IID_PKImageScanEncode;
|
||||
EXTERN_C const PKIID IID_PKImageFrameEncode;
|
||||
|
||||
EXTERN_C const PKIID IID_PKImageWmpEncode;
|
||||
|
||||
EXTERN_C const PKIID IID_PKImageWmpDecode;
|
||||
|
||||
struct IFDEntry
|
||||
{
|
||||
U16 uTag;
|
||||
U16 uType;
|
||||
U32 uCount;
|
||||
U32 uValue;
|
||||
};
|
||||
EXTERN_C const U32 IFDEntryTypeSizes[13];
|
||||
EXTERN_C const U32 SizeofIFDEntry;
|
||||
|
||||
//================================================================
|
||||
typedef float Float;
|
||||
|
||||
typedef enum tagPKStreamFlags
|
||||
{
|
||||
PKStreamOpenRead = 0x00000000UL,
|
||||
PKStreamOpenWrite = 0x00000001UL,
|
||||
PKStreamOpenReadWrite = 0x00000002UL,
|
||||
PKStreamNoLock = 0x00010000UL,
|
||||
PKStreamNoSeek = 0x00020000UL,
|
||||
PKStreamCompress = 0x00040000UL,
|
||||
} PKStreamFlags;
|
||||
|
||||
/* Undefined formats */
|
||||
#define GUID_PKPixelFormatUndefined GUID_PKPixelFormatDontCare
|
||||
|
||||
DEFINE_GUID(GUID_PKPixelFormatDontCare, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x00);
|
||||
|
||||
/* Indexed formats */
|
||||
//DEFINE_GUID(GUID_PKPixelFormat1bppIndexed, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x01);
|
||||
//DEFINE_GUID(GUID_PKPixelFormat2bppIndexed, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x02);
|
||||
//DEFINE_GUID(GUID_PKPixelFormat4bppIndexed, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x03);
|
||||
//DEFINE_GUID(GUID_PKPixelFormat8bppIndexed, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x04);
|
||||
|
||||
DEFINE_GUID(GUID_PKPixelFormatBlackWhite, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x05);
|
||||
//DEFINE_GUID(GUID_PKPixelFormat2bppGray, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x06);
|
||||
//DEFINE_GUID(GUID_PKPixelFormat4bppGray, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x07);
|
||||
DEFINE_GUID(GUID_PKPixelFormat8bppGray, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x08);
|
||||
|
||||
/* sRGB formats (gamma is approx. 2.2) */
|
||||
/* For a full definition, see the sRGB spec */
|
||||
|
||||
/* 16bpp formats */
|
||||
DEFINE_GUID(GUID_PKPixelFormat16bppRGB555, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x09);
|
||||
DEFINE_GUID(GUID_PKPixelFormat16bppRGB565, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0a);
|
||||
DEFINE_GUID(GUID_PKPixelFormat16bppGray, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0b);
|
||||
|
||||
/* 24bpp formats */
|
||||
DEFINE_GUID(GUID_PKPixelFormat24bppBGR, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0c);
|
||||
DEFINE_GUID(GUID_PKPixelFormat24bppRGB, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0d);
|
||||
|
||||
/* 32bpp format */
|
||||
DEFINE_GUID(GUID_PKPixelFormat32bppBGR, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0e);
|
||||
DEFINE_GUID(GUID_PKPixelFormat32bppBGRA, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0f);
|
||||
DEFINE_GUID(GUID_PKPixelFormat32bppPBGRA, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x10);
|
||||
DEFINE_GUID(GUID_PKPixelFormat32bppGrayFloat, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x11);
|
||||
DEFINE_GUID(GUID_PKPixelFormat32bppRGB, 0xd98c6b95, 0x3efe, 0x47d6, 0xbb, 0x25, 0xeb, 0x17, 0x48, 0xab, 0x0c, 0xf1);
|
||||
DEFINE_GUID(GUID_PKPixelFormat32bppRGBA, 0xf5c7ad2d, 0x6a8d, 0x43dd, 0xa7, 0xa8, 0xa2, 0x99, 0x35, 0x26, 0x1a, 0xe9);
|
||||
DEFINE_GUID(GUID_PKPixelFormat32bppPRGBA, 0x3cc4a650, 0xa527, 0x4d37, 0xa9, 0x16, 0x31, 0x42, 0xc7, 0xeb, 0xed, 0xba);
|
||||
|
||||
/* 48bpp format */
|
||||
DEFINE_GUID(GUID_PKPixelFormat48bppRGBFixedPoint, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x12);
|
||||
|
||||
/* scRGB formats. Gamma is 1.0 */
|
||||
/* For a full definition, see the scRGB spec */
|
||||
|
||||
/* 16bpp format */
|
||||
DEFINE_GUID(GUID_PKPixelFormat16bppGrayFixedPoint, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x13);
|
||||
|
||||
/* 32bpp format */
|
||||
DEFINE_GUID(GUID_PKPixelFormat32bppRGB101010, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x14);
|
||||
|
||||
/* 48bpp format */
|
||||
DEFINE_GUID(GUID_PKPixelFormat48bppRGB, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x15);
|
||||
|
||||
/* 64bpp format */
|
||||
DEFINE_GUID(GUID_PKPixelFormat64bppRGBA, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x16);
|
||||
DEFINE_GUID(GUID_PKPixelFormat64bppPRGBA, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x17);
|
||||
|
||||
/* 96bpp format */
|
||||
DEFINE_GUID(GUID_PKPixelFormat96bppRGBFixedPoint, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x18);
|
||||
DEFINE_GUID(GUID_PKPixelFormat96bppRGBFloat, 0xe3fed78f, 0xe8db, 0x4acf, 0x84, 0xc1, 0xe9, 0x7f, 0x61, 0x36, 0xb3, 0x27);
|
||||
|
||||
/* Floating point scRGB formats */
|
||||
DEFINE_GUID(GUID_PKPixelFormat128bppRGBAFloat, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x19);
|
||||
DEFINE_GUID(GUID_PKPixelFormat128bppPRGBAFloat, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1a);
|
||||
DEFINE_GUID(GUID_PKPixelFormat128bppRGBFloat, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1b);
|
||||
|
||||
/* CMYK formats. */
|
||||
DEFINE_GUID(GUID_PKPixelFormat32bppCMYK, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1c);
|
||||
|
||||
/* Photon formats */
|
||||
DEFINE_GUID(GUID_PKPixelFormat64bppRGBAFixedPoint, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1d);
|
||||
DEFINE_GUID(GUID_PKPixelFormat64bppRGBFixedPoint, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x40);
|
||||
DEFINE_GUID(GUID_PKPixelFormat128bppRGBAFixedPoint, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1e);
|
||||
DEFINE_GUID(GUID_PKPixelFormat128bppRGBFixedPoint, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x41);
|
||||
|
||||
DEFINE_GUID(GUID_PKPixelFormat64bppRGBAHalf, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x3a);
|
||||
DEFINE_GUID(GUID_PKPixelFormat64bppRGBHalf, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x42);
|
||||
DEFINE_GUID(GUID_PKPixelFormat48bppRGBHalf, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x3b);
|
||||
|
||||
DEFINE_GUID(GUID_PKPixelFormat32bppRGBE, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x3d);
|
||||
|
||||
DEFINE_GUID(GUID_PKPixelFormat16bppGrayHalf, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x3e);
|
||||
DEFINE_GUID(GUID_PKPixelFormat32bppGrayFixedPoint, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x3f);
|
||||
|
||||
|
||||
/* More CMYK formats and n-Channel formats */
|
||||
DEFINE_GUID(GUID_PKPixelFormat64bppCMYK, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1f);
|
||||
|
||||
DEFINE_GUID(GUID_PKPixelFormat24bpp3Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x20);
|
||||
DEFINE_GUID(GUID_PKPixelFormat32bpp4Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x21);
|
||||
DEFINE_GUID(GUID_PKPixelFormat40bpp5Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x22);
|
||||
DEFINE_GUID(GUID_PKPixelFormat48bpp6Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x23);
|
||||
DEFINE_GUID(GUID_PKPixelFormat56bpp7Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x24);
|
||||
DEFINE_GUID(GUID_PKPixelFormat64bpp8Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x25);
|
||||
|
||||
DEFINE_GUID(GUID_PKPixelFormat48bpp3Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x26);
|
||||
DEFINE_GUID(GUID_PKPixelFormat64bpp4Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x27);
|
||||
DEFINE_GUID(GUID_PKPixelFormat80bpp5Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x28);
|
||||
DEFINE_GUID(GUID_PKPixelFormat96bpp6Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x29);
|
||||
DEFINE_GUID(GUID_PKPixelFormat112bpp7Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2a);
|
||||
DEFINE_GUID(GUID_PKPixelFormat128bpp8Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2b);
|
||||
|
||||
DEFINE_GUID(GUID_PKPixelFormat40bppCMYKAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2c);
|
||||
DEFINE_GUID(GUID_PKPixelFormat80bppCMYKAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2d);
|
||||
|
||||
DEFINE_GUID(GUID_PKPixelFormat32bpp3ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2e);
|
||||
DEFINE_GUID(GUID_PKPixelFormat40bpp4ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2f);
|
||||
DEFINE_GUID(GUID_PKPixelFormat48bpp5ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x30);
|
||||
DEFINE_GUID(GUID_PKPixelFormat56bpp6ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x31);
|
||||
DEFINE_GUID(GUID_PKPixelFormat64bpp7ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x32);
|
||||
DEFINE_GUID(GUID_PKPixelFormat72bpp8ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x33);
|
||||
|
||||
DEFINE_GUID(GUID_PKPixelFormat64bpp3ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x34);
|
||||
DEFINE_GUID(GUID_PKPixelFormat80bpp4ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x35);
|
||||
DEFINE_GUID(GUID_PKPixelFormat96bpp5ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x36);
|
||||
DEFINE_GUID(GUID_PKPixelFormat112bpp6ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x37);
|
||||
DEFINE_GUID(GUID_PKPixelFormat128bpp7ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x38);
|
||||
DEFINE_GUID(GUID_PKPixelFormat144bpp8ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x39);
|
||||
|
||||
/* YCrCb from Advanced Profile */
|
||||
DEFINE_GUID(GUID_PKPixelFormat12bppYCC420, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x44);
|
||||
DEFINE_GUID(GUID_PKPixelFormat16bppYCC422, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x45);
|
||||
DEFINE_GUID(GUID_PKPixelFormat20bppYCC422, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x46);
|
||||
DEFINE_GUID(GUID_PKPixelFormat32bppYCC422, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x47);
|
||||
DEFINE_GUID(GUID_PKPixelFormat24bppYCC444, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x48);
|
||||
DEFINE_GUID(GUID_PKPixelFormat30bppYCC444, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x49);
|
||||
DEFINE_GUID(GUID_PKPixelFormat48bppYCC444, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x4a);
|
||||
DEFINE_GUID(GUID_PKPixelFormat16bpp48bppYCC444FixedPoint, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x4b);
|
||||
DEFINE_GUID(GUID_PKPixelFormat20bppYCC420Alpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x4c);
|
||||
DEFINE_GUID(GUID_PKPixelFormat24bppYCC422Alpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x4d);
|
||||
DEFINE_GUID(GUID_PKPixelFormat30bppYCC422Alpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x4e);
|
||||
DEFINE_GUID(GUID_PKPixelFormat48bppYCC422Alpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x4f);
|
||||
DEFINE_GUID(GUID_PKPixelFormat32bppYCC444Alpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x50);
|
||||
DEFINE_GUID(GUID_PKPixelFormat40bppYCC444Alpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x51);
|
||||
DEFINE_GUID(GUID_PKPixelFormat64bppYCC444Alpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x52);
|
||||
DEFINE_GUID(GUID_PKPixelFormat64bppYCC444AlphaFixedPoint, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x53);
|
||||
|
||||
//YUV
|
||||
#define GUID_PKPixelFormat12bppYUV420 GUID_PKPixelFormat12bppYCC420
|
||||
#define GUID_PKPixelFormat16bppYUV422 GUID_PKPixelFormat16bppYCC422
|
||||
#define GUID_PKPixelFormat24bppYUV444 GUID_PKPixelFormat24bppYCC444
|
||||
|
||||
/* CMYKDIRECT from Advanced Profile */
|
||||
DEFINE_GUID(GUID_PKPixelFormat32bppCMYKDIRECT, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x54);
|
||||
DEFINE_GUID(GUID_PKPixelFormat64bppCMYKDIRECT, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x55);
|
||||
DEFINE_GUID(GUID_PKPixelFormat40bppCMYKDIRECTAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x56);
|
||||
DEFINE_GUID(GUID_PKPixelFormat80bppCMYKDIRECTAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x43);
|
||||
|
||||
// PhotometricInterpretation
|
||||
#define PK_PI_W0 0 // WhiteIsZero
|
||||
#define PK_PI_B0 1 // BlackIsZero
|
||||
#define PK_PI_RGB 2
|
||||
#define PK_PI_RGBPalette 3
|
||||
#define PK_PI_TransparencyMask 4
|
||||
#define PK_PI_CMYK 5
|
||||
#define PK_PI_YCbCr 6
|
||||
#define PK_PI_CIELab 8
|
||||
|
||||
#define PK_PI_NCH 100
|
||||
#define PK_PI_RGBE 101
|
||||
|
||||
#define PK_pixfmtNul 0x00000000
|
||||
#define PK_pixfmtHasAlpha 0x00000010
|
||||
#define PK_pixfmtPreMul 0x00000020
|
||||
#define PK_pixfmtBGR 0x00000040
|
||||
#define PK_pixfmtNeedConvert 0x80000000
|
||||
|
||||
#define LOOKUP_FORWARD 0
|
||||
#define LOOKUP_BACKWARD_TIF 1
|
||||
|
||||
typedef unsigned long WMP_GRBIT;
|
||||
typedef GUID PKPixelFormatGUID;
|
||||
|
||||
typedef struct tagPKPixelInfo
|
||||
{
|
||||
const PKPixelFormatGUID* pGUIDPixFmt;
|
||||
|
||||
size_t cChannel;
|
||||
COLORFORMAT cfColorFormat;
|
||||
BITDEPTH_BITS bdBitDepth;
|
||||
U32 cbitUnit;
|
||||
|
||||
WMP_GRBIT grBit;
|
||||
|
||||
// TIFF
|
||||
U32 uInterpretation;
|
||||
U32 uSamplePerPixel;
|
||||
U32 uBitsPerSample;
|
||||
U32 uSampleFormat;
|
||||
} PKPixelInfo;
|
||||
|
||||
//================================================================
|
||||
ERR PKAlloc(void** ppv, size_t cb);
|
||||
ERR PKFree(void** ppv);
|
||||
|
||||
//----------------------------------------------------------------
|
||||
//ERR GetPixelInfo(PKPixelFormatGUID enPixelFormat, const PKPixelInfo** ppPI);
|
||||
ERR PixelFormatLookup(PKPixelInfo* pPI, U8 uLookupType);
|
||||
const PKPixelFormatGUID* GetPixelFormatFromHash(const U8 uPFHash);
|
||||
|
||||
ERR GetImageEncodeIID(const char* szExt, const PKIID** ppIID);
|
||||
ERR GetImageDecodeIID(const char* szExt, const PKIID** ppIID);
|
||||
|
||||
|
||||
//================================================================
|
||||
#ifdef __ANSI__
|
||||
struct tagPKFactory;
|
||||
struct tagPKCodecFactory;
|
||||
struct tagPKImageDecode;
|
||||
struct tagPKImageEncode;
|
||||
struct tagPKFormatConverter;
|
||||
#define PKFactory struct tagPKFactory
|
||||
#define PKCodecFactory struct tagPKCodecFactory
|
||||
#define PKImageDecode struct tagPKImageDecode
|
||||
#define PKImageEncode struct tagPKImageEncode
|
||||
#define PKFormatConverter struct tagPKFormatConverter
|
||||
#else // __ANSI__
|
||||
typedef struct tagPKFactory PKFactory;
|
||||
typedef struct tagPKCodecFactory PKCodecFactory;
|
||||
typedef struct tagPKImageDecode PKImageDecode;
|
||||
typedef struct tagPKImageEncode PKImageEncode;
|
||||
typedef struct tagPKFormatConverter PKFormatConverter;
|
||||
#endif // __ANSI__
|
||||
//================================================================
|
||||
typedef struct tagPKStream
|
||||
{
|
||||
ERR (*InitializeFromFilename)(const char*, ULong);
|
||||
|
||||
ERR (*Release)(void);
|
||||
|
||||
FILE* fp;
|
||||
} PKStream;
|
||||
|
||||
|
||||
//================================================================
|
||||
typedef struct tagPKFactory
|
||||
{
|
||||
ERR (*CreateStream)(PKStream**);
|
||||
|
||||
ERR (*CreateStreamFromFilename)(struct WMPStream**, const char*, const char*);
|
||||
ERR (*CreateStreamFromMemory)(struct WMPStream**, void*, size_t);
|
||||
|
||||
ERR (*Release)(PKFactory**);
|
||||
#ifdef __ANSI__
|
||||
#undef PKFactory
|
||||
#endif // __ANSI__
|
||||
} PKFactory;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
ERR PKCreateFactory_CreateStream(PKStream** ppStream);
|
||||
ERR PKCreateFactory_Release(PKFactory** ppFactory);
|
||||
|
||||
EXTERN_C ERR PKCreateFactory(PKFactory**, U32);
|
||||
|
||||
|
||||
//================================================================
|
||||
typedef struct tagPKCodecFactory
|
||||
{
|
||||
ERR (*CreateCodec)(const PKIID*, void**);
|
||||
ERR (*CreateDecoderFromFile)(const char*, PKImageDecode**);
|
||||
ERR (*CreateFormatConverter)(PKFormatConverter**);
|
||||
|
||||
ERR (*Release)(PKCodecFactory**);
|
||||
#ifdef __ANSI__
|
||||
#undef PKCodecFactory
|
||||
#endif // __ANSI__
|
||||
} PKCodecFactory;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
ERR PKCodecFactory_CreateCodec(const PKIID* iid, void** ppv);
|
||||
ERR PKCreateCodecFactory_Release(PKCodecFactory** ppCFactory);
|
||||
|
||||
EXTERN_C ERR PKCreateCodecFactory(PKCodecFactory**, U32);
|
||||
|
||||
//================================================================
|
||||
|
||||
typedef enum BANDEDENCSTATE
|
||||
{
|
||||
BANDEDENCSTATE_UNINITIALIZED = 0,
|
||||
BANDEDENCSTATE_INIT,
|
||||
BANDEDENCSTATE_ENCODING,
|
||||
BANDEDENCSTATE_TERMINATED,
|
||||
BANDEDENCSTATE_NONBANDEDENCODE,
|
||||
} BANDEDENCSTATE;
|
||||
|
||||
typedef struct tagPKImageEncode
|
||||
{
|
||||
//ERR (*GetPixelFormat)(MILPixelFormat*));
|
||||
ERR (*Initialize)(PKImageEncode*, struct WMPStream*, void*, size_t);
|
||||
ERR (*Terminate)(PKImageEncode*);
|
||||
|
||||
ERR (*SetPixelFormat)(PKImageEncode*, PKPixelFormatGUID);
|
||||
ERR (*SetSize)(PKImageEncode*, I32, I32);
|
||||
ERR (*SetResolution)(PKImageEncode*, Float, Float);
|
||||
ERR (*SetColorContext)(PKImageEncode *pIE, const U8 *pbColorContext,
|
||||
U32 cbColorContext);
|
||||
ERR (*SetDescriptiveMetadata)(PKImageEncode *pIE,
|
||||
const DESCRIPTIVEMETADATA *pDescMetadata);
|
||||
|
||||
ERR (*WritePixels)(PKImageEncode*, U32, U8*, U32);
|
||||
ERR (*WriteSource)(PKImageEncode*, PKFormatConverter*, PKRect*);
|
||||
|
||||
// Banded encode API - currently only implemented for WMP encoder
|
||||
ERR (*WritePixelsBandedBegin)(PKImageEncode* pEncoder, struct WMPStream *pPlanarAlphaTempFile);
|
||||
ERR (*WritePixelsBanded)(PKImageEncode* pEncoder, U32 cLines, U8* pbPixels, U32 cbStride, Bool fLastCall);
|
||||
ERR (*WritePixelsBandedEnd)(PKImageEncode* pEncoder);
|
||||
#define TEMPFILE_COPYBUF_SIZE 8192 // Means when using tempfile for planar alpha banded encode, copy this many bytes at a time
|
||||
|
||||
ERR (*Transcode)(PKImageEncode*, PKImageDecode*, CWMTranscodingParam*);
|
||||
|
||||
ERR (*CreateNewFrame)(PKImageEncode*, void*, size_t);
|
||||
|
||||
ERR (*Release)(PKImageEncode**);
|
||||
|
||||
struct WMPStream* pStream;
|
||||
size_t offStart;
|
||||
|
||||
PKPixelFormatGUID guidPixFormat;
|
||||
|
||||
U32 uWidth;
|
||||
U32 uHeight;
|
||||
U32 idxCurrentLine;
|
||||
|
||||
Float fResX;
|
||||
Float fResY;
|
||||
|
||||
U32 cFrame;
|
||||
|
||||
Bool fHeaderDone;
|
||||
size_t offPixel;
|
||||
size_t cbPixel;
|
||||
U8 *pbColorContext;
|
||||
U32 cbColorContext;
|
||||
U8 *pbEXIFMetadata;
|
||||
U32 cbEXIFMetadataByteCount;
|
||||
U8 *pbGPSInfoMetadata;
|
||||
U32 cbGPSInfoMetadataByteCount;
|
||||
U8 *pbIPTCNAAMetadata;
|
||||
U32 cbIPTCNAAMetadataByteCount;
|
||||
U8 *pbXMPMetadata;
|
||||
U32 cbXMPMetadataByteCount;
|
||||
U8 *pbPhotoshopMetadata;
|
||||
U32 cbPhotoshopMetadataByteCount;
|
||||
DESCRIPTIVEMETADATA sDescMetadata;
|
||||
|
||||
Bool bWMP;//for the encoder in decoding
|
||||
|
||||
struct
|
||||
{
|
||||
WmpDEMisc wmiDEMisc;
|
||||
CWMImageInfo wmiI;
|
||||
CWMIStrCodecParam wmiSCP;
|
||||
CTXSTRCODEC ctxSC;
|
||||
CWMImageInfo wmiI_Alpha;
|
||||
CWMIStrCodecParam wmiSCP_Alpha;
|
||||
CTXSTRCODEC ctxSC_Alpha;
|
||||
|
||||
Bool bHasAlpha;
|
||||
Long nOffImage;
|
||||
Long nCbImage;
|
||||
Long nOffAlpha;
|
||||
Long nCbAlpha;
|
||||
|
||||
ORIENTATION oOrientation;
|
||||
|
||||
// Banded encode state variables
|
||||
BANDEDENCSTATE eBandedEncState;
|
||||
struct WMPStream *pPATempFile;
|
||||
} WMP;
|
||||
|
||||
#ifdef __ANSI__
|
||||
#undef PKImageEncode
|
||||
#endif // __ANSI__
|
||||
} PKImageEncode;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
ERR PKImageEncode_Create_WMP(PKImageEncode** ppIE);
|
||||
|
||||
ERR PKImageEncode_Initialize(PKImageEncode* pIE, struct WMPStream* pStream, void* pvParam, size_t cbParam);
|
||||
ERR PKImageEncode_Terminate(PKImageEncode* pIE);
|
||||
ERR PKImageEncode_SetPixelFormat(PKImageEncode* pIE, PKPixelFormatGUID enPixelFormat);
|
||||
ERR PKImageEncode_SetSize(PKImageEncode* pIE, I32 iWidth, I32 iHeight);
|
||||
ERR PKImageEncode_SetResolution(PKImageEncode* pIE, Float rX, Float rY);
|
||||
ERR PKImageEncode_SetColorContext(PKImageEncode *pIE, const U8 *pbColorContext, U32 cbColorContext);
|
||||
ERR PKImageEncode_SetDescriptiveMetadata(PKImageEncode *pIE, const DESCRIPTIVEMETADATA *pDescMetadata);
|
||||
ERR PKImageEncode_WritePixels(PKImageEncode* pIE, U32 cLine, U8* pbPixel, U32 cbStride);
|
||||
ERR PKImageEncode_CreateNewFrame(PKImageEncode* pIE, void* pvParam, size_t cbParam);
|
||||
ERR PKImageEncode_Release(PKImageEncode** ppIE);
|
||||
|
||||
ERR PKImageEncode_SetXMPMetadata_WMP(PKImageEncode *pIE, const U8 *pbXMPMetadata, U32 cbXMPMetadata);
|
||||
ERR PKImageEncode_SetEXIFMetadata_WMP(PKImageEncode *pIE, const U8 *pbEXIFMetadata, U32 cbEXIFMetadata);
|
||||
ERR PKImageEncode_SetGPSInfoMetadata_WMP(PKImageEncode *pIE, const U8 *pbGPSInfoMetadata, U32 cbGPSInfoMetadata);
|
||||
ERR PKImageEncode_SetIPTCNAAMetadata_WMP(PKImageEncode *pIE, const U8 *pbIPTCNAAMetadata, U32 cbIPTCNAAMetadata);
|
||||
ERR PKImageEncode_SetPhotoshopMetadata_WMP(PKImageEncode *pIE, const U8 *pbPhotoshopMetadata, U32 cbPhotoshopMetadata);
|
||||
|
||||
void FreeDescMetadata(DPKPROPVARIANT *pvar);
|
||||
|
||||
ERR PKImageEncode_Create(PKImageEncode** ppIE);
|
||||
|
||||
//================================================================
|
||||
typedef struct tagPKImageDecode
|
||||
{
|
||||
ERR (*Initialize)(PKImageDecode*, struct WMPStream* pStream);
|
||||
|
||||
ERR (*GetPixelFormat)(PKImageDecode*, PKPixelFormatGUID*);
|
||||
ERR (*GetSize)(PKImageDecode*, I32*, I32*);
|
||||
ERR (*GetResolution)(PKImageDecode*, Float*, Float*);
|
||||
ERR (*GetColorContext)(PKImageDecode *pID, U8 *pbColorContext,
|
||||
U32 *pcbColorContext);
|
||||
ERR (*GetDescriptiveMetadata)(PKImageDecode *pIE,
|
||||
DESCRIPTIVEMETADATA *pDescMetadata);
|
||||
|
||||
ERR (*GetRawStream)(PKImageDecode*, struct WMPStream**);
|
||||
|
||||
ERR (*Copy)(PKImageDecode*, const PKRect*, U8*, U32);
|
||||
|
||||
ERR (*GetFrameCount)(PKImageDecode*, U32*);
|
||||
ERR (*SelectFrame)(PKImageDecode*, U32);
|
||||
|
||||
ERR (*Release)(PKImageDecode**);
|
||||
|
||||
struct WMPStream* pStream;
|
||||
Bool fStreamOwner;
|
||||
size_t offStart;
|
||||
|
||||
PKPixelFormatGUID guidPixFormat;
|
||||
|
||||
U32 uWidth;
|
||||
U32 uHeight;
|
||||
U32 idxCurrentLine;
|
||||
|
||||
Float fResX;
|
||||
Float fResY;
|
||||
|
||||
U32 cFrame;
|
||||
|
||||
struct
|
||||
{
|
||||
WmpDEMisc wmiDEMisc;
|
||||
CWMImageInfo wmiI;
|
||||
CWMIStrCodecParam wmiSCP;
|
||||
CTXSTRCODEC ctxSC;
|
||||
CWMImageInfo wmiI_Alpha;
|
||||
CWMIStrCodecParam wmiSCP_Alpha;
|
||||
CTXSTRCODEC ctxSC_Alpha;
|
||||
|
||||
Bool bHasAlpha;
|
||||
Long nOffImage;
|
||||
Long nCbImage;
|
||||
Long nOffAlpha;
|
||||
Long nCbAlpha;
|
||||
Bool bIgnoreOverlap;
|
||||
size_t DecoderCurrMBRow;
|
||||
size_t DecoderCurrAlphaMBRow;
|
||||
size_t cMarker;
|
||||
size_t cLinesDecoded;
|
||||
size_t cLinesCropped; // Lines may be cropped from the top - buffer for subsequent decodes must be adjusted
|
||||
Bool fFirstNonZeroDecode;
|
||||
|
||||
Bool fOrientationFromContainer;
|
||||
ORIENTATION oOrientationFromContainer; // Tag 0xBC02 in HD Photo container
|
||||
|
||||
DESCRIPTIVEMETADATA sDescMetadata;
|
||||
} WMP;
|
||||
|
||||
#ifdef __ANSI__
|
||||
#undef PKImageDecode
|
||||
#endif // __ANSI__
|
||||
} PKImageDecode;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
ERR PKImageDecode_Create_WMP(PKImageDecode** ppID);
|
||||
|
||||
ERR PKImageDecode_Initialize(PKImageDecode* pID, struct WMPStream* pStream);
|
||||
ERR PKImageDecode_GetPixelFormat(PKImageDecode* pID, PKPixelFormatGUID* pPF);
|
||||
ERR PKImageDecode_GetSize(PKImageDecode* pID, I32* piWidth, I32* piHeight);
|
||||
ERR PKImageDecode_GetResolution(PKImageDecode* pID, Float* pfrX, Float* pfrY);
|
||||
ERR PKImageDecode_GetColorContext(PKImageDecode *pID, U8 *pbColorContext, U32 *pcbColorContext);
|
||||
ERR PKImageDecode_GetDescriptiveMetadata(PKImageDecode *pID, DESCRIPTIVEMETADATA *pDescMetadata);
|
||||
ERR PKImageDecode_Copy(PKImageDecode* pID, const PKRect* pRect, U8* pb, U32 cbStride);
|
||||
ERR PKImageDecode_GetFrameCount(PKImageDecode* pID, U32* puCount);
|
||||
ERR PKImageDecode_SelectFrame(PKImageDecode* pID, U32 uFrame);
|
||||
ERR PKImageDecode_Release(PKImageDecode** ppID);
|
||||
|
||||
ERR PKImageDecode_GetXMPMetadata_WMP(PKImageDecode *pID, U8 *pbXMPMetadata, U32 *pcbXMPMetadata);
|
||||
ERR PKImageDecode_GetEXIFMetadata_WMP(PKImageDecode *pID, U8 *pbEXIFMetadata, U32 *pcbEXIFMetadata);
|
||||
ERR PKImageDecode_GetGPSInfoMetadata_WMP(PKImageDecode *pID, U8 *pbGPSInfoMetadata, U32 *pcbGPSInfoMetadata);
|
||||
ERR PKImageDecode_GetIPTCNAAMetadata_WMP(PKImageDecode *pID, U8 *pbIPTCNAAMetadata, U32 *pcbIPTCNAAMetadata);
|
||||
ERR PKImageDecode_GetPhotoshopMetadata_WMP(PKImageDecode *pID, U8 *pbPhotoshopMetadata, U32 *pcbPhotoshopMetadata);
|
||||
|
||||
ERR PKImageDecode_Create(PKImageDecode** ppID);
|
||||
ERR PKCodecFactory_CreateDecoderFromFile(const char* szFilename, PKImageDecode** ppDecoder);
|
||||
|
||||
//================================================================
|
||||
typedef struct tagPKFormatConverter
|
||||
{
|
||||
ERR (*Initialize)(PKFormatConverter*, PKImageDecode*, char *pExt, PKPixelFormatGUID);
|
||||
ERR (*InitializeConvert)(PKFormatConverter* pFC, const PKPixelFormatGUID enPFFrom,
|
||||
char *pExt, PKPixelFormatGUID enPFTTo);
|
||||
|
||||
ERR (*GetPixelFormat)(PKFormatConverter*, PKPixelFormatGUID*);
|
||||
ERR (*GetSourcePixelFormat)(PKFormatConverter*, PKPixelFormatGUID*);
|
||||
ERR (*GetSize)(PKFormatConverter*, I32*, I32*);
|
||||
ERR (*GetResolution)(PKFormatConverter*, Float*, Float*);
|
||||
|
||||
ERR (*Copy)(PKFormatConverter*, const PKRect*, U8*, U32);
|
||||
ERR (*Convert)(PKFormatConverter*, const PKRect*, U8*, U32);
|
||||
|
||||
ERR (*Release)(PKFormatConverter**);
|
||||
|
||||
PKImageDecode* pDecoder;
|
||||
PKPixelFormatGUID enPixelFormat;
|
||||
#ifdef __ANSI__
|
||||
#undef PKFormatConverter
|
||||
#endif // __ANSI__
|
||||
} PKFormatConverter;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
ERR PKImageEncode_Transcode(PKImageEncode* pIE, PKFormatConverter* pFC, PKRect* pRect);
|
||||
ERR PKImageEncode_WriteSource(PKImageEncode* pIE, PKFormatConverter* pFC, PKRect* pRect);
|
||||
ERR PKFormatConverter_Initialize(PKFormatConverter* pFC, PKImageDecode* pID, char *pExt, PKPixelFormatGUID enPF);
|
||||
ERR PKFormatConverter_InitializeConvert(PKFormatConverter* pFC, const PKPixelFormatGUID enPFFrom,
|
||||
char *pExt, PKPixelFormatGUID enPFTo);
|
||||
ERR PKFormatConverter_GetPixelFormat(PKFormatConverter* pFC, PKPixelFormatGUID* pPF);
|
||||
ERR PKFormatConverter_GetSourcePixelFormat(PKFormatConverter* pFC, PKPixelFormatGUID* pPF);
|
||||
ERR PKFormatConverter_GetSize(PKFormatConverter* pFC, I32* piWidth, I32* piHeight);
|
||||
ERR PKFormatConverter_GetResolution(PKFormatConverter* pFC, Float* pfrX, Float* pfrY);
|
||||
ERR PKFormatConverter_Copy(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride);
|
||||
ERR PKFormatConverter_Convert(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride);
|
||||
ERR PKFormatConverter_Release(PKFormatConverter** ppFC);
|
||||
|
||||
// Think of this as static member of PKFormatConverter "class"
|
||||
ERR PKFormatConverter_EnumConversions(const PKPixelFormatGUID *pguidSourcePF,
|
||||
const U32 iIndex,
|
||||
const PKPixelFormatGUID **ppguidTargetPF);
|
||||
|
||||
ERR PKCodecFactory_CreateFormatConverter(PKFormatConverter** ppFConverter);
|
||||
|
||||
//----------------------------------------------------------------
|
||||
ERR PKAlloc(void** ppv, size_t cb);
|
||||
ERR PKFree(void** ppv);
|
||||
ERR PKAllocAligned(void** ppv, size_t cb, size_t iAlign);
|
||||
ERR PKFreeAligned(void** ppv);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,905 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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 "JXRMeta.h"
|
||||
#include "JXRGlue.h"
|
||||
|
||||
|
||||
|
||||
// read and write big and little endian words/dwords from a buffer on both big and little endian cpu's
|
||||
// with full buffer overflow checking
|
||||
|
||||
|
||||
|
||||
ERR getbfcpy(U8* pbdest, const U8* pb, size_t cb, size_t ofs, U32 n)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
FailIf(ofs + n > cb, WMP_errBufferOverflow);
|
||||
memcpy(pbdest, &pb[ofs], n);
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ERR getbfw(const U8* pb, size_t cb, size_t ofs, U16* pw)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
FailIf(ofs + sizeof(U16) > cb, WMP_errBufferOverflow);
|
||||
*pw = (U16)( pb[ofs] + ( pb[ofs + 1] << 8 ) );
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ERR getbfdw(const U8* pb, size_t cb, size_t ofs, U32* pdw)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
FailIf(ofs + sizeof(U32) > cb, WMP_errBufferOverflow);
|
||||
*pdw = pb[ofs] + ( pb[ofs + 1] << 8 ) + ( pb[ofs + 2] << 16UL ) + ( pb[ofs + 3] << 24UL );
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ERR getbfwbig(const U8* pb, size_t cb, size_t ofs, U16* pw)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
FailIf(ofs + sizeof(U16) > cb, WMP_errBufferOverflow);
|
||||
*pw = (U16)( pb[ofs + 1] + ( pb[ofs] << 8 ) );
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ERR getbfdwbig(const U8* pb, size_t cb, size_t ofs, U32* pdw)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
FailIf(ofs + sizeof(U32) > cb, WMP_errBufferOverflow);
|
||||
*pdw = pb[ofs + 3] + ( pb[ofs + 2] << 8 ) + ( pb[ofs + 1] << 16UL ) + ( pb[ofs] << 24UL );
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ERR getbfwe(const U8* pb, size_t cb, size_t ofs, U16* pw, U8 endian)
|
||||
{
|
||||
if ( endian == WMP_INTEL_ENDIAN )
|
||||
return ( getbfw(pb, cb, ofs, pw) );
|
||||
else
|
||||
return ( getbfwbig(pb, cb, ofs, pw) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
ERR getbfdwe(const U8* pb, size_t cb, size_t ofs, U32* pdw, U8 endian)
|
||||
{
|
||||
if ( endian == WMP_INTEL_ENDIAN )
|
||||
return ( getbfdw(pb, cb, ofs, pdw) );
|
||||
else
|
||||
return ( getbfdwbig(pb, cb, ofs, pdw) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
ERR setbfcpy(U8* pb, size_t cb, size_t ofs, const U8* pbset, size_t cbset)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
FailIf(ofs + cbset > cb, WMP_errBufferOverflow);
|
||||
memcpy(&pb[ofs], pbset, cbset);
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ERR setbfw(U8* pb, size_t cb, size_t ofs, U16 dw)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
FailIf(ofs + sizeof(U16) > cb, WMP_errBufferOverflow);
|
||||
pb[ofs] = (U8)dw;
|
||||
pb[ofs + 1] = (U8)( dw >> 8 );
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ERR setbfdw(U8* pb, size_t cb, size_t ofs, U32 dw)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
FailIf(ofs + sizeof(U32) > cb, WMP_errBufferOverflow);
|
||||
pb[ofs] = (U8)dw;
|
||||
pb[ofs + 1] = (U8)( dw >> 8 );
|
||||
pb[ofs + 2] = (U8)( dw >> 16 );
|
||||
pb[ofs + 3] = (U8)( dw >> 24 );
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ERR setbfwbig(U8* pb, size_t cb, size_t ofs, U16 dw)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
FailIf(ofs + sizeof(U16) > cb, WMP_errBufferOverflow);
|
||||
pb[ofs + 1] = (U8)dw;
|
||||
pb[ofs] = (U8)( dw >> 8 );
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ERR setbfdwbig(U8* pb, size_t cb, size_t ofs, U32 dw)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
FailIf(ofs + sizeof(U32) > cb, WMP_errBufferOverflow);
|
||||
pb[ofs + 3] = (U8)dw;
|
||||
pb[ofs + 2] = (U8)( dw >> 8 );
|
||||
pb[ofs + 1] = (U8)( dw >> 16 );
|
||||
pb[ofs] = (U8)( dw >> 24 );
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================================================================
|
||||
// BufferCalcIFDSize (arbitrary endian)
|
||||
// StreamCalcIFDSize (little endian)
|
||||
//
|
||||
// count up the number of bytes needed to store the IFD and all
|
||||
// associated data including a subordinate interoperability IFD if any
|
||||
//================================================================
|
||||
|
||||
|
||||
|
||||
ERR BufferCalcIFDSize(const U8* pbdata, size_t cbdata, U32 ofsifd, U8 endian, U32* pcbifd)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
U16 cDir;
|
||||
U16 i;
|
||||
U32 ofsdir;
|
||||
U32 cbifd = 0;
|
||||
U32 cbEXIFIFD = 0;
|
||||
U32 cbGPSInfoIFD = 0;
|
||||
U32 cbInteroperabilityIFD = 0;
|
||||
|
||||
*pcbifd = 0;
|
||||
Call(getbfwe(pbdata, cbdata, ofsifd, &cDir, endian));
|
||||
|
||||
cbifd = sizeof(U16) + cDir * SizeofIFDEntry + sizeof(U32);
|
||||
ofsdir = ofsifd + sizeof(U16);
|
||||
for ( i = 0; i < cDir; i++ )
|
||||
{
|
||||
U16 tag;
|
||||
U16 type;
|
||||
U32 count;
|
||||
U32 value;
|
||||
U32 datasize;
|
||||
|
||||
Call(getbfwe(pbdata, cbdata, ofsdir, &tag, endian));
|
||||
Call(getbfwe(pbdata, cbdata, ofsdir + sizeof(U16), &type, endian));
|
||||
Call(getbfdwe(pbdata, cbdata, ofsdir + 2 * sizeof(U16), &count, endian));
|
||||
Call(getbfdwe(pbdata, cbdata, ofsdir + 2 * sizeof(U16) + sizeof(U32), &value, endian));
|
||||
FailIf(type == 0 || type >= sizeof(IFDEntryTypeSizes) / sizeof(IFDEntryTypeSizes[0]), WMP_errFail);
|
||||
if ( tag == WMP_tagEXIFMetadata )
|
||||
{
|
||||
Call(BufferCalcIFDSize(pbdata, cbdata, value, endian, &cbEXIFIFD));
|
||||
}
|
||||
else if ( tag == WMP_tagGPSInfoMetadata )
|
||||
{
|
||||
Call(BufferCalcIFDSize(pbdata, cbdata, value, endian, &cbGPSInfoIFD));
|
||||
}
|
||||
else if ( tag == WMP_tagInteroperabilityIFD )
|
||||
{
|
||||
Call(BufferCalcIFDSize(pbdata, cbdata, value, endian, &cbInteroperabilityIFD));
|
||||
}
|
||||
else
|
||||
{
|
||||
datasize = IFDEntryTypeSizes[type] * count;
|
||||
if ( datasize > 4 )
|
||||
cbifd += datasize;
|
||||
}
|
||||
ofsdir += SizeofIFDEntry;
|
||||
}
|
||||
if ( cbEXIFIFD != 0 )
|
||||
cbifd += ( cbifd & 1 ) + cbEXIFIFD;
|
||||
if ( cbGPSInfoIFD != 0 )
|
||||
cbifd += ( cbifd & 1 ) + cbGPSInfoIFD;
|
||||
if ( cbInteroperabilityIFD != 0 )
|
||||
cbifd += ( cbifd & 1 ) + cbInteroperabilityIFD;
|
||||
|
||||
*pcbifd = cbifd;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
ERR StreamCalcIFDSize(struct WMPStream* pWS, U32 uIFDOfs, U32 *pcbifd)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
size_t offCurPos = 0;
|
||||
Bool GetPosOK = FALSE;
|
||||
U16 cDir;
|
||||
U32 i;
|
||||
U32 ofsdir;
|
||||
U32 cbifd = 0;
|
||||
U32 cbEXIFIFD = 0;
|
||||
U32 cbGPSInfoIFD = 0;
|
||||
U32 cbInteroperabilityIFD = 0;
|
||||
|
||||
*pcbifd = 0;
|
||||
Call(pWS->GetPos(pWS, &offCurPos));
|
||||
GetPosOK = TRUE;
|
||||
|
||||
Call(GetUShort(pWS, uIFDOfs, &cDir));
|
||||
cbifd = sizeof(U16) + cDir * SizeofIFDEntry + sizeof(U32);
|
||||
ofsdir = uIFDOfs + sizeof(U16);
|
||||
for ( i = 0; i < cDir; i++ )
|
||||
{
|
||||
U16 tag;
|
||||
U16 type;
|
||||
U32 count;
|
||||
U32 value;
|
||||
U32 datasize;
|
||||
|
||||
Call(GetUShort(pWS, ofsdir, &tag));
|
||||
Call(GetUShort(pWS, ofsdir + sizeof(U16), &type));
|
||||
Call(GetULong(pWS, ofsdir + 2 * sizeof(U16), &count));
|
||||
Call(GetULong(pWS, ofsdir + 2 * sizeof(U16) + sizeof(U32), &value));
|
||||
FailIf(type == 0 || type >= sizeof(IFDEntryTypeSizes) / sizeof(IFDEntryTypeSizes[0]), WMP_errUnsupportedFormat);
|
||||
if ( tag == WMP_tagEXIFMetadata )
|
||||
{
|
||||
Call(StreamCalcIFDSize(pWS, value, &cbEXIFIFD));
|
||||
}
|
||||
else if ( tag == WMP_tagGPSInfoMetadata )
|
||||
{
|
||||
Call(StreamCalcIFDSize(pWS, value, &cbGPSInfoIFD));
|
||||
}
|
||||
else if ( tag == WMP_tagInteroperabilityIFD )
|
||||
{
|
||||
Call(StreamCalcIFDSize(pWS, value, &cbInteroperabilityIFD));
|
||||
}
|
||||
else
|
||||
{
|
||||
datasize = IFDEntryTypeSizes[type] * count;
|
||||
if ( datasize > 4 )
|
||||
cbifd += datasize;
|
||||
}
|
||||
ofsdir += SizeofIFDEntry;
|
||||
}
|
||||
if ( cbEXIFIFD != 0 )
|
||||
cbifd += ( cbifd & 1 ) + cbEXIFIFD;
|
||||
if ( cbGPSInfoIFD != 0 )
|
||||
cbifd += ( cbifd & 1 ) + cbGPSInfoIFD;
|
||||
if ( cbInteroperabilityIFD != 0 )
|
||||
cbifd += ( cbifd & 1 ) + cbInteroperabilityIFD;
|
||||
*pcbifd = cbifd;
|
||||
|
||||
Cleanup:
|
||||
if ( GetPosOK )
|
||||
Call(pWS->SetPos(pWS, offCurPos));
|
||||
return ( err );
|
||||
}
|
||||
|
||||
|
||||
|
||||
// src IFD copied to dst IFD with any nested IFD's
|
||||
// src IFD is arbitrary endian, arbitrary data arrangement
|
||||
// dst IFD is little endian, data arranged in tag order
|
||||
// dst IFD tags are ordered the same as src IFD so src IFD tags must be in order
|
||||
ERR BufferCopyIFD(const U8* pbsrc, U32 cbsrc, U32 ofssrc, U8 endian, U8* pbdst, U32 cbdst, U32* pofsdst)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
U16 cDir;
|
||||
U16 i;
|
||||
U16 ofsEXIFIFDEntry = 0;
|
||||
U16 ofsGPSInfoIFDEntry = 0;
|
||||
U16 ofsInteroperabilityIFDEntry = 0;
|
||||
U32 ofsEXIFIFD = 0;
|
||||
U32 ofsGPSInfoIFD = 0;
|
||||
U32 ofsInteroperabilityIFD = 0;
|
||||
U32 ofsdstnextdata;
|
||||
U32 ofsdst = *pofsdst;
|
||||
U32 ofssrcdir;
|
||||
U32 ofsdstdir;
|
||||
U32 ofsnextifd;
|
||||
|
||||
Call(getbfwe(pbsrc, cbsrc, ofssrc, &cDir, endian));
|
||||
Call(setbfw(pbdst, cbdst, ofsdst, cDir));
|
||||
ofsnextifd = ofsdst + sizeof(U16) + SizeofIFDEntry * cDir;
|
||||
ofsdstnextdata = ofsnextifd + sizeof(U32);
|
||||
|
||||
ofssrcdir = ofssrc + sizeof(U16);
|
||||
ofsdstdir = ofsdst + sizeof(U16);
|
||||
for ( i = 0; i < cDir; i++ )
|
||||
{
|
||||
U16 tag;
|
||||
U16 type;
|
||||
U32 count;
|
||||
U32 value;
|
||||
U32 size;
|
||||
|
||||
Call(getbfwe(pbsrc, cbsrc, ofssrcdir, &tag, endian));
|
||||
Call(setbfw(pbdst, cbdst, ofsdstdir, tag));
|
||||
|
||||
Call(getbfwe(pbsrc, cbsrc, ofssrcdir + sizeof(U16), &type, endian));
|
||||
Call(setbfw(pbdst, cbdst, ofsdstdir + sizeof(U16), type));
|
||||
|
||||
Call(getbfdwe(pbsrc, cbsrc, ofssrcdir + 2 * sizeof(U16), &count, endian));
|
||||
Call(setbfdw(pbdst, cbdst, ofsdstdir + 2 * sizeof(U16), count));
|
||||
|
||||
Call(getbfdwe(pbsrc, cbsrc, ofssrcdir + 2 * sizeof(U16) + sizeof(U32), &value, endian));
|
||||
Call(setbfdw(pbdst, cbdst, ofsdstdir + 2 * sizeof(U16) + sizeof(U32), 0));
|
||||
|
||||
FailIf(type == 0 || type >= sizeof(IFDEntryTypeSizes) / sizeof(IFDEntryTypeSizes[0]), WMP_errFail);
|
||||
if ( tag == WMP_tagEXIFMetadata )
|
||||
{
|
||||
ofsEXIFIFDEntry = (U16) ofsdstdir;
|
||||
ofsEXIFIFD = value;
|
||||
}
|
||||
else if ( tag == WMP_tagGPSInfoMetadata )
|
||||
{
|
||||
ofsGPSInfoIFDEntry = (U16) ofsdstdir;
|
||||
ofsGPSInfoIFD = value;
|
||||
}
|
||||
else if ( tag == WMP_tagInteroperabilityIFD )
|
||||
{
|
||||
ofsInteroperabilityIFDEntry = (U16) ofsdstdir;
|
||||
ofsInteroperabilityIFD = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
U32 ofsdstdata = ofsdstdir + 2 * sizeof(U16) + sizeof(U32);
|
||||
U32 ofssrcdata = ofssrcdir + 2 * sizeof(U16) + sizeof(U32);
|
||||
size = count * IFDEntryTypeSizes[type];
|
||||
if ( size > 4 )
|
||||
{
|
||||
ofssrcdata = value;
|
||||
Call(setbfdw(pbdst, cbdst, ofsdstdata, ofsdstnextdata));
|
||||
ofsdstdata = ofsdstnextdata;
|
||||
ofsdstnextdata += size;
|
||||
}
|
||||
FailIf(ofssrcdata + size > cbsrc || ofsdstdata + size > cbdst, WMP_errBufferOverflow);
|
||||
if ( size == count || endian == WMP_INTEL_ENDIAN )
|
||||
// size == count means 8-bit data means endian doesn't matter
|
||||
memcpy(&pbdst[ofsdstdata], &pbsrc[ofssrcdata], size);
|
||||
else
|
||||
{ // big endian source and endian matters
|
||||
U32 j;
|
||||
|
||||
switch ( IFDEntryTypeSizes[type] )
|
||||
{
|
||||
case 2:
|
||||
for ( j = 0; j < count; j++ )
|
||||
{
|
||||
U16 w;
|
||||
getbfwbig(pbsrc, cbsrc, ofssrcdata + j * sizeof(U16), &w);
|
||||
setbfw(pbdst, cbdst, ofsdstdata + j * sizeof(U16), w);
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if ( type == WMP_typDOUBLE )
|
||||
{
|
||||
for ( j = 0; j < count; j++ )
|
||||
{
|
||||
U32 dwlo;
|
||||
U32 dwhi;
|
||||
getbfdwbig(pbsrc, cbsrc, ofssrcdata + j * 8, &dwhi);
|
||||
getbfdwbig(pbsrc, cbsrc, ofssrcdata + j * 8 + sizeof(U32), &dwlo);
|
||||
setbfdw(pbdst, cbdst, ofsdstdata + j * 8, dwlo);
|
||||
setbfdw(pbdst, cbdst, ofsdstdata + j * 8 + sizeof(U32), dwhi);
|
||||
}
|
||||
break;
|
||||
}
|
||||
count *= 2;
|
||||
// RATIONAL's fall through to be handled as LONG's
|
||||
case 4:
|
||||
for ( j = 0; j < count; j++ )
|
||||
{
|
||||
U32 dw;
|
||||
getbfdwbig(pbsrc, cbsrc, ofssrcdata + j * sizeof(U32), &dw);
|
||||
setbfdw(pbdst, cbdst, ofsdstdata + j * sizeof(U32), dw);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ofssrcdir += SizeofIFDEntry;
|
||||
ofsdstdir += SizeofIFDEntry;
|
||||
}
|
||||
Call(setbfdw(pbdst, cbdst, ofsnextifd, 0)); // no nextIFD
|
||||
|
||||
if ( ofsEXIFIFDEntry != 0 )
|
||||
{
|
||||
ofsdstnextdata += ( ofsdstnextdata & 1 );
|
||||
Call(setbfdw(pbdst, cbdst, ofsEXIFIFDEntry + 2 * sizeof(U16) + sizeof(U32), ofsdstnextdata));
|
||||
Call(BufferCopyIFD(pbsrc, cbsrc, ofsEXIFIFD, endian, pbdst, cbdst, &ofsdstnextdata));
|
||||
}
|
||||
if ( ofsGPSInfoIFDEntry != 0 )
|
||||
{
|
||||
ofsdstnextdata += ( ofsdstnextdata & 1 );
|
||||
Call(setbfdw(pbdst, cbdst, ofsGPSInfoIFDEntry + 2 * sizeof(U16) + sizeof(U32), ofsdstnextdata));
|
||||
Call(BufferCopyIFD(pbsrc, cbsrc, ofsGPSInfoIFD, endian, pbdst, cbdst, &ofsdstnextdata));
|
||||
}
|
||||
if ( ofsInteroperabilityIFDEntry != 0 )
|
||||
{
|
||||
ofsdstnextdata += ( ofsdstnextdata & 1 );
|
||||
Call(setbfdw(pbdst, cbdst, ofsInteroperabilityIFDEntry + 2 * sizeof(U16) + sizeof(U32), ofsdstnextdata));
|
||||
Call(BufferCopyIFD(pbsrc, cbsrc, ofsInteroperabilityIFD, endian, pbdst, cbdst, &ofsdstnextdata));
|
||||
}
|
||||
*pofsdst = ofsdstnextdata;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// src IFD copied to dst IFD with any nested IFD's
|
||||
// src IFD is little endian, arbitrary data arrangement
|
||||
// dst IFD is little endian, data arranged in tag order
|
||||
// dst IFD tags are ordered the same as src IFD so src IFD tags must be in order
|
||||
ERR StreamCopyIFD(struct WMPStream* pWS, U32 ofssrc, U8* pbdst, U32 cbdst, U32* pofsdst)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
size_t offCurPos = 0;
|
||||
Bool GetPosOK = FALSE;
|
||||
U16 cDir;
|
||||
U16 i;
|
||||
U16 ofsEXIFIFDEntry = 0;
|
||||
U16 ofsGPSInfoIFDEntry = 0;
|
||||
U16 ofsInteroperabilityIFDEntry = 0;
|
||||
U32 ofsEXIFIFD = 0;
|
||||
U32 ofsGPSInfoIFD = 0;
|
||||
U32 ofsInteroperabilityIFD = 0;
|
||||
U32 ofsdstnextdata;
|
||||
U32 ofsdst = *pofsdst;
|
||||
U32 ofssrcdir;
|
||||
U32 ofsdstdir;
|
||||
U32 ofsnextifd;
|
||||
|
||||
Call(pWS->GetPos(pWS, &offCurPos));
|
||||
GetPosOK = TRUE;
|
||||
|
||||
Call(GetUShort(pWS, ofssrc, &cDir));
|
||||
Call(setbfw(pbdst, cbdst, ofsdst, cDir));
|
||||
|
||||
ofsnextifd = ofsdst + sizeof(U16) + SizeofIFDEntry * cDir;
|
||||
ofsdstnextdata = ofsnextifd + sizeof(U32);
|
||||
|
||||
ofssrcdir = ofssrc + sizeof(U16);
|
||||
ofsdstdir = ofsdst + sizeof(U16);
|
||||
for ( i = 0; i < cDir; i++ )
|
||||
{
|
||||
U16 tag;
|
||||
U16 type;
|
||||
U32 count;
|
||||
U32 value;
|
||||
U32 size;
|
||||
|
||||
Call(GetUShort(pWS, ofssrcdir, &tag));
|
||||
Call(setbfw(pbdst, cbdst, ofsdstdir, tag));
|
||||
|
||||
Call(GetUShort(pWS, ofssrcdir + sizeof(U16), &type));
|
||||
Call(setbfw(pbdst, cbdst, ofsdstdir + sizeof(U16), type));
|
||||
|
||||
Call(GetULong(pWS, ofssrcdir + 2 * sizeof(U16), &count));
|
||||
Call(setbfdw(pbdst, cbdst, ofsdstdir + 2 * sizeof(U16), count));
|
||||
|
||||
Call(GetULong(pWS, ofssrcdir + 2 * sizeof(U16) + sizeof(U32), &value));
|
||||
Call(setbfdw(pbdst, cbdst, ofsdstdir + 2 * sizeof(U16) + sizeof(U32), 0));
|
||||
|
||||
FailIf(type == 0 || type >= sizeof(IFDEntryTypeSizes) / sizeof(IFDEntryTypeSizes[0]), WMP_errFail);
|
||||
if ( tag == WMP_tagEXIFMetadata )
|
||||
{
|
||||
ofsEXIFIFDEntry = (U16) ofsdstdir;
|
||||
ofsEXIFIFD = value;
|
||||
}
|
||||
else if ( tag == WMP_tagGPSInfoMetadata )
|
||||
{
|
||||
ofsGPSInfoIFDEntry = (U16) ofsdstdir;
|
||||
ofsGPSInfoIFD = value;
|
||||
}
|
||||
else if ( tag == WMP_tagInteroperabilityIFD )
|
||||
{
|
||||
ofsInteroperabilityIFDEntry = (U16) ofsdstdir;
|
||||
ofsInteroperabilityIFD = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
U32 ofsdstdata = ofsdstdir + 2 * sizeof(U16) + sizeof(U32);
|
||||
U32 ofssrcdata = ofssrcdir + 2 * sizeof(U16) + sizeof(U32);
|
||||
size = count * IFDEntryTypeSizes[type];
|
||||
if ( size > 4 )
|
||||
{
|
||||
ofssrcdata = value;
|
||||
Call(setbfdw(pbdst, cbdst, ofsdstdata, ofsdstnextdata));
|
||||
ofsdstdata = ofsdstnextdata;
|
||||
ofsdstnextdata += size;
|
||||
}
|
||||
FailIf(ofsdstdata + size > cbdst, WMP_errBufferOverflow);
|
||||
Call(pWS->SetPos(pWS, ofssrcdata));
|
||||
Call(pWS->Read(pWS, &pbdst[ofsdstdata], size));
|
||||
}
|
||||
ofssrcdir += SizeofIFDEntry;
|
||||
ofsdstdir += SizeofIFDEntry;
|
||||
}
|
||||
Call(setbfdw(pbdst, cbdst, ofsnextifd, 0)); // no nextIFD
|
||||
|
||||
if ( ofsEXIFIFDEntry != 0 )
|
||||
{
|
||||
ofsdstnextdata += ( ofsdstnextdata & 1 );
|
||||
Call(setbfdw(pbdst, cbdst, ofsEXIFIFDEntry + 2 * sizeof(U16) + sizeof(U32), ofsdstnextdata));
|
||||
Call(StreamCopyIFD(pWS, ofsEXIFIFD, pbdst, cbdst, &ofsdstnextdata));
|
||||
}
|
||||
if ( ofsGPSInfoIFDEntry != 0 )
|
||||
{
|
||||
ofsdstnextdata += ( ofsdstnextdata & 1 );
|
||||
Call(setbfdw(pbdst, cbdst, ofsGPSInfoIFDEntry + 2 * sizeof(U16) + sizeof(U32), ofsdstnextdata));
|
||||
Call(StreamCopyIFD(pWS, ofsGPSInfoIFD, pbdst, cbdst, &ofsdstnextdata));
|
||||
}
|
||||
if ( ofsInteroperabilityIFDEntry != 0 )
|
||||
{
|
||||
ofsdstnextdata += ( ofsdstnextdata & 1 );
|
||||
Call(setbfdw(pbdst, cbdst, ofsInteroperabilityIFDEntry + 2 * sizeof(U16) + sizeof(U32), ofsdstnextdata));
|
||||
Call(StreamCopyIFD(pWS, ofsInteroperabilityIFD, pbdst, cbdst, &ofsdstnextdata));
|
||||
}
|
||||
*pofsdst = ofsdstnextdata;
|
||||
|
||||
Cleanup:
|
||||
if ( GetPosOK )
|
||||
Call(pWS->SetPos(pWS, offCurPos));
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================================================================
|
||||
ERR GetUShort(
|
||||
__in_ecount(1) struct WMPStream* pWS,
|
||||
size_t offPos,
|
||||
__out_ecount(1) U16* puValue)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
U8 cVal;
|
||||
|
||||
Call(pWS->SetPos(pWS, offPos));
|
||||
Call(pWS->Read(pWS, &cVal, sizeof(cVal)));
|
||||
puValue[0] = (U16) cVal;
|
||||
Call(pWS->Read(pWS, &cVal, sizeof(cVal)));
|
||||
puValue[0] += ((U16) cVal) << 8;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PutUShort(
|
||||
__in_ecount(1) struct WMPStream* pWS,
|
||||
size_t offPos,
|
||||
U16 uValue)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
U8 cVal = (U8) uValue;
|
||||
|
||||
Call(pWS->SetPos(pWS, offPos));
|
||||
Call(pWS->Write(pWS, &cVal, sizeof(cVal)));
|
||||
cVal = (U8) (uValue >> 8);
|
||||
Call(pWS->Write(pWS, &cVal, sizeof(cVal)));
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR GetULong(
|
||||
__in_ecount(1) struct WMPStream* pWS,
|
||||
size_t offPos,
|
||||
__out_ecount(1) U32* puValue)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
U8 cVal;
|
||||
|
||||
Call(pWS->SetPos(pWS, offPos));
|
||||
Call(pWS->Read(pWS, &cVal, sizeof(cVal)));
|
||||
puValue[0] = (U32) cVal;
|
||||
Call(pWS->Read(pWS, &cVal, sizeof(cVal)));
|
||||
puValue[0] += ((U32) cVal) << 8;
|
||||
Call(pWS->Read(pWS, &cVal, sizeof(cVal)));
|
||||
puValue[0] += ((U32) cVal) << 16;
|
||||
Call(pWS->Read(pWS, &cVal, sizeof(cVal)));
|
||||
puValue[0] += ((U32) cVal) << 24;
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
ERR PutULong(
|
||||
__in_ecount(1) struct WMPStream* pWS,
|
||||
size_t offPos,
|
||||
U32 uValue)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
U8 cVal = (U8) uValue;
|
||||
|
||||
Call(pWS->SetPos(pWS, offPos));
|
||||
Call(pWS->Write(pWS, &cVal, sizeof(cVal)));
|
||||
cVal = (U8) (uValue >> 8);
|
||||
Call(pWS->Write(pWS, &cVal, sizeof(cVal)));
|
||||
cVal = (U8) (uValue >> 16);
|
||||
Call(pWS->Write(pWS, &cVal, sizeof(cVal)));
|
||||
cVal = (U8) (uValue >> 24);
|
||||
Call(pWS->Write(pWS, &cVal, sizeof(cVal)));
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
ERR ReadBinaryData(__in_ecount(1) struct WMPStream* pWS,
|
||||
const __in_win U32 uCount,
|
||||
const __in_win U32 uValue,
|
||||
U8 **ppbData)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
U8 *pbData = NULL;
|
||||
|
||||
Call(PKAlloc((void **) &pbData, uCount + 2)); // Allocate buffer to store data with space for an added ascii or unicode null
|
||||
if (uCount <= 4)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < uCount; i++)
|
||||
pbData[i] = ((U8*)&uValue)[i]; // Copy least sig bytes - we assume 'II' type TIFF files
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t offPosPrev;
|
||||
|
||||
Call(pWS->GetPos(pWS, &offPosPrev));
|
||||
Call(pWS->SetPos(pWS, uValue));
|
||||
Call(pWS->Read(pWS, pbData, uCount));
|
||||
Call(pWS->SetPos(pWS, offPosPrev));
|
||||
}
|
||||
|
||||
*ppbData = pbData;
|
||||
|
||||
Cleanup:
|
||||
if (Failed(err))
|
||||
{
|
||||
if (pbData)
|
||||
PKFree((void **) &pbData);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
ERR ReadPropvar(__in_ecount(1) struct WMPStream* pWS,
|
||||
const __in_win U16 uType,
|
||||
const __in_win U32 uCount,
|
||||
const __in_win U32 uValue,
|
||||
__out_win DPKPROPVARIANT *pvar)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
// U8 *pbData = NULL;
|
||||
|
||||
memset(pvar, 0, sizeof(*pvar));
|
||||
if (uCount == 0)
|
||||
goto Cleanup; // Nothing to read in here
|
||||
|
||||
switch (uType)
|
||||
{
|
||||
case WMP_typASCII:
|
||||
pvar->vt = DPKVT_LPSTR;
|
||||
Call(ReadBinaryData(pWS, uCount, uValue, (U8 **) &pvar->VT.pszVal));
|
||||
assert(0 == pvar->VT.pszVal[uCount - 1]); // Check that it's null-terminated
|
||||
// make sure (ReadBinaryData allocated uCount + 2 so this and unicode can have forced nulls)
|
||||
pvar->VT.pszVal[uCount] = 0;
|
||||
break;
|
||||
|
||||
case WMP_typBYTE:
|
||||
case WMP_typUNDEFINED:
|
||||
// Return as regular C array rather than safearray, as this type is sometimes
|
||||
// used to convey unicode (which does not require a count field). Caller knows
|
||||
// uCount and can convert to safearray if necessary.
|
||||
pvar->vt = (DPKVT_BYREF | DPKVT_UI1);
|
||||
Call(ReadBinaryData(pWS, uCount, uValue, &pvar->VT.pbVal));
|
||||
break;
|
||||
|
||||
case WMP_typSHORT:
|
||||
if (1 == uCount)
|
||||
{
|
||||
pvar->vt = DPKVT_UI2;
|
||||
pvar->VT.uiVal = (U16)(uValue & 0x0000FFFF);
|
||||
}
|
||||
else if (2 == uCount)
|
||||
{
|
||||
pvar->vt = DPKVT_UI4;
|
||||
pvar->VT.ulVal = uValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(FALSE); // NYI
|
||||
FailIf(TRUE, WMP_errNotYetImplemented);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(FALSE); // Unhandled type
|
||||
FailIf(TRUE, WMP_errNotYetImplemented);
|
||||
break;
|
||||
}
|
||||
|
||||
Cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
ERR WriteWmpDE(
|
||||
__in_ecount(1) struct WMPStream* pWS,
|
||||
size_t *pOffPos,
|
||||
const __in_ecount(1) WmpDE* pDE,
|
||||
const U8 *pbData,
|
||||
U32 *pcbDataWrittenToOffset)
|
||||
{
|
||||
ERR err = WMP_errSuccess;
|
||||
size_t offPos = *pOffPos;
|
||||
|
||||
assert(-1 != pDE->uCount);
|
||||
assert(-1 != pDE->uValueOrOffset);
|
||||
|
||||
if (pcbDataWrittenToOffset)
|
||||
{
|
||||
assert(pbData); // Makes no sense to provide this arg without pbData
|
||||
*pcbDataWrittenToOffset = 0;
|
||||
}
|
||||
|
||||
Call(PutUShort(pWS, offPos, pDE->uTag)); offPos += 2;
|
||||
Call(PutUShort(pWS, offPos, pDE->uType)); offPos += 2;
|
||||
Call(PutULong(pWS, offPos, pDE->uCount)); offPos += 4;
|
||||
|
||||
switch (pDE->uType)
|
||||
{
|
||||
|
||||
case WMP_typASCII:
|
||||
case WMP_typUNDEFINED:
|
||||
case WMP_typBYTE:
|
||||
if (pDE->uCount <= 4)
|
||||
{
|
||||
U8 pad[4] = {0};
|
||||
Call(pWS->SetPos(pWS, offPos));
|
||||
|
||||
if (NULL == pbData)
|
||||
pbData = (U8*)&pDE->uValueOrOffset;
|
||||
|
||||
Call(pWS->Write(pWS, pbData, pDE->uCount));
|
||||
Call(pWS->Write(pWS, pad, 4 - pDE->uCount)); offPos += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
Call(PutULong(pWS, offPos, pDE->uValueOrOffset)); offPos += 4;
|
||||
|
||||
// Write the data if requested to do so
|
||||
if (pbData)
|
||||
{
|
||||
Call(pWS->SetPos(pWS, pDE->uValueOrOffset));
|
||||
Call(pWS->Write(pWS, pbData, pDE->uCount));
|
||||
Call(pWS->SetPos(pWS, offPos));
|
||||
*pcbDataWrittenToOffset = pDE->uCount;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WMP_typSHORT:
|
||||
if (pDE->uCount <= 2)
|
||||
{
|
||||
U16 uiShrt1 = 0;
|
||||
U16 uiShrt2 = 0;
|
||||
|
||||
if (NULL == pbData)
|
||||
pbData = (U8*)&pDE->uValueOrOffset;
|
||||
|
||||
if (pDE->uCount > 0)
|
||||
uiShrt1 = *((U16*)pbData);
|
||||
|
||||
if (pDE->uCount > 1)
|
||||
{
|
||||
assert(FALSE); // Untested - remove this assert after this has been tested
|
||||
uiShrt2 = *(U16*)(pbData + 2);
|
||||
}
|
||||
|
||||
Call(PutUShort(pWS, offPos, uiShrt1)); offPos += 2;
|
||||
Call(PutUShort(pWS, offPos, uiShrt2)); offPos += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(FALSE); // Untested - remove this assert after this has been tested
|
||||
Call(PutULong(pWS, offPos, pDE->uValueOrOffset)); offPos += 4;
|
||||
|
||||
// Write the data if requested to do so
|
||||
if (pbData)
|
||||
{
|
||||
U32 i;
|
||||
Call(pWS->SetPos(pWS, pDE->uValueOrOffset));
|
||||
for (i = 0; i < pDE->uCount; i++)
|
||||
{
|
||||
const U16 uiShort = *(U16*)(pbData + i*sizeof(U16));
|
||||
Call(PutUShort(pWS, offPos, uiShort)); // Write one at a time for endian purposes - but inefficient
|
||||
}
|
||||
Call(pWS->SetPos(pWS, offPos));
|
||||
*pcbDataWrittenToOffset = pDE->uCount * sizeof(U16);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case WMP_typFLOAT:
|
||||
case WMP_typLONG:
|
||||
if (pDE->uCount <= 1)
|
||||
{
|
||||
if (NULL == pbData)
|
||||
pbData = (U8*)&pDE->uValueOrOffset;
|
||||
|
||||
Call(PutULong(pWS, offPos, *(U32*)pbData)); offPos += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(FALSE); // Untested - remove this assert after this has been tested
|
||||
Call(PutULong(pWS, offPos, pDE->uValueOrOffset)); offPos += 4;
|
||||
|
||||
// Write the data if requested to do so
|
||||
if (pbData)
|
||||
{
|
||||
U32 i;
|
||||
Call(pWS->SetPos(pWS, pDE->uValueOrOffset));
|
||||
for (i = 0; i < pDE->uCount; i++)
|
||||
{
|
||||
const U32 uLong = *(U32*)(pbData + i*sizeof(U32));
|
||||
Call(PutULong(pWS, offPos, uLong)); // Write one at a time for endian purposes - but inefficient
|
||||
}
|
||||
Call(pWS->SetPos(pWS, offPos));
|
||||
*pcbDataWrittenToOffset = pDE->uCount * sizeof(U32);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(FALSE); // Alert the programmer
|
||||
Call(WMP_errInvalidParameter);
|
||||
break;
|
||||
}
|
||||
|
||||
Cleanup:
|
||||
*pOffPos = offPos;
|
||||
return err;
|
||||
}
|
||||
|
|
@ -0,0 +1,258 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//*@@@---@@@@******************************************************************
|
||||
#pragma once
|
||||
|
||||
#include <windowsmediaphoto.h>
|
||||
#ifndef WIN32
|
||||
#include <wmspecstring.h>
|
||||
#endif
|
||||
|
||||
#ifndef UNREFERENCED_PARAMETER
|
||||
#define UNREFERENCED_PARAMETER(P) { (P) = (P); }
|
||||
#endif
|
||||
|
||||
//================================================================
|
||||
// Container
|
||||
//================================================================
|
||||
|
||||
// Keep these in sort order so that we can easily confirm we are outputting tags in ascending order
|
||||
#define WMP_tagNull 0
|
||||
|
||||
#define WMP_tagDocumentName 0x010d // Descriptive metadata tag
|
||||
#define WMP_tagImageDescription 0x010e // Descriptive metadata tag
|
||||
#define WMP_tagCameraMake 0x010f // Descriptive metadata tag
|
||||
#define WMP_tagCameraModel 0x0110 // Descriptive metadata tag
|
||||
#define WMP_tagPageName 0x011d // Descriptive metadata tag
|
||||
#define WMP_tagPageNumber 0x0129 // Descriptive metadata tag
|
||||
#define WMP_tagSoftware 0x0131 // Descriptive metadata tag
|
||||
#define WMP_tagDateTime 0x0132 // Descriptive metadata tag
|
||||
#define WMP_tagArtist 0x013b // Descriptive metadata tag
|
||||
#define WMP_tagHostComputer 0x013c // Descriptive metadata tag
|
||||
|
||||
#define WMP_tagXMPMetadata 0x02bc
|
||||
|
||||
#define WMP_tagRatingStars 0x4746 // Descriptive metadata tag
|
||||
#define WMP_tagRatingValue 0x4749 // Descriptive metadata tag
|
||||
#define WMP_tagCopyright 0x8298 // Descriptive metadata tag
|
||||
|
||||
#define WMP_tagEXIFMetadata 0x8769
|
||||
#define WMP_tagGPSInfoMetadata 0x8825
|
||||
#define WMP_tagIPTCNAAMetadata 0x83bb
|
||||
#define WMP_tagPhotoshopMetadata 0x8649
|
||||
#define WMP_tagInteroperabilityIFD 0xa005
|
||||
#define WMP_tagIccProfile 0x8773 // Need to use same tag as TIFF!!
|
||||
|
||||
#define WMP_tagCaption 0x9c9b // Descriptive metadata tag
|
||||
|
||||
#define WMP_tagPixelFormat 0xbc01
|
||||
#define WMP_tagTransformation 0xbc02
|
||||
#define WMP_tagCompression 0xbc03
|
||||
#define WMP_tagImageType 0xbc04
|
||||
|
||||
#define WMP_tagImageWidth 0xbc80
|
||||
#define WMP_tagImageHeight 0xbc81
|
||||
|
||||
#define WMP_tagWidthResolution 0xbc82
|
||||
#define WMP_tagHeightResolution 0xbc83
|
||||
|
||||
#define WMP_tagImageOffset 0xbcc0
|
||||
#define WMP_tagImageByteCount 0xbcc1
|
||||
#define WMP_tagAlphaOffset 0xbcc2
|
||||
#define WMP_tagAlphaByteCount 0xbcc3
|
||||
#define WMP_tagImageDataDiscard 0xbcc4
|
||||
#define WMP_tagAlphaDataDiscard 0xbcc5
|
||||
|
||||
|
||||
#define WMP_typBYTE 1
|
||||
#define WMP_typASCII 2
|
||||
#define WMP_typSHORT 3
|
||||
#define WMP_typLONG 4
|
||||
#define WMP_typRATIONAL 5
|
||||
#define WMP_typSBYTE 6
|
||||
#define WMP_typUNDEFINED 7
|
||||
#define WMP_typSSHORT 8
|
||||
#define WMP_typSLONG 9
|
||||
#define WMP_typSRATIONAL 10
|
||||
#define WMP_typFLOAT 11
|
||||
#define WMP_typDOUBLE 12
|
||||
|
||||
|
||||
#define WMP_valCompression 0xbc
|
||||
#define WMP_valWMPhotoID WMP_valCompression
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#define __in_win __in
|
||||
#define __out_win __out
|
||||
#endif
|
||||
|
||||
|
||||
//================================================================
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DPKVT_EMPTY = 0,
|
||||
DPKVT_UI1 = 17,
|
||||
DPKVT_UI2 = 18,
|
||||
DPKVT_UI4 = 19,
|
||||
DPKVT_LPSTR = 30,
|
||||
DPKVT_LPWSTR = 31,
|
||||
DPKVT_BYREF = 0x4000,
|
||||
} DPKVARTYPE;
|
||||
|
||||
typedef struct DPKPROPVARIANT
|
||||
{
|
||||
DPKVARTYPE vt;
|
||||
union
|
||||
{
|
||||
U8 bVal; // DPKVT_UI1
|
||||
U16 uiVal; // DPKVT_UI2
|
||||
U32 ulVal; // DPKVT_UI4
|
||||
char *pszVal; // DPKVT_LPSTR
|
||||
U16 *pwszVal; // DPKVT_LPWSTR
|
||||
U8 *pbVal; // DPKVT_BYREF | DPKVT_UI1
|
||||
} VT;
|
||||
} DPKPROPVARIANT;
|
||||
|
||||
typedef struct DESCRIPTIVEMETADATA
|
||||
{
|
||||
DPKPROPVARIANT pvarImageDescription; // WMP_tagImageDescription
|
||||
DPKPROPVARIANT pvarCameraMake; // WMP_tagCameraMake
|
||||
DPKPROPVARIANT pvarCameraModel; // WMP_tagCameraModel
|
||||
DPKPROPVARIANT pvarSoftware; // WMP_tagSoftware
|
||||
DPKPROPVARIANT pvarDateTime; // WMP_tagDateTime
|
||||
DPKPROPVARIANT pvarArtist; // WMP_tagArtist
|
||||
DPKPROPVARIANT pvarCopyright; // WMP_tagCopyright
|
||||
DPKPROPVARIANT pvarRatingStars; // WMP_tagRatingStars
|
||||
DPKPROPVARIANT pvarRatingValue; // WMP_tagRatingValue
|
||||
DPKPROPVARIANT pvarCaption; // WMP_tagCaption
|
||||
DPKPROPVARIANT pvarDocumentName; // WMP_tagDocumentName
|
||||
DPKPROPVARIANT pvarPageName; // WMP_tagPageName
|
||||
DPKPROPVARIANT pvarPageNumber; // WMP_tagPageNumber
|
||||
DPKPROPVARIANT pvarHostComputer; // WMP_tagHostComputer
|
||||
} DESCRIPTIVEMETADATA;
|
||||
|
||||
typedef struct tagWmpDE
|
||||
{
|
||||
U16 uTag;
|
||||
U16 uType;
|
||||
U32 uCount;
|
||||
U32 uValueOrOffset;
|
||||
} WmpDE;
|
||||
|
||||
typedef struct tagWmpDEMisc
|
||||
{
|
||||
U32 uImageOffset;
|
||||
U32 uImageByteCount;
|
||||
U32 uAlphaOffset;
|
||||
U32 uAlphaByteCount;
|
||||
|
||||
U32 uOffPixelFormat;
|
||||
U32 uOffImageByteCount;
|
||||
U32 uOffAlphaOffset;
|
||||
U32 uOffAlphaByteCount;
|
||||
U32 uColorProfileOffset;
|
||||
U32 uColorProfileByteCount;
|
||||
U32 uXMPMetadataOffset;
|
||||
U32 uXMPMetadataByteCount;
|
||||
U32 uEXIFMetadataOffset;
|
||||
U32 uEXIFMetadataByteCount;
|
||||
U32 uGPSInfoMetadataOffset;
|
||||
U32 uGPSInfoMetadataByteCount;
|
||||
U32 uIPTCNAAMetadataOffset;
|
||||
U32 uIPTCNAAMetadataByteCount;
|
||||
U32 uPhotoshopMetadataOffset;
|
||||
U32 uPhotoshopMetadataByteCount;
|
||||
U32 uDescMetadataOffset;
|
||||
U32 uDescMetadataByteCount;
|
||||
} WmpDEMisc;
|
||||
|
||||
|
||||
//================================================================
|
||||
EXTERN_C ERR GetUShort(
|
||||
__in_ecount(1) struct WMPStream* pWS,
|
||||
size_t offPos,
|
||||
__out_ecount(1) U16* puValue
|
||||
);
|
||||
|
||||
EXTERN_C ERR PutUShort(
|
||||
__in_ecount(1) struct WMPStream* pWS,
|
||||
size_t offPos,
|
||||
U16 uValue
|
||||
);
|
||||
|
||||
EXTERN_C ERR GetULong(
|
||||
__in_ecount(1) struct WMPStream* pWS,
|
||||
size_t offPos,
|
||||
__out_ecount(1) U32* puValue
|
||||
);
|
||||
|
||||
EXTERN_C ERR PutULong(
|
||||
__in_ecount(1) struct WMPStream* pWS,
|
||||
size_t offPos,
|
||||
U32 uValue
|
||||
);
|
||||
|
||||
EXTERN_C ERR WriteWmpDE(
|
||||
__in_ecount(1) struct WMPStream* pWS,
|
||||
size_t *pOffPos,
|
||||
const __in_ecount(1) WmpDE* pDE,
|
||||
const U8 *pbData,
|
||||
U32 *pcbDataWrittenToOffset
|
||||
);
|
||||
|
||||
|
||||
EXTERN_C ERR ReadPropvar(__in_ecount(1) struct WMPStream* pWS,
|
||||
const __in_win U16 uType,
|
||||
const __in_win U32 uCount,
|
||||
const __in_win U32 uValue,
|
||||
__out_win DPKPROPVARIANT *pvar);
|
||||
|
||||
|
||||
|
||||
// read and write little endian words/dwords from a buffer on both big and little endian cpu's
|
||||
// with full buffer overflow checking
|
||||
|
||||
#define WMP_INTEL_ENDIAN ('I')
|
||||
|
||||
EXTERN_C ERR getbfcpy(U8* pbdest, const U8* pb, size_t cb, size_t ofs, U32 n);
|
||||
EXTERN_C ERR getbfw(const U8* pb, size_t cb, size_t ofs, U16* pw);
|
||||
EXTERN_C ERR getbfdw(const U8* pb, size_t cb, size_t ofs, U32* pdw);
|
||||
EXTERN_C ERR getbfwbig(const U8* pb, size_t cb, size_t ofs, U16* pw);
|
||||
EXTERN_C ERR getbfdwbig(const U8* pb, size_t cb, size_t ofs, U32* pdw);
|
||||
EXTERN_C ERR getbfwe(const U8* pb, size_t cb, size_t ofs, U16* pw, U8 endian);
|
||||
EXTERN_C ERR getbfdwe(const U8* pb, size_t cb, size_t ofs, U32* pdw, U8 endian);
|
||||
EXTERN_C ERR setbfcpy(U8* pb, size_t cb, size_t ofs, const U8* pbset, size_t cbset);
|
||||
EXTERN_C ERR setbfw(U8* pb, size_t cb, size_t ofs, U16 dw);
|
||||
EXTERN_C ERR setbfdw(U8* pb, size_t cb, size_t ofs, U32 dw);
|
||||
EXTERN_C ERR setbfwbig(U8* pb, size_t cb, size_t ofs, U16 dw);
|
||||
EXTERN_C ERR setbfdwbig(U8* pb, size_t cb, size_t ofs, U32 dw);
|
||||
EXTERN_C ERR BufferCalcIFDSize(const U8* pb, size_t cb, U32 uIFDOfs, U8 endian, U32 *pcbifd);
|
||||
EXTERN_C ERR StreamCalcIFDSize(struct WMPStream* pWS, U32 uIFDOfs, U32 *pcbifd);
|
||||
EXTERN_C ERR BufferCopyIFD(const U8* pbsrc, U32 cbsrc, U32 ofssrc, U8 endian, U8* pbdest, U32 cbdest, U32* pofsdest);
|
||||
EXTERN_C ERR StreamCopyIFD(struct WMPStream* pWS, U32 ofssrc, U8* pbdest, U32 cbdest, U32* pofsdest);
|
Loading…
Reference in New Issue