From 8624b8567abdc069df472d77388972cfc0ae58b5 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 23 Jul 2023 12:21:38 +0200 Subject: [PATCH 01/98] some hacking - compiles and unittests work --- Src/JxrDecode/Jxr/JXRGlue.c | 7 +- Src/JxrDecode/Jxr/JXRTest.c | 182 +++++++++++++++++++++ Src/JxrDecode/Jxr/JXRTest.h | 22 +++ Src/JxrDecode/Jxr/JXRTestBmp.c | 4 + Src/JxrDecode/Jxr/JXRTestHdr.c | 3 + Src/JxrDecode/Jxr/JXRTestPnm.c | 5 + Src/JxrDecode/Jxr/JXRTestTif.c | 4 + Src/JxrDecode/Jxr/JXRTestWrapper.c | 88 +++++----- Src/JxrDecode/Jxr/JXRTestWrapper.h | 40 +++-- Src/JxrDecode/Jxr/adapthuff.c | 15 +- Src/JxrDecode/Jxr/common.h | 6 +- Src/JxrDecode/Jxr/decode.c | 12 +- Src/JxrDecode/Jxr/encode.c | 12 +- Src/JxrDecode/Jxr/image.c | 3 +- Src/JxrDecode/JxrDecode.cpp | 3 +- Src/JxrDecode/JxrDecode.h | 247 ++++++++++++++--------------- 16 files changed, 438 insertions(+), 215 deletions(-) diff --git a/Src/JxrDecode/Jxr/JXRGlue.c b/Src/JxrDecode/Jxr/JXRGlue.c index d1fb1e6b..687bc11e 100644 --- a/Src/JxrDecode/Jxr/JXRGlue.c +++ b/Src/JxrDecode/Jxr/JXRGlue.c @@ -255,9 +255,7 @@ ERR PixelFormatLookup(PKPixelInfo* pPI, U8 uLookupType) const PKPixelFormatGUID* GetPixelFormatFromHash(const U8 uPFHash) { - int i; - - for (i = 0; i < sizeof2(pixelInfo); i++) + for (int i = 0; i < sizeof2(pixelInfo); i++) { if (pixelInfo[i].pGUIDPixFmt->Data4[7] == uPFHash) return pixelInfo[i].pGUIDPixFmt; @@ -284,10 +282,9 @@ static ERR GetIIDInfo(const char* szExt, const PKIIDInfo** ppInfo) {".wdp", &IID_PKImageUnsupported, &IID_PKImageWmpDecode}, {".hdp", &IID_PKImageUnsupported, &IID_PKImageWmpDecode}, }; - size_t i = 0; *ppInfo = NULL; - for (i = 0; i < sizeof2(iidInfo); ++i) + for (size_t i = 0; i < sizeof2(iidInfo); ++i) { if (0 == PKStrnicmp(szExt, iidInfo[i].szExt, strlen(iidInfo[i].szExt))) { diff --git a/Src/JxrDecode/Jxr/JXRTest.c b/Src/JxrDecode/Jxr/JXRTest.c index 712c9216..4a60f470 100644 --- a/Src/JxrDecode/Jxr/JXRTest.c +++ b/Src/JxrDecode/Jxr/JXRTest.c @@ -27,6 +27,187 @@ //*@@@---@@@@****************************************************************** #include "JXRTest.h" +#include "JXRTestWrapper.h" +//EXTERN_C const PKIID IID_PKImageBmpDecode; +const PKIID IID_PKImageBmpDecode = 202; +const PKIID IID_PKImageEncodeWrapper = 109; +static ERR GetTestInfo(const char* szExt, const PKIIDInfo** ppInfo) +{ + ERR err = WMP_errSuccess; + + static PKIIDInfo iidInfo[] = { + {"wrapper", &IID_PKImageEncodeWrapper, /*don't care/not used*/&IID_PKImageBmpDecode }, + /* {".bmp", &IID_PKImageBmpEncode, &IID_PKImageBmpDecode}, + {".ppm", &IID_PKImagePnmEncode, &IID_PKImagePnmDecode}, + {".pgm", &IID_PKImagePnmEncode, &IID_PKImagePnmDecode}, + {".pnm", &IID_PKImagePnmEncode, &IID_PKImagePnmDecode}, + {".pfm", &IID_PKImagePnmEncode, &IID_PKImagePnmDecode}, + {".tif", &IID_PKImageTifEncode, &IID_PKImageTifDecode}, + {".hdr", &IID_PKImageHdrEncode, &IID_PKImageHdrDecode}, + {".iyuv", &IID_PKImageIyuvEncode, &IID_PKImageIyuvDecode}, + {".yuv422", &IID_PKImageYuv422Encode, &IID_PKImageYuv422Decode}, + {".yuv444", &IID_PKImageYuv444Encode, &IID_PKImageYuv444Decode},*/ + }; + 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 GetTestEncodeIID(const char* szExt, const PKIID** ppIID) +{ + ERR err = WMP_errSuccess; + + const PKIIDInfo* pInfo = NULL; + + Call(GetTestInfo(szExt, &pInfo)); + *ppIID = pInfo->pIIDEnc; + +Cleanup: + return err; +} + +//ERR PKImageEncode_Initialize_Wrapper(struct tagPKImageEncode* pIE, struct WMPStream* stream, void* vp, size_t size); +//ERR PKImageEncode_Create_Wrapper(struct tagPKImageEncode** ppIE); +//ERR PKImageEncode_WritePixels_Wrapper( +//struct PKImageEncode* pIE, +//U32 cLine, +//U8* pbPixel, +//U32 cbStride); +ERR PKImageEncode_Initialize_Wrapper(PKImageEncode* pIE, struct WMPStream* stream, void* vp, size_t size) +{ + if (size != sizeof(JxrTestWrapperInitializeInfo)) + { + return WMP_errInvalidArgument; + } + + JxrTestWrapperInitializeInfo* ptrInfo = (JxrTestWrapperInitializeInfo*)vp; + pIE->WRAPPER.info = *ptrInfo; + return WMP_errSuccess; +} + +ERR PKImageEncode_WritePixels_Wrapper( + PKImageEncode* pIE, + U32 cLine, + U8* pbPixel, + U32 cbStride) +{ + pIE->WRAPPER.info.pfnPutData( + pIE->guidPixFormat, + pIE->uWidth, + pIE->uHeight, + cLine, + pbPixel, + cbStride, + pIE->WRAPPER.info.userParamPutData); + return WMP_errSuccess; +} + +ERR PKImageEncode_Create_Wrapper(PKImageEncode** ppIE) +{ + ERR err = WMP_errSuccess; + + PKImageEncode* pIE = NULL; + + Call(PKImageEncode_Create(ppIE)); + + pIE = *ppIE; + pIE->Initialize = PKImageEncode_Initialize_Wrapper; + pIE->WritePixels = PKImageEncode_WritePixels_Wrapper; + +Cleanup: + return err; +} + + +ERR PKTestFactory_CreateCodec(const PKIID* iid, void** ppv) +{ + ERR err = WMP_errSuccess; + + /*if (IID_PKImageBmpEncode == *iid) + { + Call(PKImageEncode_Create_BMP((PKImageEncode**)ppv)); + } + else if (IID_PKImagePnmEncode == *iid) + { + Call(PKImageEncode_Create_PNM((PKImageEncode**)ppv)); + } + else if (IID_PKImageTifEncode == *iid) + { + Call(PKImageEncode_Create_TIF((PKImageEncode**)ppv)); + } + else if (IID_PKImageHdrEncode == *iid) + { + Call(PKImageEncode_Create_HDR((PKImageEncode**)ppv)); + } + else if (IID_PKImageIyuvEncode == *iid) + { + Call(PKImageEncode_Create_IYUV((PKImageEncode**)ppv)); + } + else if (IID_PKImageYuv422Encode == *iid) + { + Call(PKImageEncode_Create_YUV422((PKImageEncode**)ppv)); + } + else if (IID_PKImageYuv444Encode == *iid) + { + Call(PKImageEncode_Create_YUV444((PKImageEncode**)ppv)); + } + else */if (IID_PKImageEncodeWrapper == *iid) + { + Call(PKImageEncode_Create_Wrapper((PKImageEncode**)ppv)); + } + /* + else if (IID_PKImageBmpDecode == *iid) + { + Call(PKImageDecode_Create_BMP((PKTestDecode**)ppv)); + } + else if (IID_PKImagePnmDecode == *iid) + { + Call(PKImageDecode_Create_PNM((PKTestDecode**)ppv)); + } + else if (IID_PKImageTifDecode == *iid) + { + Call(PKImageDecode_Create_TIF((PKTestDecode**)ppv)); + } + else if (IID_PKImageHdrDecode == *iid) + { + Call(PKImageDecode_Create_HDR((PKTestDecode**)ppv)); + } + else if (IID_PKImageIyuvDecode == *iid) + { + Call(PKImageDecode_Create_IYUV((PKTestDecode**)ppv)); + } + else if (IID_PKImageYuv422Decode == *iid) + { + Call(PKImageDecode_Create_YUV422((PKTestDecode**)ppv)); + } + else if (IID_PKImageYuv444Decode == *iid) + { + Call(PKImageDecode_Create_YUV444((PKTestDecode**)ppv)); + }*/ + + else + { + Call(WMP_errUnsupportedFormat); + } + +Cleanup: + return err; +} + +#if false //================================================================ const PKIID IID_PKImagePnmEncode = 102; @@ -319,3 +500,4 @@ ERR PKTestDecode_Create( Cleanup: return err; } +#endif \ No newline at end of file diff --git a/Src/JxrDecode/Jxr/JXRTest.h b/Src/JxrDecode/Jxr/JXRTest.h index de34a4a9..8b9aa244 100644 --- a/Src/JxrDecode/Jxr/JXRTest.h +++ b/Src/JxrDecode/Jxr/JXRTest.h @@ -27,6 +27,27 @@ //*@@@---@@@@****************************************************************** #pragma once +//================================================================ +#include "JXRGlue.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef struct tagPKIIDInfo + { + const char* szExt; + const PKIID* pIIDEnc; + const PKIID* pIIDDec; + } PKIIDInfo; +ERR GetTestEncodeIID(const char* szExt, const PKIID** ppIID); +ERR PKTestFactory_CreateCodec(const PKIID* iid, void** ppv); +#ifdef __cplusplus +} +#endif +//================================================================ + + + +#if false #include "JXRGlue.h" #include "JXRTestWrapper.h" @@ -165,3 +186,4 @@ ERR PKTestDecode_Create(PKTestDecode** ppID); } // extern "C" #endif +#endif diff --git a/Src/JxrDecode/Jxr/JXRTestBmp.c b/Src/JxrDecode/Jxr/JXRTestBmp.c index 103e37bd..4e615af4 100644 --- a/Src/JxrDecode/Jxr/JXRTestBmp.c +++ b/Src/JxrDecode/Jxr/JXRTestBmp.c @@ -25,6 +25,9 @@ // POSSIBILITY OF SUCH DAMAGE. // //*@@@---@@@@****************************************************************** + +#if false + #include #include @@ -398,3 +401,4 @@ ERR PKImageDecode_Create_BMP( return err; } +#endif \ No newline at end of file diff --git a/Src/JxrDecode/Jxr/JXRTestHdr.c b/Src/JxrDecode/Jxr/JXRTestHdr.c index 195b3b5f..58dcc012 100644 --- a/Src/JxrDecode/Jxr/JXRTestHdr.c +++ b/Src/JxrDecode/Jxr/JXRTestHdr.c @@ -1,3 +1,4 @@ +#if false //*@@@+++@@@@****************************************************************** // // Copyright © Microsoft Corp. @@ -240,3 +241,5 @@ ERR PKImageDecode_Create_HDR( return err; } + +#endif \ No newline at end of file diff --git a/Src/JxrDecode/Jxr/JXRTestPnm.c b/Src/JxrDecode/Jxr/JXRTestPnm.c index 47111e5d..1f537b73 100644 --- a/Src/JxrDecode/Jxr/JXRTestPnm.c +++ b/Src/JxrDecode/Jxr/JXRTestPnm.c @@ -25,6 +25,9 @@ // POSSIBILITY OF SUCH DAMAGE. // //*@@@---@@@@****************************************************************** + +#if false + #ifndef ANSI #define _CRT_SECURE_NO_WARNINGS #endif// ANSI @@ -329,3 +332,5 @@ ERR PKImageDecode_Create_PNM( return err; } + +#endif \ No newline at end of file diff --git a/Src/JxrDecode/Jxr/JXRTestTif.c b/Src/JxrDecode/Jxr/JXRTestTif.c index d3cb9844..8cd21585 100644 --- a/Src/JxrDecode/Jxr/JXRTestTif.c +++ b/Src/JxrDecode/Jxr/JXRTestTif.c @@ -25,6 +25,9 @@ // POSSIBILITY OF SUCH DAMAGE. // //*@@@---@@@@****************************************************************** + +#if false + #include #include @@ -934,3 +937,4 @@ ERR PKImageDecode_Create_TIF(PKTestDecode** ppID) return err; } +#endif \ No newline at end of file diff --git a/Src/JxrDecode/Jxr/JXRTestWrapper.c b/Src/JxrDecode/Jxr/JXRTestWrapper.c index a33473c4..4b18cdea 100644 --- a/Src/JxrDecode/Jxr/JXRTestWrapper.c +++ b/Src/JxrDecode/Jxr/JXRTestWrapper.c @@ -6,47 +6,47 @@ #include "strcodec.h" #include "JXRTest.h" -ERR PKImageEncode_Initialize_Wrapper(PKImageEncode* pIE, struct WMPStream* stream, void* vp, size_t size) -{ - if (size!=sizeof(JxrTestWrapperInitializeInfo)) - { - return WMP_errInvalidArgument; - } - - JxrTestWrapperInitializeInfo* ptrInfo = (JxrTestWrapperInitializeInfo*)vp; - pIE->WRAPPER.info = *ptrInfo; - return WMP_errSuccess; -} - -ERR PKImageEncode_WritePixels_Wrapper( - PKImageEncode* pIE, - U32 cLine, - U8* pbPixel, - U32 cbStride) -{ - pIE->WRAPPER.info.pfnPutData( - pIE->guidPixFormat, - pIE->uWidth, - pIE->uHeight, - cLine, - pbPixel, - cbStride, - pIE->WRAPPER.info.userParamPutData); - return WMP_errSuccess; -} - -ERR PKImageEncode_Create_Wrapper(PKImageEncode** ppIE) -{ - ERR err = WMP_errSuccess; - - PKImageEncode* pIE = NULL; - - Call(PKImageEncode_Create(ppIE)); - - pIE = *ppIE; - pIE->Initialize = PKImageEncode_Initialize_Wrapper; - pIE->WritePixels = PKImageEncode_WritePixels_Wrapper; - -Cleanup: - return err; -} \ No newline at end of file +//ERR PKImageEncode_Initialize_Wrapper(PKImageEncode* pIE, struct WMPStream* stream, void* vp, size_t size) +//{ +// if (size!=sizeof(JxrTestWrapperInitializeInfo)) +// { +// return WMP_errInvalidArgument; +// } +// +// JxrTestWrapperInitializeInfo* ptrInfo = (JxrTestWrapperInitializeInfo*)vp; +// pIE->WRAPPER.info = *ptrInfo; +// return WMP_errSuccess; +//} +// +//ERR PKImageEncode_WritePixels_Wrapper( +// PKImageEncode* pIE, +// U32 cLine, +// U8* pbPixel, +// U32 cbStride) +//{ +// pIE->WRAPPER.info.pfnPutData( +// pIE->guidPixFormat, +// pIE->uWidth, +// pIE->uHeight, +// cLine, +// pbPixel, +// cbStride, +// pIE->WRAPPER.info.userParamPutData); +// return WMP_errSuccess; +//} +// +//ERR PKImageEncode_Create_Wrapper(PKImageEncode** ppIE) +//{ +// ERR err = WMP_errSuccess; +// +// PKImageEncode* pIE = NULL; +// +// Call(PKImageEncode_Create(ppIE)); +// +// pIE = *ppIE; +// pIE->Initialize = PKImageEncode_Initialize_Wrapper; +// pIE->WritePixels = PKImageEncode_WritePixels_Wrapper; +// +//Cleanup: +// return err; +//} \ No newline at end of file diff --git a/Src/JxrDecode/Jxr/JXRTestWrapper.h b/Src/JxrDecode/Jxr/JXRTestWrapper.h index d6f64d37..f299e2fb 100644 --- a/Src/JxrDecode/Jxr/JXRTestWrapper.h +++ b/Src/JxrDecode/Jxr/JXRTestWrapper.h @@ -1,14 +1,30 @@ #pragma once -typedef struct tagJxrTestWrapperInitializeInfo -{ - void(*pfnPutData)( - PKPixelFormatGUID pixeltype, - unsigned int width, - unsigned int height, - unsigned int cLines, - void* ptrData, - unsigned int stride, - void* userParam); - void* userParamPutData; -} JxrTestWrapperInitializeInfo; + +#ifdef __cplusplus +extern "C" { +#endif + typedef struct tagJxrTestWrapperInitializeInfo + { + void(*pfnPutData)( + PKPixelFormatGUID pixeltype, + unsigned int width, + unsigned int height, + unsigned int cLines, + void* ptrData, + unsigned int stride, + void* userParam); + void* userParamPutData; + } JxrTestWrapperInitializeInfo; + + //ERR PKImageEncode_Initialize_Wrapper(struct tagPKImageEncode* pIE, struct WMPStream* stream, void* vp, size_t size); + //ERR PKImageEncode_Create_Wrapper(struct tagPKImageEncode** ppIE); + //ERR PKImageEncode_WritePixels_Wrapper( + //struct PKImageEncode* pIE, + //U32 cLine, + //U8* pbPixel, + //U32 cbStride); + +#ifdef __cplusplus +} +#endif diff --git a/Src/JxrDecode/Jxr/adapthuff.c b/Src/JxrDecode/Jxr/adapthuff.c index 0aa12fbe..da1c584e 100644 --- a/Src/JxrDecode/Jxr/adapthuff.c +++ b/Src/JxrDecode/Jxr/adapthuff.c @@ -28,13 +28,6 @@ #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, @@ -127,9 +120,7 @@ static const short g12HuffLookupTable[5][56] = {{ **********************************************************************/ Void Clean (CAdaptiveHuffman *pAdHuff) { - if (pAdHuff == NULL) - return; - free (pAdHuff); + free(pAdHuff); } CAdaptiveHuffman *Allocate (Int iNSymbols, CODINGMODE cm) @@ -407,8 +398,8 @@ static const Int g12DeltaTable[] = { /********************************************************************** Adapt fixed length codes based on discriminant **********************************************************************/ -static const Int THRESHOLD = 8; -static const Int MEMORY = 8; +const Int THRESHOLD = 8; +const Int MEMORY = 8; Void AdaptDiscriminant (CAdaptiveHuffman *pAdHuff) { diff --git a/Src/JxrDecode/Jxr/common.h b/Src/JxrDecode/Jxr/common.h index 297a19a2..600dc3bc 100644 --- a/Src/JxrDecode/Jxr/common.h +++ b/Src/JxrDecode/Jxr/common.h @@ -124,8 +124,8 @@ Void Adapt (CAdaptiveHuffman *pAdHuff, Bool bFixedTables); Void AdaptFixed (CAdaptiveHuffman *pAdHuff); Void AdaptDiscriminant (CAdaptiveHuffman *pAdHuff); -#ifndef _PREFAST_ -#pragma warning(disable:4068) -#endif +////#ifndef _PREFAST_ +////#pragma warning(disable:4068) +////#endif #endif // WMI_COMMON_H diff --git a/Src/JxrDecode/Jxr/decode.c b/Src/JxrDecode/Jxr/decode.c index 70ec5f37..82195cc4 100644 --- a/Src/JxrDecode/Jxr/decode.c +++ b/Src/JxrDecode/Jxr/decode.c @@ -40,12 +40,12 @@ 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 +////#ifdef MEM_TRACE +////#define TRACE_MALLOC 1 +////#define TRACE_NEW 0 +////#define TRACE_HEAP 0 +////#include "memtrace.h" +////#endif /****************************************************************** Free Adaptive Huffman Table diff --git a/Src/JxrDecode/Jxr/encode.c b/Src/JxrDecode/Jxr/encode.c index bd4fceba..82db3415 100644 --- a/Src/JxrDecode/Jxr/encode.c +++ b/Src/JxrDecode/Jxr/encode.c @@ -32,12 +32,12 @@ #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 +////#ifdef MEM_TRACE +////#define TRACE_MALLOC 1 +////#define TRACE_NEW 0 +////#define TRACE_HEAP 0 +////#include "memtrace.h" +////#endif /************************************************************************* Context allocation diff --git a/Src/JxrDecode/Jxr/image.c b/Src/JxrDecode/Jxr/image.c index 32aa99c8..9bcfe4be 100644 --- a/Src/JxrDecode/Jxr/image.c +++ b/Src/JxrDecode/Jxr/image.c @@ -173,8 +173,7 @@ Void ResetCodingContext(CCodingContext *pContext) Void InitZigzagScan(CCodingContext * pContext) { if (NULL != pContext) { - Int i; - for (i=0; i<16; i++) { + for (Int 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]]; diff --git a/Src/JxrDecode/JxrDecode.cpp b/Src/JxrDecode/JxrDecode.cpp index 11cc3484..57fa2d13 100644 --- a/Src/JxrDecode/JxrDecode.cpp +++ b/Src/JxrDecode/JxrDecode.cpp @@ -7,7 +7,8 @@ #include #include "JxrDecode.h" #include "Jxr/JXRTest.h" -#include "Jxr/JXRTestWrapper.h" +//#include "Jxr/JXRTestWrapper.h" +#include "Jxr/JXRGlue.h" using namespace JxrDecode; diff --git a/Src/JxrDecode/JxrDecode.h b/Src/JxrDecode/JxrDecode.h index 66eb4671..73c312bf 100644 --- a/Src/JxrDecode/JxrDecode.h +++ b/Src/JxrDecode/JxrDecode.h @@ -10,129 +10,128 @@ namespace JxrDecode { - enum class PixelFormat + enum class PixelFormat + { + dontCare, + _24bppBGR, + _1bppBlackWhite, + _8bppGray, + _16bppGray, + _16bppGrayFixedPoint, + _16bppGrayHalf, + _32bppGrayFixedPoint, + _32bppGrayFloat, + _24bppRGB, + _48bppRGB, + _48bppRGBFixedPoint, + _48bppRGBHalf, + _96bppRGBFixedPoint, + _128bppRGBFloat, + _32bppRGBE, + _32bppCMYK, + _64bppCMYK, + _32bppBGRA, + _64bppRGBA, + _64bppRGBAFixedPoint, + _64bppRGBAHalf, + _128bppRGBAFixedPoint, + _128bppRGBAFloat, + _16bppBGR555, + _16bppBGR565, + _32bppBGR101010, + _40bppCMYKA, + _80bppCMYKA, + _32bppBGR, + + invalid + }; + + const char* PixelFormatAsInformalString(PixelFormat pfmt); + + enum class Orientation :std::uint8_t + { + // 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 + }; + + enum class Subband : std::uint8_t + { + 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 + }; + + struct WMPDECAPPARGS + { + JxrDecode::PixelFormat pixFormat; + + // region decode + size_t rLeftX; + size_t rTopY; + size_t rWidth; + size_t rHeight; + + std::uint8_t cPostProcStrength; + JxrDecode::Orientation oOrientation; + JxrDecode::Subband sbSubband; + /* // thumbnail + size_t tThumbnailFactor; + + // orientation + ORIENTATION oOrientation; + + // post processing + U8 cPostProcStrength; + */ + std::uint8_t uAlphaMode; // 0:no alpha 1: alpha only else: something + alpha + /* + SUBBAND sbSubband; // which subbands to keep (for transcoding) + + BITSTREAMFORMAT bfBitstreamFormat; // desired bitsream format (for transcoding) + + CWMIStrCodecParam wmiSCP; + + Bool bIgnoreOverlap;*/ + bool bIgnoreOverlap; + + void Clear() { - dontCare, - _24bppBGR, - _1bppBlackWhite, - _8bppGray, - _16bppGray, - _16bppGrayFixedPoint, - _16bppGrayHalf, - _32bppGrayFixedPoint, - _32bppGrayFloat, - _24bppRGB, - _48bppRGB, - _48bppRGBFixedPoint, - _48bppRGBHalf, - _96bppRGBFixedPoint, - _128bppRGBFloat, - _32bppRGBE, - _32bppCMYK, - _64bppCMYK, - _32bppBGRA, - _64bppRGBA, - _64bppRGBAFixedPoint, - _64bppRGBAHalf, - _128bppRGBAFixedPoint, - _128bppRGBAFloat, - _16bppBGR555, - _16bppBGR565, - _32bppBGR101010, - _40bppCMYKA, - _80bppCMYKA, - _32bppBGR, - - invalid - }; - - const char* PixelFormatAsInformalString(PixelFormat pfmt); - - enum class Orientation :std::uint8_t - { - // 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 - }; - - enum class Subband : std::uint8_t - { - 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 - }; - - struct WMPDECAPPARGS - { - JxrDecode::PixelFormat pixFormat; - - // region decode - size_t rLeftX; - size_t rTopY; - size_t rWidth; - size_t rHeight; - - std::uint8_t cPostProcStrength; - JxrDecode::Orientation oOrientation; - JxrDecode::Subband sbSubband; - /* // thumbnail - size_t tThumbnailFactor; - - // orientation - ORIENTATION oOrientation; - - // post processing - U8 cPostProcStrength; - */ - std::uint8_t uAlphaMode; // 0:no alpha 1: alpha only else: something + alpha - /* - SUBBAND sbSubband; // which subbands to keep (for transcoding) - - BITSTREAMFORMAT bfBitstreamFormat; // desired bitsream format (for transcoding) - - CWMIStrCodecParam wmiSCP; - - Bool bIgnoreOverlap;*/ - bool bIgnoreOverlap; - - void Clear() - { - memset(this, 0, sizeof(*this)); - this->pixFormat = JxrDecode::PixelFormat::dontCare; - //args->bVerbose = FALSE; - //args->tThumbnailFactor = 0; - this->oOrientation = Orientation::O_NONE; - this->cPostProcStrength = 0; - this->uAlphaMode = 255; - this->sbSubband = JxrDecode::Subband::SB_ALL; - } - }; - - - typedef void* codecHandle; - - codecHandle Initialize(); - - void Decode( - codecHandle h, - const WMPDECAPPARGS* decArgs, - const void* ptrData, - size_t size, - const std::function& selectDestPixFmt, - std::function deliverData); - - void Destroy(codecHandle h); - + memset(this, 0, sizeof(*this)); + this->pixFormat = JxrDecode::PixelFormat::dontCare; + //args->bVerbose = FALSE; + //args->tThumbnailFactor = 0; + this->oOrientation = Orientation::O_NONE; + this->cPostProcStrength = 0; + this->uAlphaMode = 255; + this->sbSubband = JxrDecode::Subband::SB_ALL; + } + }; + + + typedef void* codecHandle; + + codecHandle Initialize(); + + void Decode( + codecHandle h, + const WMPDECAPPARGS* decArgs, + const void* ptrData, + size_t size, + const std::function& selectDestPixFmt, + std::function deliverData); + + void Destroy(codecHandle h); } From 2d552aa5464b81842d9f9ce15c4c541e4c50dc7e Mon Sep 17 00:00:00 2001 From: ptahmose Date: Wed, 26 Jul 2023 23:48:39 +0200 Subject: [PATCH 02/98] somewhat working now --- Src/JxrDecode/CMakeLists.txt | 64 +- Src/JxrDecode/JxrDecode.cpp | 13 +- Src/JxrDecode/JxrDecode2.cpp | 182 + Src/JxrDecode/JxrDecode2.h | 55 + Src/JxrDecode/jxrlib/common/include/guiddef.h | 232 ++ .../jxrlib/common/include/wmspecstring.h | 342 ++ .../jxrlib/common/include/wmspecstrings_adt.h | 71 + Src/JxrDecode/jxrlib/image/decode/decode.c | 200 + Src/JxrDecode/jxrlib/image/decode/decode.h | 143 + Src/JxrDecode/jxrlib/image/decode/segdec.c | 1208 ++++++ .../jxrlib/image/decode/strInvTransform.c | 1888 +++++++++ .../jxrlib/image/decode/strPredQuantDec.c | 539 +++ Src/JxrDecode/jxrlib/image/decode/strdec.c | 3628 +++++++++++++++++ Src/JxrDecode/jxrlib/image/sys/common.h | 131 + Src/JxrDecode/jxrlib/image/sys/strTransform.h | 50 + Src/JxrDecode/jxrlib/image/sys/strcodec.c | 1257 ++++++ Src/JxrDecode/jxrlib/image/sys/strcodec.h | 679 +++ .../jxrlib/image/sys/windowsmediaphoto.h | 515 +++ Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c | 975 +++++ Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h | 645 +++ Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c | 2281 +++++++++++ Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c | 905 ++++ Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h | 260 ++ Src/libCZI/decoder.cpp | 56 +- Src/libCZI/decoder.h | 1 + 25 files changed, 16294 insertions(+), 26 deletions(-) create mode 100644 Src/JxrDecode/JxrDecode2.cpp create mode 100644 Src/JxrDecode/JxrDecode2.h create mode 100644 Src/JxrDecode/jxrlib/common/include/guiddef.h create mode 100644 Src/JxrDecode/jxrlib/common/include/wmspecstring.h create mode 100644 Src/JxrDecode/jxrlib/common/include/wmspecstrings_adt.h create mode 100644 Src/JxrDecode/jxrlib/image/decode/decode.c create mode 100644 Src/JxrDecode/jxrlib/image/decode/decode.h create mode 100644 Src/JxrDecode/jxrlib/image/decode/segdec.c create mode 100644 Src/JxrDecode/jxrlib/image/decode/strInvTransform.c create mode 100644 Src/JxrDecode/jxrlib/image/decode/strPredQuantDec.c create mode 100644 Src/JxrDecode/jxrlib/image/decode/strdec.c create mode 100644 Src/JxrDecode/jxrlib/image/sys/common.h create mode 100644 Src/JxrDecode/jxrlib/image/sys/strTransform.h create mode 100644 Src/JxrDecode/jxrlib/image/sys/strcodec.c create mode 100644 Src/JxrDecode/jxrlib/image/sys/strcodec.h create mode 100644 Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h create mode 100644 Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c create mode 100644 Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h create mode 100644 Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c create mode 100644 Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c create mode 100644 Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h diff --git a/Src/JxrDecode/CMakeLists.txt b/Src/JxrDecode/CMakeLists.txt index c8f95d72..69bb1a38 100644 --- a/Src/JxrDecode/CMakeLists.txt +++ b/Src/JxrDecode/CMakeLists.txt @@ -11,13 +11,13 @@ add_library(JxrDecodeStatic OBJECT stdafx.h targetver.h Jxr/adapthuff.c - Jxr/decode.c + #Jxr/decode.c Jxr/encode.c Jxr/image.c - Jxr/JXRGlue.c - Jxr/JXRGlueJxr.c + #Jxr/JXRGlue.c + #Jxr/JXRGlueJxr.c Jxr/JXRGluePFC.c - Jxr/JXRMeta.c + #Jxr/JXRMeta.c Jxr/JXRTest.c Jxr/JXRTestBmp.c Jxr/JXRTestHdr.c @@ -28,38 +28,64 @@ add_library(JxrDecodeStatic OBJECT Jxr/JXRTranscode.c Jxr/perfTimerANSI.c Jxr/postprocess.c - Jxr/segdec.c + #Jxr/segdec.c Jxr/segenc.c - Jxr/strcodec.c - Jxr/strdec.c + #Jxr/strcodec.c + #Jxr/strdec.c Jxr/strdec_x86.c Jxr/strenc.c Jxr/strenc_x86.c Jxr/strFwdTransform.c - Jxr/strInvTransform.c + #Jxr/strInvTransform.c Jxr/strPredQuant.c - Jxr/strPredQuantDec.c + #Jxr/strPredQuantDec.c Jxr/strPredQuantEnc.c Jxr/strTransform.c - Jxr/common.h - Jxr/decode.h + #Jxr/common.h + #Jxr/decode.h Jxr/encode.h - Jxr/JXRGlue.h - Jxr/JXRMeta.h + #Jxr/JXRGlue.h + #Jxr/JXRMeta.h Jxr/JXRTest.h Jxr/JXRTestWrapper.h Jxr/perfTimer.h - Jxr/strcodec.h - Jxr/strTransform.h - Jxr/windowsmediaphoto.h + #Jxr/strcodec.h + #Jxr/strTransform.h + #Jxr/windowsmediaphoto.h Jxr/_x86/_x86.h Jxr/priv_guiddef.h Jxr/wmsal.h - Jxr/wmspecstring.h - Jxr/wmspecstrings_adt.h + #Jxr/wmspecstring.h + #Jxr/wmspecstrings_adt.h Jxr/wmspecstrings_strict.h Jxr/wmspecstrings_undef.h - Jxr/jxr_defines.h) + Jxr/jxr_defines.h + + "JxrDecode2.h" + "JxrDecode2.cpp" + + "jxrlib/common/include/guiddef.h" + "jxrlib/common/include/wmspecstring.h" + "jxrlib/common/include/wmspecstrings_adt.h" + + "jxrlib/image/decode/decode.c" + "jxrlib/image/decode/decode.h" + "jxrlib/image/decode/segdec.c" + "jxrlib/image/decode/strdec.c" + "jxrlib/image/decode/strInvTransform.c" + "jxrlib/image/decode/strPredQuantDec.c" + + "jxrlib/image/sys/strcodec.h" + "jxrlib/image/sys/strcodec.c" + "jxrlib/image/sys/windowsmediaphoto.h" + "jxrlib/image/sys/common.h" + "jxrlib/image/sys/strTransform.h" + + "jxrlib/jxrgluelib/JXRGlue.h" + "jxrlib/jxrgluelib/JXRGlue.c" + "jxrlib/jxrgluelib/JXRGlueJxr.c" + "jxrlib/jxrgluelib/JXRMeta.h" + "jxrlib/jxrgluelib/JXRMeta.c" ) set_target_properties(JxrDecodeStatic PROPERTIES CXX_STANDARD 11) diff --git a/Src/JxrDecode/JxrDecode.cpp b/Src/JxrDecode/JxrDecode.cpp index 57fa2d13..f7703338 100644 --- a/Src/JxrDecode/JxrDecode.cpp +++ b/Src/JxrDecode/JxrDecode.cpp @@ -6,9 +6,10 @@ #include #include #include "JxrDecode.h" -#include "Jxr/JXRTest.h" +//#include "Jxr/JXRTest.h" //#include "Jxr/JXRTestWrapper.h" -#include "Jxr/JXRGlue.h" +//#include "Jxr/JXRGlue.h" +#include "jxrlib/jxrgluelib/JXRGlue.h" using namespace JxrDecode; @@ -21,7 +22,7 @@ ERR WmpDecAppCreateEncoderFromExt( PKImageEncode** ppIE) { ERR err = WMP_errSuccess; - const PKIID* pIID = NULL; +/* const PKIID* pIID = NULL; //UNREFERENCED_PARAMETER(pCFactory); @@ -30,7 +31,7 @@ ERR WmpDecAppCreateEncoderFromExt( // Create encoder PKTestFactory_CreateCodec(pIID, reinterpret_cast(ppIE)); - + */ //Cleanup: return err; } @@ -333,12 +334,12 @@ void JxrDecode::Decode(codecHandle h, const WMPDECAPPARGS* decArgs, const void* if (Failed(err)) { ThrowError("WmpDecAppCreateEncoderFromExt failed", err); } std::unique_ptr upEncoder(pEncoder, [](PKImageEncode* p)->void {p->Release(&p); }); - struct tagJxrTestWrapperInitializeInfo wrapperInfo; + /*struct tagJxrTestWrapperInitializeInfo wrapperInfo; wrapperInfo.userParamPutData = &deliverData; wrapperInfo.pfnPutData = DeliverData; err = upEncoder->Initialize(upEncoder.get(), nullptr, &wrapperInfo, sizeof(wrapperInfo)); - if (Failed(err)) { ThrowError("Encoder::Initialize failed", err); } +*/ if (Failed(err)) { ThrowError("Encoder::Initialize failed", err); } err = upEncoder->SetPixelFormat(upEncoder.get(), args_guidPixFormat); if (Failed(err)) { ThrowError("SetPixelFormat failed", err); } upEncoder->WMP.wmiSCP.bBlackWhite = upDecoder->WMP.wmiSCP.bBlackWhite; diff --git a/Src/JxrDecode/JxrDecode2.cpp b/Src/JxrDecode/JxrDecode2.cpp new file mode 100644 index 00000000..dabdecf3 --- /dev/null +++ b/Src/JxrDecode/JxrDecode2.cpp @@ -0,0 +1,182 @@ +#include "JxrDecode2.h" +#include +#include "jxrlib/jxrgluelib/JXRGlue.h" + +#include "jxrlib/image/sys/Windowsmediaphoto.h" + +void JxrDecode2::Decode( + codecHandle h, + // const WMPDECAPPARGS* decArgs, + const void* ptrData, + size_t size, + const std::function& selectDestPixFmt, + std::function deliverData) +{ + ERR err; + PKFactory* pFactory = nullptr; + err = PKCreateFactory(&pFactory, PK_SDK_VERSION); + //if (Failed(err)) { ThrowError("PKCreateFactory failed", err); } + std::unique_ptr upFactory(pFactory, [](PKFactory* p)->void {p->Release(&p); }); + + PKCodecFactory* pCodecFactory = NULL; + err = PKCreateCodecFactory(&pCodecFactory, WMP_SDK_VERSION); + //if (Failed(err)) { ThrowError("PKCreateCodecFactory failed", err); } + std::unique_ptr upCodecFactory(pCodecFactory, [](PKCodecFactory* p)->void {p->Release(&p); }); + + /* const PKIID* pIID = NULL; + + GetImageDecodeIID((const char*)".jxr", &pIID); + PKCodecFactory_CreateCodec(pIID, (void**)&pDecoder); + std::unique_ptr upDecoder(pDecoder, [](PKImageDecode* p)->void {p->Release(&p); });*/ + + WMPStream* pStream; + err = pFactory->CreateStreamFromMemory(&pStream, const_cast(ptrData), size); + + PKImageDecode* pDecoder; + upCodecFactory->CreateDecoderFromStream(pStream, &pDecoder); + std::unique_ptr upDecoder(pDecoder, [](PKImageDecode* p)->void {p->Release(&p); }); + + + PKPixelFormatGUID args_guidPixFormat; + PKPixelInfo PI; + + // take decoder color format and try to look up better one + // (e.g. 32bppBGR -> 24bppBGR etc.) + PKPixelInfo newPI; + newPI.pGUIDPixFmt = PI.pGUIDPixFmt = &upDecoder->guidPixFormat; + PixelFormatLookup(&newPI, LOOKUP_FORWARD); + PixelFormatLookup(&newPI, LOOKUP_BACKWARD_TIF); + args_guidPixFormat = *newPI.pGUIDPixFmt; + + /*if (decArgs->pixFormat == PixelFormat::dontCare) + { + if (selectDestPixFmt) + { + PI.pGUIDPixFmt = &upDecoder->guidPixFormat; + I32 w, h; + upDecoder->GetSize(upDecoder.get(), &w, &h); + PixelFormat pixFmtFromDecoder = PixelFormatFromPkPixelFormat(upDecoder->guidPixFormat); + PixelFormat destFmtChosen = selectDestPixFmt(pixFmtFromDecoder, w, h); + + args_guidPixFormat = *PkPixelFormatFromPixelFormat(destFmtChosen); + //args_guidPixFormat = selectDestPixFmt(*PI.pGUIDPixFmt); + } + else + { + // take decoder color format and try to look up better one + // (e.g. 32bppBGR -> 24bppBGR etc.) + PKPixelInfo newPI; + newPI.pGUIDPixFmt = PI.pGUIDPixFmt = &upDecoder->guidPixFormat; + PixelFormatLookup(&newPI, LOOKUP_FORWARD); + PixelFormatLookup(&newPI, LOOKUP_BACKWARD_TIF); + args_guidPixFormat = *newPI.pGUIDPixFmt; + } + } + else + { + PI.pGUIDPixFmt = PkPixelFormatFromPixelFormat(decArgs->pixFormat); + args_guidPixFormat = *PI.pGUIDPixFmt; + }*/ + + // == color transcoding, + if (IsEqualGUID(args_guidPixFormat, GUID_PKPixelFormat8bppGray) || IsEqualGUID(args_guidPixFormat, GUID_PKPixelFormat16bppGray)) { // ** => Y transcoding + upDecoder->guidPixFormat = args_guidPixFormat; + upDecoder->WMP.wmiI.cfColorFormat = Y_ONLY; + } + else if (IsEqualGUID(args_guidPixFormat, GUID_PKPixelFormat24bppRGB) && upDecoder->WMP.wmiI.cfColorFormat == CMYK) { // CMYK = > RGB + upDecoder->WMP.wmiI.cfColorFormat = CF_RGB; + upDecoder->guidPixFormat = args_guidPixFormat; + upDecoder->WMP.wmiI.bRGB = 1; //RGB + } + + PixelFormatLookup(&PI, LOOKUP_FORWARD); + + /*std::uint8_t args_uAlphaMode = decArgs->uAlphaMode; + if (255 == args_uAlphaMode)//user didn't set + { + if (!!(PI.grBit & PK_pixfmtHasAlpha)) + args_uAlphaMode = 2;//default is image & alpha for formats with alpha + else + args_uAlphaMode = 0;//otherwise, 0 + }*/ + + upDecoder->WMP.wmiSCP.bfBitstreamFormat = BITSTREAMFORMAT::SPATIAL;// args.bfBitstreamFormat; only used for transcoding? + + upDecoder->WMP.wmiSCP.uAlphaMode = 0;// args_uAlphaMode; + + upDecoder->WMP.wmiSCP.sbSubband = SB_ALL;// (SUBBAND)(std::underlying_type::type)decArgs->sbSubband; + upDecoder->WMP.bIgnoreOverlap = FALSE;// decArgs->bIgnoreOverlap ? 1 : 0; + + upDecoder->WMP.wmiI.cfColorFormat = PI.cfColorFormat; + + upDecoder->WMP.wmiI.bdBitDepth = PI.bdBitDepth; + upDecoder->WMP.wmiI.cBitsPerUnit = PI.cbitUnit; + + //==== Validate thumbnail decode parameters ===== + upDecoder->WMP.wmiI.cThumbnailWidth = upDecoder->WMP.wmiI.cWidth; + upDecoder->WMP.wmiI.cThumbnailHeight = upDecoder->WMP.wmiI.cHeight; + upDecoder->WMP.wmiI.bSkipFlexbits = FALSE; + /*if (args.tThumbnailFactor > 0 && args.tThumbnailFactor != SKIPFLEXBITS) { + size_t tSize = ((size_t)1 << args.tThumbnailFactor); + + pDecoder->WMP.wmiI.cThumbnailWidth = (pDecoder->WMP.wmiI.cWidth + tSize - 1) / tSize; + pDecoder->WMP.wmiI.cThumbnailHeight = (pDecoder->WMP.wmiI.cHeight + tSize - 1) / tSize; + + if (pDecoder->WMP.wmiI.cfColorFormat == YUV_420 || pDecoder->WMP.wmiI.cfColorFormat == YUV_422) { // unsupported thumbnail format + pDecoder->WMP.wmiI.cfColorFormat = YUV_444; + } + } + else if (args.tThumbnailFactor == SKIPFLEXBITS) { + pDecoder->WMP.wmiI.bSkipFlexbits = TRUE; + }*/ + + /* if (decArgs->rWidth == 0 || decArgs->rHeight == 0) + { // no region decode + upDecoder->WMP.wmiI.cROILeftX = 0; + upDecoder->WMP.wmiI.cROITopY = 0; + upDecoder->WMP.wmiI.cROIWidth = upDecoder->WMP.wmiI.cThumbnailWidth; + upDecoder->WMP.wmiI.cROIHeight = upDecoder->WMP.wmiI.cThumbnailHeight; + } + else + { + upDecoder->WMP.wmiI.cROILeftX = decArgs->rLeftX; + upDecoder->WMP.wmiI.cROITopY = decArgs->rTopY; + upDecoder->WMP.wmiI.cROIWidth = decArgs->rWidth; + upDecoder->WMP.wmiI.cROIHeight = decArgs->rHeight; + }*/ + upDecoder->WMP.wmiI.cROILeftX = 0; + upDecoder->WMP.wmiI.cROITopY = 0; + upDecoder->WMP.wmiI.cROIWidth = pDecoder->WMP.wmiI.cWidth; + upDecoder->WMP.wmiI.cROIHeight = upDecoder->WMP.wmiI.cWidth; + + upDecoder->WMP.wmiI.oOrientation = O_NONE;// static_cast(decArgs->oOrientation); + + upDecoder->WMP.wmiI.cPostProcStrength = 0;// decArgs->cPostProcStrength; + + upDecoder->WMP.wmiSCP.bVerbose = 0; + + U32 cFrame; + err = upDecoder->GetFrameCount(upDecoder.get(), &cFrame); + //if (Failed(err)) { ThrowError("GetFrameCount failed", err); } + if (cFrame != 1) + { + //throw std::logic_error("Not expecting to find more than one image here."); + } + + I32 width, height; + pDecoder->GetSize(pDecoder, &width, &height); + size_t bytes_per_pixel = pDecoder->WMP.wmiI.cBitsPerUnit / 8; + + PKRect rc; + rc.X = 0; + rc.Y = 0; + rc.Width = width; + rc.Height = height; + + void* pImage = malloc(width * height * bytes_per_pixel); + upDecoder->Copy(upDecoder.get(), &rc, (U8*)pImage, width * bytes_per_pixel); + + deliverData(JxrDecode2::PixelFormat::_24bppBGR, width, height, height, pImage, width * bytes_per_pixel); + free(pImage); +} + diff --git a/Src/JxrDecode/JxrDecode2.h b/Src/JxrDecode/JxrDecode2.h new file mode 100644 index 00000000..a356f3f6 --- /dev/null +++ b/Src/JxrDecode/JxrDecode2.h @@ -0,0 +1,55 @@ +#pragma once + +#include + +class JxrDecode2 +{ +public: + enum class PixelFormat + { + dontCare, + _24bppBGR, + _1bppBlackWhite, + _8bppGray, + _16bppGray, + _16bppGrayFixedPoint, + _16bppGrayHalf, + _32bppGrayFixedPoint, + _32bppGrayFloat, + _24bppRGB, + _48bppRGB, + _48bppRGBFixedPoint, + _48bppRGBHalf, + _96bppRGBFixedPoint, + _128bppRGBFloat, + _32bppRGBE, + _32bppCMYK, + _64bppCMYK, + _32bppBGRA, + _64bppRGBA, + _64bppRGBAFixedPoint, + _64bppRGBAHalf, + _128bppRGBAFixedPoint, + _128bppRGBAFloat, + _16bppBGR555, + _16bppBGR565, + _32bppBGR101010, + _40bppCMYKA, + _80bppCMYKA, + _32bppBGR, + + invalid + }; + + typedef void* codecHandle; + + void Decode( + codecHandle h, + // const WMPDECAPPARGS* decArgs, + const void* ptrData, + size_t size, + const std::function& selectDestPixFmt, + std::function deliverData); + + +}; diff --git a/Src/JxrDecode/jxrlib/common/include/guiddef.h b/Src/JxrDecode/jxrlib/common/include/guiddef.h new file mode 100644 index 00000000..3a3c5e1b --- /dev/null +++ b/Src/JxrDecode/jxrlib/common/include/guiddef.h @@ -0,0 +1,232 @@ +//+--------------------------------------------------------------------------- +// +// 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. +// +// File: guiddef.h +// +// Contents: GUID definition +// +//---------------------------------------------------------------------------- + +#ifndef GUID_DEFINED +#define GUID_DEFINED +#if defined(__midl) +typedef struct { + unsigned long Data1; + unsigned short Data2; + unsigned short Data3; + byte Data4[8]; +} GUID; +#else +typedef struct _GUID { +#if defined(_WINDOWS_) || !__LP64__ + unsigned long Data1; +#else + unsigned int Data1; +#endif + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[8]; +} GUID; +#endif +#endif + +#ifndef FAR +#if defined(_WIN32) || defined(__ANSI__) +#define FAR +#else +#define FAR _far +#endif +#endif + +#ifndef DECLSPEC_SELECTANY +#if (_MSC_VER >= 1100) +#define DECLSPEC_SELECTANY __declspec(selectany) +#else +#define DECLSPEC_SELECTANY +#endif +#endif + +#ifndef EXTERN_C +#ifdef __cplusplus +#define EXTERN_C extern "C" +#else +#define EXTERN_C extern +#endif +#endif + +#ifdef DEFINE_GUID +#undef DEFINE_GUID +#endif + +#ifdef INITGUID +#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + const GUID DECLSPEC_SELECTANY name \ + = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } +#else +#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + EXTERN_C const GUID FAR name +#endif // INITGUID + +#if _MSC_VER < 1900 +#define DEFINE_OLEGUID(name, l, w1, w2) DEFINE_GUID(name, l, w1, w2, 0xC0,0,0,0,0,0,0,0x46) +#endif + +#ifndef _GUIDDEF_H_ +#define _GUIDDEF_H_ + +#ifndef __LPGUID_DEFINED__ +#define __LPGUID_DEFINED__ +typedef GUID* LPGUID; +#endif + +#ifndef __LPCGUID_DEFINED__ +#define __LPCGUID_DEFINED__ +typedef const GUID* LPCGUID; +#endif + +#ifndef __IID_DEFINED__ +#define __IID_DEFINED__ + +typedef GUID IID; +typedef IID* LPIID; +#define IID_NULL GUID_NULL +#define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2) +typedef GUID CLSID; +typedef CLSID* LPCLSID; +#define CLSID_NULL GUID_NULL +#define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2) +typedef GUID FMTID; +typedef FMTID* LPFMTID; +#define FMTID_NULL GUID_NULL +#define IsEqualFMTID(rfmtid1, rfmtid2) IsEqualGUID(rfmtid1, rfmtid2) + +#ifdef __midl_proxy +#define __MIDL_CONST +#else +#define __MIDL_CONST const +#endif + +#ifndef _REFGUID_DEFINED +#define _REFGUID_DEFINED +#ifdef __cplusplus +#define REFGUID const GUID & +#else +#define REFGUID const GUID * __MIDL_CONST +#endif +#endif + +#ifndef _REFIID_DEFINED +#define _REFIID_DEFINED +#ifdef __cplusplus +#define REFIID const IID & +#else +#define REFIID const IID * __MIDL_CONST +#endif +#endif + +#ifndef _REFCLSID_DEFINED +#define _REFCLSID_DEFINED +#ifdef __cplusplus +#define REFCLSID const IID & +#else +#define REFCLSID const IID * __MIDL_CONST +#endif +#endif + +#ifndef _REFFMTID_DEFINED +#define _REFFMTID_DEFINED +#ifdef __cplusplus +#define REFFMTID const IID & +#else +#define REFFMTID const IID * __MIDL_CONST +#endif +#endif + +#endif // !__IID_DEFINED__ + +#if !defined (__midl) +#if !defined (_SYS_GUID_OPERATORS_) +#define _SYS_GUID_OPERATORS_ +#include + +// Faster (but makes code fatter) inline version...use sparingly +#ifdef __cplusplus +__inline int InlineIsEqualGUID(REFGUID rguid1, REFGUID rguid2) +{ + return ( + ((unsigned long*)&rguid1)[0] == ((unsigned long*)&rguid2)[0] && + ((unsigned long*)&rguid1)[1] == ((unsigned long*)&rguid2)[1] && + ((unsigned long*)&rguid1)[2] == ((unsigned long*)&rguid2)[2] && + ((unsigned long*)&rguid1)[3] == ((unsigned long*)&rguid2)[3]); +} + +__inline int IsEqualGUID(REFGUID rguid1, REFGUID rguid2) +{ + return !memcmp(&rguid1, &rguid2, sizeof(GUID)); +} + +#else // ! __cplusplus + +#define InlineIsEqualGUID(rguid1, rguid2) \ + (((unsigned long *) rguid1)[0] == ((unsigned long *) rguid2)[0] && \ + ((unsigned long *) rguid1)[1] == ((unsigned long *) rguid2)[1] && \ + ((unsigned long *) rguid1)[2] == ((unsigned long *) rguid2)[2] && \ + ((unsigned long *) rguid1)[3] == ((unsigned long *) rguid2)[3]) + +#define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID))) + +#endif // __cplusplus + +#ifdef __INLINE_ISEQUAL_GUID +#undef IsEqualGUID +#define IsEqualGUID(rguid1, rguid2) InlineIsEqualGUID(rguid1, rguid2) +#endif + +// Same type, different name + +#define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2) +#define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2) + + +#if !defined _SYS_GUID_OPERATOR_EQ_ && !defined _NO_SYS_GUID_OPERATOR_EQ_ +#define _SYS_GUID_OPERATOR_EQ_ +// A couple of C++ helpers + +#ifdef __cplusplus +__inline int operator==(REFGUID guidOne, REFGUID guidOther) +{ + return IsEqualGUID(guidOne, guidOther); +} + +__inline int operator!=(REFGUID guidOne, REFGUID guidOther) +{ + return !(guidOne == guidOther); +} +#endif +#endif // _SYS_GUID_OPERATOR_EQ_ +#endif // _SYS_GUID_OPERATORS_ +#endif // __midl +#endif // _GUIDDEF_H_ diff --git a/Src/JxrDecode/jxrlib/common/include/wmspecstring.h b/Src/JxrDecode/jxrlib/common/include/wmspecstring.h new file mode 100644 index 00000000..9bdc98e9 --- /dev/null +++ b/Src/JxrDecode/jxrlib/common/include/wmspecstring.h @@ -0,0 +1,342 @@ +//*@@@+++@@@@****************************************************************** +// +// 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 _WMSPECSTRING_H_ +#define _WMSPECSTRING_H_ + +#if (!defined UNDER_CE && !defined NO_WINDOWS && !defined SPECSTRINGS_H) +#define SPECSTRINGS_H +/************************************************************************* +* See specstrings_strict.h for documentation of all user visible macros. +*************************************************************************/ +#if _MSC_VER +#pragma once +#endif +#include + +#ifndef __SAL_H_FULL_VER +#define __SAL_H_FULL_VER 140050727 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + /* version specific fixes to bring sal.h upto date */ +#if __SAL_H_FULL_VER <= 140050727 + +/* Missing from RTM sal.h */ +#if !defined(__midl) && defined(_PREFAST_) && _MSC_VER >= 1000 + +#define __inexpressible_readableTo(size) __declspec("SAL_readableTo(inexpressibleCount('" SPECSTRINGIZE(size) "'))") +#define __inexpressible_writableTo(size) __declspec("SAL_writableTo(inexpressibleCount('" SPECSTRINGIZE(size) "'))") +#define __inner_bound __declspec("SAL_bound") +#define __inner_range(lb,ub) __declspec("SAL_range(" SPECSTRINGIZE(lb) "," SPECSTRINGIZE(ub) ")") +#define __inner_assume_bound_dec __inline __nothrow void __AssumeBoundInt(__post __inner_bound int i) {i;} +#define __inner_assume_bound(i) __AssumeBoundInt(i); +#define __inner_allocator __declspec("SAL_allocator") +#else +#define __inexpressible_readableTo(size) +#define __inexpressible_writableTo(size) +#define __inner_bound +#define __inner_range(lb,ub) +#define __inner_assume_bound_dec +#define __inner_assume_bound(i) +#define __inner_allocator +#endif + +#define __xcount(size) __notnull __inexpressible_writableTo(size) +#define __in_xcount(size) __in __pre __inexpressible_readableTo(size) +#define __out_xcount(size) __xcount(size) __post __valid __refparam +#define __out_xcount_part(size,length) __out_xcount(size) __post __inexpressible_readableTo(length) +#define __out_xcount_full(size) __out_xcount_part(size,size) +#define __inout_xcount(size) __out_xcount(size) __pre __valid +#define __inout_xcount_part(size,length) __out_xcount_part(size,length) __pre __valid __pre __inexpressible_readableTo(length) +#define __inout_xcount_full(size) __inout_xcount_part(size,size) +#define __xcount_opt(size) __xcount(size) __exceptthat __maybenull +#define __in_xcount_opt(size) __in_xcount(size) __exceptthat __maybenull +#define __out_xcount_opt(size) __out_xcount(size) __exceptthat __maybenull +#define __out_xcount_part_opt(size,length) __out_xcount_part(size,length) __exceptthat __maybenull +#define __out_xcount_full_opt(size) __out_xcount_full(size) __exceptthat __maybenull +#define __inout_xcount_opt(size) __inout_xcount(size) __exceptthat __maybenull +#define __inout_xcount_part_opt(size,length) __inout_xcount_part(size,length) __exceptthat __maybenull +#define __inout_xcount_full_opt(size) __inout_xcount_full(size) __exceptthat __maybenull +#define __deref_xcount(size) __ecount(1) __post __elem_readableTo(1) __post __deref __notnull __post __deref __inexpressible_writableTo(size) +#define __deref_in __in __pre __deref __deref __readonly +#define __deref_in_ecount(size) __deref_in __pre __deref __elem_readableTo(size) +#define __deref_in_bcount(size) __deref_in __pre __deref __byte_readableTo(size) +#define __deref_in_xcount(size) __deref_in __pre __deref __inexpressible_readableTo(size) +#define __deref_out_xcount(size) __deref_xcount(size) __post __deref __valid __refparam +#define __deref_out_xcount_part(size,length) __deref_out_xcount(size) __post __deref __inexpressible_readableTo(length) +#define __deref_out_xcount_full(size) __deref_out_xcount_part(size,size) +#define __deref_out_xcount(size) __deref_xcount(size) __post __deref __valid __refparam +#define __inout_xcount_opt(size) __inout_xcount(size) __exceptthat __maybenull +#define __inout_xcount_part_opt(size,length) __inout_xcount_part(size,length) __exceptthat __maybenull +#define __inout_xcount_full_opt(size) __inout_xcount_full(size) __exceptthat __maybenull +#define __deref_xcount(size) __ecount(1) __post __elem_readableTo(1) __post __deref __notnull __post __deref __inexpressible_writableTo(size) +#define __deref_in __in __pre __deref __deref __readonly +#define __deref_in_ecount(size) __deref_in __pre __deref __elem_readableTo(size) +#define __deref_in_bcount(size) __deref_in __pre __deref __byte_readableTo(size) +#define __deref_in_xcount(size) __deref_in __pre __deref __inexpressible_readableTo(size) +#define __deref_out_xcount(size) __deref_xcount(size) __post __deref __valid __refparam +#define __deref_out_xcount_part(size,length) __deref_out_xcount(size) __post __deref __inexpressible_readableTo(length) +#define __deref_out_xcount_full(size) __deref_out_xcount_part(size,size) +#define __deref_out_xcount(size) __deref_xcount(size) __post __deref __valid __refparam +#define __deref_inout_xcount(size) __deref_inout __pre __deref __inexpressible_writableTo(size) __post __deref __inexpressible_writableTo(size) +#define __deref_inout_xcount_part(size,length) __deref_inout_xcount(size) __pre __deref __inexpressible_readableTo(length) __post __deref __inexpressible_readableTo(length) +#define __deref_inout_xcount_full(size) __deref_inout_xcount_part(size,size) +#define __deref_xcount_opt(size) __deref_xcount(size) __post __deref __exceptthat __maybenull +#define __deref_in_opt __deref_in __pre __deref __exceptthat __maybenull +#define __deref_in_ecount_opt(size) __deref_in_ecount(size) __pre __deref __exceptthat __maybenull +#define __deref_in_bcount_opt(size) __deref_in_bcount(size) __pre __deref __exceptthat __maybenull +#define __deref_in_xcount_opt(size) __deref_in_xcount(size) __pre __deref __exceptthat __maybenull +#define __deref_out_xcount_opt(size) __deref_out_xcount(size) __post __deref __exceptthat __maybenull +#define __deref_out_xcount_part_opt(size,length) __deref_out_xcount_part(size,length) __post __deref __exceptthat __maybenull +#define __deref_out_xcount_full_opt(size) __deref_out_xcount_full(size) __post __deref __exceptthat __maybenull +#define __deref_inout_xcount_opt(size) __deref_inout_xcount(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull +#define __deref_inout_xcount_part_opt(size,length) __deref_inout_xcount_part(size,length) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull +#define __deref_inout_xcount_full_opt(size) __deref_inout_xcount_full(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull +#define __deref_opt_xcount(size) __deref_xcount(size) __exceptthat __maybenull +#define __deref_opt_in __deref_in __exceptthat __maybenull +#define __deref_opt_in_ecount(size) __deref_in_ecount(size) __exceptthat __maybenull +#define __deref_opt_in_bcount(size) __deref_in_bcount(size) __exceptthat __maybenull +#define __deref_opt_in_xcount(size) __deref_in_xcount(size) __exceptthat __maybenull +#define __deref_opt_out_xcount(size) __deref_out_xcount(size) __exceptthat __maybenull +#define __deref_opt_out_xcount_part(size,length) __deref_out_xcount_part(size,length) __exceptthat __maybenull +#define __deref_opt_out_xcount_full(size) __deref_out_xcount_full(size) __exceptthat __maybenull +#define __deref_opt_inout_xcount(size) __deref_inout_xcount(size) __exceptthat __maybenull +#define __deref_opt_inout_xcount_part(size,length) __deref_inout_xcount_part(size,length) __exceptthat __maybenull +#define __deref_opt_inout_xcount_full(size) __deref_inout_xcount_full(size) __exceptthat __maybenull +#define __deref_opt_xcount_opt(size) __deref_xcount_opt(size) __exceptthat __maybenull +#define __deref_opt_in_opt __deref_in_opt __exceptthat __maybenull +#define __deref_opt_in_ecount_opt(size) __deref_in_ecount_opt(size) __exceptthat __maybenull +#define __deref_opt_in_bcount_opt(size) __deref_in_bcount_opt(size) __exceptthat __maybenull +#define __deref_opt_in_xcount_opt(size) __deref_in_xcount_opt(size) __exceptthat __maybenull +#define __deref_opt_out_xcount_opt(size) __deref_out_xcount_opt(size) __exceptthat __maybenull +#define __deref_opt_out_xcount_part_opt(size,length) __deref_out_xcount_part_opt(size,length) __exceptthat __maybenull +#define __deref_opt_out_xcount_full_opt(size) __deref_out_xcount_full_opt(size) __exceptthat __maybenull +#define __deref_opt_inout_xcount_opt(size) __deref_inout_xcount_opt(size) __exceptthat __maybenull +#define __deref_opt_inout_xcount_part_opt(size,length) __deref_inout_xcount_part_opt(size,length) __exceptthat __maybenull +#define __deref_opt_inout_xcount_full_opt(size) __deref_inout_xcount_full_opt(size) __exceptthat __maybenull +/* Must protect redfinitions of macros to workaround rc.exe issues. */ +#ifndef RC_INVOKED +#undef __nullnullterminated +#define __nullnullterminated __xcount("string terminated by two nulls") +#undef __checkReturn +#define __checkReturn __post __inner_checkReturn +#endif +#endif //__SAL_H_FULL_VER <= 140050727 + +/************************************************************************ + New extensions to sal.h follow here. +*************************************************************************/ + +#if (_MSC_VER >= 1000) && !defined(__midl) && defined(_PREFAST_) +#define __file_parser(typ) __declspec("SAL_file_parser(function, " #typ ")") +#define __file_parser_class(typ) __declspec("SAL_file_parser(class, " #typ ")") +#define __file_parser_library(typ) extern int __declspec("SAL_file_parser(library, " #typ ")") __iSALFileParserLibrary##typ; +#define __source_code_content(typ) extern int __declspec("SAL_source_code_content(" #typ ")") __iSAL_Source_Code_Content##typ; +#define __class_code_content(typ) __declspec("SAL_class_code_content(" #typ ")") +#define __analysis_assert(e) __assume(e) +#define __analysis_hint(hint) __declspec("SAL_analysisHint(" #hint ")") +/* Internal defintions */ +#define __inner_data_source(src_raw) __declspec("SAL_untrusted_data_source(" src_raw ")") +#define __inner_this_data_source(src_raw) __declspec("SAL_untrusted_data_source_this(" src_raw ")") +#define __inner_out_validated(typ_raw) __declspec("SAL_post") __declspec("SAL_validated(" typ_raw ")") +#define __inner_this_out_validated(typ_raw) __declspec("SAL_validated_this(" typ_raw ")") +#define __inner_assume_validated_dec __inline __nothrow void __AssumeValidated(__inner_out_validated("BY_DESIGN") const void *p) {p;} +#define __inner_assume_validated(p) __AssumeValidated(p) +#define __inner_transfer(formal) __declspec("SAL_transfer_adt_property_from(" SPECSTRINGIZE(formal) ")") +#define __inner_encoded __declspec("SAL_encoded") + +#define __$adt_prop(adt,prop) __declspec("SAL_adt("#adt","#prop")") +#define __$adt_add_prop(adt,prop) __declspec("SAL_add_adt_property("#adt","#prop")") +#define __$adt_remove_prop(adt,prop) __declspec("SAL_remove_adt_property("#adt","#prop")") +#define __$adt_transfer_prop(arg) __declspec("SAL_transfer_adt_property_from("#arg")") +#define __$adt_type_props(typ) __declspec("SAL_post_type("#typ")") +#define __$volatile __declspec("SAL_volatile") +#define __$nonvolatile __declspec("SAL_nonvolatile") +#define __$possibly_notnulltermiated __declspec("SAL_RequiresZeroTermination(sometimes)") +#else +#define __file_parser(typ) +#define __file_parser_class(typ) +#define __file_parser_library(typ) +#define __source_code_content(typ) +#define __class_code_content(typ) +#define __analysis_assert(e) +#define __analysis_hint(hint) +/* Internal defintions */ +#define __inner_data_source(src_raw) +#define __inner_this_data_source(src_raw) +#define __inner_out_validated(typ_raw) +#define __inner_this_out_validated(typ_raw) +#define __inner_assume_validated_dec +#define __inner_assume_validated(p) +#define __inner_transfer(formal) +#define __inner_encoded +#define __$adt_prop(adt,prop) +#define __$adt_add_prop(adt,prop) +#define __$adt_remove_prop(adt,prop) +#define __$adt_transfer_prop(arg) +#define __$adt_type_props(typ) +#define __$volatile +#define __$nonvolatile +#define __$possibly_notnulltermiated +#endif // #if (_MSC_VER >= 1000) && !defined(__midl) && defined(_PREFAST_) + +#define __field_ecount(size) __notnull __elem_writableTo(size) +#define __field_bcount(size) __notnull __byte_writableTo(size) +#define __field_xcount(size) __notnull __inexpressible_writableTo(size) + +#define __field_ecount_opt(size) __maybenull __elem_writableTo(size) +#define __field_bcount_opt(size) __maybenull __byte_writableTo(size) +#define __field_xcount_opt(size) __maybenull __inexpressible_writableTo(size) + +#define __field_ecount_part(size,init) __notnull __elem_writableTo(size) __elem_readableTo(init) +#define __field_bcount_part(size,init) __notnull __byte_writableTo(size) __byte_readableTo(init) +#define __field_xcount_part(size,init) __notnull __inexpressible_writableTo(size) __inexpressible_readableTo(init) + +#define __field_ecount_part_opt(size,init) __maybenull __elem_writableTo(size) __elem_readableTo(init) +#define __field_bcount_part_opt(size,init) __maybenull __byte_writableTo(size) __byte_readableTo(init) +#define __field_xcount_part_opt(size,init) __maybenull __inexpressible_writableTo(size) __inexpressible_readableTo(init) + +#define __field_ecount_full(size) __field_ecount_part(size,size) +#define __field_bcount_full(size) __field_bcount_part(size,size) +#define __field_xcount_full(size) __field_xcount_part(size,size) + +#define __field_ecount_full_opt(size) __field_ecount_part_opt(size,size) +#define __field_bcount_full_opt(size) __field_bcount_part_opt(size,size) +#define __field_xcount_full_opt(size) __field_xcount_part_opt(size,size) + +#define __struct_bcount(size) __field_bcount(size) +#define __struct_xcount(size) __field_xcount(size) + +#if !defined(__out_awcount) +#define __out_awcount(expr,size) __pre __notnull \ + __byte_writableTo((expr) ? (size) : (size) * 2) \ + __post __valid __refparam +#endif +#if !defined(__in_awcount) +#define __in_awcount(expr,size) __pre __valid \ + __pre __deref __readonly \ + __byte_readableTo((expr) ? (size) : (size) * 2) +#endif + +/* integer related macros */ +#define __allocator __inner_allocator +#define __bound __inner_bound +#define __range(lb,ub) __inner_range(lb,ub) +#define __in_bound __pre __inner_bound +#define __out_bound __post __inner_bound +#define __deref_out_bound __post __deref __inner_bound +#define __in_range(lb,ub) __pre __inner_range(lb,ub) +#define __out_range(lb,ub) __post __inner_range(lb,ub) +#define __deref_in_range(lb,ub) __pre __deref __inner_range(lb,ub) +#define __deref_out_range(lb,ub) __post __deref __inner_range(lb,ub) +#define __field_range(lb,ub) __range(lb,ub) +#define __field_data_source(src_sym) __inner_data_source(#src_sym) + +/* Pentraion review macros */ +#define __in_data_source(src_sym) __pre __inner_data_source(#src_sym) +#define __out_data_source(src_sym) __post __inner_data_source(#src_sym) +#define __out_validated(typ_sym) __inner_out_validated(#typ_sym) +#define __this_out_data_source(src_sym) __inner_this_data_source(#src_sym) +#define __this_out_validated(typ_sym) __inner_this_out_validated(#typ_sym) +#define __transfer(formal) __post __inner_transfer(formal) +#define __rpc_entry __inner_control_entrypoint(RPC) +#define __kernel_entry __inner_control_entrypoint(UserToKernel) +#define __gdi_entry __inner_control_entrypoint(GDI) +#define __encoded_pointer __inner_encoded +#define __encoded_array __inner_encoded +#define __field_encoded_pointer __inner_encoded +#define __field_encoded_array __inner_encoded +#define __type_has_adt_prop(adt,prop) __$adt_prop(adt,prop) +#define __out_has_adt_prop(adt,prop) __post __$adt_add_prop(adt,prop) +#define __out_not_has_adt_prop(adt,prop) __post __$adt_remove_prop(adt,prop) +#define __out_transfer_adt_prop(arg) __post __$adt_transfer_prop(arg) +#define __out_has_type_adt_props(typ) __post __$adt_type_props(typ) + +/* useful PFD related macros */ +#define __possibly_notnulltermiated __post __$possibly_notnulltermiated + +#if defined(_WINDOWS_) +/* Windows Internal */ +#define __volatile __$volatile +#define __nonvolatile __$nonvolatile +#define __deref_volatile __deref __volatile +#define __deref_nonvolatile __deref __nonvolatile +#endif + +/* declare stub functions for macros */ + __inner_assume_validated_dec + __inner_assume_bound_dec + +#define __assume_validated(p) __inner_assume_validated(p) +#define __assume_bound(i) __inner_assume_bound(i) +#ifdef __cplusplus +} +#endif +#include +#ifdef _PREFIX_ +/************************************************************************** +* Defintion of __pfx_assume and __pfx_assert. Thse should be the only +* defintions of these functions. +***************************************************************************/ +#if __cplusplus +extern "C" void __pfx_assert(bool, const char*); +extern "C" void __pfx_assume(bool, const char*); +#else +void __pfx_assert(int, const char*); +void __pfx_assume(int, const char*); +#endif +/************************************************************************** +* Redefintion of __analysis_assume and __analysis_assert for PREFIX build +**************************************************************************/ +#undef __analysis_assume +#undef __analysis_assert +#define __analysis_assume(e) (__pfx_assume(e,"pfx_assume"),__assume(e)); +#define __analysis_assert(e) (__pfx_assert(e,"pfx_assert"),__assume(e)); +#endif /* ifdef _PREFIX_ */ + +/************************************************************************** +* This include should always be the last thing in this file. +* Must avoid redfinitions of macros to workaround rc.exe issues. +***************************************************************************/ +#if !(defined(RC_INVOKED) || defined(SORTPP_PASS)) +#include +#endif /* if !(defined(RC_INVOKED) || defined(SORTPP_PASS)) */ +#endif /* #ifndef SPECSTRINGS_H */ + +// Some CE versions don't have specstrings.h, some have very old version without +// __specstrings defined. So we handle CE separately in wmasalce.h +#if defined(UNDER_CE) || defined(NO_WINDOWS) +#include "wmspecstringce.h" +#endif + +#endif //_WMSPECSTRING_H_ + diff --git a/Src/JxrDecode/jxrlib/common/include/wmspecstrings_adt.h b/Src/JxrDecode/jxrlib/common/include/wmspecstrings_adt.h new file mode 100644 index 00000000..66d95767 --- /dev/null +++ b/Src/JxrDecode/jxrlib/common/include/wmspecstrings_adt.h @@ -0,0 +1,71 @@ +//*@@@+++@@@@****************************************************************** +// +// 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 +/************************************************************************* +* DEFINITIONS OF NEW TYPES +*************************************************************************/ +#if !defined(__midl) +#define __$compname_props \ + __type_has_adt_prop(compname,nullterminated) \ + __type_has_adt_prop(compname,valid_schars) \ + __type_has_adt_prop(compname,correct_len) \ + __nullterminated +#if defined(UNICODE) || defined(_UNICODE) +#define __$TCHAR unsigned short +#else +#define __$TCHAR char +#endif +typedef __$compname_props char* ValidCompNameA; +typedef __$compname_props unsigned short* ValidCompNameW; +typedef __$compname_props const unsigned short* ConstValidCompNameW; +typedef __$compname_props __$TCHAR* SAL_ValidCompNameT; +typedef __$compname_props const __$TCHAR* SAL_ConstValidCompNameT; +#undef __$compname_props +#undef __$TCHAR +#endif + +/************************************************************************* +* DEFINITIONS OF INLINE FUNCTIONS FOR CASTING TO THE NEW TYPES : USER +*************************************************************************/ +#if (_MSC_VER >= 1000) && !defined(__midl) && defined(_PREFAST_) +#ifdef __cplusplus +extern "C" { +#endif + void __inline __nothrow __SAL_ValidCompNameA(__out_has_type_adt_props(ValidCompNameA) const void* expr) { expr; } + void __inline __nothrow __SAL_ValidCompNameW(__out_has_type_adt_props(ValidCompNameW) const void* expr) { expr; } +#ifdef __cplusplus +} +#endif +#define __assume_ValidCompNameA(expr) __SAL_ValidCompNameA(expr) +#define __assume_ValidCompNameW(expr) __SAL_ValidCompNameW(expr) +#else +#define __assume_ValidCompNameA(expr) +#define __assume_ValidCompNameW(expr) +#endif + diff --git a/Src/JxrDecode/jxrlib/image/decode/decode.c b/Src/JxrDecode/jxrlib/image/decode/decode.c new file mode 100644 index 00000000..0b9400f9 --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/decode/decode.c @@ -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 "../sys/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); + } +} + diff --git a/Src/JxrDecode/jxrlib/image/decode/decode.h b/Src/JxrDecode/jxrlib/image/decode/decode.h new file mode 100644 index 00000000..a4eacef5 --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/decode/decode.h @@ -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 + diff --git a/Src/JxrDecode/jxrlib/image/decode/segdec.c b/Src/JxrDecode/jxrlib/image/decode/segdec.c new file mode 100644 index 00000000..a3828394 --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/decode/segdec.c @@ -0,0 +1,1208 @@ +//*@@@+++@@@@****************************************************************** +// +// 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 "../sys/strcodec.h" +#include "decode.h" + +#ifdef MEM_TRACE +#define TRACE_MALLOC 1 +#define TRACE_NEW 0 +#define TRACE_HEAP 0 +#include "memtrace.h" +#endif + +extern const int dctIndex[3][16]; +extern const int blkOffset[16]; +extern const int blkOffsetUV[4]; +static Int DecodeSignificantAbsLevel(struct CAdaptiveHuffman* pAHexpt, BitIOInfo* pIO); + +//#undef X86OPT_INLINE + +#ifdef X86OPT_INLINE +#define _FORCEINLINE __forceinline +#else // X86OPT_INLINE +#define _FORCEINLINE +#endif // X86OPT_INLINE + +//================================================================ +// Memory access functions +//================================================================ +static U32 _FORCEINLINE _load4(void* pv) +{ +#ifdef _BIG__ENDIAN_ + return (*(U32*)pv); +#else // _BIG__ENDIAN_ +#if defined(_M_IA64) || defined(_ARM_) + U32 v; + v = ((U16*)pv)[0]; + v |= ((U32)((U16*)pv)[1]) << 16; + return _byteswap_ulong(v); +#else // _M_IA64 + U32 v; + memcpy(&v, pv, sizeof(U32)); + return _byteswap_ulong(v); +#endif // _M_IA64 +#endif // _BIG__ENDIAN_ +} + +static _FORCEINLINE U32 _peekBit16(BitIOInfo* pIO, U32 cBits) +{ + PEEKBIT16(pIO, cBits); + // masking is not needed here because shift of unsigned int is implemented as a logical shift (SHR)! +} + +#define LOAD16 _load4 +static _FORCEINLINE U32 _flushBit16(BitIOInfo* pIO, U32 cBits) +{ + FLUSHBIT16(pIO, cBits); +} + +static _FORCEINLINE U32 _getBit16(BitIOInfo* pIO, U32 cBits) +{ + U32 uiRet = _peekBit16(pIO, cBits); + _flushBit16(pIO, cBits); + + return uiRet; +} + +#define SIGN_BIT(TypeOrValue) (((UInt) 1) << (8 * sizeof (TypeOrValue) - 1)) +/*********************************************************************************************************** + Huffman decode (input is a fully built Huffman table) +***********************************************************************************************************/ +Int getHuff(const short* pDecodeTable, BitIOInfo* pIO) +{ + Int iSymbol, iSymbolHuff; + iSymbol = pDecodeTable[peekBit16(pIO, HUFFMAN_DECODE_ROOT_BITS)]; + + flushBit16(pIO, iSymbol < 0 ? HUFFMAN_DECODE_ROOT_BITS : iSymbol & ((1 << HUFFMAN_DECODE_ROOT_BITS_LOG) - 1)); + iSymbolHuff = iSymbol >> HUFFMAN_DECODE_ROOT_BITS_LOG; + + if (iSymbolHuff < 0) { + iSymbolHuff = iSymbol; + while ((iSymbolHuff = pDecodeTable[iSymbolHuff + SIGN_BIT(pDecodeTable[0]) + getBit16(pIO, 1)]) < 0); + } + return (iSymbolHuff); +} + +#if 1 +static _FORCEINLINE U32 _getBool16(BitIOInfo* pIO) +{ + U32 uiRet = pIO->uiAccumulator >> 31;//_peekBit16(pIO, 1); + //_flushBit16(pIO, 1); + pIO->cBitsUsed++; + if (pIO->cBitsUsed < 16) { + pIO->uiAccumulator <<= 1; + } + else { + pIO->pbCurrent = MASKPTR(pIO->pbCurrent + ((pIO->cBitsUsed >> 3)/* & 2*/), pIO->iMask); + pIO->cBitsUsed &= 16 - 1; + pIO->uiAccumulator = LOAD16(pIO->pbCurrent) << pIO->cBitsUsed; + } + + return uiRet; +} + +static _FORCEINLINE I32 _getSign(BitIOInfo* pIO) +{ + I32 uiRet = (int)pIO->uiAccumulator >> 31;//_peekBit16(pIO, 1); + //_flushBit16(pIO, 1); + pIO->cBitsUsed++; + if (pIO->cBitsUsed < 16) { + pIO->uiAccumulator <<= 1; + } + else { + pIO->pbCurrent = MASKPTR(pIO->pbCurrent + ((pIO->cBitsUsed >> 3)/* & 2*/), pIO->iMask); + pIO->cBitsUsed &= 16 - 1; + pIO->uiAccumulator = LOAD16(pIO->pbCurrent) << pIO->cBitsUsed; + } + + return uiRet; +} +#else +#define _getBool16(x) _getBit16((x),1) +#define _getSign(x) (-_getBit16((x),1)) +#endif + +/** this function returns cBits if zero is read, or a signed value if first cBits are not all zero **/ +static _FORCEINLINE I32 _getBit16s(BitIOInfo* pIO, U32 cBits) +{ + I32 iRet = (I32)_peekBit16(pIO, cBits + 1); + iRet = ((iRet >> 1) ^ (-(iRet & 1))) + (iRet & 1); + _flushBit16(pIO, cBits + (iRet != 0)); + return iRet; +} + +/************************************************************************* + Huffman decoding with short tables +*************************************************************************/ +static _FORCEINLINE Int _getHuffShort(const short* pDecodeTable, BitIOInfo* pIO) +{ + Int iSymbol = pDecodeTable[_peekBit16(pIO, HUFFMAN_DECODE_ROOT_BITS)]; + assert(iSymbol >= 0); + // for some strange reason, inlining flushBit doesn't work well + flushBit16(pIO, iSymbol & ((1 << HUFFMAN_DECODE_ROOT_BITS_LOG) - 1)); + return (iSymbol >> HUFFMAN_DECODE_ROOT_BITS_LOG); +} +/************************************************************************* + Adapt + Huffman init +*************************************************************************/ +static Int AdaptDecFixed(CAdaptiveHuffman* pAH) +{ + AdaptDiscriminant(pAH); + return ICERR_OK; +} + +/************************************************************************* + DecodeCBP +*************************************************************************/ +static Void DecodeCBP(CWMImageStrCodec* pSC, CCodingContext* pContext) +{ + BitIOInfo* pIO = pContext->m_pIOAC; + const COLORFORMAT cf = pSC->m_param.cfColorFormat; + const Int iChannel = (cf == NCOMPONENT || cf == CMYK) ? (Int)pSC->m_param.cNumChannels : 1; + Int iCBPCY, iCBPCU, iCBPCV; + Int k, iBlock, i; + Int iNumCBP; + Bool bIsChroma; + CAdaptiveHuffman* pAHCBP = pContext->m_pAdaptHuffCBPCY; + CAdaptiveHuffman* pAHCBP1 = pContext->m_pAdaptHuffCBPCY1; + CAdaptiveHuffman* pAHex1 = pContext->m_pAHexpt[1]; + + readIS_L1(pSC, pIO); + + for (i = 0; i < iChannel; i++) { + + iCBPCY = iCBPCU = iCBPCV = 0; + iNumCBP = _getHuffShort(pAHCBP1->m_hufDecTable, pIO); + pAHCBP1->m_iDiscriminant += pAHCBP1->m_pDelta[iNumCBP]; + + switch (iNumCBP) { + case 2: + iNumCBP = _getBit16(pIO, 2); + if (iNumCBP == 0) + iNumCBP = 3; + else if (iNumCBP == 1) + iNumCBP = 5; + else { + static const Int aTab[] = { 6, 9, 10, 12 }; + iNumCBP = aTab[iNumCBP * 2 + _getBool16(pIO) - 4]; + } + break; + case 1: + iNumCBP = 1 << _getBit16(pIO, 2); + break; + case 3: + iNumCBP = 0xf ^ (1 << _getBit16(pIO, 2)); + break; + case 4: + iNumCBP = 0xf; + } + + for (iBlock = 0; iBlock < 4; iBlock++) { + if (iNumCBP & (1 << iBlock)) { + static const UInt gFLC0[] = { 0,2,1,2,2,0 }; + static const UInt gOff0[] = { 0,4,2,8,12,1 }; + static const UInt gOut0[] = { 0,15,3,12, 1,2,4,8, 5,6,9,10, 7,11,13,14 }; + Int iNumBlockCBP = getHuff(pAHCBP->m_hufDecTable, pIO); + unsigned int val = (unsigned int)iNumBlockCBP + 1, iCode1; + + pAHCBP->m_iDiscriminant += pAHCBP->m_pDelta[iNumBlockCBP]; + iNumBlockCBP = 0; + + if (val >= 6) { // chroma present + if (_getBool16(pIO)) { + iNumBlockCBP = 0x10; + } + else if (_getBool16(pIO)) { + iNumBlockCBP = 0x20; + } + else { + iNumBlockCBP = 0x30; + } + if (val == 9) { + if (_getBool16(pIO)) { + // do nothing + } + else if (_getBool16(pIO)) { + val = 10; + } + else { + val = 11; + } + } + val -= 6; + } + iCode1 = gOff0[val]; + if (gFLC0[val]) { + iCode1 += _getBit16(pIO, gFLC0[val]); + } + iNumBlockCBP += gOut0[iCode1]; + + switch (cf) { + case YUV_444: + iCBPCY |= ((iNumBlockCBP & 0xf) << (iBlock * 4)); + for (k = 0; k < 2; k++) { + bIsChroma = ((iNumBlockCBP >> (k + 4)) & 0x01); + if (bIsChroma) { // U is present in block + Int iCode = _getHuffShort(pAHex1->m_hufDecTable, pIO); + switch (iCode) { + case 1: + iCode = _getBit16(pIO, 2); + if (iCode == 0) + iCode = 3; + else if (iCode == 1) + iCode = 5; + else { + static const Int aTab[] = { 6, 9, 10, 12 }; + iCode = aTab[iCode * 2 + _getBool16(pIO) - 4]; + } + break; + case 0: + iCode = 1 << _getBit16(pIO, 2); + break; + case 2: + iCode = 0xf ^ (1 << _getBit16(pIO, 2)); + break; + case 3: + iCode = 0xf; + } + if (k == 0) + iCBPCU |= (iCode << (iBlock * 4)); + else + iCBPCV |= (iCode << (iBlock * 4)); + } + } + break; + + case YUV_420: + iCBPCY |= ((iNumBlockCBP & 0xf) << (iBlock * 4)); + iCBPCU |= ((iNumBlockCBP >> 4) & 0x1) << (iBlock); + iCBPCV |= ((iNumBlockCBP >> 5) & 0x1) << (iBlock); + break; + + case YUV_422: + iCBPCY |= ((iNumBlockCBP & 0xf) << (iBlock * 4)); + for (k = 0; k < 2; k++) { + Int iCode = 5; + const Int iShift[4] = { 0, 1, 4, 5 }; + if ((iNumBlockCBP >> (k + 4)) & 0x01) { + if (_getBool16(pIO)) { + iCode = 1; + } + else if (_getBool16(pIO)) { + iCode = 4; + } + iCode <<= iShift[iBlock]; + if (k == 0) iCBPCU |= iCode; + else iCBPCV |= iCode; + } + } + break; + + default: + iCBPCY |= (iNumBlockCBP << (iBlock * 4)); + } + } + } + + pSC->MBInfo.iDiffCBP[i] = iCBPCY; + if (cf == YUV_420 || cf == YUV_444 || cf == YUV_422) { + pSC->MBInfo.iDiffCBP[1] = iCBPCU; + pSC->MBInfo.iDiffCBP[2] = iCBPCV; + } + } +} + +/************************************************************************* + Experimental code -- decodeBlock + SR = <0 1 2> == + alphabet 12: + pAHexpt[0] == + alphabet 6: + pAHexpt[1] == + pAHexpt[2] == + alphabet 4: + pAHexpt[3] == (SR may be last or insignificant only) + alphabet f(run) (this can be extended to 6 contexts - SL and SR') + pAHexpt[4] == + alphabet f(lev) (this can be extended to 9 contexts) + pAHexpt[5-6] == first symbol + pAHexpt[7-8] == condition on SRn no use +*************************************************************************/ + +Int _FORCEINLINE DecodeSignificantRun(Int iMaxRun, struct CAdaptiveHuffman* pAHexpt, BitIOInfo* pIO) +{ + Int iIndex; + static const Int aRemap[] = { 1,2,3,5,7, 1,2,3,5,7, /*1,2,3,4,6, */1,2,3,4,5 }; + Int iBin = gSignificantRunBin[iMaxRun]; + Int iRun = 0, iFLC = 0; + + if (iMaxRun < 5) { + if (iMaxRun == 1) { + return 1; + } + else if (_getBool16(pIO)) { + return 1; + } + else if (iMaxRun == 2 || _getBool16(pIO)) { + return 2; + } + else if (iMaxRun == 3 || _getBool16(pIO)) { + return 3; + } + return 4; + } + iIndex = _getHuffShort(pAHexpt->m_hufDecTable, pIO); + iIndex += iBin * 5; + iRun = aRemap[iIndex]; + iFLC = gSignificantRunFixedLength[iIndex]; + if (iFLC) { + iRun += _getBit16(pIO, iFLC); + } + return iRun; +} + +#ifndef X86OPT_INLINE +static Void DecodeFirstIndex(Int* pIndex, struct CAdaptiveHuffman* pAHexpt, + BitIOInfo* pIO) +#else +static __forceinline Void DecodeFirstIndex(Int* pIndex, struct CAdaptiveHuffman* pAHexpt, + BitIOInfo* pIO) +#endif +{ + Int iIndex; + iIndex = getHuff(pAHexpt->m_hufDecTable, pIO); + pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex]; + pAHexpt->m_iDiscriminant1 += pAHexpt->m_pDelta1[iIndex]; + *pIndex = iIndex; +} + +#ifndef X86OPT_INLINE +static Void DecodeIndex(Int* pIndex, Int iLoc, struct CAdaptiveHuffman* pAHexpt, + BitIOInfo* pIO) +#else +static __forceinline Void DecodeIndex(Int* pIndex, Int iLoc, + struct CAdaptiveHuffman* pAHexpt, BitIOInfo* pIO) +#endif +{ + Int iIndex; + if (iLoc < 15) { + iIndex = _getHuffShort(pAHexpt->m_hufDecTable, pIO); + pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex]; + pAHexpt->m_iDiscriminant1 += pAHexpt->m_pDelta1[iIndex]; + *pIndex = iIndex; + } + else if (iLoc == 15) { + if (_getBool16(pIO) == 0) { + iIndex = 0; + } + else if (_getBool16(pIO) == 0) { + iIndex = 2; + } + else { + iIndex = 1 + 2 * _getBool16(pIO); + } + *pIndex = iIndex; + } + else { //if (iLoc == 16) { /* deterministic */ + Int iSL = _getBit16(pIO, 1/* + 1*/); + *pIndex = iSL;// >> 1; + } +} + +static _FORCEINLINE Int DecodeBlock(Bool bChroma, Int* aLocalCoef, struct CAdaptiveHuffman** pAHexpt, + const Int iContextOffset, BitIOInfo* pIO, Int iLocation) +{ + Int iSR, iSRn, iIndex, iNumNonzero = 1, iCont, iSign; + struct CAdaptiveHuffman** pAH1 = pAHexpt + iContextOffset + bChroma * 3; + + /** first symbol **/ + DecodeFirstIndex(&iIndex, /*&iSign, */pAH1[0], pIO); + iSR = (iIndex & 1); + iSRn = iIndex >> 2; + + iCont = iSR & iSRn; + iSign = _getSign(pIO); + + if (iIndex & 2 /* iSL */) { + aLocalCoef[1] = (DecodeSignificantAbsLevel(pAHexpt[6 + iContextOffset + iCont], pIO) ^ iSign) - iSign; + } + else { + aLocalCoef[1] = (1 | iSign); // 0 -> 1; -1 -> -1 + } + aLocalCoef[0] = 0; + if (iSR == 0) { + aLocalCoef[0] = DecodeSignificantRun(15 - iLocation, pAHexpt[0], pIO); + } + iLocation += aLocalCoef[0] + 1; + + while (iSRn != 0) { + iSR = iSRn & 1; + aLocalCoef[iNumNonzero * 2] = 0; + if (iSR == 0) { + aLocalCoef[iNumNonzero * 2] = DecodeSignificantRun(15 - iLocation, pAHexpt[0], pIO); + } + iLocation += aLocalCoef[iNumNonzero * 2] + 1; + DecodeIndex(&iIndex, /*&iSign, */iLocation, pAH1[iCont + 1], pIO); + iSRn = iIndex >> 1; + + assert(iSRn >= 0 && iSRn < 3); + iCont &= iSRn; /** huge difference! **/ + iSign = _getSign(pIO); + + if (iIndex & 1 /* iSL */) { + aLocalCoef[iNumNonzero * 2 + 1] = + (DecodeSignificantAbsLevel(pAHexpt[6 + iContextOffset + iCont], pIO) ^ iSign) - iSign; + } + else { + aLocalCoef[iNumNonzero * 2 + 1] = (1 | iSign); // 0 -> 1; -1 -> -1 (was 1 + (iSign * 2)) + } + iNumNonzero++; + } + return iNumNonzero; +} + +/************************************************************************* + DecodeBlockHighpass : +*************************************************************************/ +static _FORCEINLINE Int DecodeBlockHighpass(const Bool bChroma, struct CAdaptiveHuffman** pAHexpt, + BitIOInfo* pIO, const Int iQP, Int* pCoef, CAdaptiveScan* pScan) +{ + const Int iContextOffset = CTDC + CONTEXTX; + UInt iLoc = 1; + Int iSR, iSRn, iIndex, iNumNonzero = 1, iCont, iSign, iLevel; + struct CAdaptiveHuffman** pAH1 = pAHexpt + iContextOffset + bChroma * 3; + const CAdaptiveScan* pConstScan = (const CAdaptiveScan*)pScan; + + /** first symbol **/ + DecodeFirstIndex(&iIndex, /*&iSign, */pAH1[0], pIO); + iSR = (iIndex & 1); + iSRn = iIndex >> 2; + + iCont = iSR & iSRn; + iSign = _getSign(pIO); + + iLevel = (iQP ^ iSign) - iSign; + if (iIndex & 2 /* iSL */) { + iLevel *= DecodeSignificantAbsLevel(pAHexpt[6 + iContextOffset + iCont], pIO);// ^ iSign) - iSign; + } + //else { + // iLevel = (1 | iSign); // 0 -> 1; -1 -> -1 + //} + if (iSR == 0) { + iLoc += DecodeSignificantRun(15 - iLoc, pAHexpt[0], pIO); + } + iLoc &= 0xf; + pCoef[pConstScan[iLoc].uScan] = (PixelI)iLevel;//(PixelI)(iQP * iLevel); + pScan[iLoc].uTotal++; + if (iLoc && pScan[iLoc].uTotal > pScan[iLoc - 1].uTotal) { + CAdaptiveScan cTemp = pScan[iLoc]; + pScan[iLoc] = pScan[iLoc - 1]; + pScan[iLoc - 1] = cTemp; + } + iLoc = (iLoc + 1) & 0xf; + //iLoc++; + + while (iSRn != 0) { + iSR = iSRn & 1; + if (iSR == 0) { + iLoc += DecodeSignificantRun(15 - iLoc, pAHexpt[0], pIO); + if (iLoc >= 16) + return 16; + } + DecodeIndex(&iIndex, /*&iSign, */iLoc + 1, pAH1[iCont + 1], pIO); + iSRn = iIndex >> 1; + + assert(iSRn >= 0 && iSRn < 3); + iCont &= iSRn; /** huge difference! **/ + iSign = _getSign(pIO); + + iLevel = (iQP ^ iSign) - iSign; + if (iIndex & 1 /* iSL */) { + iLevel *= DecodeSignificantAbsLevel(pAHexpt[6 + iContextOffset + iCont], pIO);// ^ iSign) - iSign; + //iLevel = (DecodeSignificantAbsLevel (pAHexpt[6 + iContextOffset + iCont], pIO) ^ iSign) - iSign; + } + //else { + // iLevel = (1 | iSign); // 0 -> 1; -1 -> -1 (was 1 + (iSign * 2)) + //} + + pCoef[pConstScan[iLoc].uScan] = (PixelI)iLevel;//(PixelI)(iQP * iLevel); + pScan[iLoc].uTotal++; + if (iLoc && pScan[iLoc].uTotal > pScan[iLoc - 1].uTotal) { + CAdaptiveScan cTemp = pScan[iLoc]; + pScan[iLoc] = pScan[iLoc - 1]; + pScan[iLoc - 1] = cTemp; + } + + iLoc = (iLoc + 1) & 0xf; + iNumNonzero++; + } + return iNumNonzero; +} + +/************************************************************************* + DecodeBlockAdaptive +*************************************************************************/ +static _FORCEINLINE Int DecodeBlockAdaptive(Bool bNoSkip, Bool bChroma, CAdaptiveHuffman** pAdHuff, + BitIOInfo* pIO, BitIOInfo* pIOFL, + PixelI* pCoeffs, CAdaptiveScan* pScan, + const Int iModelBits, const Int iTrim, const Int iQP, + const Int* pOrder, const Bool bSkipFlexbits) +{ + // const Int iLocation = 1; + // const Int iContextOffset = CTDC + CONTEXTX; + Int kk, iNumNonzero = 0, iFlex = iModelBits - iTrim; + + if (iFlex < 0 || bSkipFlexbits) + iFlex = 0; + + if (bNoSkip) { + const Int iQP1 = (iQP << iModelBits); + iNumNonzero = DecodeBlockHighpass(bChroma, pAdHuff, pIO, iQP1, pCoeffs, pScan); + } + if (iFlex) { + UInt k; + if (iQP + iTrim == 1) { // only iTrim = 0, iQP = 1 is legal + assert(iTrim == 0); + assert(iQP == 1); + + for (k = 1; k < 16; k++) { + PixelI* pk = pCoeffs + pOrder[k]; + if (*pk < 0) { + Int fine = _getBit16(pIOFL, iFlex); + *pk -= (PixelI)(fine); + } + else if (*pk > 0) { + Int fine = _getBit16(pIOFL, iFlex); + *pk += (PixelI)(fine); + } + else { + *pk = (PixelI)(_getBit16s(pIOFL, iFlex)); + } + } + } + else { + const Int iQP1 = iQP << iTrim; + for (k = 1; k < 16; k++) { + kk = pCoeffs[pOrder[k]]; + if (kk < 0) { + Int fine = _getBit16(pIOFL, iFlex); + pCoeffs[pOrder[k]] -= (PixelI)(iQP1 * fine); + } + else if (kk > 0) { + Int fine = _getBit16(pIOFL, iFlex); + pCoeffs[pOrder[k]] += (PixelI)(iQP1 * fine); + } + else { + pCoeffs[pOrder[k]] = (PixelI)(iQP1 * _getBit16s(pIOFL, iFlex)); + } + } + } + } + + return iNumNonzero; +} + + +/************************************************************************* + GetCoeffs +*************************************************************************/ +static _FORCEINLINE Int DecodeCoeffs(CWMImageStrCodec* pSC, CCodingContext* pContext, + Int iMBX, Int iMBY, + BitIOInfo* pIO, BitIOInfo* pIOFL) +{ + CWMITile* pTile = pSC->pTile + pSC->cTileColumn; + const COLORFORMAT cf = pSC->m_param.cfColorFormat; + const Int iChannels = (Int)pSC->m_param.cNumChannels; + const Int iPlanes = (cf == YUV_420 || cf == YUV_422) ? 1 : iChannels; + Int iQP; + CAdaptiveScan* pScan; + PixelI* pCoeffs; + Int i, iBlock, iSubblock, iNBlocks = 4; + Int iModelBits = pContext->m_aModelAC.m_iFlcBits[0]; + Int aLaplacianMean[2] = { 0, 0 }, * pLM = aLaplacianMean + 0; + const Int* pOrder = dctIndex[0]; + const Int iOrient = pSC->MBInfo.iOrientation; + Bool bChroma = FALSE; + + Int iCBPCU = pSC->MBInfo.iCBP[1]; + Int iCBPCV = pSC->MBInfo.iCBP[2]; + Int iCBPCY = pSC->MBInfo.iCBP[0]; + + UNREFERENCED_PARAMETER(iMBX); + UNREFERENCED_PARAMETER(iMBY); + + /** set scan arrays and other MB level constants **/ + if (iOrient == 1) { + pScan = pContext->m_aScanVert; + } + else { + pScan = pContext->m_aScanHoriz; + } + + if (cf == YUV_420) { + iNBlocks = 6; + iCBPCY += (iCBPCU << 16) + (iCBPCV << 20); + } + else if (cf == YUV_422) { + iNBlocks = 8; + iCBPCY += (iCBPCU << 16) + (iCBPCV << 24); + } + + for (i = 0; i < iPlanes; i++) { + Int iIndex = 0, iNumNonZero; + + if (pSC->WMISCP.sbSubband != SB_NO_FLEXBITS) + readIS_L1(pSC, pIOFL); + + for (iBlock = 0; iBlock < iNBlocks; iBlock++) { + + readIS_L2(pSC, pIO); + if (pIO != pIOFL) + readIS_L2(pSC, pIOFL); + + iQP = (pSC->m_param.bTranscode ? 1 : pTile->pQuantizerHP[iPlanes > 1 ? i : (iBlock > 3 ? (cf == YUV_420 ? iBlock - 3 : iBlock / 2 - 1) : 0)][pSC->MBInfo.iQIndexHP].iQP); + + for (iSubblock = 0; iSubblock < 4; iSubblock++, iIndex++, iCBPCY >>= 1) { + pCoeffs = pSC->p1MBbuffer[i] + blkOffset[iIndex & 0xf]; + + //if (iBlock < 4) {//(cf == YUV_444) { + //bBlockNoSkip = ((iTempCBPC & (1 << iIndex1)) != 0); + //pCoeffs = pSC->p1MBbuffer[iBlock >> 2] + blkOffset[iIndex & 0xf]; + //} + //else { + if (iBlock >= 4) { + if (cf == YUV_420) { + pCoeffs = pSC->p1MBbuffer[iBlock - 3] + blkOffsetUV[iSubblock]; + } + else { // YUV_422 + pCoeffs = pSC->p1MBbuffer[1 + (1 & (iBlock >> 1))] + ((iBlock & 1) * 32) + blkOffsetUV_422[iSubblock]; + } + } + + /** read AC values **/ + assert(pSC->m_Dparam->bSkipFlexbits == 0 || pSC->WMISCP.bfBitstreamFormat == FREQUENCY || pSC->WMISCP.sbSubband == SB_NO_FLEXBITS); + iNumNonZero = DecodeBlockAdaptive((iCBPCY & 1), bChroma, pContext->m_pAHexpt, + pIO, pIOFL, pCoeffs, pScan, iModelBits, pContext->m_iTrimFlexBits, + iQP, pOrder, pSC->m_Dparam->bSkipFlexbits); + if (iNumNonZero > 16) // something is wrong! + return ICERR_ERROR; + // shouldn't this be > 15? + (*pLM) += iNumNonZero; + } + if (iBlock == 3) { + iModelBits = pContext->m_aModelAC.m_iFlcBits[1]; + pLM = aLaplacianMean + 1; + bChroma = TRUE; + } + } + + iCBPCY = pSC->MBInfo.iCBP[(i + 1) & 0xf]; + assert(MAX_CHANNELS == 16); + } + + /** update model at end of MB **/ + UpdateModelMB(cf, iChannels, aLaplacianMean, &(pContext->m_aModelAC)); + return ICERR_OK; +} + +/************************************************************************* + DecodeSignificantAbsLevel +*************************************************************************/ +#ifndef X86OPT_INLINE +static Int DecodeSignificantAbsLevel(struct CAdaptiveHuffman* pAHexpt, BitIOInfo* pIO) +#else +static __forceinline Int DecodeSignificantAbsLevel(struct CAdaptiveHuffman* pAHexpt, BitIOInfo* pIO) +#endif +{ + UInt iIndex; + Int iFixed, iLevel; + static const Int aRemap[] = { 2, 3, 4, 6, 10, 14 }; + static const Int aFixedLength[] = { 0, 0, 1, 2, 2, 2 }; + + iIndex = (UInt)getHuff(pAHexpt->m_hufDecTable, pIO); + assert(iIndex <= 6); + pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex]; + if (iIndex < 2) { + iLevel = iIndex + 2; // = aRemap[iIndex] + } + else if (iIndex < 6) { + iFixed = aFixedLength[iIndex]; + iLevel = aRemap[iIndex] + _getBit16(pIO, iFixed); + } + else { + iFixed = _getBit16(pIO, 4) + 4; + if (iFixed == 19) { + iFixed += _getBit16(pIO, 2); + if (iFixed == 22) { + iFixed += _getBit16(pIO, 3); + } + } + iLevel = 2 + (1 << iFixed); + iIndex = getBit32(pIO, iFixed); + iLevel += iIndex; + } + return iLevel; +} + +U8 decodeQPIndex(BitIOInfo* pIO, U8 cBits) +{ + if (_getBit16(pIO, 1) == 0) + return 0; + return (U8)(_getBit16(pIO, cBits) + 1); +} + +/************************************************************************* + DecodeSecondStageCoeff +*************************************************************************/ +Int DecodeMacroblockLowpass(CWMImageStrCodec* pSC, CCodingContext* pContext, + Int iMBX, Int iMBYdummy) +{ + const COLORFORMAT cf = pSC->m_param.cfColorFormat; + const Int iChannels = (Int)pSC->m_param.cNumChannels; + const Int iFullPlanes = (cf == YUV_420 || cf == YUV_422) ? 2 : iChannels; + Int k; + CAdaptiveScan* pScan = pContext->m_aScanLowpass; + BitIOInfo* pIO = pContext->m_pIOLP; + Int iModelBits = pContext->m_aModelLP.m_iFlcBits[0]; + Int aRLCoeffs[32], iNumNonzero = 0, iIndex = 0; + Int aLaplacianMean[2] = { 0, 0 }, * pLM = aLaplacianMean; + Int iChannel, iCBP = 0; +#ifndef ARMOPT_BITIO // ARM opt always uses 32-bit version of getBits + U32(*getBits)(BitIOInfo * pIO, U32 cBits) = _getBit16; +#endif + CWMIMBInfo* pMBInfo = &pSC->MBInfo; + I32* aDC[MAX_CHANNELS]; + + UNREFERENCED_PARAMETER(iMBX); + UNREFERENCED_PARAMETER(iMBYdummy); + + readIS_L1(pSC, pIO); + if ((pSC->WMISCP.bfBitstreamFormat != SPATIAL) && (pSC->pTile[pSC->cTileColumn].cBitsLP > 0)) // MB-based LP QP index + pMBInfo->iQIndexLP = decodeQPIndex(pIO, pSC->pTile[pSC->cTileColumn].cBitsLP); + + // set arrays + for (k = 0; k < (Int)pSC->m_param.cNumChannels; k++) { + aDC[k & 15] = pMBInfo->iBlockDC[k]; + } + + /** reset adaptive scan totals **/ + if (pSC->m_bResetRGITotals) { + int iScale = 2; + int iWeight = iScale * 16; + pScan[0].uTotal = MAXTOTAL; + for (k = 1; k < 16; k++) { + pScan[k].uTotal = iWeight; + iWeight -= iScale; + } + } + + /** in raw mode, this can take 6% of the bits in the extreme low rate case!!! **/ + if (cf == YUV_420 || cf == YUV_422 || cf == YUV_444) { + int iCountM = pContext->m_iCBPCountMax, iCountZ = pContext->m_iCBPCountZero; + int iMax = iFullPlanes * 4 - 5; /* actually (1 << iNChannels) - 1 **/ + if (iCountZ <= 0 || iCountM < 0) { + iCBP = 0; + if (_getBool16(pIO)) { + iCBP = 1; + k = _getBit16(pIO, iFullPlanes - 1); + if (k) { + iCBP = k * 2 + _getBit16(pIO, 1); + } + } + if (iCountM < iCountZ) + iCBP = iMax - iCBP; + } + else { + iCBP = _getBit16(pIO, iFullPlanes); + } + + iCountM += 1 - 4 * (iCBP == iMax);//(b + c - 2*a); + iCountZ += 1 - 4 * (iCBP == 0);//(a + b - 2*c); + if (iCountM < -8) + iCountM = -8; + else if (iCountM > 7) + iCountM = 7; + pContext->m_iCBPCountMax = iCountM; + + if (iCountZ < -8) + iCountZ = -8; + else if (iCountZ > 7) + iCountZ = 7; + pContext->m_iCBPCountZero = iCountZ; + } + else { /** 1 or N channel **/ + for (iChannel = 0; iChannel < iChannels; iChannel++) + iCBP |= (getBits(pIO, 1) << iChannel); + } + +#ifndef ARMOPT_BITIO // ARM opt always uses 32-bit version of getBits + if (pContext->m_aModelLP.m_iFlcBits[0] > 14 || pContext->m_aModelLP.m_iFlcBits[1] > 14) { + getBits = getBit32; + } +#endif + + for (iChannel = 0; iChannel < iFullPlanes; iChannel++) { + PixelI* pCoeffs = aDC[iChannel]; + + if (iCBP & 1) { + iNumNonzero = DecodeBlock(iChannel > 0, aRLCoeffs, pContext->m_pAHexpt, + CTDC, pIO, 1 + 9 * ((cf == YUV_420) && (iChannel == 1)) + + ((cf == YUV_422) && (iChannel == 1))); + + if ((cf == YUV_420 || cf == YUV_422) && iChannel) { + Int aTemp[16]; //14 required, 16 for security + static const Int aRemap[] = { 4, 1,2,3, 5,6,7 }; + const Int* pRemap = aRemap + (cf == YUV_420); + const Int iCount = (cf == YUV_420) ? 6 : 14; + + (*pLM) += iNumNonzero; + iIndex = 0; + memset(aTemp, 0, sizeof(aTemp)); + + for (k = 0; k < iNumNonzero; k++) { + iIndex += aRLCoeffs[k * 2]; + aTemp[iIndex & 0xf] = aRLCoeffs[k * 2 + 1]; + iIndex++; + } + + for (k = 0; k < iCount; k++) { + aDC[(k & 1) + 1][pRemap[k >> 1]] = aTemp[k]; + } + } + else { + (*pLM) += iNumNonzero; + iIndex = 1; + + for (k = 0; k < iNumNonzero; k++) { + iIndex += aRLCoeffs[k * 2]; + pCoeffs[pScan[iIndex].uScan] = aRLCoeffs[k * 2 + 1]; + pScan[iIndex].uTotal++; + if (pScan[iIndex].uTotal > pScan[iIndex - 1].uTotal) { + CAdaptiveScan cTemp = pScan[iIndex]; + pScan[iIndex] = pScan[iIndex - 1]; + pScan[iIndex - 1] = cTemp; + } + iIndex++; + } + } + } + + if (iModelBits) { + if ((cf == YUV_420 || cf == YUV_422) && iChannel) { + for (k = 1; k < (cf == YUV_420 ? 4 : 8); k++) { + if (aDC[1][k] > 0) { + aDC[1][k] <<= iModelBits; + aDC[1][k] += getBits(pIO, iModelBits); + } + else if (aDC[1][k] < 0) { + aDC[1][k] <<= iModelBits; + aDC[1][k] -= getBits(pIO, iModelBits); + } + else { + aDC[1][k] = getBits(pIO, iModelBits); + if (aDC[1][k] && _getBool16(pIO)) + aDC[1][k] = -aDC[1][k]; + } + + if (aDC[2][k] > 0) { + aDC[2][k] <<= iModelBits; + aDC[2][k] += getBits(pIO, iModelBits); + } + else if (aDC[2][k] < 0) { + aDC[2][k] <<= iModelBits; + aDC[2][k] -= getBits(pIO, iModelBits); + } + else { + aDC[2][k] = getBits(pIO, iModelBits); + if (aDC[2][k] && _getBool16(pIO)) + aDC[2][k] = -aDC[2][k]; + } + } + } + else { +#ifdef WIN32 + const Int iMask = (1 << iModelBits) - 1; +#endif // WIN32 + for (k = 1; k < 16; k++) { +#ifdef WIN32 + if (pCoeffs[k]) { + Int r1 = _rotl(pCoeffs[k], iModelBits); + pCoeffs[k] = (r1 ^ getBits(pIO, iModelBits)) - (r1 & iMask); + } +#else // WIN32 + if (pCoeffs[k] > 0) { + pCoeffs[k] <<= iModelBits; + pCoeffs[k] += getBits(pIO, iModelBits); + } + else if (pCoeffs[k] < 0) { + // left-shift the positive value and set the negative sign back afterwards + pCoeffs[k] = -(-pCoeffs[k] << iModelBits); + pCoeffs[k] -= getBits(pIO, iModelBits); + } +#endif // WIN32 + else { + //pCoeffs[k] = getBits (pIO, iModelBits); + //if (pCoeffs[k] && _getBool16 (pIO)) + // pCoeffs[k] = -pCoeffs[k]; + Int r1 = _peekBit16(pIO, iModelBits + 1); + pCoeffs[k] = ((r1 >> 1) ^ (-(r1 & 1))) + (r1 & 1); + _flushBit16(pIO, iModelBits + (pCoeffs[k] != 0)); + } + } + } + } + pLM = aLaplacianMean + 1; + iModelBits = pContext->m_aModelLP.m_iFlcBits[1]; + + iCBP >>= 1; + } + + UpdateModelMB(cf, iChannels, aLaplacianMean, &(pContext->m_aModelLP)); + + if (pSC->m_bResetContext) { + AdaptLowpassDec(pContext); + } + + return ICERR_OK; +} + +/************************************************************************* + 8 bit YUV 420 macroblock decode function with 4x4 transform + Index order is as follows: + Y: U: V: + 0 1 4 5 16 17 20 21 + 2 3 6 7 18 19 22 23 + 8 9 12 13 + 10 11 14 15 + + DCAC coefficients stored for 4x4 - offsets (x == no storage) + Y: + x x x [0..3] + x x x [4..7] + x x x [8..11] + [16..19] [20..23] [24..27] [28..31,12..15] + + U, V: + x [0..3] + [8..11] [4..7,12..15] +*************************************************************************/ +Int DecodeMacroblockDC(CWMImageStrCodec* pSC, CCodingContext* pContext, Int iMBX, Int iMBY) +{ + CWMITile* pTile = pSC->pTile + pSC->cTileColumn; + CWMIMBInfo* pMBInfo = &pSC->MBInfo; + const COLORFORMAT cf = pSC->m_param.cfColorFormat; + const Int iChannels = (Int)pSC->m_param.cNumChannels; + BitIOInfo* pIO = pContext->m_pIODC; + Int iIndex, i; + Int aLaplacianMean[2] = { 0, 0 }, * pLM = aLaplacianMean; + Int iModelBits = pContext->m_aModelDC.m_iFlcBits[0]; + struct CAdaptiveHuffman* pAH; + Int iQDCY, iQDCU, iQDCV; + // const Int iChromaElements = (cf == YUV_420) ? 8 * 8 : ((cf == YUV_422) ? 8 * 16 : 16 * 16); + + UNREFERENCED_PARAMETER(iMBX); + UNREFERENCED_PARAMETER(iMBY); + + for (i = 0; i < iChannels; i++) + memset(pMBInfo->iBlockDC[i], 0, 16 * sizeof(I32)); + + readIS_L1(pSC, pIO); + + pMBInfo->iQIndexLP = pMBInfo->iQIndexHP = 0; + + if (pSC->WMISCP.bfBitstreamFormat == SPATIAL && pSC->WMISCP.sbSubband != SB_DC_ONLY) { + if (pTile->cBitsLP > 0) // MB-based LP QP index + pMBInfo->iQIndexLP = decodeQPIndex(pIO, pTile->cBitsLP); + if (pSC->WMISCP.sbSubband != SB_NO_HIGHPASS && pTile->cBitsHP > 0) // MB-based HP QP index + pMBInfo->iQIndexHP = decodeQPIndex(pIO, pTile->cBitsHP); + } + if (pTile->cBitsHP == 0 && pTile->cNumQPHP > 1) // use LP QP + pMBInfo->iQIndexHP = pMBInfo->iQIndexLP; + if (pMBInfo->iQIndexLP >= pTile->cNumQPLP || pMBInfo->iQIndexHP >= pTile->cNumQPHP) + return ICERR_ERROR; + + if (cf == Y_ONLY || cf == CMYK || cf == NCOMPONENT) { + for (i = 0; i < iChannels; i++) { + iQDCY = 0; + /** get luminance DC **/ + if (_getBool16(pIO)) { + iQDCY = DecodeSignificantAbsLevel(pContext->m_pAHexpt[3], pIO) - 1; + *pLM += 1; + } + if (iModelBits) { + iQDCY = (iQDCY << iModelBits) | _getBit16(pIO, iModelBits); + } + if (iQDCY && _getBool16(pIO)) + iQDCY = -iQDCY; + pMBInfo->iBlockDC[i][0] = iQDCY; + + pLM = aLaplacianMean + 1; + iModelBits = pContext->m_aModelDC.m_iFlcBits[1]; + } + } + else { + /** find significant level in 3D **/ + pAH = pContext->m_pAHexpt[2]; + iIndex = getHuff(pAH->m_hufDecTable, pIO); + iQDCY = iIndex >> 2; + iQDCU = (iIndex >> 1) & 1; + iQDCV = iIndex & 1; + + /** get luminance DC **/ + if (iQDCY) { + iQDCY = DecodeSignificantAbsLevel(pContext->m_pAHexpt[3], pIO) - 1; + *pLM += 1; + } + if (iModelBits) { + iQDCY = (iQDCY << iModelBits) | _getBit16(pIO, iModelBits); + } + if (iQDCY && _getBool16(pIO)) + iQDCY = -iQDCY; + pMBInfo->iBlockDC[0][0] = iQDCY; + + /** get chrominance DC **/ + pLM = aLaplacianMean + 1; + iModelBits = pContext->m_aModelDC.m_iFlcBits[1]; + + if (iQDCU) { + iQDCU = DecodeSignificantAbsLevel(pContext->m_pAHexpt[4], pIO) - 1; + *pLM += 1; + } + if (iModelBits) { + iQDCU = (iQDCU << iModelBits) | _getBit16(pIO, iModelBits); + } + if (iQDCU && _getBool16(pIO)) + iQDCU = -iQDCU; + pMBInfo->iBlockDC[1][0] = iQDCU; + + if (iQDCV) { + iQDCV = DecodeSignificantAbsLevel(pContext->m_pAHexpt[4], pIO) - 1; + *pLM += 1; + } + if (iModelBits) { + iQDCV = (iQDCV << iModelBits) | _getBit16(pIO, iModelBits); + } + if (iQDCV && _getBool16(pIO)) + iQDCV = -iQDCV; + pMBInfo->iBlockDC[2][0] = iQDCV; + } + + UpdateModelMB(cf, iChannels, aLaplacianMean, &(pContext->m_aModelDC)); + + if (((!(pSC->WMISCP.bfBitstreamFormat != FREQUENCY || pSC->m_Dparam->cThumbnailScale < 16)) || pSC->WMISCP.sbSubband == SB_DC_ONLY) && pSC->m_bResetContext) { + Int kk; + for (kk = 2; kk < 5; kk++) { + if (ICERR_OK != AdaptDecFixed(pContext->m_pAHexpt[kk])) { + return ICERR_ERROR; + } + } + } + + return ICERR_OK; +} + +/************************************************************************* + DecodeMacroblockHighpass +*************************************************************************/ +Int DecodeMacroblockHighpass(CWMImageStrCodec* pSC, CCodingContext* pContext, + Int iMBX, Int iMBY) +{ + /** reset adaptive scan totals **/ + if (pSC->m_bResetRGITotals) { + int iScale = 2, k; + int iWeight = iScale * 16; + pContext->m_aScanHoriz[0].uTotal = pContext->m_aScanVert[0].uTotal = MAXTOTAL; + for (k = 1; k < 16; k++) { + pContext->m_aScanHoriz[k].uTotal = pContext->m_aScanVert[k].uTotal = iWeight; + iWeight -= iScale; + } + } + if ((pSC->WMISCP.bfBitstreamFormat != SPATIAL) && (pSC->pTile[pSC->cTileColumn].cBitsHP > 0)) { // MB-based HP QP index + pSC->MBInfo.iQIndexHP = decodeQPIndex(pContext->m_pIOAC, pSC->pTile[pSC->cTileColumn].cBitsHP); + if (pSC->MBInfo.iQIndexHP >= pSC->pTile[pSC->cTileColumn].cNumQPHP) + goto ErrorExit; + } + else if (pSC->pTile[pSC->cTileColumn].cBitsHP == 0 && pSC->pTile[pSC->cTileColumn].cNumQPHP > 1) // use LP QP + pSC->MBInfo.iQIndexHP = pSC->MBInfo.iQIndexLP; + + + DecodeCBP(pSC, pContext); + predCBPDec(pSC, pContext); + + if (DecodeCoeffs(pSC, pContext, iMBX, iMBY, + pContext->m_pIOAC, pContext->m_pIOFL) != ICERR_OK) + goto ErrorExit; + + if (pSC->m_bResetContext) { + AdaptHighpassDec(pContext); + } + + return ICERR_OK; +ErrorExit: + return ICERR_ERROR; +} + +/************************************************************************* + Adapt +*************************************************************************/ +Int AdaptLowpassDec(CCodingContext* pSC) +{ + Int kk; + for (kk = 0; kk < CONTEXTX + CTDC; kk++) { + if (ICERR_OK != AdaptDecFixed(pSC->m_pAHexpt[kk])) { + goto ErrorExit; + } + } + return ICERR_OK; + +ErrorExit: + return ICERR_ERROR; + +} + +Int AdaptHighpassDec(CCodingContext* pSC) +{ + Int kk; + if (ICERR_OK != AdaptDecFixed(pSC->m_pAdaptHuffCBPCY)) { + goto ErrorExit; + } + if (ICERR_OK != AdaptDecFixed(pSC->m_pAdaptHuffCBPCY1)) { + goto ErrorExit; + } + for (kk = 0; kk < CONTEXTX; kk++) { + if (ICERR_OK != AdaptDecFixed(pSC->m_pAHexpt[kk + CONTEXTX + CTDC])) { + goto ErrorExit; + } + } + + return ICERR_OK; + +ErrorExit: + return ICERR_ERROR; +} diff --git a/Src/JxrDecode/jxrlib/image/decode/strInvTransform.c b/Src/JxrDecode/jxrlib/image/decode/strInvTransform.c new file mode 100644 index 00000000..d77df7d6 --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/decode/strInvTransform.c @@ -0,0 +1,1888 @@ +//*@@@+++@@@@****************************************************************** +// +// 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 "../sys/strTransform.h" +#include "../sys/strcodec.h" +#include "decode.h" + +/** rotation by -pi/8 **/ +#define IROTATE1(a, b) (a) -= (((b) + 1) >> 1), (b) += (((a) + 1) >> 1) // this works well too +#define IROTATE2(a, b) (a) -= (((b)*3 + 4) >> 3), (b) += (((a)*3 + 4) >> 3) // this works well too + +/** local functions **/ +static Void invOddOdd(PixelI*, PixelI*, PixelI*, PixelI*); +static Void invOddOddPost(PixelI*, PixelI*, PixelI*, PixelI*); +static Void invOdd(PixelI*, PixelI*, PixelI*, PixelI*); +static Void strHSTdec(PixelI*, PixelI*, PixelI*, PixelI*); +static Void strHSTdec1(PixelI*, PixelI*); +static Void strHSTdec1_alternate(PixelI*, PixelI*); +static Void strHSTdec1_edge(PixelI* pa, PixelI* pd); + +/** IDCT stuff **/ +/** reordering should be combined with zigzag scan **/ +/** data order before IDCT **/ +/** 0 8 4 6 **/ +/** 2 10 14 12 **/ +/** 1 11 15 13 **/ +/** 9 3 7 5 **/ +/** data order after IDCT **/ +/** 0 1 2 3 **/ +/** 4 5 6 7 **/ +/** 8 9 10 11 **/ +/** 12 13 14 15 **/ +Void strIDCT4x4Stage1(PixelI* p) +{ + /** top left corner, butterfly => butterfly **/ + strDCT2x2up(p + 0, p + 1, p + 2, p + 3); + + /** top right corner, -pi/8 rotation => butterfly **/ + invOdd(p + 5, p + 4, p + 7, p + 6); + + /** bottom left corner, butterfly => -pi/8 rotation **/ + invOdd(p + 10, p + 8, p + 11, p + 9); + + /** bottom right corner, -pi/8 rotation => -pi/8 rotation **/ + invOddOdd(p + 15, p + 14, p + 13, p + 12); + + /** butterfly **/ + //FOURBUTTERFLY(p, 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15); + FOURBUTTERFLY_HARDCODED1(p); +} + +Void strIDCT4x4Stage2(PixelI* p) +{ + /** bottom left corner, butterfly => -pi/8 rotation **/ + invOdd(p + 32, p + 48, p + 96, p + 112); + + /** top right corner, -pi/8 rotation => butterfly **/ + invOdd(p + 128, p + 192, p + 144, p + 208); + + /** bottom right corner, -pi/8 rotation => -pi/8 rotation **/ + invOddOdd(p + 160, p + 224, p + 176, p + 240); + + /** top left corner, butterfly => butterfly **/ + strDCT2x2up(p + 0, p + 64, p + 16, p + 80); + + /** butterfly **/ + FOURBUTTERFLY(p, 0, 192, 48, 240, 64, 128, 112, 176, 16, 208, 32, 224, 80, 144, 96, 160); +} + +Void strNormalizeDec(PixelI* p, Bool bChroma) +{ + int i; + if (!bChroma) { + //for (i = 0; i < 256; i += 16) { + // p[i] <<= 2; + //} + } + else { + for (i = 0; i < 256; i += 16) { + p[i] += p[i]; + } + } +} + +/** 2x2 DCT with post-scaling - for use on decoder side **/ +Void strDCT2x2dnDec(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 * 2; + *pb = b * 2; + *pc = c * 2; + *pd = d * 2; +} + + +/** post filter stuff **/ +/** 2-point post for boundaries **/ +Void strPost2(PixelI* a, PixelI* b) +{ + *b += ((*a + 4) >> 3); + *a += ((*b + 2) >> 2); + *b += ((*a + 4) >> 3); +} + +Void strPost2_alternate(PixelI* pa, PixelI* pb) +{ + PixelI a, b; + a = *pa; + b = *pb; + + /** rotate **/ + b += ((a + 2) >> 2); + a += ((b + 1) >> 1); + a += (b >> 5); + a += (b >> 9); + a += (b >> 13); + + b += ((a + 2) >> 2); + + *pa = a; + *pb = b; +} + +Void strPost2x2(PixelI* pa, PixelI* pb, PixelI* pc, PixelI* pd) +{ + PixelI a, b, c, d; + a = *pa; + b = *pb; + c = *pc; + d = *pd; + + /** butterflies **/ + a += d; + b += c; + d -= (a + 1) >> 1; + c -= (b + 1) >> 1; + + /** rotate **/ + b += ((a + 2) >> 2); + a += ((b + 1) >> 1); + b += ((a + 2) >> 2); + + /** butterflies **/ + d += (a + 1) >> 1; + c += (b + 1) >> 1; + a -= d; + b -= c; + + *pa = a; + *pb = b; + *pc = c; + *pd = d; +} + +Void strPost2x2_alternate(PixelI* pa, PixelI* pb, PixelI* pc, PixelI* pd) +{ + PixelI a, b, c, d; + a = *pa; + b = *pb; + c = *pc; + d = *pd; + + /** butterflies **/ + a += d; + b += c; + d -= (a + 1) >> 1; + c -= (b + 1) >> 1; + + /** rotate **/ + b += ((a + 2) >> 2); + a += ((b + 1) >> 1); + a += (b >> 5); + a += (b >> 9); + a += (b >> 13); + b += ((a + 2) >> 2); + + /** butterflies **/ + d += (a + 1) >> 1; + c += (b + 1) >> 1; + a -= d; + b -= c; + + *pa = a; + *pb = b; + *pc = c; + *pd = d; +} + +/** 4-point post for boundaries **/ +Void strPost4(PixelI* pa, PixelI* pb, PixelI* pc, PixelI* pd) +{ + PixelI a, b, c, d; + a = *pa; + b = *pb; + c = *pc; + d = *pd; + + a += d, b += c; + d -= ((a + 1) >> 1), c -= ((b + 1) >> 1); + + IROTATE1(c, d); + + d += ((a + 1) >> 1), c += ((b + 1) >> 1); + a -= d - ((d * 3 + 16) >> 5), b -= c - ((c * 3 + 16) >> 5); + d += ((a * 3 + 8) >> 4), c += ((b * 3 + 8) >> 4); + a += ((d * 3 + 16) >> 5), b += ((c * 3 + 16) >> 5); + + *pa = a; + *pb = b; + *pc = c; + *pd = d; +} + +Void strPost4_alternate(PixelI* pa, PixelI* pb, PixelI* pc, PixelI* pd) +{ + PixelI a, b, c, d; + a = *pa; + b = *pb; + c = *pc; + d = *pd; + + a += d, b += c; + d -= ((a + 1) >> 1), c -= ((b + 1) >> 1); + + strHSTdec1_edge(&a, &d); strHSTdec1_edge(&b, &c); + IROTATE1(c, d); + d += ((a + 1) >> 1), c += ((b + 1) >> 1); + + a -= d, b -= c; + + *pa = a; + *pb = b; + *pc = c; + *pd = d; +} + +/***************************************************************************************** + Input data offsets: + (15)(14)|(10+64)(11+64) p0 (15)(14)|(74)(75) + (13)(12)|( 8+64)( 9+64) (13)(12)|(72)(73) + --------+-------------- --------+-------- + ( 5)( 4)|( 0+64) (1+64) p1 ( 5)( 4)|(64)(65) + ( 7)( 6)|( 2+64) (3+64) ( 7)( 6)|(66)(67) +*****************************************************************************************/ +Void DCCompensate(PixelI* a, PixelI* b, PixelI* c, PixelI* d, int iDC) +{ + iDC = iDC >> 1; + *a -= iDC; + *d -= iDC; + *b += iDC; + *c += iDC; +} + +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +int ClipDCL(int iDCL, int iAltDCL) +{ + int iClipDCL = 0; + if (iDCL > 0) { + if (iAltDCL > 0) + iClipDCL = min(iDCL, iAltDCL); + else + iClipDCL = 0; + } + else if (iDCL < 0) { + if (iAltDCL < 0) + iClipDCL = max(iDCL, iAltDCL); + else + iClipDCL = 0; + } + return iClipDCL; +} + +Void strPost4x4Stage1Split(PixelI* p0, PixelI* p1, Int iOffset, Int iHPQP, Bool bHPAbsent) +{ + int iDCLAlt1, iDCLAlt2, iDCLAlt3, iDCLAlt0; + int iDCL1, iDCL2, iDCL3, iDCL0; + int iTmp1, iTmp2, iTmp3, iTmp0; + + PixelI* p2 = p0 + 72 - iOffset; + PixelI* p3 = p1 + 64 - iOffset; + p0 += 12; + p1 += 4; + + /** buttefly **/ + strDCT2x2dn(p0 + 0, p2 + 0, p1 + 0, p3 + 0); + strDCT2x2dn(p0 + 1, p2 + 1, p1 + 1, p3 + 1); + strDCT2x2dn(p0 + 2, p2 + 2, p1 + 2, p3 + 2); + strDCT2x2dn(p0 + 3, p2 + 3, p1 + 3, p3 + 3); + + /** bottom right corner: -pi/8 rotation => -pi/8 rotation **/ + invOddOddPost(p3 + 0, p3 + 1, p3 + 2, p3 + 3); + + /** anti diagonal corners: rotation by -pi/8 **/ + IROTATE1(p1[2], p1[3]); + IROTATE1(p1[0], p1[1]); + IROTATE1(p2[1], p2[3]); + IROTATE1(p2[0], p2[2]); + + /** butterfly **/ + strHSTdec1(p0 + 0, p3 + 0); + strHSTdec1(p0 + 1, p3 + 1); + strHSTdec1(p0 + 2, p3 + 2); + strHSTdec1(p0 + 3, p3 + 3); + strHSTdec(p0 + 0, p2 + 0, p1 + 0, p3 + 0); + strHSTdec(p0 + 1, p2 + 1, p1 + 1, p3 + 1); + strHSTdec(p0 + 2, p2 + 2, p1 + 2, p3 + 2); + strHSTdec(p0 + 3, p2 + 3, p1 + 3, p3 + 3); + + iTmp0 = (*(p0 + 0) + *(p1 + 0) + *(p2 + 0) + *(p3 + 0)) >> 1; + iTmp1 = (*(p0 + 1) + *(p1 + 1) + *(p2 + 1) + *(p3 + 1)) >> 1; + iTmp2 = (*(p0 + 2) + *(p1 + 2) + *(p2 + 2) + *(p3 + 2)) >> 1; + iTmp3 = (*(p0 + 3) + *(p1 + 3) + *(p2 + 3) + *(p3 + 3)) >> 1; + iDCL0 = (iTmp0 * 595 + 65536) >> 17; //Approximating 27/5947 + iDCL1 = (iTmp1 * 595 + 65536) >> 17; + iDCL2 = (iTmp2 * 595 + 65536) >> 17; + iDCL3 = (iTmp3 * 595 + 65536) >> 17; + if ((abs(iDCL0) < iHPQP && iHPQP > 20) || bHPAbsent) { + iDCLAlt0 = (*(p0 + 0) - *(p1 + 0) - *(p2 + 0) + *(p3 + 0)) >> 1; + iDCL0 = ClipDCL(iDCL0, iDCLAlt0); + DCCompensate(p0 + 0, p2 + 0, p1 + 0, p3 + 0, iDCL0); + } + if ((abs(iDCL1) < iHPQP && iHPQP > 20) || bHPAbsent) { + iDCLAlt1 = (*(p0 + 1) - *(p1 + 1) - *(p2 + 1) + *(p3 + 1)) >> 1; + iDCL1 = ClipDCL(iDCL1, iDCLAlt1); + DCCompensate(p0 + 1, p2 + 1, p1 + 1, p3 + 1, iDCL1); + } + if ((abs(iDCL2) < iHPQP && iHPQP > 20) || bHPAbsent) { + iDCLAlt2 = (*(p0 + 2) - *(p1 + 2) - *(p2 + 2) + *(p3 + 2)) >> 1; + iDCL2 = ClipDCL(iDCL2, iDCLAlt2); + DCCompensate(p0 + 2, p2 + 2, p1 + 2, p3 + 2, iDCL2); + } + if ((abs(iDCL3) < iHPQP && iHPQP > 20) || bHPAbsent) { + iDCLAlt3 = (*(p0 + 3) - *(p1 + 3) - *(p2 + 3) + *(p3 + 3)) >> 1; + iDCL3 = ClipDCL(iDCL3, iDCLAlt3); + DCCompensate(p0 + 3, p2 + 3, p1 + 3, p3 + 3, iDCL3); + } +} + +Void strPost4x4Stage1(PixelI* p, Int iOffset, Int iHPQP, Bool bHPAbsent) +{ + strPost4x4Stage1Split(p, p + 16, iOffset, iHPQP, bHPAbsent); +} + +Void strPost4x4Stage1Split_alternate(PixelI* p0, PixelI* p1, Int iOffset) +{ + PixelI* p2 = p0 + 72 - iOffset; + PixelI* p3 = p1 + 64 - iOffset; + p0 += 12; + p1 += 4; + + /** buttefly **/ + strDCT2x2dn(p0 + 0, p2 + 0, p1 + 0, p3 + 0); + strDCT2x2dn(p0 + 1, p2 + 1, p1 + 1, p3 + 1); + strDCT2x2dn(p0 + 2, p2 + 2, p1 + 2, p3 + 2); + strDCT2x2dn(p0 + 3, p2 + 3, p1 + 3, p3 + 3); + + /** bottom right corner: -pi/8 rotation => -pi/8 rotation **/ + invOddOddPost(p3 + 0, p3 + 1, p3 + 2, p3 + 3); + + /** anti diagonal corners: rotation by -pi/8 **/ + IROTATE1(p1[2], p1[3]); + IROTATE1(p1[0], p1[1]); + IROTATE1(p2[1], p2[3]); + IROTATE1(p2[0], p2[2]); + + /** butterfly **/ + strHSTdec1_alternate(p0 + 0, p3 + 0); + strHSTdec1_alternate(p0 + 1, p3 + 1); + strHSTdec1_alternate(p0 + 2, p3 + 2); + strHSTdec1_alternate(p0 + 3, p3 + 3); + strHSTdec(p0 + 0, p2 + 0, p1 + 0, p3 + 0); + strHSTdec(p0 + 1, p2 + 1, p1 + 1, p3 + 1); + strHSTdec(p0 + 2, p2 + 2, p1 + 2, p3 + 2); + strHSTdec(p0 + 3, p2 + 3, p1 + 3, p3 + 3); +} + +Void strPost4x4Stage1_alternate(PixelI* p, Int iOffset) +{ + strPost4x4Stage1Split_alternate(p, p + 16, iOffset); +} + +/***************************************************************************************** + Input data offsets: + (15)(14)|(10+32)(11+32) p0 (15)(14)|(42)(43) + (13)(12)|( 8+32)( 9+32) (13)(12)|(40)(41) + --------+-------------- --------+-------- + ( 5)( 4)|( 0+32) (1+32) p1 ( 5)( 4)|(32)(33) + ( 7)( 6)|( 2+32) (3+32) ( 7)( 6)|(34)(35) +*****************************************************************************************/ + +/***************************************************************************************** + Input data offsets: + ( -96)(-32)|(32)( 96) p0 + ( -80)(-16)|(48)(112) + -----------+------------ + (-128)(-64)|( 0)( 64) p1 + (-112)(-48)|(16)( 80) +*****************************************************************************************/ +Void strPost4x4Stage2Split(PixelI* p0, PixelI* p1) +{ + /** buttefly **/ + strDCT2x2dn(p0 - 96, p0 + 96, p1 - 112, p1 + 80); + strDCT2x2dn(p0 - 32, p0 + 32, p1 - 48, p1 + 16); + strDCT2x2dn(p0 - 80, p0 + 112, p1 - 128, p1 + 64); + strDCT2x2dn(p0 - 16, p0 + 48, p1 - 64, p1 + 0); + + /** bottom right corner: -pi/8 rotation => -pi/8 rotation **/ + invOddOddPost(p1 + 0, p1 + 64, p1 + 16, p1 + 80); + + /** anti diagonal corners: rotation by -pi/8 **/ + IROTATE1(p0[48], p0[32]); + IROTATE1(p0[112], p0[96]); + IROTATE1(p1[-64], p1[-128]); + IROTATE1(p1[-48], p1[-112]); + + /** butterfly **/ + strHSTdec1(p0 - 96, p1 + 80); + strHSTdec1(p0 - 32, p1 + 16); + strHSTdec1(p0 - 80, p1 + 64); + strHSTdec1(p0 - 16, p1 + 0); + + strHSTdec(p0 - 96, p1 - 112, p0 + 96, p1 + 80); + strHSTdec(p0 - 32, p1 - 48, p0 + 32, p1 + 16); + strHSTdec(p0 - 80, p1 - 128, p0 + 112, p1 + 64); + strHSTdec(p0 - 16, p1 - 64, p0 + 48, p1 + 0); +} + +Void strPost4x4Stage2Split_alternate(PixelI* p0, PixelI* p1) +{ + /** buttefly **/ + strDCT2x2dn(p0 - 96, p0 + 96, p1 - 112, p1 + 80); + strDCT2x2dn(p0 - 32, p0 + 32, p1 - 48, p1 + 16); + strDCT2x2dn(p0 - 80, p0 + 112, p1 - 128, p1 + 64); + strDCT2x2dn(p0 - 16, p0 + 48, p1 - 64, p1 + 0); + + /** bottom right corner: -pi/8 rotation => -pi/8 rotation **/ + invOddOddPost(p1 + 0, p1 + 64, p1 + 16, p1 + 80); + + /** anti diagonal corners: rotation by -pi/8 **/ + IROTATE1(p0[48], p0[32]); + IROTATE1(p0[112], p0[96]); + IROTATE1(p1[-64], p1[-128]); + IROTATE1(p1[-48], p1[-112]); + + /** butterfly **/ + strHSTdec1_alternate(p0 - 96, p1 + 80); + strHSTdec1_alternate(p0 - 32, p1 + 16); + strHSTdec1_alternate(p0 - 80, p1 + 64); + strHSTdec1_alternate(p0 - 16, p1 + 0); + + strHSTdec(p0 - 96, p1 - 112, p0 + 96, p1 + 80); + strHSTdec(p0 - 32, p1 - 48, p0 + 32, p1 + 16); + strHSTdec(p0 - 80, p1 - 128, p0 + 112, p1 + 64); + strHSTdec(p0 - 16, p1 - 64, p0 + 48, p1 + 0); +} + +/** + Hadamard+Scale transform + for some strange reason, breaking up the function into two blocks, strHSTdec1 and strHSTdec + seems to work faster +**/ +static Void strHSTdec1(PixelI* pa, PixelI* pd) +{ + /** different realization : does rescaling as well! **/ + PixelI a, d; + a = *pa; + d = *pd; + + a += d; + d = (a >> 1) - d; + a += (d * 3 + 0) >> 3; + d += (a * 3 + 0) >> 4; + //a += (d * 3 + 4) >> 3; + + *pa = a; + *pd = d; +} + +static Void strHSTdec1_alternate(PixelI* pa, PixelI* pd) +{ + /** different realization : does rescaling as well! **/ + PixelI a, d; + a = *pa; + d = *pd; + + a += d; + d = (a >> 1) - d; + a += (d * 3 + 0) >> 3; + d += (a * 3 + 0) >> 4; + //a += (d * 3 + 4) >> 3; + + d += (a >> 7); + d -= (a >> 10); + + *pa = a; + *pd = d; +} + +static Void strHSTdec1_edge(PixelI* pa, PixelI* pd) +{ + /** different realization as compared to scaling operator for 2D case **/ + PixelI a, d; + a = *pa; + d = *pd; + + a += d; + d = (a >> 1) - d; + a += (d * 3 + 0) >> 3; + d += (a * 3 + 0) >> 4; + + //Scaling modification of adding 7/1024 in 2 steps (without multiplication by 7). + d += (a >> 7); + d -= (a >> 10); + + a += (d * 3 + 4) >> 3; + d -= (a >> 1); + a += d; + // End new operations + + *pa = a; + *pd = -d; // Negative sign needed here for 1D scaling case to ensure correct scaling. +} + +static Void strHSTdec(PixelI* pa, PixelI* pb, PixelI* pc, PixelI* pd) +{ + /** different realization : does rescaling as well! **/ + PixelI a, b, c, d; + a = *pa; + b = *pb; + c = *pc; + d = *pd; + + b -= c; + a += (d * 3 + 4) >> 3; + + d -= (b >> 1); + c = ((a - b) >> 1) - c; + *pc = d; + *pd = c; + *pa = a - c, * pb = b + d; +} + +/** Kron(Rotate(pi/8), Rotate(pi/8)) **/ +static Void invOddOdd(PixelI* pa, PixelI* pb, PixelI* pc, PixelI* pd) +{ + PixelI a, b, c, d, t1, t2; + a = *pa; + b = *pb; + c = *pc; + d = *pd; + + /** butterflies **/ + d += a; + c -= b; + a -= (t1 = d >> 1); + b += (t2 = c >> 1); + + /** rotate pi/4 **/ + a -= (b * 3 + 3) >> 3; + b += (a * 3 + 3) >> 2; + a -= (b * 3 + 4) >> 3; + + /** butterflies **/ + b -= t2; + a += t1; + c += b; + d -= a; + + /** sign flips **/ + *pa = a; + *pb = -b; + *pc = -c; + *pd = d; +} + +/** Kron(Rotate(pi/8), Rotate(pi/8)) **/ +static Void invOddOddPost(PixelI* pa, PixelI* pb, PixelI* pc, PixelI* pd) +{ + PixelI a, b, c, d, t1, t2; + a = *pa; + b = *pb; + c = *pc; + d = *pd; + + /** butterflies **/ + d += a; + c -= b; + a -= (t1 = d >> 1); + b += (t2 = c >> 1); + + /** rotate pi/4 **/ + a -= (b * 3 + 6) >> 3; + b += (a * 3 + 2) >> 2; + a -= (b * 3 + 4) >> 3; + + /** butterflies **/ + b -= t2; + a += t1; + c += b; + d -= a; + + *pa = a; + *pb = b; + *pc = c; + *pd = d; +} + + +/** Kron(Rotate(-pi/8), [1 1; 1 -1]/sqrt(2)) **/ +/** [D C A B] => [a b c d] **/ +Void invOdd(PixelI* pa, PixelI* pb, PixelI* pc, PixelI* pd) +{ + PixelI a, b, c, d; + a = *pa; + b = *pb; + c = *pc; + d = *pd; + + /** butterflies **/ + b += d; + a -= c; + d -= (b) >> 1; + c += (a + 1) >> 1; + + /** rotate pi/8 **/ + IROTATE2(a, b); + IROTATE2(c, d); + + /** butterflies **/ + c -= (b + 1) >> 1; + d = ((a + 1) >> 1) - d; + b += c; + a -= d; + + *pa = a; + *pb = b; + *pc = c; + *pd = d; +} + +/************************************************************************* + Top-level function to inverse tranform possible part of a macroblock +*************************************************************************/ +Int invTransformMacroblock(CWMImageStrCodec* pSC) +{ + const OVERLAP olOverlap = pSC->WMISCP.olOverlap; + const COLORFORMAT cfColorFormat = pSC->m_param.cfColorFormat; + // const BITDEPTH_BITS bdBitDepth = pSC->WMII.bdBitDepth; + const Bool left = (pSC->cColumn == 0), right = (pSC->cColumn == pSC->cmbWidth); + const Bool top = (pSC->cRow == 0), bottom = (pSC->cRow == pSC->cmbHeight); + const Bool topORbottom = (top || bottom), leftORright = (left || right); + const Bool topORleft = (top || left), bottomORright = (bottom || right); + const size_t mbWidth = pSC->cmbWidth, mbX = pSC->cColumn; + PixelI* p = NULL;// * pt = NULL; + size_t i; + const size_t iChannels = (cfColorFormat == YUV_420 || cfColorFormat == YUV_422) ? 1 : pSC->m_param.cNumChannels; + const size_t tScale = pSC->m_Dparam->cThumbnailScale; + Int j = 0; + + Int qp[MAX_CHANNELS], dcqp[MAX_CHANNELS], iStrength = (1 << pSC->WMII.cPostProcStrength); + // ERR_CODE result = ICERR_OK; + + Bool bHPAbsent = (pSC->WMISCP.sbSubband == SB_NO_HIGHPASS || pSC->WMISCP.sbSubband == SB_DC_ONLY); + + if (pSC->WMII.cPostProcStrength > 0) { + // threshold for post processing + for (i = 0; i < iChannels; i++) { + qp[i] = pSC->pTile[pSC->cTileColumn].pQuantizerLP[i][pSC->MBInfo.iQIndexLP].iQP * iStrength * (olOverlap == OL_NONE ? 2 : 1); + dcqp[i] = pSC->pTile[pSC->cTileColumn].pQuantizerDC[i][0].iQP * iStrength; + } + + if (left) // a new MB row + slideOneMBRow(pSC->pPostProcInfo, pSC->m_param.cNumChannels, mbWidth, top, bottom); // previous current row becomes previous row + } + + //================================================================ + // 400_Y, 444_YUV + for (i = 0; i < iChannels && tScale < 16; ++i) + { + PixelI* const p0 = pSC->p0MBbuffer[i]; + PixelI* const p1 = pSC->p1MBbuffer[i]; + + Int iHPQP = 255; + if (!bHPAbsent) + iHPQP = pSC->pTile[pSC->cTileColumn].pQuantizerHP[i][pSC->MBInfo.iQIndexHP].iQP; + + //================================ + // second level inverse transform + if (!bottomORright) + { + if (pSC->WMII.cPostProcStrength > 0) + updatePostProcInfo(pSC->pPostProcInfo, p1, mbX, i); // update postproc info before IDCT + + strIDCT4x4Stage2(p1); + if (pSC->m_param.bScaledArith) { + strNormalizeDec(p1, (i != 0)); + } + } + + //================================ + // second level inverse overlap + if (OL_TWO == olOverlap) + { + if (leftORright && (!topORbottom)) + { + j = left ? 0 : -128; + strPost4(p0 + j + 32, p0 + j + 48, p1 + j + 0, p1 + j + 16); + strPost4(p0 + j + 96, p0 + j + 112, p1 + j + 64, p1 + j + 80); + } + + if (!leftORright) + { + if (topORbottom) + { + p = top ? p1 : p0 + 32; + strPost4(p - 128, p - 64, p + 0, p + 64); + strPost4(p - 112, p - 48, p + 16, p + 80); + p = NULL; + } + else + { + strPost4x4Stage2Split(p0, p1); + } + } + } + + if (pSC->WMII.cPostProcStrength > 0) + postProcMB(pSC->pPostProcInfo, p0, p1, mbX, i, dcqp[i]); // second stage deblocking + + //================================ + // first level inverse transform + if (tScale >= 4) // bypass first level transform for 4:1 and smaller thumbnail + continue; + + if (!top) + { + for (j = (left ? 32 : -96); j < (right ? 32 : 160); j += 64) + { + strIDCT4x4Stage1(p0 + j + 0); + strIDCT4x4Stage1(p0 + j + 16); + } + } + + if (!bottom) + { + for (j = (left ? 0 : -128); j < (right ? 0 : 128); j += 64) + { + strIDCT4x4Stage1(p1 + j + 0); + strIDCT4x4Stage1(p1 + j + 16); + } + } + + //================================ + // first level inverse overlap + if (OL_NONE != olOverlap) + { + if (leftORright) + { + j = left ? 0 + 10 : -64 + 14; + if (!top) + { + p = p0 + 16 + j; + strPost4(p + 0, p - 2, p + 6, p + 8); + strPost4(p + 1, p - 1, p + 7, p + 9); + strPost4(p + 16, p + 14, p + 22, p + 24); + strPost4(p + 17, p + 15, p + 23, p + 25); + p = NULL; + } + if (!bottom) + { + p = p1 + j; + strPost4(p + 0, p - 2, p + 6, p + 8); + strPost4(p + 1, p - 1, p + 7, p + 9); + p = NULL; + } + if (!topORbottom) + { + strPost4(p0 + 48 + j + 0, p0 + 48 + j - 2, p1 - 10 + j, p1 - 8 + j); + strPost4(p0 + 48 + j + 1, p0 + 48 + j - 1, p1 - 9 + j, p1 - 7 + j); + } + } + + if (top) + { + for (j = (left ? 0 : -192); j < (right ? -64 : 64); j += 64) + { + p = p1 + j; + strPost4(p + 5, p + 4, p + 64, p + 65); + strPost4(p + 7, p + 6, p + 66, p + 67); + p = NULL; + + strPost4x4Stage1(p1 + j, 0, iHPQP, bHPAbsent); + } + } + else if (bottom) + { + for (j = (left ? 0 : -192); j < (right ? -64 : 64); j += 64) + { + strPost4x4Stage1(p0 + 16 + j, 0, iHPQP, bHPAbsent); + strPost4x4Stage1(p0 + 32 + j, 0, iHPQP, bHPAbsent); + + p = p0 + 48 + j; + strPost4(p + 15, p + 14, p + 74, p + 75); + strPost4(p + 13, p + 12, p + 72, p + 73); + p = NULL; + } + } + else + { + for (j = (left ? 0 : -192); j < (right ? -64 : 64); j += 64) + { + strPost4x4Stage1(p0 + 16 + j, 0, iHPQP, bHPAbsent); + strPost4x4Stage1(p0 + 32 + j, 0, iHPQP, bHPAbsent); + strPost4x4Stage1Split(p0 + 48 + j, p1 + j, 0, iHPQP, bHPAbsent); + strPost4x4Stage1(p1 + j, 0, iHPQP, bHPAbsent); + } + } + } + + if (pSC->WMII.cPostProcStrength > 0 && (!topORleft)) + postProcBlock(pSC->pPostProcInfo, p0, p1, mbX, i, qp[i]); // destairing and first stage deblocking + } + + //================================================================ + // 420_UV + for (i = 0; i < (YUV_420 == cfColorFormat ? 2U : 0U) && tScale < 16; ++i) + { + PixelI* const p0 = pSC->p0MBbuffer[1 + i];//(0 == i ? pSC->pU0 : pSC->pV0); + PixelI* const p1 = pSC->p1MBbuffer[1 + i];//(0 == i ? pSC->pU1 : pSC->pV1); + + Int iHPQP = 255; + if (!bHPAbsent) + iHPQP = pSC->pTile[pSC->cTileColumn].pQuantizerHP[i][pSC->MBInfo.iQIndexHP].iQP; + + //======================================== + // second level inverse transform (420_UV) + if (!bottomORright) + { + if (!pSC->m_param.bScaledArith) { + strDCT2x2dn(p1, p1 + 32, p1 + 16, p1 + 48); + } + else { + strDCT2x2dnDec(p1, p1 + 32, p1 + 16, p1 + 48); + } + } + + //======================================== + // second level inverse overlap (420_UV) + if (OL_TWO == olOverlap) + { + if (leftORright && !topORbottom) + { + j = (left ? 0 : -32); + strPost2(p0 + j + 16, p1 + j); + } + + if (!leftORright) + { + if (topORbottom) + { + p = (top ? p1 : p0 + 16); + strPost2(p - 32, p); + p = NULL; + } + else { + strPost2x2(p0 - 16, p0 + 16, p1 - 32, p1); + } + } + } + + //======================================== + // first level inverse transform (420_UV) + if (tScale >= 4) // bypass first level transform for 4:1 and smaller thumbnail + continue; + + if (!top) + { + for (j = (left ? 16 : -16); j < (right ? 16 : 48); j += 32) + { + strIDCT4x4Stage1(p0 + j); + } + } + + if (!bottom) + { + for (j = (left ? 0 : -32); j < (right ? 0 : 32); j += 32) + { + strIDCT4x4Stage1(p1 + j); + } + } + + //======================================== + // first level inverse overlap (420_UV) + if (OL_NONE != olOverlap) + { + if (!left && !top) + { + if (bottom) + { + for (j = -48; j < (right ? -16 : 16); j += 32) + { + p = p0 + j; + strPost4(p + 15, p + 14, p + 42, p + 43); + strPost4(p + 13, p + 12, p + 40, p + 41); + p = NULL; + } + } + else + { + for (j = -48; j < (right ? -16 : 16); j += 32) + { + strPost4x4Stage1Split(p0 + j, p1 - 16 + j, 32, iHPQP, bHPAbsent); + } + } + + if (right) + { + if (!bottom) + { + strPost4(p0 - 2, p0 - 4, p1 - 28, p1 - 26); + strPost4(p0 - 1, p0 - 3, p1 - 27, p1 - 25); + } + + strPost4(p0 - 18, p0 - 20, p0 - 12, p0 - 10); + strPost4(p0 - 17, p0 - 19, p0 - 11, p0 - 9); + } + else + { + strPost4x4Stage1(p0 - 32, 32, iHPQP, bHPAbsent); + } + + strPost4x4Stage1(p0 - 64, 32, iHPQP, bHPAbsent); + } + else if (top) + { + for (j = (left ? 0 : -64); j < (right ? -32 : 0); j += 32) + { + p = p1 + j + 4; + strPost4(p + 1, p + 0, p + 28, p + 29); + strPost4(p + 3, p + 2, p + 30, p + 31); + p = NULL; + } + } + else if (left) + { + if (!bottom) + { + strPost4(p0 + 26, p0 + 24, p1 + 0, p1 + 2); + strPost4(p0 + 27, p0 + 25, p1 + 1, p1 + 3); + } + + strPost4(p0 + 10, p0 + 8, p0 + 16, p0 + 18); + strPost4(p0 + 11, p0 + 9, p0 + 17, p0 + 19); + } + } + } + + //================================================================ + // 422_UV + for (i = 0; i < (YUV_422 == cfColorFormat ? 2U : 0U) && tScale < 16; ++i) + { + PixelI* const p0 = pSC->p0MBbuffer[1 + i];//(0 == i ? pSC->pU0 : pSC->pV0); + PixelI* const p1 = pSC->p1MBbuffer[1 + i];//(0 == i ? pSC->pU1 : pSC->pV1); + + Int iHPQP = 255; + if (!bHPAbsent) + iHPQP = pSC->pTile[pSC->cTileColumn].pQuantizerHP[i][pSC->MBInfo.iQIndexHP].iQP; + + //======================================== + // second level inverse transform (422_UV) + if ((!bottomORright) && pSC->m_Dparam->cThumbnailScale < 16) + { + // 1D lossless HT + p1[0] -= ((p1[32] + 1) >> 1); + p1[32] += p1[0]; + + if (!pSC->m_param.bScaledArith) { + strDCT2x2dn(p1 + 0, p1 + 64, p1 + 16, p1 + 80); + strDCT2x2dn(p1 + 32, p1 + 96, p1 + 48, p1 + 112); + } + else { + strDCT2x2dnDec(p1 + 0, p1 + 64, p1 + 16, p1 + 80); + strDCT2x2dnDec(p1 + 32, p1 + 96, p1 + 48, p1 + 112); + } + } + + //======================================== + // second level inverse overlap (422_UV) + if (OL_TWO == olOverlap) + { + if (!bottom) + { + if (leftORright) + { + if (!top) + { + j = (left ? 0 : -64); + strPost2(p0 + 48 + j, p1 + j); + } + + j = (left ? 16 : -48); + strPost2(p1 + j, p1 + j + 16); + } + else + { + if (top) + { + strPost2(p1 - 64, p1); + } + else + { + strPost2x2(p0 - 16, p0 + 48, p1 - 64, p1); + } + + strPost2x2(p1 - 48, p1 + 16, p1 - 32, p1 + 32); + } + } + else if (!leftORright) + { + strPost2(p0 - 16, p0 + 48); + } + } + + //======================================== + // first level inverse transform (422_UV) + if (tScale >= 4) // bypass first level transform for 4:1 and smaller thumbnail + continue; + + if (!top) + { + for (j = (left ? 48 : -16); j < (right ? 48 : 112); j += 64) + { + strIDCT4x4Stage1(p0 + j); + } + } + + if (!bottom) + { + for (j = (left ? 0 : -64); j < (right ? 0 : 64); j += 64) + { + strIDCT4x4Stage1(p1 + j + 0); + strIDCT4x4Stage1(p1 + j + 16); + strIDCT4x4Stage1(p1 + j + 32); + } + } + + //======================================== + // first level inverse overlap (422_UV) + if (OL_NONE != olOverlap) + { + if (!top) + { + if (leftORright) + { + j = (left ? 32 + 10 : -32 + 14); + + p = p0 + j; + strPost4(p + 0, p - 2, p + 6, p + 8); + strPost4(p + 1, p - 1, p + 7, p + 9); + + p = NULL; + } + + for (j = (left ? 0 : -128); j < (right ? -64 : 0); j += 64) + { + strPost4x4Stage1(p0 + j + 32, 0, iHPQP, bHPAbsent); + } + } + + if (!bottom) + { + if (leftORright) + { + j = (left ? 0 + 10 : -64 + 14); + + p = p1 + j; + strPost4(p + 0, p - 2, p + 6, p + 8); + strPost4(p + 1, p - 1, p + 7, p + 9); + + p += 16; + strPost4(p + 0, p - 2, p + 6, p + 8); + strPost4(p + 1, p - 1, p + 7, p + 9); + + p = NULL; + } + + for (j = (left ? 0 : -128); j < (right ? -64 : 0); j += 64) + { + strPost4x4Stage1(p1 + j + 0, 0, iHPQP, bHPAbsent); + strPost4x4Stage1(p1 + j + 16, 0, iHPQP, bHPAbsent); + } + } + + if (topORbottom) + { + p = (top ? p1 + 5 : p0 + 48 + 13); + for (j = (left ? 0 : -128); j < (right ? -64 : 0); j += 64) + { + strPost4(p + j + 0, p + j - 1, p + j + 59, p + j + 60); + strPost4(p + j + 2, p + j + 1, p + j + 61, p + j + 62); + } + p = NULL; + } + else + { + if (leftORright) + { + j = (left ? 0 + 0 : -64 + 4); + strPost4(p0 + j + 48 + 10 + 0, p0 + j + 48 + 10 - 2, p1 + j + 0, p1 + j + 2); + strPost4(p0 + j + 48 + 10 + 1, p0 + j + 48 + 10 - 1, p1 + j + 1, p1 + j + 3); + } + + for (j = (left ? 0 : -128); j < (right ? -64 : 0); j += 64) + { + strPost4x4Stage1Split(p0 + j + 48, p1 + j + 0, 0, iHPQP, bHPAbsent); + } + } + } + } + + return ICERR_OK; +} + +Int invTransformMacroblock_alteredOperators_hard(CWMImageStrCodec* pSC) +{ + const OVERLAP olOverlap = pSC->WMISCP.olOverlap; + const COLORFORMAT cfColorFormat = pSC->m_param.cfColorFormat; + // const BITDEPTH_BITS bdBitDepth = pSC->WMII.bdBitDepth; + const Bool left = (pSC->cColumn == 0), right = (pSC->cColumn == pSC->cmbWidth); + const Bool top = (pSC->cRow == 0), bottom = (pSC->cRow == pSC->cmbHeight); + const Bool topORbottom = (top || bottom), leftORright = (left || right); + const Bool topORleft = (top || left), bottomORright = (bottom || right); + Bool leftAdjacentColumn = (pSC->cColumn == 1), rightAdjacentColumn = (pSC->cColumn == pSC->cmbWidth - 1); + // Bool topAdjacentRow = (pSC->cRow == 1), bottomAdjacentRow = (pSC->cRow == pSC->cmbHeight - 1); + const size_t mbWidth = pSC->cmbWidth; + PixelI* p = NULL;// * pt = NULL; + size_t i; + const size_t iChannels = (cfColorFormat == YUV_420 || cfColorFormat == YUV_422) ? 1 : pSC->m_param.cNumChannels; + const size_t tScale = pSC->m_Dparam->cThumbnailScale; + Int j = 0; + + Int qp[MAX_CHANNELS], dcqp[MAX_CHANNELS], iStrength = (1 << pSC->WMII.cPostProcStrength); + // ERR_CODE result = ICERR_OK; + +#define mbX pSC->mbX +#define mbY pSC->mbY +#define tileX pSC->tileX +#define tileY pSC->tileY +#define bVertTileBoundary pSC->bVertTileBoundary +#define bHoriTileBoundary pSC->bHoriTileBoundary +#define bOneMBLeftVertTB pSC->bOneMBLeftVertTB +#define bOneMBRightVertTB pSC->bOneMBRightVertTB +#define iPredBefore pSC->iPredBefore +#define iPredAfter pSC->iPredAfter + + if (pSC->WMISCP.bUseHardTileBoundaries) { + //Add tile location information + if (pSC->cColumn == 0) { + bVertTileBoundary = FALSE; + tileY = 0; + } + bOneMBLeftVertTB = bOneMBRightVertTB = FALSE; + if (tileY > 0 && tileY <= pSC->WMISCP.cNumOfSliceMinus1H && (pSC->cColumn - 1) == pSC->WMISCP.uiTileY[tileY]) + bOneMBRightVertTB = TRUE; + if (tileY < pSC->WMISCP.cNumOfSliceMinus1H && pSC->cColumn == pSC->WMISCP.uiTileY[tileY + 1]) { + bVertTileBoundary = TRUE; + tileY++; + } + else + bVertTileBoundary = FALSE; + if (tileY < pSC->WMISCP.cNumOfSliceMinus1H && (pSC->cColumn + 1) == pSC->WMISCP.uiTileY[tileY + 1]) + bOneMBLeftVertTB = TRUE; + + if (pSC->cRow == 0) { + bHoriTileBoundary = FALSE; + tileX = 0; + } + else if (mbY != pSC->cRow && tileX < pSC->WMISCP.cNumOfSliceMinus1V && pSC->cRow == pSC->WMISCP.uiTileX[tileX + 1]) { + bHoriTileBoundary = TRUE; + tileX++; + } + else if (mbY != pSC->cRow) + bHoriTileBoundary = FALSE; + } + else { + bVertTileBoundary = FALSE; + bHoriTileBoundary = FALSE; + bOneMBLeftVertTB = FALSE; + bOneMBRightVertTB = FALSE; + } + mbX = pSC->cColumn, mbY = pSC->cRow; + + if (pSC->WMII.cPostProcStrength > 0) { + // threshold for post processing + for (i = 0; i < iChannels; i++) { + qp[i] = pSC->pTile[pSC->cTileColumn].pQuantizerLP[i][pSC->MBInfo.iQIndexLP].iQP * iStrength * (olOverlap == OL_NONE ? 2 : 1); + dcqp[i] = pSC->pTile[pSC->cTileColumn].pQuantizerDC[i][0].iQP * iStrength; + } + + if (left) // a new MB row + slideOneMBRow(pSC->pPostProcInfo, pSC->m_param.cNumChannels, mbWidth, top, bottom); // previous current row becomes previous row + } + + //================================================================ + // 400_Y, 444_YUV + for (i = 0; i < iChannels && tScale < 16; ++i) + { + PixelI* const p0 = pSC->p0MBbuffer[i]; + PixelI* const p1 = pSC->p1MBbuffer[i]; + + //================================ + // second level inverse transform + if (!bottomORright) + { + if (pSC->WMII.cPostProcStrength > 0) + updatePostProcInfo(pSC->pPostProcInfo, p1, mbX, i); // update postproc info before IDCT + + strIDCT4x4Stage2(p1); + if (pSC->m_param.bScaledArith) { + strNormalizeDec(p1, (i != 0)); + } + } + + //================================ + // second level inverse overlap + if (OL_TWO == olOverlap) + { + /* Corner operations */ + if ((top || bHoriTileBoundary) && (left || bVertTileBoundary)) + strPost4_alternate(p1 + 0, p1 + 64, p1 + 0 + 16, p1 + 64 + 16); + if ((top || bHoriTileBoundary) && (right || bVertTileBoundary)) + strPost4_alternate(p1 - 128, p1 - 64, p1 - 128 + 16, p1 - 64 + 16); + if ((bottom || bHoriTileBoundary) && (left || bVertTileBoundary)) + strPost4_alternate(p0 + 32, p0 + 96, p0 + 32 + 16, p0 + 96 + 16); + if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary)) + strPost4_alternate(p0 - 96, p0 - 32, p0 - 96 + 16, p0 - 32 + 16); + if ((leftORright || bVertTileBoundary) && (!topORbottom && !bHoriTileBoundary)) + { + if (left || bVertTileBoundary) { + j = 0; + strPost4_alternate(p0 + j + 32, p0 + j + 48, p1 + j + 0, p1 + j + 16); + strPost4_alternate(p0 + j + 96, p0 + j + 112, p1 + j + 64, p1 + j + 80); + } + if (right || bVertTileBoundary) { + j = -128; + strPost4_alternate(p0 + j + 32, p0 + j + 48, p1 + j + 0, p1 + j + 16); + strPost4_alternate(p0 + j + 96, p0 + j + 112, p1 + j + 64, p1 + j + 80); + } + } + + if (!leftORright) + { + if ((topORbottom || bHoriTileBoundary) && !bVertTileBoundary) + { + if (top || bHoriTileBoundary) { + p = p1; + strPost4_alternate(p - 128, p - 64, p + 0, p + 64); + strPost4_alternate(p - 112, p - 48, p + 16, p + 80); + p = NULL; + } + if (bottom || bHoriTileBoundary) { + p = p0 + 32; + strPost4_alternate(p - 128, p - 64, p + 0, p + 64); + strPost4_alternate(p - 112, p - 48, p + 16, p + 80); + p = NULL; + } + } + + if (!topORbottom && !bHoriTileBoundary && !bVertTileBoundary) + strPost4x4Stage2Split_alternate(p0, p1); + } + } + + if (pSC->WMII.cPostProcStrength > 0) + postProcMB(pSC->pPostProcInfo, p0, p1, mbX, i, dcqp[i]); // second stage deblocking + + //================================ + // first level inverse transform + if (tScale >= 4) // bypass first level transform for 4:1 and smaller thumbnail + continue; + + if (!top) + { + for (j = (left ? 32 : -96); j < (right ? 32 : 160); j += 64) + { + strIDCT4x4Stage1(p0 + j + 0); + strIDCT4x4Stage1(p0 + j + 16); + } + } + + if (!bottom) + { + for (j = (left ? 0 : -128); j < (right ? 0 : 128); j += 64) + { + // if(tScale == 2 && bdBitDepth != BD_1){ + // MIPgen(p1 + j + 0); + // MIPgen(p1 + j + 16); + // } + strIDCT4x4Stage1(p1 + j + 0); + strIDCT4x4Stage1(p1 + j + 16); + } + } + + //================================ + // first level inverse overlap + if (OL_NONE != olOverlap) + { + if (leftORright || bVertTileBoundary) + { + /* Corner operations */ + if ((top || bHoriTileBoundary) && (left || bVertTileBoundary)) + strPost4_alternate(p1 + 0, p1 + 1, p1 + 2, p1 + 3); + if ((top || bHoriTileBoundary) && (right || bVertTileBoundary)) + strPost4_alternate(p1 - 59, p1 - 60, p1 - 57, p1 - 58); + if ((bottom || bHoriTileBoundary) && (left || bVertTileBoundary)) + strPost4_alternate(p0 + 48 + 10, p0 + 48 + 11, p0 + 48 + 8, p0 + 48 + 9); + if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary)) + strPost4_alternate(p0 - 1, p0 - 2, p0 - 3, p0 - 4); + if (left || bVertTileBoundary) { + j = 0 + 10; + if (!top) + { + p = p0 + 16 + j; + strPost4_alternate(p + 0, p - 2, p + 6, p + 8); + strPost4_alternate(p + 1, p - 1, p + 7, p + 9); + strPost4_alternate(p + 16, p + 14, p + 22, p + 24); + strPost4_alternate(p + 17, p + 15, p + 23, p + 25); + p = NULL; + } + if (!bottom) + { + p = p1 + j; + strPost4_alternate(p + 0, p - 2, p + 6, p + 8); + strPost4_alternate(p + 1, p - 1, p + 7, p + 9); + p = NULL; + } + if (!topORbottom && !bHoriTileBoundary) + { + strPost4_alternate(p0 + 48 + j + 0, p0 + 48 + j - 2, p1 - 10 + j, p1 - 8 + j); + strPost4_alternate(p0 + 48 + j + 1, p0 + 48 + j - 1, p1 - 9 + j, p1 - 7 + j); + } + } + if (right || bVertTileBoundary) { + j = -64 + 14; + if (!top) + { + p = p0 + 16 + j; + strPost4_alternate(p + 0, p - 2, p + 6, p + 8); + strPost4_alternate(p + 1, p - 1, p + 7, p + 9); + strPost4_alternate(p + 16, p + 14, p + 22, p + 24); + strPost4_alternate(p + 17, p + 15, p + 23, p + 25); + p = NULL; + } + if (!bottom) + { + p = p1 + j; + strPost4_alternate(p + 0, p - 2, p + 6, p + 8); + strPost4_alternate(p + 1, p - 1, p + 7, p + 9); + p = NULL; + } + if (!topORbottom && !bHoriTileBoundary) + { + strPost4_alternate(p0 + 48 + j + 0, p0 + 48 + j - 2, p1 - 10 + j, p1 - 8 + j); + strPost4_alternate(p0 + 48 + j + 1, p0 + 48 + j - 1, p1 - 9 + j, p1 - 7 + j); + } + } + } + + if (top || bHoriTileBoundary) + { + for (j = (left ? 0 : -192); j < (right ? -64 : 64); j += 64) + { + if (!bVertTileBoundary || j != -64) { + p = p1 + j; + strPost4_alternate(p + 5, p + 4, p + 64, p + 65); + strPost4_alternate(p + 7, p + 6, p + 66, p + 67); + p = NULL; + + strPost4x4Stage1_alternate(p1 + j, 0); + } + } + } + + if (bottom || bHoriTileBoundary) + { + for (j = (left ? 0 : -192); j < (right ? -64 : 64); j += 64) + { + if (!bVertTileBoundary || j != -64) { + strPost4x4Stage1_alternate(p0 + 16 + j, 0); + strPost4x4Stage1_alternate(p0 + 32 + j, 0); + + p = p0 + 48 + j; + strPost4_alternate(p + 15, p + 14, p + 74, p + 75); + strPost4_alternate(p + 13, p + 12, p + 72, p + 73); + p = NULL; + } + } + } + + if (!top && !bottom && !bHoriTileBoundary) + { + for (j = (left ? 0 : -192); j < (right ? -64 : 64); j += 64) + { + if (!bVertTileBoundary || j != -64) { + strPost4x4Stage1_alternate(p0 + 16 + j, 0); + strPost4x4Stage1_alternate(p0 + 32 + j, 0); + strPost4x4Stage1Split_alternate(p0 + 48 + j, p1 + j, 0); + strPost4x4Stage1_alternate(p1 + j, 0); + } + } + } + } + + if (pSC->WMII.cPostProcStrength > 0 && (!topORleft)) + postProcBlock(pSC->pPostProcInfo, p0, p1, mbX, i, qp[i]); // destairing and first stage deblocking + } + + //================================================================ + // 420_UV + for (i = 0; i < (YUV_420 == cfColorFormat ? 2U : 0U) && tScale < 16; ++i) + { + PixelI* const p0 = pSC->p0MBbuffer[1 + i];//(0 == i ? pSC->pU0 : pSC->pV0); + PixelI* const p1 = pSC->p1MBbuffer[1 + i];//(0 == i ? pSC->pU1 : pSC->pV1); + + //======================================== + // second level inverse transform (420_UV) + if (!bottomORright) + { + if (!pSC->m_param.bScaledArith) { + strDCT2x2dn(p1, p1 + 32, p1 + 16, p1 + 48); + } + else { + strDCT2x2dnDec(p1, p1 + 32, p1 + 16, p1 + 48); + } + } + + //======================================== + // second level inverse overlap (420_UV) + if (OL_TWO == olOverlap) + { + if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_DIFF(p1 - 64 + 0, *(p1 - 64 + 32)); + if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary)) + iPredBefore[i][0] = *(p1 + 0); + if ((right || bVertTileBoundary) && (top || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_DIFF(p1 - 64 + 32, iPredBefore[i][0]); + if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_DIFF(p0 - 64 + 16, *(p0 - 64 + 48)); + if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) + iPredBefore[i][1] = *(p0 + 16); + if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_DIFF(p0 - 64 + 48, iPredBefore[i][1]); + + if ((leftORright || bVertTileBoundary) && !topORbottom && !bHoriTileBoundary) + { + if (left || bVertTileBoundary) + strPost2_alternate(p0 + 0 + 16, p1 + 0); + if (right || bVertTileBoundary) + strPost2_alternate(p0 + -32 + 16, p1 + -32); + } + + if (!leftORright) + { + if ((topORbottom || bHoriTileBoundary) && !bVertTileBoundary) + { + if (top || bHoriTileBoundary) + strPost2_alternate(p1 - 32, p1); + if (bottom || bHoriTileBoundary) + strPost2_alternate(p0 + 16 - 32, p0 + 16); + } + else if (!topORbottom && !bHoriTileBoundary && !bVertTileBoundary) { + strPost2x2_alternate(p0 - 16, p0 + 16, p1 - 32, p1); + } + } + if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_ADD(p1 - 64 + 0, *(p1 - 64 + 32)); + if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary)) + iPredAfter[i][0] = *(p1 + 0); + if ((right || bVertTileBoundary) && (top || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_ADD(p1 - 64 + 32, iPredAfter[i][0]); + if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_ADD(p0 - 64 + 16, *(p0 - 64 + 48)); + if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) + iPredAfter[i][1] = *(p0 + 16); + if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_ADD(p0 - 64 + 48, iPredAfter[i][1]); + } + + //======================================== + // first level inverse transform (420_UV) + if (tScale >= 4) // bypass first level transform for 4:1 and smaller thumbnail + continue; + + if (!top) + { + // In order to allow correction operation of corner chroma overlap operators (fixed) + // processing of left most MB column must be delayed by one MB + // Thus left MB not processed until leftAdjacentColumn = 1 + for (j = ((left) ? 48 : ((leftAdjacentColumn || bOneMBRightVertTB) ? -48 : -16)); j < ((right || bVertTileBoundary) ? 16 : 48); j += 32) + { + strIDCT4x4Stage1(p0 + j); + } + } + + if (!bottom) + { + // In order to allow correction operation of corner chroma overlap operators (fixed) + // processing of left most MB column must be delayed by one MB + // Thus left MB not processed until leftAdjacentColumn = 1 + for (j = ((left) ? 32 : ((leftAdjacentColumn || bOneMBRightVertTB) ? -64 : -32)); j < ((right || bVertTileBoundary) ? 0 : 32); j += 32) + { + strIDCT4x4Stage1(p1 + j); + } + } + + //======================================== + // first level inverse overlap (420_UV) + if (OL_NONE != olOverlap) + { + /* Corner operations */ + /* Change because the top-left corner ICT will not have happened until leftAdjacentColumn ==1 */ + if ((top || bHoriTileBoundary) && (leftAdjacentColumn || bOneMBRightVertTB)) + strPost4_alternate(p1 - 64 + 0, p1 - 64 + 1, p1 - 64 + 2, p1 - 64 + 3); + if ((top || bHoriTileBoundary) && (right || bVertTileBoundary)) + strPost4_alternate(p1 - 27, p1 - 28, p1 - 25, p1 - 26); + /* Change because the bottom-left corner ICT will not have happened until leftAdjacentColumn ==1 */ + if ((bottom || bHoriTileBoundary) && (leftAdjacentColumn || bOneMBRightVertTB)) + strPost4_alternate(p0 - 64 + 16 + 10, p0 - 64 + 16 + 11, p0 - 64 + 16 + 8, p0 - 64 + 16 + 9); + if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary)) + strPost4_alternate(p0 - 1, p0 - 2, p0 - 3, p0 - 4); + if (!left && !top) + { + /* Change because the vertical 1-D overlap operations of the left edge pixels cannot be performed until leftAdjacentColumn ==1 */ + if (leftAdjacentColumn || bOneMBRightVertTB) + { + if (!bottom && !bHoriTileBoundary) + { + strPost4_alternate(p0 - 64 + 26, p0 - 64 + 24, p1 - 64 + 0, p1 - 64 + 2); + strPost4_alternate(p0 - 64 + 27, p0 - 64 + 25, p1 - 64 + 1, p1 - 64 + 3); + } + + strPost4_alternate(p0 - 64 + 10, p0 - 64 + 8, p0 - 64 + 16, p0 - 64 + 18); + strPost4_alternate(p0 - 64 + 11, p0 - 64 + 9, p0 - 64 + 17, p0 - 64 + 19); + } + if (bottom || bHoriTileBoundary) + { + p = p0 + -48; + strPost4_alternate(p + 15, p + 14, p + 42, p + 43); + strPost4_alternate(p + 13, p + 12, p + 40, p + 41); + p = NULL; + + if (!right && !bVertTileBoundary) + { + p = p0 + -16; + strPost4_alternate(p + 15, p + 14, p + 42, p + 43); + strPost4_alternate(p + 13, p + 12, p + 40, p + 41); + p = NULL; + } + } + else + { + strPost4x4Stage1Split_alternate(p0 + -48, p1 - 16 + -48, 32); + + if (!right && !bVertTileBoundary) + strPost4x4Stage1Split_alternate(p0 + -16, p1 - 16 + -16, 32); + } + + if (right || bVertTileBoundary) + { + if (!bottom && !bHoriTileBoundary) + { + strPost4_alternate(p0 - 2, p0 - 4, p1 - 28, p1 - 26); + strPost4_alternate(p0 - 1, p0 - 3, p1 - 27, p1 - 25); + } + + strPost4_alternate(p0 - 18, p0 - 20, p0 - 12, p0 - 10); + strPost4_alternate(p0 - 17, p0 - 19, p0 - 11, p0 - 9); + } + else + { + strPost4x4Stage1_alternate(p0 - 32, 32); + } + + strPost4x4Stage1_alternate(p0 - 64, 32); + } + + if (top || bHoriTileBoundary) + { + if (!left) + { + p = p1 + -64 + 4; + strPost4_alternate(p + 1, p + 0, p + 28, p + 29); + strPost4_alternate(p + 3, p + 2, p + 30, p + 31); + p = NULL; + } + + if (!left && !right && !bVertTileBoundary) + { + p = p1 + -32 + 4; + strPost4_alternate(p + 1, p + 0, p + 28, p + 29); + strPost4_alternate(p + 3, p + 2, p + 30, p + 31); + p = NULL; + } + } + } + } + + //================================================================ + // 422_UV + for (i = 0; i < (YUV_422 == cfColorFormat ? 2U : 0U) && tScale < 16; ++i) + { + PixelI* const p0 = pSC->p0MBbuffer[1 + i];//(0 == i ? pSC->pU0 : pSC->pV0); + PixelI* const p1 = pSC->p1MBbuffer[1 + i];//(0 == i ? pSC->pU1 : pSC->pV1); + + //======================================== + // second level inverse transform (422_UV) + if ((!bottomORright) && pSC->m_Dparam->cThumbnailScale < 16) + { + // 1D lossless HT + p1[0] -= ((p1[32] + 1) >> 1); + p1[32] += p1[0]; + + if (!pSC->m_param.bScaledArith) { + strDCT2x2dn(p1 + 0, p1 + 64, p1 + 16, p1 + 80); + strDCT2x2dn(p1 + 32, p1 + 96, p1 + 48, p1 + 112); + } + else { + strDCT2x2dnDec(p1 + 0, p1 + 64, p1 + 16, p1 + 80); + strDCT2x2dnDec(p1 + 32, p1 + 96, p1 + 48, p1 + 112); + } + } + + //======================================== + // second level inverse overlap (422_UV) + if (OL_TWO == olOverlap) + { + if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_DIFF(p1 - 128 + 0, *(p1 - 128 + 64)); + + if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary)) + iPredBefore[i][0] = *(p1 + 0); + if ((right || bVertTileBoundary) && (top || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_DIFF(p1 - 128 + 64, iPredBefore[i][0]); + + if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_DIFF(p0 - 128 + 48, *(p0 - 128 + 112)); + + if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) + iPredBefore[i][1] = *(p0 + 48); + if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_DIFF(p0 - 128 + 112, iPredBefore[i][1]); + + if (!bottom) + { + if (leftORright || bVertTileBoundary) + { + if (!top && !bHoriTileBoundary) + { + if (left || bVertTileBoundary) + strPost2_alternate(p0 + 48 + 0, p1 + 0); + + if (right || bVertTileBoundary) + strPost2_alternate(p0 + 48 + -64, p1 + -64); + } + + if (left || bVertTileBoundary) + strPost2_alternate(p1 + 16, p1 + 16 + 16); + + if (right || bVertTileBoundary) + strPost2_alternate(p1 + -48, p1 + -48 + 16); + } + + if (!leftORright && !bVertTileBoundary) + { + if (top || bHoriTileBoundary) + strPost2_alternate(p1 - 64, p1); + else + strPost2x2_alternate(p0 - 16, p0 + 48, p1 - 64, p1); + + strPost2x2_alternate(p1 - 48, p1 + 16, p1 - 32, p1 + 32); + } + } + + if ((bottom || bHoriTileBoundary) && (!leftORright && !bVertTileBoundary)) + strPost2_alternate(p0 - 16, p0 + 48); + + if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_ADD(p1 - 128 + 0, *(p1 - 128 + 64)); + + if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary)) + iPredAfter[i][0] = *(p1 + 0); + if ((right || bVertTileBoundary) && (top || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_ADD(p1 - 128 + 64, iPredAfter[i][0]); + + if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_ADD(p0 - 128 + 48, *(p0 - 128 + 112)); + + if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) + iPredAfter[i][1] = *(p0 + 48); + if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_ADD(p0 - 128 + 112, iPredAfter[i][1]); + } + + //======================================== + // first level inverse transform (422_UV) + if (tScale >= 4) // bypass first level transform for 4:1 and smaller thumbnail + continue; + + if (!top) + { + // Need to delay processing of left column until leftAdjacentColumn = 1 for corner overlap operators + // Since 422 has no vertical downsampling, no top MB delay of processing is necessary + for (j = (left ? 112 : ((leftAdjacentColumn || bOneMBRightVertTB) ? -80 : -16)); j < ((right || bVertTileBoundary) ? 48 : 112); j += 64) + { + strIDCT4x4Stage1(p0 + j); + } + } + + if (!bottom) + { + // Need to delay processing of left column until leftAdjacentColumn = 1 for corner overlap operators + // Since 422 has no vertical downsampling, no top MB delay of processing is necessary + for (j = (left ? 64 : ((leftAdjacentColumn || bOneMBRightVertTB) ? -128 : -64)); j < ((right || bVertTileBoundary) ? 0 : 64); j += 64) + { + strIDCT4x4Stage1(p1 + j + 0); + strIDCT4x4Stage1(p1 + j + 16); + strIDCT4x4Stage1(p1 + j + 32); + } + } + + //======================================== + // first level inverse overlap (422_UV) + if (OL_NONE != olOverlap) + { + /* Corner operations */ + if ((top || bHoriTileBoundary) && (leftAdjacentColumn || bOneMBRightVertTB)) + strPost4_alternate(p1 - 128 + 0, p1 - 128 + 1, p1 - 128 + 2, p1 - 128 + 3); + if ((top || bHoriTileBoundary) && (right || bVertTileBoundary)) + strPost4_alternate(p1 - 59, p1 - 60, p1 - 57, p1 - 58); + if ((bottom || bHoriTileBoundary) && (leftAdjacentColumn || bOneMBRightVertTB)) + strPost4_alternate(p0 - 128 + 48 + 10, p0 - 128 + 48 + 11, p0 - 128 + 48 + 8, p0 - 128 + 48 + 9); + if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary)) + strPost4_alternate(p0 - 1, p0 - 2, p0 - 3, p0 - 4); + if (!top) + { + // Need to delay processing of left column until leftAdjacentColumn = 1 for corner overlap operators + if (leftAdjacentColumn || bOneMBRightVertTB) { + p = p0 + 32 + 10 - 128; + strPost4_alternate(p + 0, p - 2, p + 6, p + 8); + strPost4_alternate(p + 1, p - 1, p + 7, p + 9); + p = NULL; + } + + if (right || bVertTileBoundary) { + p = p0 + -32 + 14; + strPost4_alternate(p + 0, p - 2, p + 6, p + 8); + strPost4_alternate(p + 1, p - 1, p + 7, p + 9); + p = NULL; + } + + for (j = (left ? 0 : -128); j < ((right || bVertTileBoundary) ? -64 : 0); j += 64) + strPost4x4Stage1_alternate(p0 + j + 32, 0); + } + + if (!bottom) + { + // Need to delay processing of left column until leftAdjacentColumn = 1 for corner overlap operators + if (leftAdjacentColumn || bOneMBRightVertTB) + { + p = p1 + 0 + 10 - 128; + strPost4_alternate(p + 0, p - 2, p + 6, p + 8); + strPost4_alternate(p + 1, p - 1, p + 7, p + 9); + p += 16; + strPost4_alternate(p + 0, p - 2, p + 6, p + 8); + strPost4_alternate(p + 1, p - 1, p + 7, p + 9); + p = NULL; + } + + if (right || bVertTileBoundary) + { + p = p1 + -64 + 14; + strPost4_alternate(p + 0, p - 2, p + 6, p + 8); + strPost4_alternate(p + 1, p - 1, p + 7, p + 9); + p += 16; + strPost4_alternate(p + 0, p - 2, p + 6, p + 8); + strPost4_alternate(p + 1, p - 1, p + 7, p + 9); + p = NULL; + } + + for (j = (left ? 0 : -128); j < ((right || bVertTileBoundary) ? -64 : 0); j += 64) + { + strPost4x4Stage1_alternate(p1 + j + 0, 0); + strPost4x4Stage1_alternate(p1 + j + 16, 0); + } + } + + if (topORbottom || bHoriTileBoundary) + { + if (top || bHoriTileBoundary) { + p = p1 + 5; + for (j = (left ? 0 : -128); j < ((right || bVertTileBoundary) ? -64 : 0); j += 64) + { + strPost4_alternate(p + j + 0, p + j - 1, p + j + 59, p + j + 60); + strPost4_alternate(p + j + 2, p + j + 1, p + j + 61, p + j + 62); + } + p = NULL; + } + + if (bottom || bHoriTileBoundary) { + p = p0 + 48 + 13; + for (j = (left ? 0 : -128); j < ((right || bVertTileBoundary) ? -64 : 0); j += 64) + { + strPost4_alternate(p + j + 0, p + j - 1, p + j + 59, p + j + 60); + strPost4_alternate(p + j + 2, p + j + 1, p + j + 61, p + j + 62); + } + p = NULL; + } + } + else + { + // Need to delay processing of left column until leftAdjacentColumn = 1 for corner overlap operators + if (leftAdjacentColumn || bOneMBRightVertTB) + { + j = 0 + 0 - 128; + strPost4_alternate(p0 + j + 48 + 10 + 0, p0 + j + 48 + 10 - 2, p1 + j + 0, p1 + j + 2); + strPost4_alternate(p0 + j + 48 + 10 + 1, p0 + j + 48 + 10 - 1, p1 + j + 1, p1 + j + 3); + } + + if (right || bVertTileBoundary) + { + j = -64 + 4; + strPost4_alternate(p0 + j + 48 + 10 + 0, p0 + j + 48 + 10 - 2, p1 + j + 0, p1 + j + 2); + strPost4_alternate(p0 + j + 48 + 10 + 1, p0 + j + 48 + 10 - 1, p1 + j + 1, p1 + j + 3); + } + + for (j = (left ? 0 : -128); j < ((right || bVertTileBoundary) ? -64 : 0); j += 64) + strPost4x4Stage1Split_alternate(p0 + j + 48, p1 + j + 0, 0); + } + } + } + + return ICERR_OK; +} diff --git a/Src/JxrDecode/jxrlib/image/decode/strPredQuantDec.c b/Src/JxrDecode/jxrlib/image/decode/strPredQuantDec.c new file mode 100644 index 00000000..b077fad0 --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/decode/strPredQuantDec.c @@ -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 "../sys/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); + } + //} +} + diff --git a/Src/JxrDecode/jxrlib/image/decode/strdec.c b/Src/JxrDecode/jxrlib/image/decode/strdec.c new file mode 100644 index 00000000..5fb36727 --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/decode/strdec.c @@ -0,0 +1,3628 @@ +//*@@@+++@@@@****************************************************************** +// +// 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 "../sys/strcodec.h" +#include "decode.h" +#include "../sys/strTransform.h" +#include +//#include "perfTimer.h" + +#ifdef MEM_TRACE +#define TRACE_MALLOC 1 +#define TRACE_NEW 0 +#define TRACE_HEAP 0 +#include "memtrace.h" +#endif + +#ifdef X86OPT_INLINE +#define _FORCEINLINE __forceinline +#else // X86OPT_INLINE +#define _FORCEINLINE +#endif // X86OPT_INLINE + +#if defined(WMP_OPT_SSE2) || defined(WMP_OPT_CC_DEC) || defined(WMP_OPT_TRFM_DEC) +void StrDecOpt(CWMImageStrCodec* pSC); +#endif // OPT defined + +Int processMacroblockDec(CWMImageStrCodec*); + +U8 readQuantizerSB(U8 pQPIndex[MAX_CHANNELS], SimpleBitIO* pIO, size_t cChannel) +{ + U8 cChMode = 0; + + if (cChannel >= MAX_CHANNELS) + return 0; + + if (cChannel > 1) + cChMode = (U8)getBit32_SB(pIO, 2); // Channel mode + + pQPIndex[0] = (U8)getBit32_SB(pIO, 8); // Y + + if (cChMode == 1) // MIXED + pQPIndex[1] = (U8)getBit32_SB(pIO, 8); // UV + else if (cChMode > 0) { // INDEPENDENT + size_t i; + + for (i = 1; i < cChannel; i++) +#pragma prefast(suppress: __WARNING_UNRELATED_LOOP_TERMINATION_NO_SIZEEXPR, "PREfast false alarm: 1 <= i < MAX_CHANNELS, no buffer over/underrun!") + pQPIndex[i] = (U8)getBit32_SB(pIO, 8); // UV + } + + return cChMode; +} + +U8 readQuantizer(CWMIQuantizer* pQuantizer[MAX_CHANNELS], BitIOInfo* pIO, size_t cChannel, size_t iPos) +{ + U8 cChMode = 0; + + if (cChannel > 1) + cChMode = (U8)getBit16(pIO, 2); // Channel mode + + pQuantizer[0][iPos].iIndex = (U8)getBit16(pIO, 8); // Y + + if (cChMode == 1) // MIXED + pQuantizer[1][iPos].iIndex = (U8)getBit16(pIO, 8); // UV + else if (cChMode > 0) { // INDEPENDENT + size_t i; + + for (i = 1; i < cChannel; i++) + pQuantizer[i][iPos].iIndex = (U8)getBit16(pIO, 8); // UV + } + + return cChMode; +} + +// packet header: 00000000 00000000 00000001 ?????xxx +// xxx: 000(spatial) 001(DC) 010(AD) 011(AC) 100(FL) 101-111(reserved) +// ?????: (iTileY * cNumOfSliceV + iTileX) % 32 +Int readPacketHeader(BitIOInfo* pIO, U8 ptPacketType, U8 pID) +{ + UNREFERENCED_PARAMETER(ptPacketType); + UNREFERENCED_PARAMETER(pID); + if (getBit16(pIO, 8) != 0 || getBit16(pIO, 8) != 0 || getBit16(pIO, 8) != 1) + return ICERR_ERROR; + getBit16(pIO, 8); + return ICERR_OK; +} + +Int readTileHeaderDC(CWMImageStrCodec* pSC, BitIOInfo* pIO) +{ + if ((pSC->m_param.uQPMode & 1) != 0) { // not DC uniform + size_t iTile; + CWMITile* pTile = pSC->pTile + pSC->cTileColumn; + + if (pSC->cTileRow + pSC->cTileColumn == 0) // allocate DC QP info + for (iTile = 0; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile++) + if (allocateQuantizer(pSC->pTile[iTile].pQuantizerDC, pSC->m_param.cNumChannels, 1) != ICERR_OK) + return ICERR_ERROR; + + pTile->cChModeDC = readQuantizer(pTile->pQuantizerDC, pIO, pSC->m_param.cNumChannels, 0); + formatQuantizer(pTile->pQuantizerDC, pTile->cChModeDC, pSC->m_param.cNumChannels, 0, TRUE, pSC->m_param.bScaledArith); + } + + return ICERR_OK; +} + +Int readTileHeaderLP(CWMImageStrCodec* pSC, BitIOInfo* pIO) +{ + if (pSC->WMISCP.sbSubband != SB_DC_ONLY && (pSC->m_param.uQPMode & 2) != 0) { // not LP uniform + CWMITile* pTile = pSC->pTile + pSC->cTileColumn; + U8 i; + + pTile->bUseDC = (getBit16(pIO, 1) == 1 ? TRUE : FALSE); + pTile->cBitsLP = 0; + pTile->cNumQPLP = 1; + + if (pSC->cTileRow > 0) + freeQuantizer(pTile->pQuantizerLP); + + if (pTile->bUseDC == TRUE) { + if (allocateQuantizer(pTile->pQuantizerLP, pSC->m_param.cNumChannels, pTile->cNumQPLP) != ICERR_OK) + return ICERR_ERROR; + useDCQuantizer(pSC, pSC->cTileColumn); + } + else { + pTile->cNumQPLP = (U8)getBit16(pIO, 4) + 1; + pTile->cBitsLP = dquantBits(pTile->cNumQPLP); + + if (allocateQuantizer(pTile->pQuantizerLP, pSC->m_param.cNumChannels, pTile->cNumQPLP) != ICERR_OK) + return ICERR_ERROR; + + for (i = 0; i < pTile->cNumQPLP; i++) { + pTile->cChModeLP[i] = readQuantizer(pTile->pQuantizerLP, pIO, pSC->m_param.cNumChannels, i); + formatQuantizer(pTile->pQuantizerLP, pTile->cChModeLP[i], pSC->m_param.cNumChannels, i, TRUE, pSC->m_param.bScaledArith); + } + } + } + + return ICERR_OK; +} + +Int readTileHeaderHP(CWMImageStrCodec* pSC, BitIOInfo* pIO) +{ + if (pSC->WMISCP.sbSubband != SB_DC_ONLY && pSC->WMISCP.sbSubband != SB_NO_HIGHPASS && (pSC->m_param.uQPMode & 4) != 0) { // not HP uniform + CWMITile* pTile = pSC->pTile + pSC->cTileColumn; + U8 i; + + pTile->bUseLP = (getBit16(pIO, 1) == 1 ? TRUE : FALSE); + pTile->cBitsHP = 0; + pTile->cNumQPHP = 1; + + if (pSC->cTileRow > 0) + freeQuantizer(pTile->pQuantizerHP); + + if (pTile->bUseLP == TRUE) { + pTile->cNumQPHP = pTile->cNumQPLP; + if (allocateQuantizer(pTile->pQuantizerHP, pSC->m_param.cNumChannels, pTile->cNumQPHP) != ICERR_OK) + return ICERR_ERROR; + useLPQuantizer(pSC, pTile->cNumQPHP, pSC->cTileColumn); + } + else { + pTile->cNumQPHP = (U8)getBit16(pIO, 4) + 1; + pTile->cBitsHP = dquantBits(pTile->cNumQPHP); + + if (allocateQuantizer(pTile->pQuantizerHP, pSC->m_param.cNumChannels, pTile->cNumQPHP) != ICERR_OK) + return ICERR_ERROR; + + for (i = 0; i < pTile->cNumQPHP; i++) { + pTile->cChModeHP[i] = readQuantizer(pTile->pQuantizerHP, pIO, pSC->m_param.cNumChannels, i); + formatQuantizer(pTile->pQuantizerHP, pTile->cChModeHP[i], pSC->m_param.cNumChannels, i, FALSE, pSC->m_param.bScaledArith); + } + } + } + + return ICERR_OK; +} + +Int readPackets(CWMImageStrCodec* pSC) +{ + if (pSC->cColumn == 0 && pSC->cRow == pSC->WMISCP.uiTileY[pSC->cTileRow]) { // start of a new horizontal slice + size_t k; + + if (pSC->m_bSecondary) { + if (pSC->cNumBitIO > 0) { + for (k = 0; k <= pSC->WMISCP.cNumOfSliceMinus1V; k++) { + // reset coding contexts + ResetCodingContextDec(&pSC->m_pCodingContext[k]); + } + } + else { // for multiple decoding calls! + ResetCodingContextDec(&pSC->m_pCodingContext[0]); + } + } + else { + // get sizes of each packet and update index table + for (k = 0; k < pSC->cNumBitIO; k++) { + if (pSC->ppWStream != NULL) { // new API + unsigned cBands = (pSC->WMISCP.bfBitstreamFormat == SPATIAL ? 1 : pSC->cSB); + struct WMPStream** ppWS = pSC->ppWStream + (pSC->WMISCP.cNumOfSliceMinus1V + 1) * pSC->cTileRow * cBands + + k / cBands * cBands + (k % cBands); + + if (pSC->cTileRow > 0 && pSC->m_ppBitIO[k]->pWS != NULL) // attached to the same packet of the tile on top + detachISRead(pSC, pSC->m_ppBitIO[k]); // detach it + + if (ppWS[0] != NULL) + attachISRead(pSC->m_ppBitIO[k], ppWS[0], pSC); // need to attach it + } + else { + if (pSC->cTileRow > 0) + detachISRead(pSC, pSC->m_ppBitIO[k]); + pSC->WMISCP.pWStream->SetPos(pSC->WMISCP.pWStream, pSC->pIndexTable[pSC->cNumBitIO * pSC->cTileRow + k] + pSC->cHeaderSize); + attachISRead(pSC->m_ppBitIO[k], pSC->WMISCP.pWStream, pSC); + } + } + + if (pSC->cNumBitIO == 0) { + detachISRead(pSC, pSC->pIOHeader); + if (pSC->ppWStream != NULL) {// new API + attachISRead(pSC->pIOHeader, pSC->ppWStream[0], pSC); // need to attach it + } + else { + pSC->WMISCP.pWStream->SetPos(pSC->WMISCP.pWStream, pSC->cHeaderSize); + attachISRead(pSC->pIOHeader, pSC->WMISCP.pWStream, pSC); + } + } + + for (k = 0; k <= pSC->WMISCP.cNumOfSliceMinus1V; k++) { + U8 pID = (U8)((pSC->cTileRow * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + k) & 0x1F); + + // read packet header + if (pSC->WMISCP.bfBitstreamFormat == SPATIAL) { + BitIOInfo* pIO = (pSC->cNumBitIO == 0 ? pSC->pIOHeader : pSC->m_ppBitIO[k]); + + if (pIO->pWS == NULL || readPacketHeader(pIO, 0, pID) != ICERR_OK) + return ICERR_ERROR; + pSC->m_pCodingContext[k].m_iTrimFlexBits = (pSC->m_param.bTrimFlexbitsFlag) ? getBit16(pIO, 4) : 0; + } + else { + if (pSC->m_ppBitIO[k * pSC->cSB + 0] == NULL || readPacketHeader(pSC->m_ppBitIO[k * pSC->cSB + 0], 1, pID) != ICERR_OK) + return ICERR_ERROR; + if (pSC->cSB > 1) { + if (pSC->m_ppBitIO[k * pSC->cSB + 1] == NULL || readPacketHeader(pSC->m_ppBitIO[k * pSC->cSB + 1], 2, pID) != ICERR_OK) + return ICERR_ERROR; + } + if (pSC->cSB > 2) { + if (pSC->m_ppBitIO[k * pSC->cSB + 2] == NULL || readPacketHeader(pSC->m_ppBitIO[k * pSC->cSB + 2], 3, pID) != ICERR_OK) + return ICERR_ERROR; + // readTileHeaderHP(pSC, pSC->m_ppBitIO[k * pSC->cSB + 2]); + } + if (pSC->cSB > 3) { + if (pSC->m_ppBitIO[k * pSC->cSB + 3] == NULL) + return ICERR_ERROR; + readPacketHeader(pSC->m_ppBitIO[k * pSC->cSB + 3], 4, pID); // bad flexbits packet doesn't generate an error + pSC->m_pCodingContext[k].m_iTrimFlexBits = (pSC->m_param.bTrimFlexbitsFlag) ? getBit16(pSC->m_ppBitIO[k * pSC->cSB + 3], 4) : 0; + } + } + + // reset coding contexts + ResetCodingContextDec(&pSC->m_pCodingContext[k]); + } + } + } + + if (pSC->m_bCtxLeft && pSC->m_bCtxTop && pSC->m_bSecondary == FALSE) { + CCodingContext* pContext = &pSC->m_pCodingContext[pSC->cTileColumn]; + + readTileHeaderDC(pSC, pContext->m_pIODC); + if (pSC->m_pNextSC != NULL) + readTileHeaderDC(pSC->m_pNextSC, pContext->m_pIODC); + if (pSC->cSB > 1) { + readTileHeaderLP(pSC, pContext->m_pIOLP); + if (pSC->m_pNextSC != NULL) + readTileHeaderLP(pSC->m_pNextSC, pContext->m_pIOLP); + } + if (pSC->cSB > 2) { + readTileHeaderHP(pSC, pContext->m_pIOAC); + if (pSC->m_pNextSC != NULL) + readTileHeaderHP(pSC->m_pNextSC, pContext->m_pIOAC); + } + } + + return ICERR_OK; +} + +/* inverse transform and overlap possible part of a macroblock */ +Int processMacroblockDec(CWMImageStrCodec* pSC) +{ + const OVERLAP olOverlap = pSC->WMISCP.olOverlap; + // const Bool left = (pSC->cColumn == 0); + const Bool /*top = (pSC->cRow == 0),*/ bottom = (pSC->cRow == pSC->cmbHeight); + const Bool bottomORright = (bottom || pSC->cColumn == pSC->cmbWidth); + // const size_t mbWidth = pSC->cmbWidth, mbX = pSC->cColumn; + // Int iQIndex = 0; + ERR_CODE result = ICERR_OK; + size_t j, jend = (pSC->m_pNextSC != NULL); + + for (j = 0; j <= jend; j++) { + if (!bottomORright) { + CCodingContext* pContext; + + getTilePos(pSC, pSC->cColumn, pSC->cRow); + + if (jend) { + pSC->m_pNextSC->cTileColumn = pSC->cTileColumn; + pSC->m_pNextSC->cTileRow = pSC->cTileRow; + } + + pContext = &pSC->m_pCodingContext[pSC->cTileColumn]; + + if (readPackets(pSC) != ICERR_OK) + return ICERR_ERROR; + + // check if we need to do entropy decode + if (!pSC->m_Dparam->bDecodeFullFrame) { + if (pSC->cColumn == pSC->WMISCP.uiTileX[pSC->cTileColumn]) { // switching to a new tile + size_t rLeft = pSC->m_Dparam->cROILeftX, rRight = pSC->m_Dparam->cROIRightX; + size_t rTop = pSC->m_Dparam->cROITopY, rBottom = pSC->m_Dparam->cROIBottomY; + size_t rExt = (olOverlap == OL_NONE ? 0 : olOverlap == OL_ONE ? 2 : 10); + size_t tLeft = pSC->cColumn * 16, tTop = pSC->WMISCP.uiTileY[pSC->cTileRow] * 16; + size_t tRight = (pSC->cTileColumn != pSC->WMISCP.cNumOfSliceMinus1V ? pSC->WMISCP.uiTileX[pSC->cTileColumn + 1] : pSC->cmbWidth) * 16; + size_t tBottom = (pSC->cTileRow != pSC->WMISCP.cNumOfSliceMinus1H ? pSC->WMISCP.uiTileY[pSC->cTileRow + 1] : pSC->cmbHeight) * 16; + + // tile overlaps with ROI? + pContext->m_bInROI = ((rLeft >= tRight + rExt || rTop >= tBottom + rExt || tLeft > rRight + rExt || + tTop > rBottom + rExt || pSC->cRow * 16 > rBottom + rExt) ? FALSE : TRUE); + } + } + + if (pSC->m_Dparam->bDecodeFullFrame || pContext->m_bInROI) { + if ((result = DecodeMacroblockDC(pSC, pContext, (Int)pSC->cColumn, (Int)pSC->cRow)) != ICERR_OK) + return result; + + if (pSC->m_Dparam->bDecodeLP) { + if ((result = DecodeMacroblockLowpass(pSC, pContext, (Int)pSC->cColumn, (Int)pSC->cRow)) != ICERR_OK) + return result; + } + + predDCACDec(pSC); + + dequantizeMacroblock(pSC); + + if (pSC->m_Dparam->bDecodeHP) { + if ((result = DecodeMacroblockHighpass(pSC, pContext, (Int)pSC->cColumn, (Int)pSC->cRow)) != ICERR_OK) + return result; + predACDec(pSC); + } + + /* keep necessary info for future prediction */ + updatePredInfo(pSC, &pSC->MBInfo, (Int)pSC->cColumn, pSC->m_param.cfColorFormat); + } + } + + if ((!pSC->m_Dparam->bDecodeFullFrame) && + ((pSC->cColumn * 16 > pSC->m_Dparam->cROIRightX + 25) || (pSC->cColumn * 16 + 25 < pSC->m_Dparam->cROILeftX) + || (pSC->cRow * 16 > pSC->m_Dparam->cROIBottomY + 25) || (pSC->cRow * 16 + 25 < pSC->m_Dparam->cROITopY))) + { + // do nothing + } + else { + pSC->Transform(pSC); + } + + if (jend) { + pSC->m_pNextSC->cRow = pSC->cRow; + pSC->m_pNextSC->cColumn = pSC->cColumn; + pSC = pSC->m_pNextSC; + } + } + + return result; +} + +//================================================================ +// Inverse Color Conversion +//#define _ICC1(r, g, b) (g^=b^=g^=b, r^=g^=r^=g, b += ((g) >> 1), r += ((g) >> 1), g -= (b+3*r+2) >> 2) +//#define _ICC(r, g, b) (g^=b^=g^=b, r^=g^=r^=g, b += ((g) >> 1), r += ((g) >> 1), g -= (b+3*r+2) >> 2) +//================================================================ +//#define _ICC1(r, g, b) r -= (g >> 1), g += r, r -= ((b + 1) >> 1), b += r +//#define _ICC(r, g, b) r -= (g >> 1), g += r, r -= (b >> 1), b += r + +#define _ICC(r, g, b) (g -= ((r + 0) >> 1), r -= ((b + 1) >> 1) - g, b += r) +#define _ICC_CMYK(c, m, y, k) (k -= ((m + 1) >> 1), m -= (c >> 1) - k, c -= ((y + 1) >> 1) - m, y += c) + +#define _CLIP2(l, v, h) ((v) < (l) ? (l) : ((h) < (v) ? (h) : (v))) +#define _CLIP8(v) ((U8)_CLIP2(0, v, 255)) +#define _CLIP16(v) ((I16)_CLIP2(-32768, v, 32767)) +#define _CLIPU16(v) ((U16)_CLIP2(0, v, 65535)) + +#define min(a,b) (((a) < (b)) ? (a) : (b)) + +//inverseConvert: Inverse conversion from float RGB to RGBE +static _FORCEINLINE void inverseConvert(PixelI iF, U8* pRGB, U8* pE) +{ + if (iF <= 0) { + *pRGB = *pE = 0; + } + else if ((iF >> 7) > 1) { + /** normal form **/ + *pE = (U8)(iF >> 7); //+ 1; + *pRGB = (iF & 0x7f) | 0x80; + } + else { + /** denormal form **/ + *pE = 1; + *pRGB = (U8)iF; + } +} + +#ifdef __ANSI__ +#define max(a,b) ((a) > (b) ? (a) : (b)) +#endif // __ANSI__ + +static _FORCEINLINE void inverseConvertRGBE(PixelI iFr, PixelI iFg, PixelI iFb, U8* pR, U8* pG, U8* pB, U8* pE) +{ + U8 iShift; + + U8 pR_E, pG_E, pB_E; + + inverseConvert(iFr, pR, &pR_E); + inverseConvert(iFg, pG, &pG_E); + inverseConvert(iFb, pB, &pB_E); + + *pE = max(max(pR_E, pG_E), pB_E); + + if (*pE > pR_E) { + iShift = (*pE - pR_E); + *pR = (U8)((((int)*pR) * 2 + 1) >> (iShift + 1)); + } + if (*pE > pG_E) { + iShift = (*pE - pG_E); + *pG = (U8)((((int)*pG) * 2 + 1) >> (iShift + 1)); + } + if (*pE > pB_E) { + iShift = (*pE - pB_E); + *pB = (U8)((((int)*pB) * 2 + 1) >> (iShift + 1)); + } +} + + +//pixel to float 32! +static _FORCEINLINE float pixel2float(PixelI _h, const char _c, const unsigned char _lm) +{ + union uif + { + I32 i; + float f; + } x; + + I32 s, iTempH, m, e, lmshift = (1 << _lm); + + // assert (_c <= 127); + + iTempH = (I32)_h; + s = (iTempH >> 31); + iTempH = (iTempH ^ s) - s; // abs(iTempH) + + e = (U32)iTempH >> _lm;// & ((1 << (31 - _lm)) - 1); + m = (iTempH & (lmshift - 1)) | lmshift; // actual mantissa, with normalizer + if (e == 0) { // denormal land + m ^= lmshift; // normalizer removed + e = 1; // actual exponent + } + + e += (127 - _c); + while (m < lmshift && e > 1 && m > 0) { // denormal originally, see if normal is possible + e--; + m <<= 1; + } + if (m < lmshift) // truly denormal + e = 0; + else + m ^= lmshift; + m <<= (23 - _lm); + + x.i = (s & 0x80000000) | (e << 23) | m; + + return x.f; +} + +//convert Half-16 to internal format, only need to handle sign bit +static _FORCEINLINE U16 backwardHalf(PixelI hHalf) +{ + PixelI s; + s = hHalf >> 31; + hHalf = ((hHalf & 0x7fff) ^ s) - s; // don't worry about overflow + return (U16)hHalf; +} + + +Void interpolateUV(CWMImageStrCodec* pSC) +{ + const COLORFORMAT cfExt = pSC->WMII.cfColorFormat; + const size_t cWidth = pSC->cmbWidth * 16; + PixelI* pSrcU = pSC->a0MBbuffer[1], * pSrcV = pSC->a0MBbuffer[2]; + PixelI* pDstU = pSC->pResU, * pDstV = pSC->pResV; + size_t iRow, iColumn; + size_t iIdxS = 0, iIdxD = 0; + + if (pSC->m_param.cfColorFormat == YUV_422) { // 422 => 444, interpolate horizontally + for (iRow = 0; iRow < 16; iRow++) { + for (iColumn = 0; iColumn < cWidth; iColumn += 2) { + iIdxS = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7]; + iIdxD = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; + + // copy over + pDstU[iIdxD] = pSrcU[iIdxS]; + pDstV[iIdxD] = pSrcV[iIdxS]; + + if (iColumn > 0) { + size_t iL = iColumn - 2, iIdxL = ((iL >> 4) << 8) + idxCC[iRow][iL & 15]; + size_t iC = iColumn - 1, iIdxC = ((iC >> 4) << 8) + idxCC[iRow][iC & 15]; + + // interpolate + pDstU[iIdxC] = ((pDstU[iIdxL] + pDstU[iIdxD] + 1) >> 1); + pDstV[iIdxC] = ((pDstV[iIdxL] + pDstV[iIdxD] + 1) >> 1); + } + } + + //last pixel + iIdxS = (((iColumn - 1) >> 4) << 8) + idxCC[iRow][(iColumn - 1) & 15]; + pDstU[iIdxS] = pDstU[iIdxD]; + pDstV[iIdxS] = pDstV[iIdxD]; + } + } + else { // 420 => 422 or 444, interpolate vertically + const size_t cShift = (cfExt == YUV_422 ? 3 : 4); + + for (iColumn = 0; iColumn < cWidth; iColumn += 2) { + const size_t cMB = ((iColumn >> 4) << (4 + cShift)), cPix = (iColumn >> (4 - cShift)) & ((1 << cShift) - 1); + + for (iRow = 0; iRow < 16; iRow += 2) { + iIdxS = ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7]; + iIdxD = cMB + idxCC[iRow][cPix]; + + // copy over + pDstU[iIdxD] = pSrcU[iIdxS]; + pDstV[iIdxD] = pSrcV[iIdxS]; + + if (iRow > 0) { + size_t iIdxT = cMB + idxCC[iRow - 2][cPix]; + size_t iIdxC = cMB + idxCC[iRow - 1][cPix]; + + // interpolate + pDstU[iIdxC] = ((pDstU[iIdxT] + pDstU[iIdxD] + 1) >> 1); + pDstV[iIdxC] = ((pDstV[iIdxT] + pDstV[iIdxD] + 1) >> 1); + } + } + + //last row + iIdxS = cMB + idxCC[15][cPix]; + if (pSC->cRow == pSC->cmbHeight) { // image boundary + pDstU[iIdxS] = pDstU[iIdxD]; + pDstV[iIdxS] = pDstV[iIdxD]; + } + else { // need next MB row + size_t iIdxB = ((iColumn >> 4) << 6) + idxCC_420[0][(iColumn >> 1) & 7]; + + pDstU[iIdxS] = ((pSC->a1MBbuffer[1][iIdxB] + pDstU[iIdxD] + 1) >> 1); + pDstV[iIdxS] = ((pSC->a1MBbuffer[2][iIdxB] + pDstV[iIdxD] + 1) >> 1); + } + } + + if (cfExt != YUV_422) { // 420 => 444, interpolate horizontally + for (iRow = 0; iRow < 16; iRow++) { + for (iColumn = 1; iColumn < cWidth - 2; iColumn += 2) { + size_t iIdxL = (((iColumn - 1) >> 4) << 8) + idxCC[iRow][(iColumn - 1) & 15]; + + iIdxD = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; + iIdxS = (((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]; + + pDstU[iIdxD] = ((pDstU[iIdxS] + pDstU[iIdxL] + 1) >> 1); + pDstV[iIdxD] = ((pDstV[iIdxS] + pDstV[iIdxL] + 1) >> 1); + } + + // last pixel + iIdxD = (((cWidth - 1) >> 4) << 8) + idxCC[iRow][(cWidth - 1) & 15]; + pDstU[iIdxD] = pDstU[iIdxS]; + pDstV[iIdxD] = pDstV[iIdxS]; + } + } + } +} + +// write one MB row of Y_ONLY/CF_ALPHA/YUV_444/N_CHANNEL to output buffer +Void outputNChannel(CWMImageStrCodec* pSC, size_t iFirstRow, size_t iFirstColumn, size_t cWidth, size_t cHeight, size_t iShift, PixelI iBias) +{ + const CWMImageInfo* pII = &pSC->WMII; + const size_t cChannel = pII->cfColorFormat == Y_ONLY ? 1 : pSC->WMISCP.cChannel; + // const U8 cbChannels[BDB_MAX] = {-1, 1, 2, 2, 2, 4, 4, -1, -1, }; + const U8 nLen = pSC->WMISCP.nLenMantissaOrShift; + const I8 nExpBias = pSC->WMISCP.nExpBias; + + PixelI* pChannel[16]; + size_t iChannel, iRow, iColumn; + size_t* pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * 16, iY; + + assert(cChannel <= 16); + + for (iChannel = 0; iChannel < cChannel; iChannel++) + pChannel[iChannel & 15] = pSC->a0MBbuffer[iChannel]; + + if (pSC->m_bUVResolutionChange) + pChannel[1] = pSC->pResU, pChannel[2] = pSC->pResV; + + switch (pSC->WMII.bdBitDepth) { + case BD_8: + for (iRow = iFirstRow; iRow < cHeight; iRow++) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + U8* pDst = (U8*)pSC->WMIBI.pv + iY + pOffsetX[iColumn]; + + for (iChannel = 0; iChannel < cChannel; iChannel++) { + PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift); + + pDst[iChannel] = _CLIP8(p); + } + } + } + break; + + case BD_16: + for (iRow = iFirstRow; iRow < cHeight; iRow++) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + U16* pDst = (U16*)pSC->WMIBI.pv + iY + pOffsetX[iColumn]; + + for (iChannel = 0; iChannel < cChannel; iChannel++) { + PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift); + + p <<= nLen; + pDst[iChannel] = _CLIPU16(p); + } + } + } + break; + + case BD_16S: + for (iRow = iFirstRow; iRow < cHeight; iRow++) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + I16* pDst = (I16*)pSC->WMIBI.pv + iY + pOffsetX[iColumn]; + + for (iChannel = 0; iChannel < cChannel; iChannel++) { + PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift); + + p <<= nLen; + pDst[iChannel] = _CLIP16(p); + } + } + } + break; + + case BD_16F: + for (iRow = iFirstRow; iRow < cHeight; iRow++) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + U16* pDst = (U16*)pSC->WMIBI.pv + iY + pOffsetX[iColumn]; + + for (iChannel = 0; iChannel < cChannel; iChannel++) { + PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + iBias) >> iShift); + + pDst[iChannel] = backwardHalf(p); + } + } + } + break; + + case BD_32: + for (iRow = iFirstRow; iRow < cHeight; iRow++) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + U32* pDst = (U32*)pSC->WMIBI.pv + iY + pOffsetX[iColumn]; + + for (iChannel = 0; iChannel < cChannel; iChannel++) { + PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + iBias) >> iShift); + + p <<= nLen; + pDst[iChannel] = (U32)(p); + } + } + } + break; + + case BD_32S: + for (iRow = iFirstRow; iRow < cHeight; iRow++) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + I32* pDst = (I32*)pSC->WMIBI.pv + iY + pOffsetX[iColumn]; + + for (iChannel = 0; iChannel < cChannel; iChannel++) { + PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + iBias) >> iShift); + + p <<= nLen; + pDst[iChannel] = (I32)(p); + } + } + } + break; + + case BD_32F: + for (iRow = iFirstRow; iRow < cHeight; iRow++) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + float* pDst = (float*)pSC->WMIBI.pv + iY + pOffsetX[iColumn]; + + for (iChannel = 0; iChannel < cChannel; iChannel++) { + PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + iBias) >> iShift); + + pDst[iChannel] = pixel2float(p, nExpBias, nLen); + } + } + } + break; + + default: + assert(0); + break; + } +} + +static void fixup_Y_ONLY_to_Others( + const CWMImageStrCodec* pSC, + const CWMImageBufferInfo* pBI) +{ + const CWMImageInfo* pII = &pSC->WMII; + const CWMIStrCodecParam* pSCP = &pSC->WMISCP; + size_t cWidth = 0, cHeight = 0; + size_t idxY = 0, idxX = 0; + + if (CF_RGB != pII->cfColorFormat || Y_ONLY != pSCP->cfColorFormat) + return; + + cWidth = 0 != pII->cROIWidth ? pII->cROIWidth : pII->cWidth; + cHeight = 0 != pII->cROIHeight ? pII->cROIHeight : pII->cHeight; + +#define fixup(type, nCh) \ +for (idxY = 0; idxY < cHeight; ++idxY) \ +{ \ + type * pT = (type *)((U8*)pBI->pv + pBI->cbStride * idxY); \ + for (idxX = 0; idxX < cWidth; ++idxX) \ + { \ + pT[2] = pT[1] = pT[0]; \ + pT += nCh; \ + } \ +} \ +break + + switch (pII->bdBitDepth) + { + case BD_8: + fixup(U8, (pII->cBitsPerUnit >> 3)); + break; + + case BD_16: + case BD_16S: + case BD_16F: + fixup(U16, (pII->cBitsPerUnit >> 3) / sizeof(U16)); + break; + + case BD_32: + case BD_32S: + case BD_32F: + fixup(U32, (pII->cBitsPerUnit >> 3) / sizeof(float)); + break; + + case BD_5: + case BD_10: + case BD_565: + default: + break; + } +} + +// centralized alpha channel color conversion, small perf penalty +Int outputMBRowAlpha(CWMImageStrCodec* pSC) +{ + if (pSC->WMII.bdBitDepth == BD_8 && pSC->WMISCP.cfColorFormat == CF_RGB) // has been taken care of and optimized out + return ICERR_OK; + + if (pSC->m_bSecondary == FALSE && pSC->m_pNextSC != NULL) { // with alpha channel + const BITDEPTH_BITS bd = pSC->WMII.bdBitDepth; + const PixelI iShift = (pSC->m_param.bScaledArith ? SHIFTZERO + QPFRACBITS : 0); + const size_t cHeight = min((pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16); + const size_t cWidth = (pSC->m_Dparam->cROIRightX + 1); + const size_t iFirstRow = ((pSC->cRow - 1) * 16 > pSC->m_Dparam->cROITopY ? 0 : (pSC->m_Dparam->cROITopY & 0xf)), iFirstColumn = pSC->m_Dparam->cROILeftX; + const size_t iAlphaPos = pSC->WMII.cLeadingPadding + (pSC->WMII.cfColorFormat == CMYK ? 4 : 3);//only RGB and CMYK may have interleaved alpha + const PixelI* pA = pSC->m_pNextSC->a0MBbuffer[0]; + const U8 nLen = pSC->WMISCP.nLenMantissaOrShift; + const I8 nExpBias = pSC->WMISCP.nExpBias; + size_t iRow, iColumn; + size_t* pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * 16, iY; + + if (CF_RGB != pSC->WMII.cfColorFormat && CMYK != pSC->WMII.cfColorFormat) + return ICERR_ERROR; + + if (bd == BD_8) { + const PixelI iBias = (1 << (iShift + 7)) + (iShift == 0 ? 0 : (1 << (iShift - 1))); + + for (iRow = iFirstRow; iRow < cHeight; iRow++) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + PixelI a = ((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift); + ((U8*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = _CLIP8(a); + } + } + else if (bd == BD_16) { + const PixelI iBias = (1 << (iShift + 15)) + (iShift == 0 ? 0 : (1 << (iShift - 1))); + + for (iRow = iFirstRow; iRow < cHeight; iRow++) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + PixelI a = (((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift) << nLen); + ((U16*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = _CLIPU16(a); + } + } + else if (bd == BD_16S) { + const PixelI iBias = (iShift == 0 ? 0 : (1 << (iShift - 1))); + + for (iRow = iFirstRow; iRow < cHeight; iRow++) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + PixelI a = (((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift) << nLen); + ((I16*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = _CLIP16(a); + } + } + else if (bd == BD_16F) { + const PixelI iBias = (iShift == 0 ? 0 : (1 << (iShift - 1))); + + for (iRow = iFirstRow; iRow < cHeight; iRow++) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + PixelI a = ((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift); + ((U16*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = backwardHalf(a); + } + } + else if (bd == BD_32S) { + const PixelI iBias = (iShift == 0 ? 0 : (1 << (iShift - 1))); + + for (iRow = iFirstRow; iRow < cHeight; iRow++) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + PixelI a = (((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift) << nLen); + ((I32*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = a; + } + } + else if (bd == BD_32F) { + const PixelI iBias = (iShift == 0 ? 0 : (1 << (iShift - 1))); + + for (iRow = iFirstRow; iRow < cHeight; iRow++) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + PixelI a = ((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift); + ((float*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = pixel2float(a, nExpBias, nLen); + } + } + else // not supported + return ICERR_ERROR; + } + + return ICERR_OK; +} + +Int outputMBRow(CWMImageStrCodec* pSC) +{ + const COLORFORMAT cfExt = (pSC->m_param.cfColorFormat == Y_ONLY ? Y_ONLY : pSC->WMII.cfColorFormat); + const BITDEPTH_BITS bd = pSC->WMII.bdBitDepth; + const PixelI iShift = (pSC->m_param.bScaledArith ? SHIFTZERO + QPFRACBITS : 0); + const size_t cHeight = min((pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16); + const size_t cWidth = (pSC->m_Dparam->cROIRightX + 1); + const size_t iFirstRow = ((pSC->cRow - 1) * 16 > pSC->m_Dparam->cROITopY ? 0 : (pSC->m_Dparam->cROITopY & 0xf)), iFirstColumn = pSC->m_Dparam->cROILeftX; + const PixelI* pY = pSC->a0MBbuffer[0]; + const PixelI* pU = (pSC->m_bUVResolutionChange ? pSC->pResU : pSC->a0MBbuffer[1]); + const PixelI* pV = (pSC->m_bUVResolutionChange ? pSC->pResV : pSC->a0MBbuffer[2]); + const PixelI* pA = NULL; + const size_t iB = (pSC->WMII.bRGB ? 2 : 0); + const size_t iR = 2 - iB; + const U8 nLen = pSC->WMISCP.nLenMantissaOrShift; + const I8 nExpBias = pSC->WMISCP.nExpBias; + size_t iRow, iColumn, iIdx; + size_t* pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * (cfExt == YUV_420 ? 8 : 16), iY; + + + if (pSC->m_pNextSC) { + assert(pSC->m_param.bScaledArith == pSC->m_pNextSC->m_param.bScaledArith); // will be relaxed later + } + + // guard output buffer + if (checkImageBuffer(pSC, pSC->WMII.oOrientation >= O_RCW ? pSC->WMII.cROIHeight : pSC->WMII.cROIWidth, cHeight - iFirstRow) != ICERR_OK) + return ICERR_ERROR; + + if (pSC->m_bUVResolutionChange) + interpolateUV(pSC); + + if (pSC->WMISCP.bYUVData) { + I32* pDst = (I32*)pSC->WMIBI.pv + (pSC->cRow - 1) * + (pSC->m_param.cfColorFormat == YUV_420 ? 8 : 16) * pSC->WMIBI.cbStride / sizeof(I32); + + switch (pSC->m_param.cfColorFormat) { + case Y_ONLY: + case YUV_444: + case NCOMPONENT: + { + PixelI* pChannel[16]; + size_t iChannel; + + const size_t cChannel = pSC->WMII.cfColorFormat == Y_ONLY ? 1 : pSC->WMISCP.cChannel; + assert(cChannel <= 16); + + for (iChannel = 0; iChannel < cChannel; iChannel++) + pChannel[iChannel & 15] = pSC->a0MBbuffer[iChannel]; + + for (iRow = iFirstRow; iRow < cHeight; iRow++) { + I32* pRow = pDst; + for (iColumn = iFirstColumn; iColumn < cWidth; iColumn++) { + for (iChannel = 0; iChannel < cChannel; iChannel++) { + PixelI p = pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]]; + + *pRow++ = p; + } + } + pDst += pSC->WMIBI.cbStride / sizeof(I32); + } + } + break; + + case YUV_422: + { + PixelI y0, y1, u, v; + + for (iRow = iFirstRow; iRow < cHeight; iRow++) { + I32* pRow = pDst; + for (iColumn = iFirstColumn; iColumn < cWidth; iColumn += 2) { + iIdx = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7]; + u = pU[iIdx], v = pV[iIdx]; + + y0 = pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]]; + y1 = pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]]; + + pRow[0] = u, pRow[1] = y0, pRow[2] = v, pRow[3] = y1; + pRow += 4; + } + pDst += pSC->WMIBI.cbStride / sizeof(I32); + } + } + break; + + case YUV_420: + { + PixelI y0, y1, y2, y3, u, v; + // const size_t iS4[8][4] = {{0, 1, 2, 3}, {2, 3, 0, 1}, {1, 0, 3, 2}, {3, 2, 1, 0}, {1, 3, 0, 2}, {3, 1, 2, 0}, {0, 2, 1, 3}, {2, 0, 3, 1}}; + + for (iRow = iFirstRow; iRow < cHeight; iRow += 2) { + I32* pRow = pDst; + for (iColumn = iFirstColumn; iColumn < cWidth; iColumn += 2) { + iIdx = ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7]; + u = pU[iIdx], v = pV[iIdx]; + + y0 = pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]]; + y1 = pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]]; + y2 = pY[((iColumn >> 4) << 8) + idxCC[iRow + 1][iColumn & 15]]; + y3 = pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow + 1][(iColumn + 1) & 15]]; + + pRow[0] = y0, pRow[1] = y1, pRow[2] = y2, pRow[3] = y3, pRow[4] = u, pRow[5] = v; + pRow += 6; + } + pDst += pSC->WMIBI.cbStride / sizeof(I32); + } + } + break; + + default: + assert(0); + break; + } + } + else if (bd == BD_8) { + U8* pDst; + const PixelI iBias1 = 128 << iShift; + const PixelI iBias2 = pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0; + const PixelI iBias = iBias1 + iBias2; + + switch (cfExt) { + case CF_RGB: + { + PixelI r, g, b, a; + + if (pSC->m_pNextSC && pSC->WMISCP.uAlphaMode > 0) { // RGBA + + pA = pSC->m_pNextSC->a0MBbuffer[0]; + + if (pSC->m_param.bScaledArith == FALSE) { + for (iRow = iFirstRow; iRow < cHeight; iRow++) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; + + g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; + a = pA[iIdx] + iBias; + + _ICC(r, g, b); + + pDst = (U8*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; + if ((g | b | r | a) & ~0xff) + pDst[iR] = _CLIP8(r), pDst[1] = _CLIP8(g), pDst[iB] = _CLIP8(b), pDst[3] = _CLIP8(a); + else + pDst[iR] = (U8)r, pDst[1] = (U8)g, pDst[iB] = (U8)b, pDst[3] = (U8)(a); + } + } + else { + for (iRow = iFirstRow; iRow < cHeight; iRow++) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; + + g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; + a = pA[iIdx] + iBias; + + _ICC(r, g, b); + + g >>= iShift, b >>= iShift, r >>= iShift, a >>= iShift; + pDst = (U8*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; + if ((g | b | r | a) & ~0xff) + pDst[iR] = _CLIP8(r), pDst[1] = _CLIP8(g), pDst[iB] = _CLIP8(b), pDst[3] = _CLIP8(a); + else + pDst[iR] = (U8)r, pDst[1] = (U8)g, pDst[iB] = (U8)b, pDst[3] = (U8)(a); + } + } + } + else { + if (pSC->m_param.bScaledArith == FALSE) { + for (iRow = iFirstRow; iRow < cHeight; iRow++) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; + + g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; + + _ICC(r, g, b); + + pDst = (U8*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; + if ((g | b | r) & ~0xff) + pDst[iR] = _CLIP8(r), pDst[1] = _CLIP8(g), pDst[iB] = _CLIP8(b); + else + pDst[iR] = (U8)r, pDst[1] = (U8)g, pDst[iB] = (U8)b; + } + } + else { + for (iRow = iFirstRow; iRow < cHeight; iRow++) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; + + g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; + + _ICC(r, g, b); + + g >>= iShift, b >>= iShift, r >>= iShift; + pDst = (U8*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; + if ((g | b | r) & ~0xff) + pDst[iR] = _CLIP8(r), pDst[1] = _CLIP8(g), pDst[iB] = _CLIP8(b); + else + pDst[iR] = (U8)r, pDst[1] = (U8)g, pDst[iB] = (U8)b; + } + } + } + break; + } + + case Y_ONLY: + case YUV_444: + case NCOMPONENT: + outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias); + break; + + case YUV_422: + { + PixelI y0, y1, u, v; + // const ORIENTATION oO = pSC->WMII.oOrientation; + // const size_t i0 = ((oO > O_FLIPV && oO <= O_RCW_FLIPVH) ? 1 : 0), i1 = 1 - i0; + + for (iRow = iFirstRow; iRow < cHeight; iRow++) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn += 2) { + iIdx = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7]; + u = ((pU[iIdx] + iBias) >> iShift), v = ((pV[iIdx] + iBias) >> iShift); + + y0 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift); + y1 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] + iBias) >> iShift); + + pDst = (U8*)pSC->WMIBI.pv + pOffsetX[iColumn >> 1] + iY; + if ((y0 | y1 | u | v) & ~0xff)//UYVY + pDst[0] = _CLIP8(u), pDst[1] = _CLIP8(y0), pDst[2] = _CLIP8(v), pDst[3] = _CLIP8(y1); + else + pDst[0] = (U8)u, pDst[1] = (U8)y0, pDst[2] = (U8)v, pDst[3] = (U8)y1; + } + } + } + break; + + case YUV_420: + { + PixelI y0, y1, y2, y3, u, v; + const size_t iS4[8][4] = { {0, 1, 2, 3}, {2, 3, 0, 1}, {1, 0, 3, 2}, {3, 2, 1, 0}, {1, 3, 0, 2}, {3, 1, 2, 0}, {0, 2, 1, 3}, {2, 0, 3, 1} }; + const ORIENTATION oO = pSC->WMII.oOrientation; + const size_t i0 = iS4[oO][0], i1 = iS4[oO][1], i2 = iS4[oO][2], i3 = iS4[oO][3]; + + for (iRow = iFirstRow; iRow < cHeight; iRow += 2) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> 1]; iColumn < cWidth; iColumn += 2) { + iIdx = ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7]; + u = ((pU[iIdx] + iBias) >> iShift), v = ((pV[iIdx] + iBias) >> iShift); + + y0 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift); + y1 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] + iBias) >> iShift); + y2 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow + 1][iColumn & 15]] + iBias) >> iShift); + y3 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow + 1][(iColumn + 1) & 15]] + iBias) >> iShift); + + pDst = (U8*)pSC->WMIBI.pv + pOffsetX[iColumn >> 1] + iY; + if ((y0 | y1 | y2 | y3 | u | v) & ~0xff) + pDst[i0] = _CLIP8(y0), pDst[i1] = _CLIP8(y1), pDst[i2] = _CLIP8(y2), pDst[i3] = _CLIP8(y3), pDst[4] = _CLIP8(u), pDst[5] = _CLIP8(v); + else + pDst[i0] = (U8)y0, pDst[i1] = (U8)y1, pDst[i2] = (U8)y2, pDst[i3] = (U8)y3, pDst[4] = (U8)u, pDst[5] = (U8)v; + } + } + } + break; + + case CMYK: + { + PixelI c, m, y, k; + PixelI* pK = pSC->a0MBbuffer[3]; + + for (iRow = iFirstRow; iRow < cHeight; iRow++) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; + + m = -pY[iIdx] + iBias1, c = pU[iIdx], y = -pV[iIdx], k = pK[iIdx] + iBias2; + + _ICC_CMYK(c, m, y, k); // color conversion + + c >>= iShift, m >>= iShift, y >>= iShift, k >>= iShift; + + pDst = (U8*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; + if ((c | m | y | k) & ~0xff) + pDst[0] = _CLIP8(c), pDst[1] = _CLIP8(m), pDst[2] = _CLIP8(y), pDst[3] = _CLIP8(k); + else + pDst[0] = (U8)c, pDst[1] = (U8)m, pDst[2] = (U8)y, pDst[3] = (U8)k; + } + } + } + break; + + case CF_RGBE: + { + PixelI r, g, b; + + for (iRow = iFirstRow; iRow < cHeight; iRow++) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; + + g = pY[iIdx] + iBias2, r = -pU[iIdx], b = pV[iIdx]; + + _ICC(r, g, b); + + pDst = (U8*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; + + inverseConvertRGBE(r >> iShift, g >> iShift, b >> iShift, pDst, pDst + 1, pDst + 2, pDst + 3); + } + } + } + break; + + default: + assert(0); + break; + } + } + else if (bd == BD_16) { + const PixelI iBias = (((1 << 15) >> nLen) << iShift) + (iShift == 0 ? 0 : (1 << (iShift - 1))); + U16* pDst; + + switch (cfExt) { + case CF_RGB: + { + PixelI r, g, b; + if (pSC->m_param.bScaledArith == FALSE) { + for (iRow = iFirstRow; iRow < cHeight; iRow++) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; + + g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; + + _ICC(r, g, b); + + g <<= nLen, b <<= nLen, r <<= nLen; + + pDst = (U16*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; + + if ((g | b | r) & ~0xffff) + pDst[0] = _CLIPU16(r), pDst[1] = _CLIPU16(g), pDst[2] = _CLIPU16(b); + else + pDst[0] = (U16)r, pDst[1] = (U16)g, pDst[2] = (U16)b; + } + } + else { + for (iRow = iFirstRow; iRow < cHeight; iRow++) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; + + g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; + + _ICC(r, g, b); + + g = (g >> iShift) << nLen, b = (b >> iShift) << nLen, r = (r >> iShift) << nLen; + pDst = (U16*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; + if ((g | b | r) & ~0xffff) + pDst[0] = _CLIPU16(r), pDst[1] = _CLIPU16(g), pDst[2] = _CLIPU16(b); + else + pDst[0] = (U16)r, pDst[1] = (U16)g, pDst[2] = (U16)b; + } + } + break; + } + + case Y_ONLY: + case YUV_444: + case NCOMPONENT: + outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias); + break; + + case YUV_422: + { + PixelI y0, y1, u, v; + const ORIENTATION oO = pSC->WMII.oOrientation; + const size_t i0 = ((oO == O_FLIPH || oO == O_FLIPVH || oO == O_RCW_FLIPV || oO == O_RCW_FLIPVH) ? 1 : 0), i1 = 1 - i0; + + for (iRow = iFirstRow; iRow < cHeight; iRow++) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn += 2) { + iIdx = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7]; + u = ((pU[iIdx] + iBias) >> iShift) << nLen, v = ((pV[iIdx] + iBias) >> iShift) << nLen; + + y0 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift) << nLen; + y1 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] + iBias) >> iShift) << nLen; + + pDst = (U16*)pSC->WMIBI.pv + pOffsetX[iColumn >> 1] + iY; + if ((y0 | y1 | u | v) & ~0xffff) + { + pDst[i0] = _CLIPU16(u); + pDst[i1] = _CLIPU16(y0); + pDst[2] = _CLIPU16(v); + pDst[3] = _CLIPU16(y1); + } + else + { + pDst[i0] = (U16)(u); + pDst[i1] = (U16)(y0); + pDst[2] = (U16)(v); + pDst[3] = (U16)(y1); + } + } + } + } + break; + + case YUV_420: + { + PixelI y0, y1, y2, y3, u, v; + const size_t iS4[8][4] = { {0, 1, 2, 3}, {2, 3, 0, 1}, {1, 0, 3, 2}, {3, 2, 1, 0}, {1, 3, 0, 2}, {3, 1, 2, 0}, {0, 2, 1, 3}, {2, 0, 3, 1} }; + const ORIENTATION oO = pSC->WMII.oOrientation; + const size_t i0 = iS4[oO][0], i1 = iS4[oO][1], i2 = iS4[oO][2], i3 = iS4[oO][3]; + + for (iRow = iFirstRow; iRow < cHeight; iRow += 2) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> 1]; iColumn < cWidth; iColumn += 2) { + iIdx = ((iColumn >> 3) << 6) + idxCC[iRow][(iColumn >> 1) & 7]; + u = ((pU[iIdx] + iBias) >> iShift) << nLen, v = ((pV[iIdx] + iBias) >> iShift) << nLen; + + y0 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift) << nLen; + y1 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] + iBias) >> iShift) << nLen; + y2 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow + 1][iColumn & 15]] + iBias) >> iShift) << nLen; + y3 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow + 1][(iColumn + 1) & 15]] + iBias) >> iShift) << nLen; + + pDst = (U16*)pSC->WMIBI.pv + pOffsetX[iColumn >> 1] + iY; + if ((y0 | y1 | y2 | y3 | u | v) & ~0xffff) + { + pDst[i0] = _CLIPU16(y0); + pDst[i1] = _CLIPU16(y1); + pDst[i2] = _CLIPU16(y2); + pDst[i3] = _CLIPU16(y3); + pDst[4] = _CLIPU16(u); + pDst[5] = _CLIPU16(v); + } + else + { + pDst[i0] = (U16)(y0); + pDst[i1] = (U16)(y1); + pDst[i2] = (U16)(y2); + pDst[i3] = (U16)(y3); + pDst[4] = (U16)(u); + pDst[5] = (U16)(v); + } + } + } + } + break; + + case CMYK: + { + PixelI c, m, y, k; + PixelI* pK = pSC->a0MBbuffer[3]; + const PixelI iBias1 = (32768 >> nLen) << iShift; + const PixelI iBias2 = iBias - iBias1; + + for (iRow = iFirstRow; iRow < cHeight; iRow++) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; + + m = -pY[iIdx] + iBias1, c = pU[iIdx], y = -pV[iIdx], k = pK[iIdx] + iBias2; + + _ICC_CMYK(c, m, y, k); // color conversion + + c = (c >> iShift) << nLen, m = (m >> iShift) << nLen, y = (y >> iShift) << nLen, k = (k >> iShift) << nLen; + + pDst = (U16*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; + if ((c | m | y | k) & ~0xffff) + pDst[0] = _CLIPU16(c), pDst[1] = _CLIPU16(m), pDst[2] = _CLIPU16(y), pDst[3] = _CLIPU16(k); + else + pDst[0] = (U16)(c), pDst[1] = (U16)(m), pDst[2] = (U16)(y), pDst[3] = (U16)(k); + } + } + } + break; + default: + assert(0); + break; + } + } + else if (bd == BD_16S) { + const PixelI iBias = pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0; + I16* pDst; + + switch (cfExt) { + case CF_RGB: + { + PixelI r, g, b; + + for (iRow = iFirstRow; iRow < cHeight; iRow++) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; + + g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; + + _ICC(r, g, b); + + r = (r >> iShift) << nLen, g = (g >> iShift) << nLen, b = (b >> iShift) << nLen; + + pDst = (I16*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; + pDst[0] = _CLIP16(r), pDst[1] = _CLIP16(g), pDst[2] = _CLIP16(b); + } + break; + } + + case Y_ONLY: + case YUV_444: + case NCOMPONENT: + outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias); + break; + + case CMYK: + { + PixelI c, m, y, k; + PixelI* pK = pSC->a0MBbuffer[3]; + + for (iRow = iFirstRow; iRow < cHeight; iRow++) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; + + m = -pY[iIdx], c = pU[iIdx], y = -pV[iIdx], k = pK[iIdx] + iBias; + + _ICC_CMYK(c, m, y, k); // color conversion + + c = (c >> iShift) << nLen, m = (m >> iShift) << nLen, y = (y >> iShift) << nLen, k = (k >> iShift) << nLen; + + pDst = (I16*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; + pDst[0] = (I16)(c), pDst[1] = (I16)(m), pDst[2] = (I16)(y), pDst[3] = (I16)(k); + } + } + } + break; + + default: + assert(0); + break; + } + } + else if (bd == BD_16F) { + const PixelI iBias = pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0; + U16* pDst; + + switch (cfExt) + { + case CF_RGB: + { + PixelI r, g, b; + + for (iRow = iFirstRow; iRow < cHeight; iRow++) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; + + g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; + + _ICC(r, g, b); + + pDst = (U16*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; + pDst[0] = backwardHalf(r >> iShift); + pDst[1] = backwardHalf(g >> iShift); + pDst[2] = backwardHalf(b >> iShift); + } + } + break; + } + + case Y_ONLY: + case YUV_444: + case NCOMPONENT: + outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias); + break; + + default: + assert(0); + break; + } + } + else if (bd == BD_32) { + const PixelI iBias = (((1 << 31) >> nLen) << iShift) + (iShift == 0 ? 0 : (1 << (iShift - 1))); + U32* pDst; + + switch (cfExt) + { + case CF_RGB: + { + PixelI r, g, b; + + for (iRow = iFirstRow; iRow < cHeight; iRow++) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; + + g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; + + _ICC(r, g, b); + + pDst = (U32*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; + pDst[0] = ((r >> iShift) << nLen); + pDst[1] = ((g >> iShift) << nLen); + pDst[2] = ((b >> iShift) << nLen); + } + } + } + break; + + case Y_ONLY: + case YUV_444: + case NCOMPONENT: + { + outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias); + break; + } + default: + assert(0); + break; + } + } + else if (bd == BD_32S) { + const PixelI iBias = pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0; + int* pDst; + + switch (cfExt) + { + case CF_RGB: + { + PixelI r, g, b; + + for (iRow = iFirstRow; iRow < cHeight; iRow++) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; + + g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; + + _ICC(r, g, b); + + pDst = (int*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; + pDst[0] = ((r >> iShift) << nLen); + pDst[1] = ((g >> iShift) << nLen); + pDst[2] = ((b >> iShift) << nLen); + } + } + break; + } + + case Y_ONLY: + case YUV_444: + case NCOMPONENT: + outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias); + break; + + default: + assert(0); + break; + } + } + else if (bd == BD_32F) { + const PixelI iBias = pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0; + float* pDst; + + switch (cfExt) + { + case CF_RGB: + { + PixelI r, g, b; + + for (iRow = iFirstRow; iRow < cHeight; iRow++) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; + + g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; + + _ICC(r, g, b); + + pDst = (float*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; + pDst[0] = pixel2float(r >> iShift, nExpBias, nLen); + pDst[1] = pixel2float(g >> iShift, nExpBias, nLen); + pDst[2] = pixel2float(b >> iShift, nExpBias, nLen); + } + } + break; + } + case Y_ONLY: + case YUV_444: + case NCOMPONENT: + outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias); + break; + + default: + assert(0); + break; + } + } + else if (bd == BD_5) { + const PixelI iBias = (16 << iShift) + (pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0); + PixelI r, g, b; + U16* pDst; + + assert(cfExt == CF_RGB); + + for (iRow = iFirstRow; iRow < cHeight; iRow++) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; + + g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; + + _ICC(r, g, b); + + g >>= iShift, b >>= iShift, r >>= iShift; + pDst = (U16*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; + if (pSC->m_param.bRBSwapped) + pDst[0] = (U16)_CLIP2(0, b, 31) + (((U16)_CLIP2(0, g, 31)) << 5) + (((U16)_CLIP2(0, r, 31)) << 10); + else + pDst[0] = (U16)_CLIP2(0, r, 31) + (((U16)_CLIP2(0, g, 31)) << 5) + (((U16)_CLIP2(0, b, 31)) << 10); + } + } + else if (bd == BD_565) { + const PixelI iBias = (32 << iShift) + (pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0); + PixelI r, g, b; + U16* pDst; + + assert(cfExt == CF_RGB); + + for (iRow = iFirstRow; iRow < cHeight; iRow++) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; + + g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; + + _ICC(r, g, b); + + g >>= iShift, b >>= iShift + 1, r >>= iShift + 1; + pDst = (U16*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; + if (pSC->m_param.bRBSwapped) + pDst[0] = (U16)_CLIP2(0, b, 31) + (((U16)_CLIP2(0, g, 63)) << 5) + (((U16)_CLIP2(0, r, 31)) << 11); + else + pDst[0] = (U16)_CLIP2(0, r, 31) + (((U16)_CLIP2(0, g, 63)) << 5) + (((U16)_CLIP2(0, b, 31)) << 11); + } + } + else if (bd == BD_10) { + const PixelI iBias = (512 << iShift) + (pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0); + PixelI r, g, b; + U32* pDst; + + assert(cfExt == CF_RGB); + + for (iRow = iFirstRow; iRow < cHeight; iRow++) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++) { + iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; + + g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; + + _ICC(r, g, b); + + g >>= iShift, b >>= iShift, r >>= iShift; + + pDst = (U32*)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; + if (pSC->m_param.bRBSwapped) + pDst[0] = (U32)_CLIP2(0, b, 1023) + + (((U32)_CLIP2(0, g, 1023)) << 10) + + (((U32)_CLIP2(0, r, 1023)) << 20); + else + pDst[0] = (U32)_CLIP2(0, r, 1023) + + (((U32)_CLIP2(0, g, 1023)) << 10) + + (((U32)_CLIP2(0, b, 1023)) << 20); + } + } + else if (bd == BD_1) { + const size_t iPos = pSC->WMII.cLeadingPadding; + const Int iTh = (iShift > 0) ? (1 << (iShift - 1)) : 1; + assert(cfExt == Y_ONLY && pSC->m_param.cfColorFormat == Y_ONLY); + + if (pSC->WMII.oOrientation < O_RCW) + for (iRow = iFirstRow; iRow < cHeight; iRow++) { + iY = pOffsetY[iRow] + iPos; + for (iColumn = iFirstColumn; iColumn < cWidth; iColumn++) { + U8 cByte = ((U8*)pSC->WMIBI.pv + (pOffsetX[iColumn] >> 3) + iY)[0]; + U8 cShift = (U8)(7 - (pOffsetX[iColumn] & 7)); + ((U8*)pSC->WMIBI.pv + (pOffsetX[iColumn] >> 3) + iY)[0] ^= // exor is used because we can't assume the byte was originally zero + (((pSC->WMISCP.bBlackWhite + (pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] >= iTh) + + (cByte >> cShift)) & 0x1) << cShift); + } + } + else + for (iRow = iFirstRow; iRow < cHeight; iRow++) { + iY = pOffsetY[iRow] + iPos; + for (iColumn = iFirstColumn; iColumn < cWidth; iColumn++) { + U8 cByte = ((U8*)pSC->WMIBI.pv + pOffsetX[iColumn] + (iY >> 3))[0]; + U8 cShift = (U8)(7 - (iY & 7)); // should be optimized out + ((U8*)pSC->WMIBI.pv + pOffsetX[iColumn] + (iY >> 3))[0] ^= // exor is used because we can't assume the byte was originally zero + (((pSC->WMISCP.bBlackWhite + (pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] >= iTh) + + (cByte >> cShift)) & 0x1) << cShift); + } + } + } + + if (pSC->WMISCP.uAlphaMode > 0) + if (outputMBRowAlpha(pSC) != ICERR_OK) + return ICERR_ERROR; + +#ifdef REENTRANT_MODE + pSC->WMIBI.cLinesDecoded = cHeight - iFirstRow; + + if (CF_RGB == pSC->WMII.cfColorFormat && Y_ONLY == pSC->WMISCP.cfColorFormat) + { + const CWMImageInfo* pII = &pSC->WMII; + +#define fixupFullSize(type, nCh) \ +for(iRow = iFirstRow; iRow < cHeight; iRow ++) {\ + size_t iOffsetY;\ + for(iColumn = iFirstColumn, iOffsetY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){\ + type *pT = (type*)(U8 *)pSC->WMIBI.pv + iOffsetY + pOffsetX[iColumn];\ + pT[2] = pT[1] = pT[0]; \ + pT += nCh; \ + } \ +} \ +break + + switch (pII->bdBitDepth) + { + case BD_8: + fixupFullSize(U8, (pII->cBitsPerUnit >> 3)); + break; + + case BD_16: + case BD_16S: + case BD_16F: + fixupFullSize(U16, (pII->cBitsPerUnit >> 3) / sizeof(U16)); + break; + + case BD_32: + case BD_32S: + case BD_32F: + fixupFullSize(U32, (pII->cBitsPerUnit >> 3) / sizeof(float)); + break; + + case BD_5: + case BD_10: + case BD_565: + default: + break; + } + } +#endif + + return ICERR_OK; +} + +// Y_ONLY/CF_ALPHA/YUV_444/N_CHANNEL thumbnail decode +Void outputNChannelThumbnail(CWMImageStrCodec* pSC, const PixelI cMul, const size_t rShiftY, size_t iFirstRow, size_t iFirstColumn) +{ + const size_t tScale = pSC->m_Dparam->cThumbnailScale; + const size_t cWidth = (pSC->m_Dparam->cROIRightX + 1); + const size_t cHeight = min((pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16); + const size_t cChannel = pSC->WMISCP.cChannel; + const U8 nLen = pSC->WMISCP.nLenMantissaOrShift; + const I8 nExpBias = pSC->WMISCP.nExpBias; + size_t nBits = 0; + PixelI iOffset; + PixelI* pChannel[16]; + size_t iChannel, iRow, iColumn; + size_t* pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * 16 / tScale, iY; + + while ((size_t)(1U << nBits) < tScale) + nBits++; + + assert(cChannel <= 16); + + for (iChannel = 0; iChannel < cChannel; iChannel++) + pChannel[iChannel & 15] = pSC->a0MBbuffer[iChannel]; + + if (pSC->m_bUVResolutionChange) + pChannel[1] = pSC->pResU, pChannel[2] = pSC->pResV; + + switch (pSC->WMII.bdBitDepth) { + case BD_8: + for (iOffset = (128 << rShiftY) / cMul, iRow = iFirstRow; iRow < cHeight; iRow += tScale) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + U8* pDst = (U8*)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits]; + + for (iChannel = 0; iChannel < cChannel; iChannel++) { + PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iOffset) * cMul) >> rShiftY; + + pDst[iChannel] = _CLIP8(p); + } + } + } + break; + + case BD_16: + for (iOffset = (32768 << rShiftY) / cMul, iRow = iFirstRow; iRow < cHeight; iRow += tScale) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + U16* pDst = (U16*)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits]; + + for (iChannel = 0; iChannel < cChannel; iChannel++) { + PixelI p = (((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iOffset) * cMul) >> rShiftY) << nLen; + + pDst[iChannel] = _CLIPU16(p); + } + } + } + break; + + case BD_16S: + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + I16* pDst = (I16*)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits]; + + for (iChannel = 0; iChannel < cChannel; iChannel++) { + PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] * cMul) >> rShiftY) << nLen; + + pDst[iChannel] = _CLIP16(p); + } + } + } + break; + + case BD_16F: + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + U16* pDst = (U16*)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits]; + + for (iChannel = 0; iChannel < cChannel; iChannel++) { + PixelI p = (pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] * cMul) >> rShiftY; + + pDst[iChannel] = backwardHalf(p); + } + } + } + break; + case BD_32: + for (iOffset = (((1 << 31) >> nLen) << rShiftY) / cMul, iRow = iFirstRow; iRow < cHeight; iRow += tScale) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + U32* pDst = (U32*)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits]; + + for (iChannel = 0; iChannel < cChannel; iChannel++) { + PixelI p = (((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iOffset) * cMul) >> rShiftY) << nLen; + + pDst[iChannel] = (U32)(p); + } + } + } + break; + case BD_32S: + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + I32* pDst = (I32*)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits]; + + for (iChannel = 0; iChannel < cChannel; iChannel++) { + PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] * cMul) >> rShiftY) << nLen; + + pDst[iChannel] = (I32)(p); + } + } + } + break; + case BD_32F: + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + float* pDst = (float*)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits]; + + for (iChannel = 0; iChannel < cChannel; iChannel++) { + PixelI p = (pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] * cMul) >> rShiftY; + + pDst[iChannel] = pixel2float(p, nExpBias, nLen); + } + } + } + break; + + default: + assert(0); + break; + } +} + +// centralized alpha channel thumbnail, small perf penalty +Int decodeThumbnailAlpha(CWMImageStrCodec* pSC, const size_t nBits, const PixelI cMul, const size_t rShiftY) +{ + if (pSC->m_bSecondary == FALSE && pSC->m_pNextSC != NULL) { // with alpha channel + const size_t tScale = (size_t)(1U << nBits); + const size_t cHeight = min((pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16); + const size_t cWidth = (pSC->m_Dparam->cROIRightX + 1); + const size_t iFirstRow = ((((pSC->cRow - 1) * 16 > pSC->m_Dparam->cROITopY ? 0 : (pSC->m_Dparam->cROITopY & 0xf)) + tScale - 1) / tScale * tScale); + const size_t iFirstColumn = (pSC->m_Dparam->cROILeftX + tScale - 1) / tScale * tScale; + const size_t iAlphaPos = pSC->WMII.cLeadingPadding + (pSC->WMII.cfColorFormat == CMYK ? 4 : 3);//only RGB and CMYK may have interleaved alpha + const BITDEPTH_BITS bd = pSC->WMII.bdBitDepth; + const PixelI* pSrc = pSC->m_pNextSC->a0MBbuffer[0]; + const U8 nLen = pSC->m_pNextSC->WMISCP.nLenMantissaOrShift; + const I8 nExpBias = pSC->m_pNextSC->WMISCP.nExpBias; + size_t iRow, iColumn; + size_t* pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * 16 / tScale, iY; + + if (CF_RGB != pSC->WMII.cfColorFormat && CMYK != pSC->WMII.cfColorFormat) + return ICERR_ERROR; + + if (bd == BD_8) { + const PixelI offset = (128 << rShiftY) / cMul; + + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + PixelI a = ((pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + offset) * cMul) >> rShiftY; + + ((U8*)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = _CLIP8(a); + } + } + else if (bd == BD_16) { + const PixelI offset = (32768 << rShiftY) / cMul; + + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + PixelI a = (((pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + offset) * cMul) >> rShiftY) << nLen; + + ((U16*)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = _CLIPU16(a); + } + } + else if (bd == BD_16S) { + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + PixelI a = ((pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] * cMul) >> rShiftY) << nLen; + + ((I16*)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = _CLIP16(a); + } + } + else if (bd == BD_16F) { + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + PixelI a = (pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] * cMul) >> rShiftY; + + ((U16*)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = backwardHalf(a); + } + } + else if (bd == BD_32S) { + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + PixelI a = ((pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] * cMul) >> rShiftY) << nLen; + + ((I32*)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = a; + } + } + else if (bd == BD_32F) { + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + PixelI a = (pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] * cMul) >> rShiftY; + + ((float*)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = pixel2float(a, nExpBias, nLen); + } + } + else // not supported + return ICERR_ERROR; + } + + return ICERR_OK; +} + +Int decodeThumbnail(CWMImageStrCodec* pSC) +{ + const size_t tScale = pSC->m_Dparam->cThumbnailScale; + const size_t cHeight = min((pSC->m_Dparam->bDecodeFullFrame ? pSC->WMII.cHeight : pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16); + const size_t cWidth = (pSC->m_Dparam->bDecodeFullFrame ? pSC->WMII.cWidth : pSC->m_Dparam->cROIRightX + 1); + const size_t iFirstRow = ((((pSC->cRow - 1) * 16 > pSC->m_Dparam->cROITopY ? 0 : (pSC->m_Dparam->cROITopY & 0xf)) + tScale - 1) / tScale * tScale); + const size_t iFirstColumn = (pSC->m_Dparam->cROILeftX + tScale - 1) / tScale * tScale; + const COLORFORMAT cfInt = pSC->m_param.cfColorFormat; + const COLORFORMAT cfExt = (pSC->m_param.cfColorFormat == Y_ONLY ? Y_ONLY : pSC->WMII.cfColorFormat); + const BITDEPTH_BITS bd = pSC->WMII.bdBitDepth; + const OVERLAP ol = pSC->WMISCP.olOverlap; + const size_t iB = (pSC->WMII.bRGB ? 2 : 0); + const size_t iR = 2 - iB; + + const U8 nLen = pSC->WMISCP.nLenMantissaOrShift; + const I8 nExpBias = pSC->WMISCP.nExpBias; + PixelI offset; + size_t iRow, iColumn, iIdx1, iIdx2, iIdx3 = 0, nBits = 0; + PixelI* pSrcY = pSC->a0MBbuffer[0]; + PixelI* pSrcU = pSC->a0MBbuffer[1], * pSrcV = pSC->a0MBbuffer[2]; + size_t* pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * 16 / tScale, iY; + const PixelI cMul = (tScale >= 16 ? (ol == OL_NONE ? 16 : (ol == OL_ONE ? 23 : 34)) : (tScale >= 4 ? (ol == OL_NONE ? 64 : 93) : 258)); + const size_t rShiftY = 8 + (pSC->m_param.bScaledArith ? (SHIFTZERO + QPFRACBITS) : 0); + const size_t rShiftUV = rShiftY - ((pSC->m_param.bScaledArith && tScale >= 16) ? ((cfInt == YUV_420 || cfInt == YUV_422) ? 2 : 1) : 0); + + while ((size_t)(1U << nBits) < tScale) + nBits++; + + assert(tScale == (size_t)(1U << nBits)); + + // guard output buffer + if (checkImageBuffer(pSC, pSC->WMII.oOrientation < O_RCW ? pSC->WMII.cROIWidth : pSC->WMII.cROIHeight, (cHeight - iFirstRow) / pSC->m_Dparam->cThumbnailScale) != ICERR_OK) + return ICERR_ERROR; + + if ((((pSC->cRow - 1) * 16) % tScale) != 0) + return ICERR_OK; + + if (pSC->cRow * 16 <= pSC->m_Dparam->cROITopY || pSC->cRow * 16 > pSC->m_Dparam->cROIBottomY + 16) + return ICERR_OK; + + if ((cfInt == YUV_422 || cfInt == YUV_420) && cfExt != Y_ONLY) { + PixelI* pDstU = pSC->pResU, * pDstV = pSC->pResV; + + for (iRow = 0; iRow < 16; iRow += tScale) { + for (iColumn = 0; iColumn < cWidth; iColumn += tScale) { + iIdx1 = (cfInt == YUV_422 ? ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7] : ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7]); + iIdx2 = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; + + // copy over + pDstU[iIdx2] = pSrcU[iIdx1]; + pDstV[iIdx2] = pSrcV[iIdx1]; + } + } + + if (tScale == 4) { + if (cfInt == YUV_420) { + for (iColumn = 0; iColumn < cWidth; iColumn += 8) { + iIdx1 = ((iColumn >> 4) << 8) + idxCC[0][iColumn & 15]; + iIdx2 = ((iColumn >> 4) << 8) + idxCC[4][iColumn & 15]; + iIdx3 = ((iColumn >> 4) << 8) + idxCC[8][iColumn & 15]; + + pDstU[iIdx2] = ((pDstU[iIdx1] + pDstU[iIdx3] + 1) >> 1); + pDstV[iIdx2] = ((pDstV[iIdx1] + pDstV[iIdx3] + 1) >> 1); + + iIdx1 = ((iColumn >> 4) << 8) + idxCC[12][iColumn & 15]; + pDstU[iIdx1] = pDstU[iIdx3]; + pDstV[iIdx1] = pDstV[iIdx3]; + } + } + + for (iRow = 0; iRow < 16; iRow += 4) { + for (iColumn = 0; iColumn < cWidth - 8; iColumn += 8) { + iIdx1 = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; + iIdx2 = ((iColumn >> 4) << 8) + idxCC[iRow][(iColumn + 4) & 15]; + iIdx3 = ((iColumn >> 4) << 8) + idxCC[iRow][(iColumn + 8) & 15]; + + pDstU[iIdx2] = ((pDstU[iIdx1] + pDstU[iIdx3] + 1) >> 1); + pDstV[iIdx2] = ((pDstV[iIdx1] + pDstV[iIdx3] + 1) >> 1); + } + + iIdx2 = ((iColumn >> 4) << 8) + idxCC[iRow][(iColumn + 4) & 15]; + pDstU[iIdx2] = pDstU[iIdx3]; + pDstV[iIdx2] = pDstV[iIdx3]; + } + } + + pSrcU = pDstU, pSrcV = pDstV; + } + + if (bd == BD_8) { + U8* pDst; + + offset = (128 << rShiftY) / cMul; + + switch (cfExt) { + case CF_RGB: + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV; + + _ICC(r, g, b); + + pDst = (U8*)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; + pDst[iB] = _CLIP8(b), pDst[1] = _CLIP8(g), pDst[iR] = _CLIP8(r); + } + } + break; + + case Y_ONLY: + case YUV_444: + case NCOMPONENT: + outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn); + break; + + case CF_RGBE: + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + PixelI g = ((pSrcY[iPos] * cMul) >> rShiftY), r = -((pSrcU[iPos] * cMul) >> rShiftUV), b = ((pSrcV[iPos] * cMul) >> rShiftUV); + + _ICC(r, g, b); + + pDst = (U8*)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; + inverseConvertRGBE(r, g, b, pDst, pDst + 1, pDst + 2, pDst + 3); + } + } + break; + + case CMYK: + { + PixelI* pSrcK = pSC->a0MBbuffer[3]; + PixelI iBias1 = (128 << rShiftY) / cMul, iBias2 = (((128 << rShiftUV) / cMul) >> 1); + + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + PixelI m = ((-pSrcY[iPos] + iBias1) * cMul) >> rShiftY, c = (pSrcU[iPos] * cMul) >> rShiftUV, y = -(pSrcV[iPos] * cMul) >> rShiftUV, k = ((pSrcK[iPos] + iBias2) * cMul) >> rShiftUV; + + _ICC_CMYK(c, m, y, k); + + pDst = (U8*)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; + pDst[0] = _CLIP8(c), pDst[1] = _CLIP8(m), pDst[2] = _CLIP8(y), pDst[3] = _CLIP8(k); + } + } + break; + } + default: + assert(0); + break; + } + } + if (bd == BD_16) { + U16* pDst; + + offset = (((1 << 15) >> nLen) << rShiftY) / cMul; + + switch (cfExt) { + case CF_RGB: + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV; + + _ICC(r, g, b); + + pDst = (U16*)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; + r <<= nLen, g <<= nLen, b <<= nLen; + pDst[0] = _CLIPU16(r); + pDst[1] = _CLIPU16(g); + pDst[2] = _CLIPU16(b); + } + } + break; + + case Y_ONLY: + case YUV_444: + case NCOMPONENT: + outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn); + break; + + case CMYK: + { + PixelI* pSrcK = pSC->a0MBbuffer[3]; + PixelI iBias1 = (32768 << rShiftY) / cMul, iBias2 = (((32768 << rShiftUV) / cMul) >> 1); + + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + PixelI m = ((-pSrcY[iPos] + iBias1) * cMul) >> rShiftY, c = (pSrcU[iPos] * cMul) >> rShiftUV, y = -(pSrcV[iPos] * cMul) >> rShiftUV, k = ((pSrcK[iPos] + iBias2) * cMul) >> rShiftUV; + + _ICC_CMYK(c, m, y, k); + + pDst = (U16*)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; + c <<= nLen, m <<= nLen, y <<= nLen, k <<= nLen; + pDst[0] = _CLIPU16(c); + pDst[1] = _CLIPU16(m); + pDst[2] = _CLIPU16(y); + pDst[3] = _CLIPU16(k); + } + } + break; + } + default: + assert(0); + break; + } + } + if (bd == BD_16S) { + I16* pDst; + + switch (cfExt) { + case CF_RGB: + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + PixelI g = (pSrcY[iPos] * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV; + + _ICC(r, g, b); + + pDst = (I16*)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; + r <<= nLen, g <<= nLen, b <<= nLen; + pDst[0] = _CLIP16(r); + pDst[1] = _CLIP16(g); + pDst[2] = _CLIP16(b); + } + } + break; + + case Y_ONLY: + case YUV_444: + case NCOMPONENT: + outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn); + break; + + case CMYK: + { + PixelI* pSrcK = pSC->a0MBbuffer[3]; + + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + PixelI m = -(pSrcY[iPos] * cMul) >> rShiftY, c = (pSrcU[iPos] * cMul) >> rShiftUV, y = -(pSrcV[iPos] * cMul) >> rShiftUV, k = (pSrcK[iPos] * cMul) >> rShiftUV; + + _ICC_CMYK(c, m, y, k); + + pDst = (I16*)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; + c <<= nLen, m <<= nLen, y <<= nLen, k <<= nLen; + pDst[0] = _CLIP16(c); + pDst[1] = _CLIP16(m); + pDst[2] = _CLIP16(y); + pDst[3] = _CLIP16(k); + } + } + } + break; + + default: + assert(0); + break; + } + } + else if (bd == BD_16F) { + U16* pDst; + + switch (cfExt) { + case CF_RGB: + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + PixelI g = (pSrcY[iPos] * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV; + + _ICC(r, g, b); + + pDst = (U16*)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; + pDst[0] = backwardHalf(r); + pDst[1] = backwardHalf(g); + pDst[2] = backwardHalf(b); + } + } + break; + + case Y_ONLY: + case YUV_444: + case NCOMPONENT: + outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn); + break; + + default: + assert(0); + break; + } + } + else if (bd == BD_32) { + U32* pDst; + + offset = (((1 << 31) >> nLen) << rShiftY) / cMul; + + switch (cfExt) { + case CF_RGB: + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV; + + _ICC(r, g, b); + + pDst = (U32*)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; + + pDst[0] = (U32)(r << nLen); + pDst[1] = (U32)(g << nLen); + pDst[2] = (U32)(b << nLen); + } + } + break; + + case Y_ONLY: + case YUV_444: + case NCOMPONENT: + outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn); + break; + + default: + assert(0); + break; + } + } + else if (bd == BD_32S) { + I32* pDst; + + switch (cfExt) { + case CF_RGB: + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + PixelI g = (pSrcY[iPos] * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV; + + _ICC(r, g, b); + + pDst = (I32*)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; + pDst[0] = (I32)(r << nLen); + pDst[1] = (I32)(g << nLen); + pDst[2] = (I32)(b << nLen); + } + } + break; + + case Y_ONLY: + case YUV_444: + case NCOMPONENT: + outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn); + break; + + default: + assert(0); + break; + } + } + + else if (bd == BD_32F) { + float* pDst; + + switch (cfExt) { + case CF_RGB: + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + PixelI g = (pSrcY[iPos] * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV; + + _ICC(r, g, b); + + pDst = (float*)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; + pDst[0] = pixel2float(r, nExpBias, nLen); + pDst[1] = pixel2float(g, nExpBias, nLen); + pDst[2] = pixel2float(b, nExpBias, nLen); + } + } + break; + + case Y_ONLY: + case YUV_444: + case NCOMPONENT: + outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn); + break; + + default: + assert(0); + break; + } + } + else if (bd == BD_1) { + const size_t iPos = pSC->WMII.cLeadingPadding; + Bool bBW; + U8 cByte, cShift; + assert(cfExt == Y_ONLY && pSC->m_param.cfColorFormat == Y_ONLY); + + if (pSC->WMII.oOrientation < O_RCW) { + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits] + iPos; iColumn < cWidth; iColumn += tScale) { + bBW = (pSC->WMISCP.bBlackWhite ^ (pSrcY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] > 0)); + cByte = ((U8*)pSC->WMIBI.pv + (pOffsetX[iColumn >> nBits] >> 3) + iY)[0]; + cShift = (U8)(7 - (pOffsetX[iColumn >> nBits] & 7)); + ((U8*)pSC->WMIBI.pv + (pOffsetX[iColumn >> nBits] >> 3) + iY)[0] ^= ((((bBW + (cByte >> cShift)) & 0x1)) << cShift); + } + } + else { + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits] + iPos; iColumn < cWidth; iColumn += tScale) { + bBW = (pSC->WMISCP.bBlackWhite ^ (pSrcY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] > 0)); + cByte = ((U8*)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + (iY >> 3))[0]; + cShift = (U8)(7 - (iY & 7)); + ((U8*)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + (iY >> 3))[0] ^= ((((bBW + (cByte >> cShift)) & 0x1)) << cShift); + } + } + } + else if (bd == BD_5) { + U16* pDst; + + offset = (16 << rShiftY) / cMul; + + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV; + + _ICC(r, g, b); + pDst = (U16*)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; + pDst[0] = (U16)_CLIP2(0, r, 31) + (((U16)_CLIP2(0, g, 31)) << 5) + (((U16)_CLIP2(0, b, 31)) << 10); + } + } + } + else if (bd == BD_565) { + U16* pDst; + + offset = (32 << rShiftY) / cMul; + + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV; + + _ICC(r, g, b); + r /= 2, b /= 2; + pDst = (U16*)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; + pDst[0] = (U16)_CLIP2(0, r, 31) + (((U16)_CLIP2(0, g, 63)) << 5) + (((U16)_CLIP2(0, b, 31)) << 11); + } + } + } + else if (bd == BD_10) { + U32* pDst; + + offset = (512 << rShiftY) / cMul; + + for (iRow = iFirstRow; iRow < cHeight; iRow += tScale) { + for (iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale) { + size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV; + + _ICC(r, g, b); + pDst = (U32*)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; + pDst[0] = (U32)_CLIP2(0, r, 1023) + + (((U32)_CLIP2(0, g, 1023)) << 10) + + (((U32)_CLIP2(0, b, 1023)) << 20); + } + } + } + + if (pSC->WMISCP.uAlphaMode > 0) + if (decodeThumbnailAlpha(pSC, nBits, cMul, rShiftY) != ICERR_OK) + return ICERR_ERROR; + +#ifdef REENTRANT_MODE + pSC->WMIBI.cLinesDecoded = (cHeight - iFirstRow + tScale - 1) / tScale; + if (CF_RGB == pSC->WMII.cfColorFormat && Y_ONLY == pSC->WMISCP.cfColorFormat) + { + const CWMImageInfo* pII = &pSC->WMII; + +#define fixupThumb(type, nCh) \ +for(iRow = iFirstRow; iRow < cHeight; iRow += tScale) {\ + size_t iOffsetY;\ + for(iColumn = iFirstColumn, iOffsetY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){\ + type *pT = (type*)((U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iOffsetY);\ + pT[iB] = pT[1] = pT[iR]; \ + } \ +} \ +break + + switch (pII->bdBitDepth) + { + case BD_8: + fixupThumb(U8, (pII->cBitsPerUnit >> 3)); + break; + + case BD_16: + case BD_16S: + case BD_16F: + fixupThumb(U16, (pII->cBitsPerUnit >> 3) / sizeof(U16)); + break; + + case BD_32: + case BD_32S: + case BD_32F: + fixupThumb(U32, (pII->cBitsPerUnit >> 3) / sizeof(float)); + break; + + case BD_5: + case BD_10: + case BD_565: + default: + break; + } + } +#endif + + return ICERR_OK; +} + +/************************************************************************* + Read variable length byte aligned integer +*************************************************************************/ +static size_t GetVLWordEsc(BitIOInfo* pIO, Int* iEscape) +{ + size_t s; + + if (iEscape) + *iEscape = 0; + + s = getBit32(pIO, 8); + if (s == 0xfd || s == 0xfe || s == 0xff) { + if (iEscape) + *iEscape = (Int)s; + s = 0; + } + else if (s < 0xfb) { + s = (s << 8) | getBit32(pIO, 8); + } + else { + s -= 0xfb; + if (s) { + s = getBit32(pIO, 16) << 16; + s = (s | getBit32(pIO, 16)) << 16; + s <<= 16; + } + s |= (getBit32(pIO, 16) << 16); + s |= getBit32(pIO, 16); + } + return s; +} + +//================================================================ +Int readIndexTable(CWMImageStrCodec* pSC) +{ + BitIOInfo* pIO = pSC->pIOHeader; + readIS_L1(pSC, pIO); + + if (pSC->cNumBitIO > 0) { + size_t* pTable = pSC->pIndexTable; + U32 iEntry = (U32)pSC->cNumBitIO * (pSC->WMISCP.cNumOfSliceMinus1H + 1), i; + + // read index table header [0x0001] - 2 bytes + if (getBit32(pIO, 16) != 1) + return ICERR_ERROR; + + //iBits = getBit16(pIO, 5) + 1; // how many bits per entry + for (i = 0; i < iEntry; i++) { + readIS_L1(pSC, pIO); + pTable[i] = GetVLWordEsc(pIO, NULL); // escape handling is not important since the respective band is not accessed + } + } + + pSC->cHeaderSize = GetVLWordEsc(pIO, NULL); // escape handling is not important + flushToByte(pIO); + + pSC->cHeaderSize += getPosRead(pSC->pIOHeader); // get header length + + return ICERR_OK; +} + +Int StrIODecInit(CWMImageStrCodec* pSC) +{ + if (allocateBitIOInfo(pSC) != ICERR_OK) { + return ICERR_ERROR; + } + + attachISRead(pSC->pIOHeader, pSC->WMISCP.pWStream, pSC); + + readIndexTable(pSC); + + if (pSC->WMISCP.bVerbose) { + U32 i, j; + + printf("\n%d horizontal tiles:\n", pSC->WMISCP.cNumOfSliceMinus1H + 1); + for (i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1H; i++) { + printf(" offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileY[i]); + } + + printf("\n%d vertical tiles:\n", pSC->WMISCP.cNumOfSliceMinus1V + 1); + for (i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i++) { + printf(" offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileX[i]); + } + + if (pSC->WMISCP.bfBitstreamFormat == SPATIAL) { + printf("\nSpatial order bitstream\n"); + } + else { + printf("\nFrequency order bitstream\n"); + } + + if (!pSC->m_param.bIndexTable) { + printf("\nstreaming mode, no index table.\n"); + } + else if (pSC->WMISCP.bfBitstreamFormat == SPATIAL) { + for (j = 0; j <= pSC->WMISCP.cNumOfSliceMinus1H; j++) { + for (i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i++) { + size_t* p = &pSC->pIndexTable[j * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + i]; + if (i + j != pSC->WMISCP.cNumOfSliceMinus1H + pSC->WMISCP.cNumOfSliceMinus1V) { + printf("bitstream size for tile (%d, %d): %d.\n", j, i, (int)(p[1] - p[0])); + } + else { + printf("bitstream size for tile (%d, %d): unknown.\n", j, i); + } + } + } + } + else { + for (j = 0; j <= pSC->WMISCP.cNumOfSliceMinus1H; j++) { + for (i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i++) { + size_t* p = &pSC->pIndexTable[(j * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + i) * 4]; + if (i + j != pSC->WMISCP.cNumOfSliceMinus1H + pSC->WMISCP.cNumOfSliceMinus1V) { + printf("bitstream size of (DC, LP, AC, FL) for tile (%d, %d): %d %d %d %d.\n", j, i, + (int)(p[1] - p[0]), (int)(p[2] - p[1]), (int)(p[3] - p[2]), (int)(p[4] - p[3])); + } + else { + printf("bitstream size of (DC, LP, AC, FL) for tile (%d, %d): %d %d %d unknown.\n", j, i, + (int)(p[1] - p[0]), (int)(p[2] - p[1]), (int)(p[3] - p[2])); + } + } + } + } + } + + return 0; +} + +Int StrIODecTerm(CWMImageStrCodec* pSC) +{ + detachISRead(pSC, pSC->pIOHeader); + + free(pSC->m_ppBitIO); + free(pSC->pIndexTable); + + return 0; +} + +Int initLookupTables(CWMImageStrCodec* pSC) +{ + static const U8 cbChannels[BDB_MAX] = { 1, 1, 2, 2, 2, 4, 4, 4, (U8)-1, (U8)-1, (U8)-1 }; + + CWMImageInfo* pII = &pSC->WMII; + size_t cStrideX, cStrideY; + size_t w, h, i, iFirst = 0; + Bool bReverse; + + // lookup tables for rotation and flipping + if (pSC->m_Dparam->cThumbnailScale > 1) // thumbnail + w = pII->cThumbnailWidth, h = pII->cThumbnailHeight; + else + w = pII->cWidth, h = pII->cHeight; + w += (pSC->m_Dparam->cROILeftX + pSC->m_Dparam->cThumbnailScale - 1) / pSC->m_Dparam->cThumbnailScale; + h += (pSC->m_Dparam->cROITopY + pSC->m_Dparam->cThumbnailScale - 1) / pSC->m_Dparam->cThumbnailScale; + + switch (pII->bdBitDepth) { + case BD_16: + case BD_16S: + case BD_5: + case BD_565: + case BD_16F: + cStrideY = pSC->WMIBI.cbStride / 2; + break; + + case BD_32: + case BD_32S: + case BD_32F: + case BD_10: + cStrideY = pSC->WMIBI.cbStride / 4; + break; + + default: //BD_8, BD_1 + cStrideY = pSC->WMIBI.cbStride; + break; + } + + switch (pII->cfColorFormat) { + case YUV_420: + cStrideX = 6; + w >>= 1, h >>= 1; + break; + + case YUV_422: + cStrideX = 4; + w >>= 1; + break; + + default: + cStrideX = (pII->cBitsPerUnit >> 3) / cbChannels[pII->bdBitDepth]; + break; + } + + if (pII->bdBitDepth == BD_1 || pII->bdBitDepth == BD_5 || pII->bdBitDepth == BD_10 || pII->bdBitDepth == BD_565) + cStrideX = 1; + + if (pII->oOrientation > O_FLIPVH) // rotated !! + i = cStrideX, cStrideX = cStrideY, cStrideY = i; + + pSC->m_Dparam->pOffsetX = (size_t*)malloc(w * sizeof(size_t)); + if (pSC->m_Dparam->pOffsetX == NULL || w * sizeof(size_t) < w) + return ICERR_ERROR; + /* + consider a row in the source image. if it becomes a reversed row in the target, or a reversed (upside-down)column + in the target, we have to reverse the offsets. bReverse here tells us when this happened. + */ + bReverse = (pII->oOrientation == O_FLIPH || pII->oOrientation == O_FLIPVH || + pII->oOrientation == O_RCW_FLIPV || pII->oOrientation == O_RCW_FLIPVH); + if (!pSC->m_Dparam->bDecodeFullFrame) // take care of region decode here! + iFirst = (pSC->m_Dparam->cROILeftX + pSC->m_Dparam->cThumbnailScale - 1) / pSC->m_Dparam->cThumbnailScale; + for (i = 0; i + iFirst < w; i++) { + pSC->m_Dparam->pOffsetX[i + iFirst] = pII->cLeadingPadding + (bReverse ? (pSC->m_Dparam->bDecodeFullFrame ? w : + (pSC->m_Dparam->cROIRightX - pSC->m_Dparam->cROILeftX + pSC->m_Dparam->cThumbnailScale) / pSC->m_Dparam->cThumbnailScale / ((pII->cfColorFormat == YUV_420 || pII->cfColorFormat == YUV_422) ? 2 : 1)) - 1 - i : i) * cStrideX; + } + + pSC->m_Dparam->pOffsetY = (size_t*)malloc(h * sizeof(size_t)); + if (pSC->m_Dparam->pOffsetY == NULL || h * sizeof(size_t) < h) + return ICERR_ERROR; + /* + consider a column in the source image. if it becomes an upside-down column in the target, or a reversed row + in the target, we have to reverse the offsets. bReverse here tells us when this happened. + */ + bReverse = (pII->oOrientation == O_FLIPV || pII->oOrientation == O_FLIPVH || + pII->oOrientation == O_RCW || pII->oOrientation == O_RCW_FLIPV); + if (!pSC->m_Dparam->bDecodeFullFrame) // take care of region decode here! + iFirst = (pSC->m_Dparam->cROITopY + pSC->m_Dparam->cThumbnailScale - 1) / pSC->m_Dparam->cThumbnailScale; + for (i = 0; i + iFirst < h; i++) { + pSC->m_Dparam->pOffsetY[i + iFirst] = (bReverse ? (pSC->m_Dparam->bDecodeFullFrame ? h : + (pSC->m_Dparam->cROIBottomY - pSC->m_Dparam->cROITopY + pSC->m_Dparam->cThumbnailScale) / pSC->m_Dparam->cThumbnailScale / (pII->cfColorFormat == YUV_420 ? 2 : 1)) - 1 - i : i) * cStrideY; + } + + return ICERR_OK; +} + +Void setROI(CWMImageStrCodec* pSC) +{ + CWMImageInfo* pWMII = &pSC->WMII; + CWMIStrCodecParam* pSCP = &pSC->WMISCP; + + // inscribed image size + pWMII->cWidth -= pSC->m_param.cExtraPixelsLeft + pSC->m_param.cExtraPixelsRight; + pWMII->cHeight -= pSC->m_param.cExtraPixelsTop + pSC->m_param.cExtraPixelsBottom; + + pSC->m_Dparam->bSkipFlexbits = (pSCP->sbSubband == SB_NO_FLEXBITS); + pSC->m_Dparam->bDecodeHP = (pSCP->sbSubband == SB_ALL || pSCP->sbSubband == SB_NO_FLEXBITS); + pSC->m_Dparam->bDecodeLP = (pSCP->sbSubband != SB_DC_ONLY); + pSC->m_Dparam->cThumbnailScale = 1; + while (pSC->m_Dparam->cThumbnailScale * pWMII->cThumbnailWidth < pWMII->cWidth) + pSC->m_Dparam->cThumbnailScale <<= 1; + if (pSC->WMISCP.bfBitstreamFormat == FREQUENCY) { + if (pSC->m_Dparam->cThumbnailScale >= 4) + pSC->m_Dparam->bDecodeHP = FALSE; // no need to decode HP + if (pSC->m_Dparam->cThumbnailScale >= 16) + pSC->m_Dparam->bDecodeLP = FALSE; // only need to decode DC + } + + // original image size + pWMII->cWidth += pSC->m_param.cExtraPixelsLeft + pSC->m_param.cExtraPixelsRight; + pWMII->cHeight += pSC->m_param.cExtraPixelsTop + pSC->m_param.cExtraPixelsBottom; + + /** region decode stuff */ + pSC->m_Dparam->cROILeftX = pWMII->cROILeftX * pSC->m_Dparam->cThumbnailScale + pSC->m_param.cExtraPixelsLeft; + pSC->m_Dparam->cROIRightX = pSC->m_Dparam->cROILeftX + pWMII->cROIWidth * pSC->m_Dparam->cThumbnailScale - 1; + pSC->m_Dparam->cROITopY = pWMII->cROITopY * pSC->m_Dparam->cThumbnailScale + pSC->m_param.cExtraPixelsTop; + pSC->m_Dparam->cROIBottomY = pSC->m_Dparam->cROITopY + pWMII->cROIHeight * pSC->m_Dparam->cThumbnailScale - 1; + if (pSC->m_Dparam->cROIRightX >= pWMII->cWidth) + pSC->m_Dparam->cROIRightX = pWMII->cWidth - 1; + if (pSC->m_Dparam->cROIBottomY >= pWMII->cHeight) + pSC->m_Dparam->cROIBottomY = pWMII->cHeight - 1; + + pSC->m_Dparam->bDecodeFullFrame = (pSC->m_Dparam->cROILeftX + pSC->m_Dparam->cROITopY == 0 && + ((pSC->m_Dparam->cROIRightX + 15) / 16 >= (pWMII->cWidth + 14) / 16) && ((pSC->m_Dparam->cROIBottomY + 15) / 16 >= (pWMII->cHeight + 14) / 16)); + + pSC->m_Dparam->bDecodeFullWidth = (pSC->m_Dparam->cROILeftX == 0 && ((pSC->m_Dparam->cROIRightX + 15) / 16 >= (pWMII->cWidth + 14) / 16)); + + // inscribed image size + pWMII->cWidth -= pSC->m_param.cExtraPixelsLeft + pSC->m_param.cExtraPixelsRight; + pWMII->cHeight -= pSC->m_param.cExtraPixelsTop + pSC->m_param.cExtraPixelsBottom; + + if (pSC->WMISCP.bfBitstreamFormat == FREQUENCY && pWMII->bSkipFlexbits == TRUE) + pSC->m_Dparam->bSkipFlexbits = TRUE; + + pSC->cTileColumn = pSC->cTileRow = 0; +} + +Int StrDecInit(CWMImageStrCodec* pSC) +{ + // CWMImageInfo * pWMII = &pSC->WMII; + COLORFORMAT cfInt = pSC->m_param.cfColorFormat; + COLORFORMAT cfExt = pSC->WMII.cfColorFormat; + size_t i; + + /** color transcoding with resolution change **/ + pSC->m_bUVResolutionChange = ((cfExt != Y_ONLY) && ((cfInt == YUV_420 && cfExt != YUV_420) || + (cfInt == YUV_422 && cfExt != YUV_422))) && !pSC->WMISCP.bYUVData; + if (pSC->m_bUVResolutionChange) { + pSC->pResU = (PixelI*)malloc((cfExt == YUV_422 ? 128 : 256) * pSC->cmbWidth * sizeof(PixelI)); + pSC->pResV = (PixelI*)malloc((cfExt == YUV_422 ? 128 : 256) * pSC->cmbWidth * sizeof(PixelI)); + if (pSC->pResU == NULL || pSC->pResV == NULL || (cfExt == YUV_422 ? 128 : 256) * pSC->cmbWidth * sizeof(PixelI) < pSC->cmbWidth) { + return ICERR_ERROR; + } + } + + if (allocatePredInfo(pSC) != ICERR_OK) { + return ICERR_ERROR; + } + + if (allocateTileInfo(pSC) != ICERR_OK) + return ICERR_ERROR; + + if ((pSC->m_param.uQPMode & 1) == 0) { // DC frame uniform quantization + if (allocateQuantizer(pSC->pTile[0].pQuantizerDC, pSC->m_param.cNumChannels, 1) != ICERR_OK) + return ICERR_ERROR; + setUniformQuantizer(pSC, 0); + for (i = 0; i < pSC->m_param.cNumChannels; i++) + pSC->pTile[0].pQuantizerDC[i]->iIndex = pSC->m_param.uiQPIndexDC[i]; + formatQuantizer(pSC->pTile[0].pQuantizerDC, (pSC->m_param.uQPMode >> 3) & 3, pSC->m_param.cNumChannels, 0, TRUE, pSC->m_param.bScaledArith); + } + + if (pSC->WMISCP.sbSubband != SB_DC_ONLY) { + if ((pSC->m_param.uQPMode & 2) == 0) { // LP frame uniform quantization + if (allocateQuantizer(pSC->pTile[0].pQuantizerLP, pSC->m_param.cNumChannels, 1) != ICERR_OK) + return ICERR_ERROR; + setUniformQuantizer(pSC, 1); + if ((pSC->m_param.uQPMode & 0x200) == 0) // use DC quantizer + useDCQuantizer(pSC, 0); + else { + for (i = 0; i < pSC->m_param.cNumChannels; i++) + pSC->pTile[0].pQuantizerLP[i]->iIndex = pSC->m_param.uiQPIndexLP[i]; + formatQuantizer(pSC->pTile[0].pQuantizerLP, (pSC->m_param.uQPMode >> 5) & 3, pSC->m_param.cNumChannels, 0, TRUE, pSC->m_param.bScaledArith); + } + } + + if (pSC->WMISCP.sbSubband != SB_NO_HIGHPASS) { + if ((pSC->m_param.uQPMode & 4) == 0) { // HP frame uniform quantization + if (allocateQuantizer(pSC->pTile[0].pQuantizerHP, pSC->m_param.cNumChannels, 1) != ICERR_OK) + return ICERR_ERROR; + setUniformQuantizer(pSC, 2); + + if ((pSC->m_param.uQPMode & 0x400) == 0) // use LP quantizer + useLPQuantizer(pSC, 1, 0); + else { + for (i = 0; i < pSC->m_param.cNumChannels; i++) + pSC->pTile[0].pQuantizerHP[i]->iIndex = pSC->m_param.uiQPIndexHP[i]; + formatQuantizer(pSC->pTile[0].pQuantizerHP, (pSC->m_param.uQPMode >> 7) & 3, pSC->m_param.cNumChannels, 0, FALSE, pSC->m_param.bScaledArith); + } + } + } + } + + if (pSC->WMISCP.cNumOfSliceMinus1V >= MAX_TILES || AllocateCodingContextDec(pSC, pSC->WMISCP.cNumOfSliceMinus1V + 1) != ICERR_OK) { + return ICERR_ERROR; + } + + if (pSC->m_bSecondary) { + pSC->pIOHeader = pSC->m_pNextSC->pIOHeader; + pSC->m_ppBitIO = pSC->m_pNextSC->m_ppBitIO; + pSC->cNumBitIO = pSC->m_pNextSC->cNumBitIO; + pSC->cSB = pSC->m_pNextSC->cSB; + } + + setBitIOPointers(pSC); + + return ICERR_OK; +} + +Int StrDecTerm(CWMImageStrCodec* pSC) +{ + size_t j, jend = (pSC->m_pNextSC != NULL); + + for (j = 0; j <= jend; j++) { + if (pSC->m_bUVResolutionChange) { + if (pSC->pResU != NULL) + free(pSC->pResU); + if (pSC->pResV != NULL) + free(pSC->pResV); + } + + freePredInfo(pSC); + + freeTileInfo(pSC); + + FreeCodingContextDec(pSC); + + if (j == 0) { + StrIODecTerm(pSC); + + // free lookup tables for rotation and flipping + if (pSC->m_Dparam->pOffsetX != NULL) + free(pSC->m_Dparam->pOffsetX); + if (pSC->m_Dparam->pOffsetY != NULL) + free(pSC->m_Dparam->pOffsetY); + } + + pSC = pSC->m_pNextSC; + } + + return 0; +} + +/************************************************************************* + Read header of image plane +*************************************************************************/ +Int ReadImagePlaneHeader(CWMImageInfo* pII, CWMIStrCodecParam* pSCP, + CCoreParameters* pSC, SimpleBitIO* pSB) +{ + ERR err = WMP_errSuccess; + + pSC->cfColorFormat = getBit32_SB(pSB, 3); // internal color format + FailIf((pSC->cfColorFormat < Y_ONLY || pSC->cfColorFormat > NCOMPONENT), WMP_errUnsupportedFormat); + pSCP->cfColorFormat = pSC->cfColorFormat; // this should be removed later + pSC->bScaledArith = getBit32_SB(pSB, 1); // lossless mode + + // subbands + pSCP->sbSubband = getBit32_SB(pSB, 4); + + // color parameters + switch (pSC->cfColorFormat) { + case Y_ONLY: + pSC->cNumChannels = 1; + break; + case YUV_420: + pSC->cNumChannels = 3; + getBit32_SB(pSB, 1); + pII->cChromaCenteringX = (U8)getBit32_SB(pSB, 3); + getBit32_SB(pSB, 1); + pII->cChromaCenteringY = (U8)getBit32_SB(pSB, 3); + break; + case YUV_422: + pSC->cNumChannels = 3; + getBit32_SB(pSB, 1); + pII->cChromaCenteringX = (U8)getBit32_SB(pSB, 3); + getBit32_SB(pSB, 4); + break; + case YUV_444: + pSC->cNumChannels = 3; + getBit32_SB(pSB, 4); + getBit32_SB(pSB, 4); + break; + case NCOMPONENT: + pSC->cNumChannels = (Int)getBit32_SB(pSB, 4) + 1; + getBit32_SB(pSB, 4); + break; + case CMYK: + pSC->cNumChannels = 4; + break; + default: + break; + } + + // float and 32s additional parameters + switch (pII->bdBitDepth) { + case BD_16: + case BD_16S: + case BD_32: + case BD_32S: + pSCP->nLenMantissaOrShift = (U8)getBit32_SB(pSB, 8); + break; + case BD_32F: + pSCP->nLenMantissaOrShift = (U8)getBit32_SB(pSB, 8);//float conversion parameters + pSCP->nExpBias = (I8)getBit32_SB(pSB, 8); + break; + default: + break; + } + + // quantization + pSC->uQPMode = 0; + if (getBit32_SB(pSB, 1) == 1) // DC uniform + pSC->uQPMode += (readQuantizerSB(pSC->uiQPIndexDC, pSB, pSC->cNumChannels) << 3); + else + pSC->uQPMode++; + if (pSCP->sbSubband != SB_DC_ONLY) { + if (getBit32_SB(pSB, 1) == 0) { // don't use DC QP + pSC->uQPMode += 0x200; + if (getBit32_SB(pSB, 1) == 1) // LP uniform + pSC->uQPMode += (readQuantizerSB(pSC->uiQPIndexLP, pSB, pSC->cNumChannels) << 5); + else + pSC->uQPMode += 2; + } + else + pSC->uQPMode += ((pSC->uQPMode & 1) << 1) + ((pSC->uQPMode & 0x18) << 2); + + if (pSCP->sbSubband != SB_NO_HIGHPASS) { + if (getBit32_SB(pSB, 1) == 0) { // don't use LP QP + pSC->uQPMode += 0x400; + if (getBit32_SB(pSB, 1) == 1) // HP uniform + pSC->uQPMode += (readQuantizerSB(pSC->uiQPIndexHP, pSB, pSC->cNumChannels) << 7); + else + pSC->uQPMode += 4; + } + else + pSC->uQPMode += ((pSC->uQPMode & 2) << 1) + ((pSC->uQPMode & 0x60) << 2); + } + } + + if (pSCP->sbSubband == SB_DC_ONLY) + pSC->uQPMode |= 0x200; + else if (pSCP->sbSubband == SB_NO_HIGHPASS) + pSC->uQPMode |= 0x400; + + + FailIf((pSC->uQPMode & 0x600) == 0, WMP_errInvalidParameter); // frame level QPs must be specified independently! + + flushToByte_SB(pSB); // remove this later + +Cleanup: + return WMP_errSuccess == err ? ICERR_OK : ICERR_ERROR; +} + +/************************************************************************* + Read header of image, and header of FIRST PLANE only +*************************************************************************/ +Int ReadWMIHeader( + CWMImageInfo* pII, + CWMIStrCodecParam* pSCP, + CCoreParameters* pSC) +{ + U32 i; + ERR err = WMP_errSuccess; + Bool bTilingPresent, bInscribed, bTileStretch, bAbbreviatedHeader; + struct WMPStream* pWS = pSCP->pWStream; + + SimpleBitIO SB = { 0 }; + SimpleBitIO* pSB = &SB; + + U8 szMS[8] = { 0 }; + U32 cbStream = 0; + + // U32 bits = 0; + // Int HEADERSIZE = 0; + + assert(pSC != NULL); + //================================ +// 0 + /** signature **/ + Call(pWS->Read(pWS, szMS, sizeof(szMS))); + FailIf(szMS != (U8*)strstr((char*)szMS, "WMPHOTO"), WMP_errUnsupportedFormat); + //================================ + Call(attach_SB(pSB, pWS)); + + // 8 + /** codec version and subversion **/ + i = getBit32_SB(pSB, 4); + FailIf((i != CODEC_VERSION), WMP_errIncorrectCodecVersion); + pSC->cVersion = i; + i = getBit32_SB(pSB, 4); // subversion + FailIf((i != CODEC_SUBVERSION && + i != CODEC_SUBVERSION_NEWSCALING_SOFT_TILES && i != CODEC_SUBVERSION_NEWSCALING_HARD_TILES), + WMP_errIncorrectCodecSubVersion); + pSC->cSubVersion = i; + + pSC->bUseHardTileBoundaries = FALSE; + if (pSC->cSubVersion == CODEC_SUBVERSION_NEWSCALING_HARD_TILES) + pSC->bUseHardTileBoundaries = TRUE; + + pSCP->bUseHardTileBoundaries = pSC->bUseHardTileBoundaries; + + // 9 primary parameters + bTilingPresent = (Bool)getBit32_SB(pSB, 1); // tiling present + pSCP->bfBitstreamFormat = getBit32_SB(pSB, 1); // bitstream layout + pII->oOrientation = (ORIENTATION)getBit32_SB(pSB, 3); // presentation orientation + pSC->bIndexTable = getBit32_SB(pSB, 1); + i = getBit32_SB(pSB, 2); // overlap + FailIf((i == 3), WMP_errInvalidParameter); + pSCP->olOverlap = i; + + // 11 some other parameters + bAbbreviatedHeader = (Bool)getBit32_SB(pSB, 1); // short words for size and tiles + pSCP->bdBitDepth = (BITDEPTH)getBit32_SB(pSB, 1); // long word + pSCP->bdBitDepth = BD_LONG; // remove when optimization is done + bInscribed = (Bool)getBit32_SB(pSB, 1); // windowing + pSC->bTrimFlexbitsFlag = (Bool)getBit32_SB(pSB, 1); // trim flexbits flag + bTileStretch = (Bool)getBit32_SB(pSB, 1); // tile stretching flag + pSC->bRBSwapped = (Bool)getBit32_SB(pSB, 1); // red-blue swap flag + getBit32_SB(pSB, 1); // padding / reserved bit + pSC->bAlphaChannel = (Bool)getBit32_SB(pSB, 1); // alpha channel present + + // 10 - informational + pII->cfColorFormat = getBit32_SB(pSB, 4); // source color format + pII->bdBitDepth = getBit32_SB(pSB, 4); // source bit depth + + if (BD_1alt == pII->bdBitDepth) + { + pII->bdBitDepth = BD_1; + pSCP->bBlackWhite = 1; + } + + // 12 - Variable length fields + // size + pII->cWidth = getBit32_SB(pSB, bAbbreviatedHeader ? 16 : 32) + 1; + pII->cHeight = getBit32_SB(pSB, bAbbreviatedHeader ? 16 : 32) + 1; + pSC->cExtraPixelsTop = pSC->cExtraPixelsLeft = pSC->cExtraPixelsBottom = pSC->cExtraPixelsRight = 0; + if (bInscribed == FALSE && (pII->cWidth & 0xf) != 0) + pSC->cExtraPixelsRight = 0x10 - (pII->cWidth & 0xF); + if (bInscribed == FALSE && (pII->cHeight & 0xf) != 0) + pSC->cExtraPixelsBottom = 0x10 - (pII->cHeight & 0xF); + + // tiling + pSCP->cNumOfSliceMinus1V = pSCP->cNumOfSliceMinus1H = 0; + if (bTilingPresent) { + pSCP->cNumOfSliceMinus1V = getBit32_SB(pSB, LOG_MAX_TILES); // # of vertical slices along X axis + pSCP->cNumOfSliceMinus1H = getBit32_SB(pSB, LOG_MAX_TILES); // # of horizontal slices along Y axis + } + FailIf((pSC->bIndexTable == FALSE) && (pSCP->bfBitstreamFormat == FREQUENCY || pSCP->cNumOfSliceMinus1V + pSCP->cNumOfSliceMinus1H > 0), + WMP_errUnsupportedFormat); + + // tile sizes + pSCP->uiTileX[0] = pSCP->uiTileY[0] = 0; + for (i = 0; i < pSCP->cNumOfSliceMinus1V; i++) { // width in MB of vertical slices, not needed for last slice! + pSCP->uiTileX[i + 1] = (U32)getBit32_SB(pSB, bAbbreviatedHeader ? 8 : 16) + pSCP->uiTileX[i]; + } + for (i = 0; i < pSCP->cNumOfSliceMinus1H; i++) { // width in MB of vertical slices, not needed for last slice! + pSCP->uiTileY[i + 1] = (U32)getBit32_SB(pSB, bAbbreviatedHeader ? 8 : 16) + pSCP->uiTileY[i]; + } + if (bTileStretch) { // no handling of tile stretching enabled as of now + for (i = 0; i < (pSCP->cNumOfSliceMinus1V + 1) * (pSCP->cNumOfSliceMinus1H + 1); i++) + getBit32_SB(pSB, 8); + } + + // window due to compressed domain processing + if (bInscribed) { + pSC->cExtraPixelsTop = (U8)getBit32_SB(pSB, 6); + pSC->cExtraPixelsLeft = (U8)getBit32_SB(pSB, 6); + pSC->cExtraPixelsBottom = (U8)getBit32_SB(pSB, 6); + pSC->cExtraPixelsRight = (U8)getBit32_SB(pSB, 6); + } + + if (((pII->cWidth + pSC->cExtraPixelsLeft + pSC->cExtraPixelsRight) & 0xf) + ((pII->cHeight + pSC->cExtraPixelsTop + pSC->cExtraPixelsBottom) & 0xf) != 0) { + FailIf((pII->cWidth & 0xf) + (pII->cHeight & 0xf) + pSC->cExtraPixelsLeft + pSC->cExtraPixelsTop != 0, WMP_errInvalidParameter); + FailIf(pII->cWidth <= pSC->cExtraPixelsRight || pII->cHeight <= pSC->cExtraPixelsBottom, WMP_errInvalidParameter); + pII->cWidth -= pSC->cExtraPixelsRight, pII->cHeight -= pSC->cExtraPixelsBottom; + } + + flushToByte_SB(pSB); // redundant + + // read header of first image plane + FailIf(ReadImagePlaneHeader(pII, pSCP, pSC, pSB), WMP_errUnsupportedFormat); + + // maybe UNALIGNED!!! + + //================================ + detach_SB(pSB); + pSCP->cbStream = cbStream - getByteRead_SB(pSB); + + pSCP->uAlphaMode = (pSC->bAlphaChannel ? pSCP->uAlphaMode : 0); + pSCP->cChannel = pSC->cNumChannels; + + if ((pII->bdBitDepth == BD_5 || pII->bdBitDepth == BD_10 || pII->bdBitDepth == BD_565) && + (pSCP->cfColorFormat != YUV_444 && pSCP->cfColorFormat != YUV_422 && pSCP->cfColorFormat != YUV_420 && pSCP->cfColorFormat != Y_ONLY)) + return ICERR_ERROR; + +Cleanup: + return WMP_errSuccess == err ? ICERR_OK : ICERR_ERROR; +} + +//---------------------------------------------------------------- +// streaming api init/decode/term +EXTERN_C Int ImageStrDecGetInfo( + CWMImageInfo* pII, + CWMIStrCodecParam* pSCP) +{ + ERR err = WMP_errSuccess; + size_t cMarker; + CCoreParameters aDummy; + // mark position of start of data + Call(pSCP->pWStream->GetPos(pSCP->pWStream, &cMarker)); + Call(ReadWMIHeader(pII, pSCP, &aDummy)); + // rewind to start of data + Call(pSCP->pWStream->SetPos(pSCP->pWStream, cMarker)); + return ICERR_OK; + +Cleanup: + return ICERR_ERROR; +} + +EXTERN_C Int WMPhotoValidate( + CWMImageInfo* pII, + CWMIStrCodecParam* pSCP) +{ + CWMImageInfo cII; + CWMIStrCodecParam cSCP = *pSCP; + size_t cScale = 1; + + if (ImageStrDecGetInfo(&cII, pSCP) != ICERR_OK) + return ICERR_ERROR; + + // copy over un-overwritable ImageInfo parameters + pII->bdBitDepth = cII.bdBitDepth; + pII->cWidth = cII.cWidth; + pII->cHeight = cII.cHeight; + + if (pII->cWidth == 0 || pII->cHeight == 0) + return ICERR_ERROR; + + // copy over overwritable CodecParam parameters + pSCP->bVerbose = cSCP.bVerbose; + pSCP->cbStream = cSCP.cbStream; + pSCP->pWStream = cSCP.pWStream; + if (pSCP->uAlphaMode > 1) // something + alpha + pSCP->uAlphaMode = cSCP.uAlphaMode; // something + alpha to alpha or something transcoding! + + // validate color transcoding + if (pSCP->cfColorFormat == NCOMPONENT) + pII->cfColorFormat = NCOMPONENT; + if (pSCP->cfColorFormat == CMYK && pII->cfColorFormat != Y_ONLY && pII->cfColorFormat != CF_RGB) + pII->cfColorFormat = CMYK; + if (pSCP->cfColorFormat == YUV_422 && pII->cfColorFormat == YUV_420) + pII->cfColorFormat = YUV_422; + if (pSCP->cfColorFormat == YUV_444 && (pII->cfColorFormat == YUV_422 || pII->cfColorFormat == YUV_420)) + pII->cfColorFormat = YUV_444; + if (cII.cfColorFormat == CF_RGB && pII->cfColorFormat != Y_ONLY && + pII->cfColorFormat != NCOMPONENT) // no guarantee that number of channels will be >= 3 + pII->cfColorFormat = cII.cfColorFormat; + if (cII.cfColorFormat == CF_RGBE) + pII->cfColorFormat = CF_RGBE; + + // validate thumbnail parameters + if (pII->cThumbnailWidth == 0 || pII->cThumbnailWidth > pII->cWidth) + pII->cThumbnailWidth = pII->cWidth; + if (pII->cThumbnailHeight == 0 || pII->cThumbnailHeight > pII->cHeight) + pII->cThumbnailHeight = pII->cHeight; + if ((pII->cWidth + pII->cThumbnailWidth - 1) / pII->cThumbnailWidth != (pII->cHeight + pII->cThumbnailHeight - 1) / pII->cThumbnailHeight) { + while ((pII->cWidth + cScale - 1) / cScale > pII->cThumbnailWidth && + (pII->cHeight + cScale - 1) / cScale > pII->cThumbnailHeight && (cScale << 1)) + cScale <<= 1; + } + else { + cScale = (pII->cWidth + pII->cThumbnailWidth - 1) / pII->cThumbnailWidth; + if (cScale == 0) + cScale = 1; + } + pII->cThumbnailWidth = (pII->cWidth + cScale - 1) / cScale; + pII->cThumbnailHeight = (pII->cHeight + cScale - 1) / cScale; + + // validate region decode parameters + if (pII->cROIHeight == 0 || pII->cROIWidth == 0) { + pII->cROILeftX = pII->cROITopY = 0; + pII->cROIWidth = pII->cThumbnailWidth; + pII->cROIHeight = pII->cThumbnailHeight; + } + if (pII->cROILeftX >= pII->cThumbnailWidth) + pII->cROILeftX = 0; + if (pII->cROITopY >= pII->cThumbnailHeight) + pII->cROITopY = 0; + if (pII->cROILeftX + pII->cROIWidth > pII->cThumbnailWidth) + pII->cROIWidth = pII->cThumbnailWidth - pII->cROILeftX; + if (pII->cROITopY + pII->cROIHeight > pII->cThumbnailHeight) + pII->cROIHeight = pII->cThumbnailHeight - pII->cROITopY; + + return ICERR_OK; +} + +/************************************************************************* + Initialization of CWMImageStrCodec struct +*************************************************************************/ +static Void InitializeStrDec(CWMImageStrCodec* pSC, + const CCoreParameters* pParams, const CWMImageStrCodec* pSCIn) +{ + // copy core parameters + memcpy(&(pSC->m_param), pParams, sizeof(CCoreParameters)); + + pSC->cbStruct = sizeof(*pSC); + pSC->WMII = pSCIn->WMII; + pSC->WMISCP = pSCIn->WMISCP; + + pSC->cRow = 0; + pSC->cColumn = 0; + + pSC->cmbWidth = (pSC->WMII.cWidth + 15) / 16; + pSC->cmbHeight = (pSC->WMII.cHeight + 15) / 16; + + pSC->Load = outputMBRow; // output decoding result (ICC, etc) + pSC->Transform = pParams->cSubVersion == CODEC_SUBVERSION ? + invTransformMacroblock : invTransformMacroblock_alteredOperators_hard; + pSC->TransformCenter = pSC->Transform; + + pSC->ProcessTopLeft = processMacroblockDec; + pSC->ProcessTop = processMacroblockDec; + pSC->ProcessTopRight = processMacroblockDec; + pSC->ProcessLeft = processMacroblockDec; + pSC->ProcessCenter = processMacroblockDec; + pSC->ProcessRight = processMacroblockDec; + pSC->ProcessBottomLeft = processMacroblockDec; + pSC->ProcessBottom = processMacroblockDec; + pSC->ProcessBottomRight = processMacroblockDec; + + pSC->m_pNextSC = NULL; + pSC->m_bSecondary = FALSE; +} + +/************************************************************************* + ImageStrDecInit +*************************************************************************/ +Int ImageStrDecInit( + CWMImageInfo* pII, + CWMIStrCodecParam* pSCP, + CTXSTRCODEC* pctxSC) +{ + static size_t cbChannels[BD_MAX] = { 2, 4 }; + ERR err = WMP_errSuccess; + + size_t cbChannel = 0, cblkChroma = 0; + size_t cbMacBlockStride = 0, cbMacBlockChroma = 0, cMacBlock = 0; + + CWMImageStrCodec SC = { 0 }; + CWMImageStrCodec* pSC = NULL, * pNextSC = NULL; + char* pb = NULL; + size_t cb = 0, i; + Bool bLossyTranscoding = FALSE; + Bool bUseHardTileBoundaries = FALSE; //default is soft tile boundaries + Bool bLessThan64Bit = sizeof(void*) < 8; + + *pctxSC = NULL; + + if (WMPhotoValidate(pII, pSCP) != ICERR_OK) + return ICERR_ERROR; + + if (pSCP->sbSubband == SB_ISOLATED) // can not do anything with isolated bitstream + return ICERR_ERROR; + + //================================================ + SC.WMISCP.pWStream = pSCP->pWStream; + if (ReadWMIHeader(&SC.WMII, &SC.WMISCP, &SC.m_param) != ICERR_OK) { + return ICERR_ERROR; + } + + bUseHardTileBoundaries = SC.WMISCP.bUseHardTileBoundaries; + if (SC.WMII.cfColorFormat == CMYK && pII->cfColorFormat == CF_RGB) + bLossyTranscoding = TRUE; + if (pSCP->cfColorFormat != CMYK && (pII->cfColorFormat == CMYK)) + return ICERR_ERROR; + + //================================================ + SC.WMISCP = *pSCP; + SC.WMII = *pII; + + // original image size + SC.WMII.cWidth += SC.m_param.cExtraPixelsLeft + SC.m_param.cExtraPixelsRight; + SC.WMII.cHeight += SC.m_param.cExtraPixelsTop + SC.m_param.cExtraPixelsBottom; + pII->cROILeftX += SC.m_param.cExtraPixelsLeft; + pII->cROITopY += SC.m_param.cExtraPixelsTop; + + //================================================ + cbChannel = cbChannels[SC.WMISCP.bdBitDepth]; + cblkChroma = cblkChromas[SC.m_param.cfColorFormat]; + + cbMacBlockStride = cbChannel * 16 * 16; + cbMacBlockChroma = cbChannel * 16 * cblkChroma; + cMacBlock = (SC.WMII.cWidth + 15) / 16; + + //================================================ + cb = sizeof(*pSC) + (128 - 1) + sizeof(CWMDecoderParameters); + cb += (PACKETLENGTH * 4 - 1) + (PACKETLENGTH * 2) + sizeof(*pSC->pIOHeader); + + i = (cbMacBlockStride + cbMacBlockChroma * (SC.m_param.cNumChannels - 1)) * 2; // i <= 2^15 + if (bLessThan64Bit && ((i * (cMacBlock >> 16)) & 0xffffc000)) { + /** potential overflow - 32 bit pointers insufficient to address cache **/ + return ICERR_ERROR; + } + cb += i * cMacBlock; + + pb = malloc(cb); + if (pb == NULL) + return WMP_errOutOfMemory; + memset(pb, 0, cb); + + //================================================ + pSC = (CWMImageStrCodec*)pb; pb += sizeof(*pSC); + if (pSC == NULL) + return ICERR_ERROR; + + // Set up perf timers +/* PERFTIMER_ONLY(pSC->m_fMeasurePerf = pSCP->fMeasurePerf); + PERFTIMER_NEW(pSC->m_fMeasurePerf, &pSC->m_ptEndToEndPerf); + PERFTIMER_NEW(pSC->m_fMeasurePerf, &pSC->m_ptEncDecPerf); + PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEndToEndPerf); + PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); + PERFTIMER_COPYSTARTTIME(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf, pSC->m_ptEndToEndPerf); */ + + pSC->m_Dparam = (CWMDecoderParameters*)pb; pb += sizeof(CWMDecoderParameters); + pSC->cbChannel = cbChannel; + //pSC->cNumChannels = SC.WMISCP.cChannel; + pSC->bUseHardTileBoundaries = bUseHardTileBoundaries; + + //================================================ + InitializeStrDec(pSC, &SC.m_param, &SC); + + //================================================ + // 2 Macro Row buffers for each channel + pb = ALIGNUP(pb, 128); + for (i = 0; i < pSC->m_param.cNumChannels; i++) { + pSC->a0MBbuffer[i] = (PixelI*)pb; pb += cbMacBlockStride * pSC->cmbWidth; + pSC->a1MBbuffer[i] = (PixelI*)pb; pb += cbMacBlockStride * pSC->cmbWidth; + cbMacBlockStride = cbMacBlockChroma; + } + + //================================================ + // lay 2 aligned IO buffers just below pIO struct + pb = (char*)ALIGNUP(pb, PACKETLENGTH * 4) + PACKETLENGTH * 2; + pSC->pIOHeader = (BitIOInfo*)pb; pb += sizeof(*pSC->pIOHeader); + + // if interleaved alpha is needed + if (pSC->m_param.bAlphaChannel) { + SimpleBitIO SB = { 0 }; + cbMacBlockStride = cbChannel * 16 * 16; + + // 1. allocate new pNextSC info + //================================================ + cb = sizeof(*pNextSC) + (128 - 1) + cbMacBlockStride * cMacBlock * 2; + // if primary image is safe to allocate, alpha channel is certainly safe + pb = malloc(cb); + if (pb == NULL) + return WMP_errOutOfMemory; + memset(pb, 0, cb); + //================================================ + pNextSC = (CWMImageStrCodec*)pb; pb += sizeof(*pNextSC); + + // read plane header of second image plane + Call(attach_SB(&SB, pSCP->pWStream)); + InitializeStrDec(pNextSC, &SC.m_param, &SC); + ReadImagePlaneHeader(&pNextSC->WMII, &pNextSC->WMISCP, &pNextSC->m_param, &SB); + detach_SB(&SB); + + // 2. initialize pNextSC + if (pNextSC == NULL) + return ICERR_ERROR; + pNextSC->m_Dparam = pSC->m_Dparam; + pNextSC->cbChannel = cbChannel; + //================================================ + + // 3. initialize arrays +// InitializeStrDec(pNextSC, &SC.m_param, &SC); + pNextSC->m_param.cfColorFormat = Y_ONLY; + pNextSC->m_param.cNumChannels = 1; + pNextSC->m_param.bAlphaChannel = TRUE; + //================================================ + + // 2 Macro Row buffers for each channel + pb = ALIGNUP(pb, 128); + pNextSC->a0MBbuffer[0] = (PixelI*)pb; pb += cbMacBlockStride * pNextSC->cmbWidth; + pNextSC->a1MBbuffer[0] = (PixelI*)pb; + //================================================ + pNextSC->pIOHeader = pSC->pIOHeader; + //================================================ + + // 4. link pSC->pNextSC = pNextSC + pNextSC->m_pNextSC = pSC; + pNextSC->m_bSecondary = TRUE; + + } + else + pSC->WMISCP.uAlphaMode = 0; + + //================================================ + FailIf((StrIODecInit(pSC) != ICERR_OK), WMP_errOutOfMemory); + FailIf((StrDecInit(pSC) != ICERR_OK), WMP_errOutOfMemory); + if (pNextSC) { + // 5. StrEncInit + FailIf((StrDecInit(pNextSC) != ICERR_OK), WMP_errOutOfMemory); + } + + pSC->m_pNextSC = pNextSC; + //================================================ + *pII = pSC->WMII; + *pSCP = pSC->WMISCP; + *pctxSC = (CTXSTRCODEC)pSC; + + if (pSC->WMII.cPostProcStrength) { + initPostProc(pSC->pPostProcInfo, pSC->cmbWidth, pSC->m_param.cNumChannels); + if (pSC->m_param.bAlphaChannel) + initPostProc(pNextSC->pPostProcInfo, pNextSC->cmbWidth, pNextSC->m_param.cNumChannels); + } + +/* PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); */ + +Cleanup: + return WMP_errSuccess == err ? ICERR_OK : ICERR_ERROR; +} + +Int ImageStrDecDecode( + CTXSTRCODEC ctxSC, + const CWMImageBufferInfo* pBI +#ifdef REENTRANT_MODE + , size_t* pcDecodedLines +#endif +) +{ + CWMImageStrCodec* pSC = (CWMImageStrCodec*)ctxSC; + CWMImageStrCodec* pNextSC = pSC->m_pNextSC; + size_t cMBRow, k; + + ImageDataProc ProcessLeft, ProcessCenter, ProcessRight; + ImageDataProc Transform = NULL; + const size_t iChromaElements = (pSC->m_param.cfColorFormat == YUV_420) ? 8 * 8 + : ((pSC->m_param.cfColorFormat == YUV_422) ? 8 * 16 : 16 * 16); + + if (sizeof(*pSC) != pSC->cbStruct) + { + return ICERR_ERROR; + } + + //================================ +/* PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); */ + + pSC->WMIBI = *pBI; + +#ifdef REENTRANT_MODE + if (0 == pSC->WMIBI.uiFirstMBRow) + { + setROI(pSC); + if (pNextSC) { + pNextSC->WMIBI = pSC->WMIBI; + setROI(pNextSC); + } + } +#else + setROI(pSC); + if (pNextSC) { + pNextSC->WMIBI = pSC->WMIBI; + setROI(pNextSC); + } +#endif // REENTRANT_MODE + + // optimization flags can be defined only after ROI is set! +#if defined(WMP_OPT_SSE2) || defined(WMP_OPT_CC_DEC) || defined(WMP_OPT_TRFM_DEC) + StrDecOpt(pSC); +#endif // OPT defined + + + + cMBRow = (pSC->m_Dparam->bDecodeFullFrame ? pSC->cmbHeight : ((pSC->m_Dparam->cROIBottomY + 16) >> 4)); + +#ifdef REENTRANT_MODE + if (0 == pSC->WMIBI.uiFirstMBRow) + { + if (initLookupTables(pSC) != ICERR_OK) + return ICERR_ERROR; + if (pNextSC && initLookupTables(pNextSC) != ICERR_OK) + return ICERR_ERROR; + } +#else + if (initLookupTables(pSC) != ICERR_OK) + return ICERR_ERROR; + if (pNextSC && initLookupTables(pNextSC) != ICERR_OK) + return ICERR_ERROR; +#endif // REENTRANT_MODE + +#ifndef REENTRANT_MODE + if (pSC->WMII.bdBitDepth == BD_1) { + size_t i; + + + for (i = 0; i < pSC->WMIBI.cLine; i++) + memset(pSC->WMIBI.pv, 0, pSC->WMIBI.cbStride); + } +#endif + + //================================ + // top row +#ifdef REENTRANT_MODE +#else + pSC->cRow = 0; + ProcessLeft = pSC->ProcessTopLeft; + ProcessCenter = pSC->ProcessTop; + ProcessRight = pSC->ProcessTopRight; + Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ? + invTransformMacroblock : invTransformMacroblock_alteredOperators_hard; +#endif // REENTRANT_MODE + +#ifdef REENTRANT_MODE + for (pSC->cRow = pSC->WMIBI.uiFirstMBRow; pSC->cRow <= pSC->WMIBI.uiLastMBRow; pSC->cRow++) + { + // const COLORFORMAT cfExt = (pSC->m_param.cfColorFormat == Y_ONLY ? Y_ONLY : pSC->WMII.cfColorFormat); + + if (0 == pSC->cRow) + { + ProcessLeft = pSC->ProcessTopLeft; + ProcessCenter = pSC->ProcessTop; + ProcessRight = pSC->ProcessTopRight; + Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ? + invTransformMacroblock : invTransformMacroblock_alteredOperators_hard; + } + else if (cMBRow == pSC->cRow) + { + //================================ + // bottom row + ProcessLeft = pSC->ProcessBottomLeft; + ProcessCenter = pSC->ProcessBottom; + ProcessRight = pSC->ProcessBottomRight; + Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ? + invTransformMacroblock : invTransformMacroblock_alteredOperators_hard; + } + else { // middle rows + ProcessLeft = pSC->ProcessLeft; + ProcessCenter = pSC->ProcessCenter; + ProcessRight = pSC->ProcessRight; + Transform = pSC->TransformCenter; + } +#else + //================================ + // central rows + for (pSC->cRow = 0; pSC->cRow <= cMBRow; pSC->cRow++) + { +#endif // REENTRANT_MODE + pSC->cColumn = 0; + initMRPtr(pSC); + /** zero out the transform coefficients (pull this out to once per MB row) **/ + memset(pSC->p1MBbuffer[0], 0, sizeof(PixelI) * 16 * 16 * pSC->cmbWidth); + for (k = 1; k < pSC->m_param.cNumChannels; k++) { + memset(pSC->p1MBbuffer[k], 0, sizeof(PixelI) * iChromaElements * pSC->cmbWidth); + } + if (pSC->m_pNextSC != NULL) { // alpha channel + memset(pSC->m_pNextSC->p1MBbuffer[0], 0, sizeof(PixelI) * 16 * 16 * pSC->m_pNextSC->cmbWidth); + } + + if (ProcessLeft(pSC) != ICERR_OK) + return ICERR_ERROR; + advanceMRPtr(pSC); + + pSC->Transform = Transform; + for (pSC->cColumn = 1; pSC->cColumn < pSC->cmbWidth; ++pSC->cColumn) + { + if (ProcessCenter(pSC) != ICERR_OK) + return ICERR_ERROR; + advanceMRPtr(pSC); + } + pSC->Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ? + invTransformMacroblock : invTransformMacroblock_alteredOperators_hard; + + if (ProcessRight(pSC) != ICERR_OK) + return ICERR_ERROR; + + if (pSC->cRow) { + if (pSC->m_Dparam->cThumbnailScale < 2 && (pSC->m_Dparam->bDecodeFullFrame || + ((pSC->cRow * 16 > pSC->m_Dparam->cROITopY) && (pSC->cRow * 16 <= pSC->m_Dparam->cROIBottomY + 16)))) { + if (pSC->Load(pSC) != ICERR_OK) // bypass CC for thumbnail decode + return ICERR_ERROR; + } + + if (pSC->m_Dparam->cThumbnailScale >= 2) // decode thumbnail + decodeThumbnail(pSC); + } + + advanceOneMBRow(pSC); + swapMRPtr(pSC); +#ifdef REENTRANT_MODE + * pcDecodedLines = pSC->WMIBI.cLinesDecoded; +#else + if (pSC->cRow == cMBRow - 1) { + //================================ + // bottom row + ProcessLeft = pSC->ProcessBottomLeft; + ProcessCenter = pSC->ProcessBottom; + ProcessRight = pSC->ProcessBottomRight; + Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ? + invTransformMacroblock : invTransformMacroblock_alteredOperators_hard; + } + else { + ProcessLeft = pSC->ProcessLeft; + ProcessCenter = pSC->ProcessCenter; + ProcessRight = pSC->ProcessRight; + Transform = pSC->TransformCenter; + } +#endif // REENTRANT_MODE + } + +#ifndef REENTRANT_MODE + fixup_Y_ONLY_to_Others(pSC, pBI); +#endif // REENTRANT_MODE + +/* PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); */ + return ICERR_OK; + } + +Int ImageStrDecTerm( + CTXSTRCODEC ctxSC) +{ + CWMImageStrCodec* pSC = (CWMImageStrCodec*)ctxSC; + if (NULL == pSC) + { + return ICERR_OK; + } + if (sizeof(*pSC) != pSC->cbStruct) + { + return ICERR_ERROR; + } + +/* PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); */ + + StrDecTerm(pSC); +/* PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); + PERFTIMER_REPORT(pSC->m_fMeasurePerf, pSC); + PERFTIMER_DELETE(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); + PERFTIMER_DELETE(pSC->m_fMeasurePerf, pSC->m_ptEndToEndPerf); */ + + free(pSC); + + return ICERR_OK; +} + diff --git a/Src/JxrDecode/jxrlib/image/sys/common.h b/Src/JxrDecode/jxrlib/image/sys/common.h new file mode 100644 index 00000000..1ef5c1b3 --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/sys/common.h @@ -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 diff --git a/Src/JxrDecode/jxrlib/image/sys/strTransform.h b/Src/JxrDecode/jxrlib/image/sys/strTransform.h new file mode 100644 index 00000000..3ee9a64e --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/sys/strTransform.h @@ -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 diff --git a/Src/JxrDecode/jxrlib/image/sys/strcodec.c b/Src/JxrDecode/jxrlib/image/sys/strcodec.c new file mode 100644 index 00000000..e564b8fa --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/sys/strcodec.c @@ -0,0 +1,1257 @@ +//*@@@+++@@@@****************************************************************** +// +// 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 "perfTimer.h" + +#ifdef MEM_TRACE +#define TRACE_MALLOC 1 +#define TRACE_NEW 0 +#define TRACE_HEAP 0 +#include "memtrace.h" +#endif + +//================================================================ +// Quantization index tables +//================================================================ +const int blkOffset[16] = { 0, 64, 16, 80, 128, 192, 144, 208, 32, 96, 48, 112, 160, 224, 176, 240 }; +const int blkOffsetUV[4] = { 0, 32, 16, 48 }; +const int blkOffsetUV_422[8] = { 0, 64, 16, 80, 32, 96, 48, 112 }; + +const int dctIndex[3][16] = { /** permutation matrix tailored to the transform, nothing to do with ZZS **/ + {0,5,1,6, 10,12,8,14, 2,4,3,7, 9,13,11,15}, //AC 444 + {0,5,1,6, 10,12,8,14, 2,4,3,7, 9,13,11,15}, //AC 420 + {0,128,64,208, 32,240,48,224, 16,192,80,144, 112,176,96,160 }, //DC 444 +}; + +//================================================================ +// Color conversion index table +//================================================================ +const U8 idxCC[16][16] = +{ + {0x00, 0x01, 0x05, 0x04, 0x40, 0x41, 0x45, 0x44, 0x80, 0x81, 0x85, 0x84, 0xc0, 0xc1, 0xc5, 0xc4, }, + {0x02, 0x03, 0x07, 0x06, 0x42, 0x43, 0x47, 0x46, 0x82, 0x83, 0x87, 0x86, 0xc2, 0xc3, 0xc7, 0xc6, }, + {0x0a, 0x0b, 0x0f, 0x0e, 0x4a, 0x4b, 0x4f, 0x4e, 0x8a, 0x8b, 0x8f, 0x8e, 0xca, 0xcb, 0xcf, 0xce, }, + {0x08, 0x09, 0x0d, 0x0c, 0x48, 0x49, 0x4d, 0x4c, 0x88, 0x89, 0x8d, 0x8c, 0xc8, 0xc9, 0xcd, 0xcc, }, + + {0x10, 0x11, 0x15, 0x14, 0x50, 0x51, 0x55, 0x54, 0x90, 0x91, 0x95, 0x94, 0xd0, 0xd1, 0xd5, 0xd4, }, + {0x12, 0x13, 0x17, 0x16, 0x52, 0x53, 0x57, 0x56, 0x92, 0x93, 0x97, 0x96, 0xd2, 0xd3, 0xd7, 0xd6, }, + {0x1a, 0x1b, 0x1f, 0x1e, 0x5a, 0x5b, 0x5f, 0x5e, 0x9a, 0x9b, 0x9f, 0x9e, 0xda, 0xdb, 0xdf, 0xde, }, + {0x18, 0x19, 0x1d, 0x1c, 0x58, 0x59, 0x5d, 0x5c, 0x98, 0x99, 0x9d, 0x9c, 0xd8, 0xd9, 0xdd, 0xdc, }, + + {0x20, 0x21, 0x25, 0x24, 0x60, 0x61, 0x65, 0x64, 0xa0, 0xa1, 0xa5, 0xa4, 0xe0, 0xe1, 0xe5, 0xe4, }, + {0x22, 0x23, 0x27, 0x26, 0x62, 0x63, 0x67, 0x66, 0xa2, 0xa3, 0xa7, 0xa6, 0xe2, 0xe3, 0xe7, 0xe6, }, + {0x2a, 0x2b, 0x2f, 0x2e, 0x6a, 0x6b, 0x6f, 0x6e, 0xaa, 0xab, 0xaf, 0xae, 0xea, 0xeb, 0xef, 0xee, }, + {0x28, 0x29, 0x2d, 0x2c, 0x68, 0x69, 0x6d, 0x6c, 0xa8, 0xa9, 0xad, 0xac, 0xe8, 0xe9, 0xed, 0xec, }, + + {0x30, 0x31, 0x35, 0x34, 0x70, 0x71, 0x75, 0x74, 0xb0, 0xb1, 0xb5, 0xb4, 0xf0, 0xf1, 0xf5, 0xf4, }, + {0x32, 0x33, 0x37, 0x36, 0x72, 0x73, 0x77, 0x76, 0xb2, 0xb3, 0xb7, 0xb6, 0xf2, 0xf3, 0xf7, 0xf6, }, + {0x3a, 0x3b, 0x3f, 0x3e, 0x7a, 0x7b, 0x7f, 0x7e, 0xba, 0xbb, 0xbf, 0xbe, 0xfa, 0xfb, 0xff, 0xfe, }, + {0x38, 0x39, 0x3d, 0x3c, 0x78, 0x79, 0x7d, 0x7c, 0xb8, 0xb9, 0xbd, 0xbc, 0xf8, 0xf9, 0xfd, 0xfc, }, +}; + +const U8 idxCC_420[8][8] = +{ + {0x00, 0x01, 0x05, 0x04, 0x20, 0x21, 0x25, 0x24, }, + {0x02, 0x03, 0x07, 0x06, 0x22, 0x23, 0x27, 0x26, }, + {0x0a, 0x0b, 0x0f, 0x0e, 0x2a, 0x2b, 0x2f, 0x2e, }, + {0x08, 0x09, 0x0d, 0x0c, 0x28, 0x29, 0x2d, 0x2c, }, + + {0x10, 0x11, 0x15, 0x14, 0x30, 0x31, 0x35, 0x34, }, + {0x12, 0x13, 0x17, 0x16, 0x32, 0x33, 0x37, 0x36, }, + {0x1a, 0x1b, 0x1f, 0x1e, 0x3a, 0x3b, 0x3f, 0x3e, }, + {0x18, 0x19, 0x1d, 0x1c, 0x38, 0x39, 0x3d, 0x3c, }, +}; + +/************************************************************************* + gGDISignature +*************************************************************************/ +const Char gGDISignature[] = { 'W', 'M', 'P', 'H', 'O', 'T', 'O', '\0' }; + +// check if enough memory allocated for the image buffer +Int checkImageBuffer(CWMImageStrCodec* pSC, size_t cWidth, size_t cRows) +{ + const BITDEPTH_BITS bd = pSC->WMISCP.bYUVData ? + BD_32S : pSC->WMII.bdBitDepth; + const COLORFORMAT cf = pSC->WMISCP.bYUVData ? + pSC->m_param.cfColorFormat : pSC->WMII.cfColorFormat; + size_t cBytes; + Bool bLessThan64Bit = sizeof(void*) < 8; + + if (cf == YUV_420) + cRows = (cRows + 1) / 2; + if (cRows > pSC->WMIBI.cLine) + return ICERR_ERROR; + + if (cf == YUV_422 || cf == YUV_420) + cWidth = (cWidth + 1) / 2; + + if (bLessThan64Bit && (cWidth >> ((sizeof(size_t) * 8 - 5)))) { + /** potential overflow - 32 bit pointers insufficient to address cache **/ + /** this uses 2 macroblock row constraint, which is tighter than ensuring rollover doesn't occur below **/ + return ICERR_ERROR; + } + + cBytes = pSC->WMISCP.bYUVData ? cWidth * sizeof(PixelI) * + (cf == YUV_420 ? 6 : (cf == YUV_422 ? 4 : (cf == YUV_444 ? 3 : 1))) : + (bd == BD_1 ? (pSC->WMII.cBitsPerUnit * cWidth + 7) / 8 : (pSC->WMII.cBitsPerUnit + 7) / 8 * cWidth); + + return (cBytes > pSC->WMIBI.cbStride ? ICERR_ERROR : ICERR_OK); +} + +Void writeQPIndex(BitIOInfo* pIO, U8 uiIndex, U32 cBits) +{ + if (uiIndex == 0) + putBit16(pIO, 1, 1); // default QP + else { + putBit16(pIO, 0, 1); // non default QP + putBit16(pIO, uiIndex - 1, cBits); + } +} + +U8 readQPIndex(BitIOInfo* pIO, U32 cBits) +{ + if (getBit16(pIO, 1)) + return 0; // default QP + + return (U8)getBit16(pIO, cBits) + 1; +} + +Void getTilePos(CWMImageStrCodec* pSC, size_t mbX, size_t mbY) +{ + if (mbX == 0) { // left image boundary + pSC->cTileColumn = 0; + } + else if (pSC->cTileColumn < pSC->WMISCP.cNumOfSliceMinus1V && mbX == pSC->WMISCP.uiTileX[pSC->cTileColumn + 1]) { // left tile boundary + pSC->cTileColumn++; + } + + if (mbY == 0) { // top image boundary + pSC->cTileRow = 0; + } + else if (pSC->cTileRow < pSC->WMISCP.cNumOfSliceMinus1H && mbY == pSC->WMISCP.uiTileY[pSC->cTileRow + 1]) { // top tile boundary + pSC->cTileRow++; + } + + pSC->m_bCtxLeft = (mbX == pSC->WMISCP.uiTileX[pSC->cTileColumn]); + pSC->m_bCtxTop = (mbY == pSC->WMISCP.uiTileY[pSC->cTileRow]); + + pSC->m_bResetContext = pSC->m_bResetRGITotals = (((mbX - pSC->WMISCP.uiTileX[pSC->cTileColumn]) & 0xf) == 0); + if (pSC->cTileColumn == pSC->WMISCP.cNumOfSliceMinus1V) { // last tile column + if (mbX + 1 == pSC->cmbWidth) + pSC->m_bResetContext = TRUE; + } + else if (mbX + 1 == pSC->WMISCP.uiTileX[pSC->cTileColumn + 1]) + pSC->m_bResetContext = TRUE; +} + +//================================================================ +// utility functions for 2 macro block rows +//================================================================ +Void initMRPtr(CWMImageStrCodec* pSC) +{ + size_t j, jend = (pSC->m_pNextSC != NULL); + + for (j = 0; j <= jend; j++) { + memcpy(pSC->p0MBbuffer, pSC->a0MBbuffer, sizeof(pSC->p0MBbuffer)); + memcpy(pSC->p1MBbuffer, pSC->a1MBbuffer, sizeof(pSC->p1MBbuffer)); + pSC = pSC->m_pNextSC; + } +} + +Void advanceMRPtr(CWMImageStrCodec* pSC) +{ + const COLORFORMAT cf = pSC->m_param.cfColorFormat; + const int cpChroma = cblkChromas[cf] * 16; + size_t i, j, jend = (pSC->m_pNextSC != NULL); + + assert(pSC->m_bSecondary == FALSE); + for (j = 0; j <= jend; j++) { + int cpStride = 16 * 16; + for (i = 0; i < pSC->m_param.cNumChannels; i++) { + pSC->pPlane[i] = pSC->p0MBbuffer[i]; + + pSC->p0MBbuffer[i] += cpStride; + pSC->p1MBbuffer[i] += cpStride; + + cpStride = cpChroma; + } + pSC = pSC->m_pNextSC; + } +} + +/* advance to next MB row */ +Void advanceOneMBRow(CWMImageStrCodec* pSC) +{ + size_t i, j, jend = (pSC->m_pNextSC != NULL); + CWMIPredInfo* pPredInfo; + + for (j = 0; j <= jend; j++) { + for (i = 0; i < pSC->m_param.cNumChannels; i++) { // swap current row and previous row + pPredInfo = pSC->PredInfo[i]; + pSC->PredInfo[i] = pSC->PredInfoPrevRow[i]; + pSC->PredInfoPrevRow[i] = pPredInfo; + } + pSC = pSC->m_pNextSC; + } +} + +Void swapMRPtr(CWMImageStrCodec* pSC) +{ + PixelI* pTemp[MAX_CHANNELS]; + size_t j, jend = (pSC->m_pNextSC != NULL); + + for (j = 0; j <= jend; j++) { + memcpy(pTemp, pSC->a0MBbuffer, sizeof(pSC->a0MBbuffer)); + memcpy(pSC->a0MBbuffer, pSC->a1MBbuffer, sizeof(pSC->a0MBbuffer)); + memcpy(pSC->a1MBbuffer, pTemp, sizeof(pSC->a0MBbuffer)); + pSC = pSC->m_pNextSC; + } +} + +//================================================================ +// Empty function to fill slot +//================================================================ +Int IDPEmpty(CWMImageStrCodec* pSC) +{ + UNREFERENCED_PARAMETER(pSC); + + return ICERR_OK; +} + +ERR WMPAlloc(void** ppv, size_t cb) +{ + *ppv = calloc(1, cb); + return *ppv ? WMP_errSuccess : WMP_errOutOfMemory; +} + +ERR WMPFree(void** ppv) +{ + if (*ppv) + { + free(*ppv); + *ppv = NULL; + } + + return WMP_errSuccess; +} + +//================================================================ +// Streaming I/O functions +//================================================================ +ERR CreateWS_File(struct WMPStream** ppWS, const char* szFilename, const char* szMode) +{ + ERR err = WMP_errSuccess; + struct WMPStream* pWS = NULL; + + Call(WMPAlloc((void**)ppWS, sizeof(**ppWS))); + pWS = *ppWS; + + pWS->Close = CloseWS_File; + pWS->EOS = EOSWS_File; + + pWS->Read = ReadWS_File; + pWS->Write = WriteWS_File; + //pWS->GetLine = GetLineWS_File; + + pWS->SetPos = SetPosWS_File; + pWS->GetPos = GetPosWS_File; + +#ifdef WIN32 + FailIf(0 != fopen_s(&pWS->state.file.pFile, szFilename, szMode), WMP_errFileIO); +#else + pWS->state.file.pFile = fopen(szFilename, szMode); + FailIf(NULL == pWS->state.file.pFile, WMP_errFileIO); +#endif + +Cleanup: + return err; +} + +ERR CloseWS_File(struct WMPStream** ppWS) +{ + ERR err = WMP_errSuccess; + struct WMPStream* pWS = *ppWS; + + fclose(pWS->state.file.pFile); + Call(WMPFree((void**)ppWS)); + +Cleanup: + return err; +} + +Bool EOSWS_File(struct WMPStream* pWS) +{ + return feof(pWS->state.file.pFile); +} + +ERR ReadWS_File(struct WMPStream* pWS, void* pv, size_t cb) +{ + // ERR err = WMP_errSuccess; + + return (fread(pv, cb, 1, pWS->state.file.pFile) == 1) ? WMP_errSuccess : WMP_errFileIO; +} + +ERR WriteWS_File(struct WMPStream* pWS, const void* pv, size_t cb) +{ + ERR err = WMP_errSuccess; + + if (0 != cb) + { + FailIf(1 != fwrite(pv, cb, 1, pWS->state.file.pFile), WMP_errFileIO); + } + +Cleanup: + return err; +} + +ERR SetPosWS_File(struct WMPStream* pWS, size_t offPos) +{ + ERR err = WMP_errSuccess; + + FailIf(0 != fseek(pWS->state.file.pFile, (long)offPos, SEEK_SET), WMP_errFileIO); + +Cleanup: + return err; +} + +ERR GetPosWS_File(struct WMPStream* pWS, size_t* poffPos) +{ + ERR err = WMP_errSuccess; + long lOff = 0; + + FailIf(-1 == (lOff = ftell(pWS->state.file.pFile)), WMP_errFileIO); + *poffPos = (size_t)lOff; + +Cleanup: + return err; +} + +//---------------------------------------------------------------- +ERR CreateWS_Memory(struct WMPStream** ppWS, void* pv, size_t cb) +{ + ERR err = WMP_errSuccess; + struct WMPStream* pWS = NULL; + + Call(WMPAlloc((void**)ppWS, sizeof(**ppWS))); + pWS = *ppWS; + + pWS->state.buf.pbBuf = pv; + pWS->state.buf.cbBuf = cb; + pWS->state.buf.cbCur = 0; + + pWS->Close = CloseWS_Memory; + pWS->EOS = EOSWS_Memory; + + pWS->Read = ReadWS_Memory; + pWS->Write = WriteWS_Memory; + + pWS->SetPos = SetPosWS_Memory; + pWS->GetPos = GetPosWS_Memory; + +Cleanup: + return err; +} + +ERR CloseWS_Memory(struct WMPStream** ppWS) +{ + ERR err = WMP_errSuccess; + + Call(WMPFree((void**)ppWS)); + +Cleanup: + return err; +} + +Bool EOSWS_Memory(struct WMPStream* pWS) +{ + return pWS->state.buf.cbBuf <= pWS->state.buf.cbCur; +} + +ERR ReadWS_Memory(struct WMPStream* pWS, void* pv, size_t cb) +{ + ERR err = WMP_errSuccess; + + // FailIf(pWS->state.buf.cbBuf < pWS->state.buf.cbCur, WMP_errBufferOverflow); + if (pWS->state.buf.cbBuf < pWS->state.buf.cbCur) + return err; + + FailIf(pWS->state.buf.cbCur + cb < pWS->state.buf.cbCur, WMP_errBufferOverflow); + if (pWS->state.buf.cbBuf < pWS->state.buf.cbCur + cb) + { + cb = pWS->state.buf.cbBuf - pWS->state.buf.cbCur; + } + + memcpy(pv, pWS->state.buf.pbBuf + pWS->state.buf.cbCur, cb); + pWS->state.buf.cbCur += cb; + +Cleanup: + return err; +} + +ERR WriteWS_Memory(struct WMPStream* pWS, const void* pv, size_t cb) +{ + ERR err = WMP_errSuccess; + + FailIf(pWS->state.buf.cbCur + cb < pWS->state.buf.cbCur, WMP_errBufferOverflow); + FailIf(pWS->state.buf.cbBuf < pWS->state.buf.cbCur + cb, WMP_errBufferOverflow); + + memcpy(pWS->state.buf.pbBuf + pWS->state.buf.cbCur, pv, cb); + pWS->state.buf.cbCur += cb; + +Cleanup: + return err; +} + +ERR SetPosWS_Memory(struct WMPStream* pWS, size_t offPos) +{ + ERR err = WMP_errSuccess; + + //While the following condition is possibly useful, failure occurs + //at the end of a file since packets beyond the end may be accessed + //FailIf(pWS->state.buf.cbBuf < offPos, WMP_errBufferOverflow); + pWS->state.buf.cbCur = offPos; + + //Cleanup: + return err; +} + +ERR GetPosWS_Memory(struct WMPStream* pWS, size_t* poffPos) +{ + *poffPos = pWS->state.buf.cbCur; + + return WMP_errSuccess; +} + +//================================================================= +// Linked list based WMPStream +// - for indefinite size, multiple stream out +// - reads not supported in this mode +//================================================================= +ERR CreateWS_List(struct WMPStream** ppWS) +{ + ERR err = WMP_errSuccess; + struct WMPStream* pWS = NULL; + + Call(WMPAlloc((void**)ppWS, sizeof(**ppWS) + PACKETLENGTH + sizeof(void*))); + pWS = *ppWS; + + pWS->state.buf.pbBuf = (U8*)pWS + sizeof(**ppWS) + sizeof(void*); // first buffer points here + + memset(pWS->state.buf.pbBuf - sizeof(void*), 0, sizeof(void*)); + pWS->state.buf.cbBuf = PACKETLENGTH; + pWS->state.buf.cbCur = 0; + pWS->state.buf.cbBufCount = 0; + + pWS->Close = CloseWS_List; + pWS->EOS = NULL; // doesn't get called + + pWS->Read = ReadWS_List; + pWS->Write = WriteWS_List; + + pWS->SetPos = SetPosWS_List; + pWS->GetPos = GetPosWS_List; + + //printf ("create buffer %d: %x\n", pWS->state.buf.cbBufCount, pWS->state.buf.pbBuf); + +Cleanup: + return err; +} + +ERR CloseWS_List(struct WMPStream** ppWS) +{ + ERR err = WMP_errSuccess; + + if (ppWS) { + U8* pBuf = (U8*)(ppWS[0] + 1); // pointer to buffer + U8* pNext = (U8*)(((void**)pBuf)[0]); + while (pNext) { + //struct WMPStream *pWS = ppWS[0]; + pBuf = pNext; + pNext = (U8*)(((void**)(pBuf))[0]); + //printf ("delete buffer %x\n", pBuf); + Call(WMPFree((void**)&pBuf)); + } + } + Call(WMPFree((void**)ppWS)); + +Cleanup: + return err; +} + +ERR ReadWS_List(struct WMPStream* pWS, void* pv, size_t cb) +{ + ERR err = WMP_errSuccess; + + FailIf(pWS->state.buf.cbCur + cb < pWS->state.buf.cbCur, WMP_errBufferOverflow); + if (pWS->state.buf.cbBuf < pWS->state.buf.cbCur + PACKETLENGTH * pWS->state.buf.cbBufCount + cb) + { + cb = pWS->state.buf.cbBuf - pWS->state.buf.cbCur - PACKETLENGTH * pWS->state.buf.cbBufCount; + } + + while (cb) { + size_t cl = PACKETLENGTH - pWS->state.buf.cbCur; + if (cl > cb) + cl = cb; + memcpy(pv, pWS->state.buf.pbBuf + pWS->state.buf.cbCur, cl); + pWS->state.buf.cbCur += cl; + pv = (void*)((U8*)pv + cl); + cb -= cl; + if (pWS->state.buf.cbCur == PACKETLENGTH) { + pWS->state.buf.pbBuf = (U8*)((void**)(pWS->state.buf.pbBuf - sizeof(void*)))[0] + sizeof(void*); + pWS->state.buf.cbCur = 0; + pWS->state.buf.cbBufCount++; + + //printf ("read buffer %d: %x\n", pWS->state.buf.cbBufCount, pWS->state.buf.pbBuf); + } + } + +Cleanup: + return err; +} + +ERR WriteWS_List(struct WMPStream* pWS, const void* pv, size_t cb) +{ + ERR err = WMP_errSuccess; + + FailIf(pWS->state.buf.cbCur + cb < pWS->state.buf.cbCur, WMP_errBufferOverflow); + FailIf(pWS->state.buf.cbBuf < pWS->state.buf.cbCur + cb, WMP_errBufferOverflow); + + while (cb) { + size_t cl = PACKETLENGTH - pWS->state.buf.cbCur; + if (cl > cb) + cl = cb; + memcpy(pWS->state.buf.pbBuf + pWS->state.buf.cbCur, pv, cl); + pWS->state.buf.cbCur += cl; + pv = (const void*)((U8*)pv + cl); + cb -= cl; + if (pWS->state.buf.cbCur == PACKETLENGTH) { // allocate next packet in list + U8* pBuf = NULL; + void** pPtrLoc = (void**)(pWS->state.buf.pbBuf - sizeof(void*)); + Call(WMPAlloc((void**)&pBuf, PACKETLENGTH + sizeof(void*))); + pPtrLoc[0] = (void*)pBuf; + pWS->state.buf.pbBuf = pBuf + sizeof(void*); + pWS->state.buf.cbBuf += PACKETLENGTH; + memset(pBuf, 0, sizeof(void*)); + pWS->state.buf.cbCur = 0; + pWS->state.buf.cbBufCount++; + + //printf ("create buffer %d: %x\n", pWS->state.buf.cbBufCount, pWS->state.buf.pbBuf); + } + } + +Cleanup: + return err; +} + +ERR SetPosWS_List(struct WMPStream* pWS, size_t offPos) +{ + ERR err = WMP_errSuccess; + + // get the first buffer + U8* pBuf = (U8*)(pWS + 1); // pointer to buffer + pWS->state.buf.cbCur = 0; + pWS->state.buf.cbBufCount = 0; + + while (offPos >= PACKETLENGTH && pBuf != NULL) { + pBuf = (U8*)(((void**)pBuf)[0]); + offPos -= PACKETLENGTH; + pWS->state.buf.cbBufCount++; + } + + if (pBuf == NULL) + goto Cleanup; + + pWS->state.buf.cbCur = offPos; + pWS->state.buf.pbBuf = pBuf + sizeof(void*); + //printf ("seek buffer %d: %x\n", pWS->state.buf.cbBufCount, pWS->state.buf.pbBuf); + +Cleanup: + return err; +} + +ERR GetPosWS_List(struct WMPStream* pWS, size_t* poffPos) +{ + *poffPos = pWS->state.buf.cbCur + PACKETLENGTH * pWS->state.buf.cbBufCount; + + return WMP_errSuccess; +} + +//================================================================ +// Simple BitIO access functions +//================================================================ +// init SimpleBitIO +ERR attach_SB(SimpleBitIO* pSB, struct WMPStream* pWS) +{ + pSB->pWS = pWS; + pSB->cbRead = 0; + pSB->bAccumulator = 0; + pSB->cBitLeft = 0; + + return WMP_errSuccess; +} + +// extract upto 32bit from input stream +U32 getBit32_SB(SimpleBitIO* pSB, U32 cBits) +{ + U32 rc = 0; + + while (pSB->cBitLeft < cBits) + { + rc <<= pSB->cBitLeft; + rc |= pSB->bAccumulator >> (8 - pSB->cBitLeft); + + cBits -= pSB->cBitLeft; + + pSB->pWS->Read(pSB->pWS, &pSB->bAccumulator, 1); + pSB->cbRead++; + pSB->cBitLeft = 8; + } + + rc <<= cBits; + rc |= pSB->bAccumulator >> (8 - cBits); + pSB->bAccumulator <<= cBits; + pSB->cBitLeft -= cBits; + + return rc; +} + +// ignore input to byte boundary +Void flushToByte_SB(SimpleBitIO* pSB) +{ + pSB->bAccumulator = 0; + pSB->cBitLeft = 0; +} + +// return read byte count +U32 getByteRead_SB(SimpleBitIO* pSB) +{ + return pSB->cbRead; +} + +ERR detach_SB(SimpleBitIO* pSB) +{ + assert(0 == pSB->cBitLeft); + pSB->pWS = NULL; + + return WMP_errSuccess; +} + +//================================================================ +// Memory access functions +//================================================================ +#if (defined(WIN32) && !defined(UNDER_CE)) || (defined(UNDER_CE) && defined(_ARM_)) +// WinCE ARM and Desktop x86 +#else +// other platform +#ifdef _BIG__ENDIAN_ +#define _byteswap_ulong(x) (x) +#else // _BIG__ENDIAN_ +#if _MSC_VER < 1924 +U32 _byteswap_ulong(U32 bits) +{ + U32 r = (bits & 0xffu) << 24; + r |= (bits << 8) & 0xff0000u; + r |= ((bits >> 8) & 0xff00u); + r |= ((bits >> 24) & 0xffu); + + return r; +} +#endif // _MSC_VER +#endif // _BIG__ENDIAN_ +#endif + +U32 load4BE(void* pv) +{ +#ifdef _BIG__ENDIAN_ + return (*(U32*)pv); +#else // _BIG__ENDIAN_ +#if defined(_M_IA64) || defined(_ARM_) + U32 v; + v = ((U16*)pv)[0]; + v |= ((U32)((U16*)pv)[1]) << 16; + return _byteswap_ulong(v); +#else // _M_IA64 + U32 v; + memcpy(&v, pv, sizeof(U32)); + return _byteswap_ulong(v); +#endif // _M_IA64 +#endif // _BIG__ENDIAN_ +} + +#define LOAD16 load4BE + +#ifdef _BIG__ENDIAN_ +#define WRITESWAP_ENDIAN(a) ((a)>>16) +#else // _BIG__ENDIAN_ +#define WRITESWAP_ENDIAN(a) _byteswap_ulong(a) +#endif // _BIG__ENDIAN_ + +//================================================================ +// Bit I/O functions +//================================================================ +Int allocateBitIOInfo(CWMImageStrCodec* pSC) +{ + U32 cNumBitIO; + SUBBAND sbSubband = pSC->WMISCP.sbSubband; + + pSC->cSB = (sbSubband == SB_DC_ONLY ? 1 : (sbSubband == SB_NO_HIGHPASS ? 2 : (sbSubband == SB_NO_FLEXBITS ? 3 : 4))); + + // # of additional BitIOs other than pSC->pIOHeader + if (!pSC->m_param.bIndexTable) { // pure streaming mode, no index table, no additional BitIO! + assert(pSC->WMISCP.bfBitstreamFormat == SPATIAL && pSC->WMISCP.cNumOfSliceMinus1H + pSC->WMISCP.cNumOfSliceMinus1V == 0); + cNumBitIO = 0; + } + else if (pSC->WMISCP.bfBitstreamFormat == SPATIAL) + cNumBitIO = pSC->WMISCP.cNumOfSliceMinus1V + 1; + else + cNumBitIO = (pSC->WMISCP.cNumOfSliceMinus1V + 1) * pSC->cSB; + + if (cNumBitIO > MAX_TILES * 4) + return ICERR_ERROR; + + // allocate additional BitIos + if (cNumBitIO > 0) { + U32 i = 0; + size_t cb = sizeof(BitIOInfo) * cNumBitIO + (PACKETLENGTH * 4 - 1) + PACKETLENGTH * 4 * cNumBitIO; + U8* pb = (U8*)malloc(cb); + + if (NULL == pb) return ICERR_ERROR; + memset(pb, 0, cb); + + pSC->m_ppBitIO = (BitIOInfo**)pb; + pb += sizeof(BitIOInfo) * cNumBitIO; + + pb = (U8*)ALIGNUP(pb, PACKETLENGTH * 4) + PACKETLENGTH * 2; + for (i = 0; i < cNumBitIO; ++i) { + pSC->m_ppBitIO[i] = (BitIOInfo*)pb; + pb += PACKETLENGTH * 4; + } + + // allocate index table + if (cNumBitIO > MAX_TILES * 4 || pSC->WMISCP.cNumOfSliceMinus1H >= MAX_TILES) + return ICERR_ERROR; + pSC->pIndexTable = malloc(cNumBitIO * (pSC->WMISCP.cNumOfSliceMinus1H + 1) * sizeof(size_t)); + if (NULL == pSC->pIndexTable) return ICERR_ERROR; + } + + pSC->cNumBitIO = cNumBitIO; + + return ICERR_OK; +} + +Int setBitIOPointers(CWMImageStrCodec* pSC) +{ + if (pSC->cNumBitIO > 0) { + U32 i; + + for (i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i++) { + CCodingContext* pContext = &pSC->m_pCodingContext[i]; + if (pSC->WMISCP.bfBitstreamFormat == SPATIAL) { + pContext->m_pIODC = pContext->m_pIOLP = pContext->m_pIOAC = pContext->m_pIOFL = pSC->m_ppBitIO[i]; + } + else { + U32 j = pSC->cSB; + + pContext->m_pIODC = pSC->m_ppBitIO[i * j]; + if (j > 1) + pContext->m_pIOLP = pSC->m_ppBitIO[i * j + 1]; + if (j > 2) + pContext->m_pIOAC = pSC->m_ppBitIO[i * j + 2]; + if (j > 3) + pContext->m_pIOFL = pSC->m_ppBitIO[i * j + 3]; + } + } + } + else { // streamimg mode + CCodingContext* pContext = &pSC->m_pCodingContext[0]; + pContext->m_pIODC = pContext->m_pIOLP = pContext->m_pIOAC = pContext->m_pIOFL = pSC->pIOHeader; + } + + return ICERR_OK; +} + +Int allocateTileInfo(CWMImageStrCodec* pSC) +{ + size_t i; + + if (pSC->WMISCP.cNumOfSliceMinus1V >= MAX_TILES) + return ICERR_ERROR; + pSC->pTile = (CWMITile*)malloc((pSC->WMISCP.cNumOfSliceMinus1V + 1) * sizeof(CWMITile)); + if (pSC->pTile == NULL) + return ICERR_ERROR; + memset(pSC->pTile, 0, (pSC->WMISCP.cNumOfSliceMinus1V + 1) * sizeof(CWMITile)); + + for (i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i++) + pSC->pTile[i].cNumQPHP = pSC->pTile[i].cNumQPLP = 1, pSC->pTile[i].cBitsHP = pSC->pTile[i].cBitsLP = 0; + + return ICERR_OK; +} + +Void freeTileInfo(CWMImageStrCodec* pSC) +{ + size_t iTile; + + if ((pSC->m_param.uQPMode & 1) != 0) // not DC uniform + for (iTile = 0; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile++) + freeQuantizer(pSC->pTile[iTile].pQuantizerDC); + else + freeQuantizer(pSC->pTile[0].pQuantizerDC); + + if (pSC->WMISCP.sbSubband != SB_DC_ONLY) + if ((pSC->m_param.uQPMode & 2) != 0) // not LP uniform + for (iTile = 0; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile++) + freeQuantizer(pSC->pTile[iTile].pQuantizerLP); + else + freeQuantizer(pSC->pTile[0].pQuantizerLP); + + if (pSC->WMISCP.sbSubband != SB_DC_ONLY && pSC->WMISCP.sbSubband != SB_NO_HIGHPASS) + if ((pSC->m_param.uQPMode & 4) != 0) // not HP uniform + for (iTile = 0; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile++) + freeQuantizer(pSC->pTile[iTile].pQuantizerHP); + else + freeQuantizer(pSC->pTile[0].pQuantizerHP); + + if (pSC->pTile != NULL) + free(pSC->pTile); +} + +Int allocateQuantizer(CWMIQuantizer* pQuantizer[MAX_CHANNELS], size_t cChannel, size_t cQP) +{ + size_t iCh; + + if (cQP > 16 || cChannel > MAX_CHANNELS) + return ICERR_ERROR; + pQuantizer[0] = (CWMIQuantizer*)malloc(cQP * sizeof(CWMIQuantizer) * cChannel); + if (pQuantizer[0] == NULL) + return ICERR_ERROR; + + for (iCh = 1; iCh < cChannel; iCh++) + pQuantizer[iCh] = pQuantizer[iCh - 1] + cQP; + + return ICERR_OK; +} + +Void freeQuantizer(CWMIQuantizer* pQuantizer[MAX_CHANNELS]) +{ + if (pQuantizer[0] != NULL) + free(pQuantizer[0]); +} + +Void formatQuantizer(CWMIQuantizer* pQuantizer[MAX_CHANNELS], U8 cChMode, size_t cCh, size_t iPos, Bool bShiftedUV, + Bool bScaledArith) +{ + size_t iCh; + + for (iCh = 0; iCh < cCh; iCh++) { + if (iCh > 0) + if (cChMode == 0) // uniform + pQuantizer[iCh][iPos] = pQuantizer[0][iPos]; + else if (cChMode == 1) // mixed + pQuantizer[iCh][iPos] = pQuantizer[1][iPos]; + remapQP(pQuantizer[iCh] + iPos, (iCh > 0 && bShiftedUV == TRUE) ? SHIFTZERO - 1 : SHIFTZERO, bScaledArith); + } +} + +Void setUniformQuantizer(CWMImageStrCodec* pSC, size_t sb) +{ + size_t iCh, iTile; + + for (iCh = 0; iCh < pSC->m_param.cNumChannels; iCh++) + for (iTile = 1; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile++) + if (sb == 0) // DC + pSC->pTile[iTile].pQuantizerDC[iCh] = pSC->pTile[0].pQuantizerDC[iCh]; + else if (sb == 1) // LP + pSC->pTile[iTile].pQuantizerLP[iCh] = pSC->pTile[0].pQuantizerLP[iCh]; + else // HP + pSC->pTile[iTile].pQuantizerHP[iCh] = pSC->pTile[0].pQuantizerHP[iCh]; +} + +Void useDCQuantizer(CWMImageStrCodec* pSC, size_t iTile) +{ + size_t iCh; + + for (iCh = 0; iCh < pSC->m_param.cNumChannels; iCh++) + pSC->pTile[iTile].pQuantizerLP[iCh][0] = *pSC->pTile[iTile].pQuantizerDC[iCh]; +} + +Void useLPQuantizer(CWMImageStrCodec* pSC, size_t cQP, size_t iTile) +{ + size_t iCh, iQP; + + for (iCh = 0; iCh < pSC->m_param.cNumChannels; iCh++) + for (iQP = 0; iQP < cQP; iQP++) + pSC->pTile[iTile].pQuantizerHP[iCh][iQP] = pSC->pTile[iTile].pQuantizerLP[iCh][iQP]; +} + +U8 dquantBits(U8 cQP) +{ + return (cQP < 2 ? 0 : (cQP < 4 ? 1 : (cQP < 6 ? 2 : (cQP < 10 ? 3 : 4)))); +} + +#ifndef ARMOPT_BITIO +U32 peekBit16(BitIOInfo* pIO, U32 cBits) +{ + PEEKBIT16(pIO, cBits); +} + +U32 flushBit16(BitIOInfo* pIO, U32 cBits) +{ + FLUSHBIT16(pIO, cBits); +} + +U32 getBit16(BitIOInfo* pIO, U32 cBits) +{ + U32 uiRet = peekBit16(pIO, cBits); + flushBit16(pIO, cBits); + + return uiRet; +} + +U32 getBool16(BitIOInfo* pIO) +{ + U32 uiRet = peekBit16(pIO, 1); + flushBit16(pIO, 1); + return uiRet; +} + +/** this function returns cBits if zero is read, or a signed value if first cBits are not all zero **/ +I32 getBit16s(BitIOInfo* pIO, U32 cBits) +{ + U32 uiRet = peekBit16(pIO, cBits + 1); + if (uiRet < 2) { + flushBit16(pIO, cBits); + return 0; + } + else { + flushBit16(pIO, cBits + 1); + if (uiRet & 1) + return (-(I32)(uiRet >> 1)); + else + return (I32)(uiRet >> 1); + } +} + +U32 getBit32(BitIOInfo* pIO, U32 cBits) +{ + U32 uiRet = 0; + + assert(0 <= (I32)cBits && cBits <= 32); + + if (16 < cBits) + { + uiRet = getBit16(pIO, 16); + cBits -= 16; + uiRet <<= cBits; + } + + uiRet |= getBit16(pIO, cBits); + + return uiRet; +} + +U32 flushToByte(BitIOInfo* pIO) +{ + return flushBit16(pIO, (16 - pIO->cBitsUsed) & 7); +} +#endif // ARMOPT_BITIO + +//---------------------------------------------------------------- +Void putBit16z(BitIOInfo* pIO, U32 uiBits, U32 cBits) +{ + assert(cBits <= 16); + assert(0 == uiBits >> cBits); + + pIO->uiAccumulator = (pIO->uiAccumulator << cBits) | uiBits; + pIO->cBitsUsed += cBits; + + *(U16*)pIO->pbCurrent = (U16)WRITESWAP_ENDIAN(pIO->uiAccumulator << (32 - pIO->cBitsUsed)); + + pIO->pbCurrent = MASKPTR(pIO->pbCurrent + ((pIO->cBitsUsed >> 3) & 2), pIO->iMask); + pIO->cBitsUsed &= 16 - 1; +} + +Void putBit16(BitIOInfo* pIO, U32 uiBits, U32 cBits) +{ + assert(cBits <= 16); + + uiBits &= ~(-1 << cBits); + putBit16z(pIO, uiBits, cBits); +} + +Void putBit32(BitIOInfo* pIO, U32 uiBits, U32 cBits) +{ + assert(0 <= (I32)cBits && cBits <= 32); + + if (16 < cBits) + { + putBit16(pIO, uiBits >> (cBits - 16), 16); + cBits -= 16; + } + + putBit16(pIO, uiBits, cBits); +} + +Void fillToByte(BitIOInfo* pIO) +{ + putBit16z(pIO, 0, (16 - pIO->cBitsUsed) & 7); +} + +//---------------------------------------------------------------- +U32 getBit16_S(CWMImageStrCodec* pSC, BitIOInfo* pIO, U32 cBits) +{ + U32 rc = getBit16(pIO, cBits); + readIS_L1(pSC, pIO); + + return rc; +} + +U32 putBit16_S(CWMImageStrCodec* pSC, BitIOInfo* pIO, U32 uiBits, U32 cBits) +{ + putBit16(pIO, uiBits, cBits); + writeIS_L1(pSC, pIO); + + return 0; +} + + +//---------------------------------------------------------------- +// Query buffered data size held in BitIOInfo +// Write() for Enc, Read() for Dec +//---------------------------------------------------------------- +U32 getSizeRead(BitIOInfo* pIO) +{ + return (U32)(UINTPTR_T)(pIO->pbStart + PACKETLENGTH * 2 - pIO->pbCurrent) - pIO->cBitsUsed / 8; +} + +U32 getSizeWrite(BitIOInfo* pIO) +{ + return (U32)(UINTPTR_T)(pIO->pbCurrent + (pIO->pbStart <= pIO->pbCurrent ? 0 : PACKETLENGTH * 2) - pIO->pbStart) + pIO->cBitsUsed / 8; +} + +//---------------------------------------------------------------- +// Query stream offset from attached BitIO object for dec +//---------------------------------------------------------------- +U32 getPosRead(BitIOInfo* pIO) +{ + size_t cbCached = (pIO->pbStart + PACKETLENGTH * 2 - pIO->pbCurrent) - pIO->cBitsUsed / 8; + return (U32)(pIO->offRef - cbCached); +} + +//================================================================ +// Block I/O functions +//================================================================ +#ifndef ARMOPT_BITIO +ERR attachISRead(BitIOInfo* pIO, struct WMPStream* pWS, CWMImageStrCodec* pSC) +{ + UNREFERENCED_PARAMETER(pSC); + + pWS->GetPos(pWS, &pIO->offRef); + + pIO->pbStart = (U8*)pIO - PACKETLENGTH * 2; + pIO->pbCurrent = pIO->pbStart; + + //PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); + pWS->SetPos(pWS, pIO->offRef); + pWS->Read(pWS, pIO->pbStart, PACKETLENGTH * 2); + //PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); + pIO->offRef += PACKETLENGTH * 2; + + pIO->uiAccumulator = load4BE(pIO->pbStart); + + pIO->cBitsUsed = 0; + pIO->iMask = ~(PACKETLENGTH * 2); + pIO->iMask &= ~1; + + pIO->pWS = pWS; + return WMP_errSuccess; +} + +ERR readIS(CWMImageStrCodec* pSC, BitIOInfo* pIO) +{ + ERR err = WMP_errSuccess; + + UNREFERENCED_PARAMETER(pSC); + + if (PACKET1(pIO->pbStart, pIO->pbCurrent, PACKETLENGTH)) + { + struct WMPStream* pWS = pIO->pWS; + + //PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); + //Call(0 != pIO->pWS->Read(pIO->pWS, pIO->pbStart, PACKETLENGTH)); + // TODO: add error checking code + pWS->SetPos(pWS, pIO->offRef); + pWS->Read(pWS, pIO->pbStart, PACKETLENGTH); + pIO->offRef += PACKETLENGTH; + //PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); + + // make shadow copy for first 4B + pIO->uiShadow = *(U32*)pIO->pbStart; + + // reposition pbPacket pointer + pIO->pbStart = MASKPTR(pIO->pbStart + PACKETLENGTH, pIO->iMask); + } + + //Cleanup: + return err; +} + +ERR detachISRead(CWMImageStrCodec* pSC, BitIOInfo* pIO) +{ + ERR err = WMP_errSuccess; + + struct WMPStream* pWS = pIO->pWS; + size_t cbRemain = 0; + + // we can ONLY detach IStream at byte boundary + flushToByte(pIO); + assert(0 == (pIO->cBitsUsed % 8)); + Call(readIS_L1(pSC, pIO)); + + // set stream to right offset, undo buffering + cbRemain = (pIO->pbStart + PACKETLENGTH * 2) - (pIO->pbCurrent + pIO->cBitsUsed / 8); + pWS->SetPos(pWS, pIO->offRef - cbRemain); + + pIO->pWS = NULL; +Cleanup: + return err; +} +#endif // ARMOPT_BITIO + +//---------------------------------------------------------------- +ERR attachISWrite(BitIOInfo* pIO, struct WMPStream* pWS) +{ + pWS->GetPos(pWS, &pIO->offRef); + + pIO->pbStart = (U8*)pIO - PACKETLENGTH * 2; + pIO->pbCurrent = pIO->pbStart; + + pIO->uiAccumulator = 0; + pIO->cBitsUsed = 0; + pIO->iMask = ~(PACKETLENGTH * 2); + + pIO->pWS = pWS; + return WMP_errSuccess; +} + +// write out packet if we have >=1 packet data filled +ERR writeIS(CWMImageStrCodec* pSC, BitIOInfo* pIO) +{ + ERR err = WMP_errSuccess; + + UNREFERENCED_PARAMETER(pSC); + + if (PACKET1(pIO->pbStart, pIO->pbCurrent, PACKETLENGTH)) + { + //PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); + err = pIO->pWS->Write(pIO->pWS, pIO->pbStart, PACKETLENGTH); + //PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); + Call(err); + + // reposition pbStart pointer + pIO->pbStart = MASKPTR(pIO->pbStart + PACKETLENGTH, pIO->iMask); + } + +Cleanup: + return err; +} + +// write out partially filled buffer and detach bitIO from IStream +ERR detachISWrite(CWMImageStrCodec* pSC, BitIOInfo* pIO) +{ + ERR err = WMP_errSuccess; + + // we can ONLY detach IStream at byte boundary + assert(0 == (pIO->cBitsUsed % 8)); + Call(writeIS_L1(pSC, pIO)); + + //PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); + err = pIO->pWS->Write(pIO->pWS, pIO->pbStart, pIO->pbCurrent + pIO->cBitsUsed / 8 - pIO->pbStart); + //PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); + Call(err); + + pIO->pWS = NULL; +Cleanup: + return err; +} + +#if false +//========================= +// Performance Measurement +//========================= +#ifndef DISABLE_PERF_MEASUREMENT + +void OutputIndivPerfTimer(struct PERFTIMERSTATE* pPerfTimer, + char* pszTimerName, + char* pszDescription, + float fltMegaPixels) +{ + //PERFTIMERRESULTS rResults; + Bool fResult; + + fResult = FALSE; + printf("%s (%s): ", pszTimerName, pszDescription); + if (pPerfTimer) + { + fResult = PerfTimerGetResults(pPerfTimer, &rResults); + if (fResult) + { + printf("%.3f milliseconds, %.6f MP/sec\n", (float)rResults.iElapsedTime / 1000000, + 1000000000 * fltMegaPixels / rResults.iElapsedTime); + if (rResults.iZeroTimeIntervals > 0) + { + printf(" *** WARNING: %d time intervals were measured as zero. " + "This perf timer has insufficient precision!\n\n", + (int)rResults.iZeroTimeIntervals); + } + } + } + if (FALSE == fResult) + printf("Results not available!\n"); +} + + +void OutputPerfTimerReport(CWMImageStrCodec* pState) +{ + float fltMegaPixels; + + assert(pState->m_fMeasurePerf); + + printf("***************************************************************************\n"); + printf("* Perf Report\n"); + printf("***************************************************************************\n\n"); + + fltMegaPixels = (float)pState->WMII.cWidth * pState->WMII.cHeight / 1000000; + printf("Image Width = %d, Height = %d, total MegaPixels = %.1f MP\n", + (int)pState->WMII.cWidth, (int)pState->WMII.cHeight, fltMegaPixels); + + OutputIndivPerfTimer(pState->m_ptEncDecPerf, "m_ptEncDecPerf", "excl I/O", fltMegaPixels); + OutputIndivPerfTimer(pState->m_ptEndToEndPerf, "m_ptEndToEndPerf", "incl I/O", fltMegaPixels); +} + +#endif // DISABLE_PERF_MEASUREMENT +#endif // false \ No newline at end of file diff --git a/Src/JxrDecode/jxrlib/image/sys/strcodec.h b/Src/JxrDecode/jxrlib/image/sys/strcodec.h new file mode 100644 index 00000000..92eb0001 --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/sys/strcodec.h @@ -0,0 +1,679 @@ +//*@@@+++@@@@****************************************************************** +// +// 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 + +#include "windowsmediaphoto.h" +#include "common.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 // UNREFERENCED_PARAMETER + +#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 WIN32 + TCHAR** ppTempFile; +#else + char** ppTempFile; +#endif + + // interleaved alpha support - linked structure for Alpha channel + struct CWMImageStrCodec* m_pNextSC; + Bool m_bSecondary; + + //================================ + // Perf Timers + //================================ +#if false +#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 +#endif + + // 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); diff --git a/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h b/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h new file mode 100644 index 00000000..5901b320 --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h @@ -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 +#include +#include +#include + +#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 + diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c new file mode 100644 index 00000000..1549dcd5 --- /dev/null +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c @@ -0,0 +1,975 @@ +//*@@@+++@@@@****************************************************************** +// +// 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 +#include + +#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_CreateDecoderFromMemory(char* inBuffer, size_t size, PKImageDecode** ppDecoder) +{ + ERR err = WMP_errSuccess; + + char* pExt = ".jxr"; + const PKIID* pIID = NULL; + + struct WMPStream* pStream = NULL; + PKImageDecode* pDecoder = NULL; + + // get decode PKIID + Call(GetImageDecodeIID(pExt, &pIID)); + + // create stream + Call(CreateWS_Memory(&pStream, inBuffer, size)); + + // 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_CreateDecoderFromStream(struct WMPStream* pStream, PKImageDecode** ppDecoder) +{ + ERR err = WMP_errSuccess; + + // Create decoder + Call(PKCodecFactory_CreateCodec(&IID_PKImageWmpDecode, (void**)ppDecoder)); + + // attach stream to decoder + Call((*ppDecoder)->Initialize(*ppDecoder, pStream)); + (*ppDecoder)->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->CreateDecoderFromMemory = PKCodecFactory_CreateDecoderFromMemory; + pCFactory->CreateDecoderFromStream = PKCodecFactory_CreateDecoderFromStream; + 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; +} + diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h new file mode 100644 index 00000000..1b09b7b3 --- /dev/null +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h @@ -0,0 +1,645 @@ +//*@@@+++@@@@****************************************************************** +// +// 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> +#include "../common/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(*CreateDecoderFromMemory)(char*, size_t, PKImageDecode**); + ERR(*CreateDecoderFromStream)(struct WMPStream*, 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 + diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c new file mode 100644 index 00000000..1f40a620 --- /dev/null +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c @@ -0,0 +1,2281 @@ + +//*@@@+++@@@@****************************************************************** +// +// 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 +#include +#include "JXRGlue.h" + + +static const char szHDPhotoFormat[] = "image/vnd.ms-photo"; +const U32 IFDEntryTypeSizes[] = { 0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8 }; +const U32 SizeofIFDEntry = sizeof(struct IFDEntry); + + +void CalcMetadataSizeLPSTR(const DPKPROPVARIANT var, + U16* pcInactiveMetadata, + U32* pcbOffsetSize, + U32* pcbCount) +{ + if (DPKVT_EMPTY != var.vt) + { + U32 uiLenWithNull = (U32)strlen(var.VT.pszVal) + 1; // +1 for NULL; + assert(DPKVT_LPSTR == var.vt); + + // We only use offset if size > 4 + if (uiLenWithNull > 4) + *pcbOffsetSize += uiLenWithNull; + + if (pcbCount) + *pcbCount = uiLenWithNull; + } + else + *pcInactiveMetadata += 1; +} + +void CalcMetadataSizeLPWSTR(const DPKPROPVARIANT var, + U16* pcInactiveMetadata, + U32* pcbOffsetSize, + U32* pcbCount) +{ + if (DPKVT_EMPTY != var.vt) + { + U32 uiCBWithNull = sizeof(U16) * ((U32)wcslen((wchar_t*)var.VT.pwszVal) + 1); // +1 for NULL term; + assert(DPKVT_LPWSTR == var.vt); + + // We only use offset if size > 4 + if (uiCBWithNull > 4) + *pcbOffsetSize += uiCBWithNull; + + if (pcbCount) + *pcbCount = uiCBWithNull; + } + else + *pcInactiveMetadata += 1; +} + +void CalcMetadataSizeUI2(const DPKPROPVARIANT var, + U16* pcInactiveMetadata, + U32* pcbMetadataSize) +{ + UNREFERENCED_PARAMETER(pcbMetadataSize); + if (DPKVT_EMPTY != var.vt) + { + assert(DPKVT_UI2 == var.vt); + // This is a single UI2, so it will not be written via offset, but rather as value + } + else + *pcInactiveMetadata += 1; +} + +void CalcMetadataSizeUI4(const DPKPROPVARIANT var, + U16* pcInactiveMetadata, + U32* pcbContainer) +{ + UNREFERENCED_PARAMETER(pcbContainer); + if (DPKVT_EMPTY != var.vt) + { + assert(DPKVT_UI4 == var.vt); + // This is a single UI4, so it will not be written via offset, but rather as value + } + else + *pcInactiveMetadata += 1; +} + +ERR CalcMetadataOffsetSize(PKImageEncode* pIE, + U16* pcInactiveMetadata, + U32* pcbMetadataSize) +{ + ERR err = WMP_errSuccess; + + CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarImageDescription, pcInactiveMetadata, pcbMetadataSize, NULL); + CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarCameraMake, pcInactiveMetadata, pcbMetadataSize, NULL); + CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarCameraModel, pcInactiveMetadata, pcbMetadataSize, NULL); + CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarSoftware, pcInactiveMetadata, pcbMetadataSize, NULL); + CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarDateTime, pcInactiveMetadata, pcbMetadataSize, NULL); + CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarArtist, pcInactiveMetadata, pcbMetadataSize, NULL); + CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarCopyright, pcInactiveMetadata, pcbMetadataSize, NULL); + CalcMetadataSizeUI2(pIE->sDescMetadata.pvarRatingStars, pcInactiveMetadata, pcbMetadataSize); + CalcMetadataSizeUI2(pIE->sDescMetadata.pvarRatingValue, pcInactiveMetadata, pcbMetadataSize); + CalcMetadataSizeLPWSTR(pIE->sDescMetadata.pvarCaption, pcInactiveMetadata, pcbMetadataSize, NULL); + CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarDocumentName, pcInactiveMetadata, pcbMetadataSize, NULL); + CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarPageName, pcInactiveMetadata, pcbMetadataSize, NULL); + CalcMetadataSizeUI4(pIE->sDescMetadata.pvarPageNumber, pcInactiveMetadata, pcbMetadataSize); + CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarHostComputer, pcInactiveMetadata, pcbMetadataSize, NULL); + + return err; +} + + +ERR CopyDescMetadata(DPKPROPVARIANT* pvarDst, + const DPKPROPVARIANT varSrc) +{ + ERR err = WMP_errSuccess; + size_t uiSize; + + pvarDst->vt = varSrc.vt; + switch (varSrc.vt) + { + case DPKVT_LPSTR: + pvarDst->vt = DPKVT_LPSTR; + uiSize = strlen(varSrc.VT.pszVal) + 1; + Call(PKAlloc((void**)&pvarDst->VT.pszVal, uiSize)); + memcpy(pvarDst->VT.pszVal, varSrc.VT.pszVal, uiSize); + break; + + case DPKVT_LPWSTR: + pvarDst->vt = DPKVT_LPWSTR; + uiSize = sizeof(U16) * (wcslen((wchar_t*)varSrc.VT.pwszVal) + 1); // +1 for NULL term + Call(PKAlloc((void**)&pvarDst->VT.pszVal, uiSize)); + memcpy(pvarDst->VT.pwszVal, varSrc.VT.pwszVal, uiSize); + break; + + case DPKVT_UI2: + pvarDst->VT.uiVal = varSrc.VT.uiVal; + break; + + case DPKVT_UI4: + pvarDst->VT.ulVal = varSrc.VT.ulVal; + break; + + default: + assert(FALSE); // This case is not handled + FailIf(TRUE, WMP_errNotYetImplemented); + + // *** FALL THROUGH *** + + case DPKVT_EMPTY: + memset(pvarDst, 0, sizeof(*pvarDst)); + assert(DPKVT_EMPTY == pvarDst->vt); + break; + } + +Cleanup: + return err; +} + + +void FreeDescMetadata(DPKPROPVARIANT* pvar) +{ + switch (pvar->vt) + { + case DPKVT_LPSTR: + PKFree((void**)&pvar->VT.pszVal); + break; + + case DPKVT_LPWSTR: + PKFree((void**)&pvar->VT.pwszVal); + break; + + default: + assert(FALSE); // This case is not handled + break; + + case DPKVT_EMPTY: + case DPKVT_UI2: + case DPKVT_UI4: + break; + } +} + + +ERR WriteDescMetadata(PKImageEncode* pIE, + const DPKPROPVARIANT var, + WmpDE* pwmpDE, + U32* puiCurrDescMetadataOffset, + size_t* poffPos) +{ + ERR err = WMP_errSuccess; + WmpDEMisc* pDEMisc = &pIE->WMP.wmiDEMisc; + struct WMPStream* pWS = pIE->pStream; + U32 uiMetadataOffsetSize = 0; + U32 uiCount = 0; + U32 uiDataWrittenToOffset = 0; + U16 uiTemp = 0; + + if (0 == pDEMisc->uDescMetadataOffset || 0 == pDEMisc->uDescMetadataByteCount) + goto Cleanup; // Nothing to do here + + // Sanity check before - can be equal due to remaining metadata being DPKVT_EMPTY + assert(*puiCurrDescMetadataOffset <= pDEMisc->uDescMetadataByteCount); + + switch (var.vt) + { + case DPKVT_EMPTY: + break; + + case DPKVT_LPSTR: + CalcMetadataSizeLPSTR(var, &uiTemp, &uiMetadataOffsetSize, &uiCount); + pwmpDE->uCount = uiCount; + pwmpDE->uValueOrOffset = pDEMisc->uDescMetadataOffset + *puiCurrDescMetadataOffset; + Call(WriteWmpDE(pWS, poffPos, pwmpDE, (U8*)var.VT.pszVal, &uiDataWrittenToOffset)); + break; + + case DPKVT_LPWSTR: + CalcMetadataSizeLPWSTR(var, &uiTemp, &uiMetadataOffsetSize, &uiCount); + pwmpDE->uCount = uiCount; + pwmpDE->uValueOrOffset = pDEMisc->uDescMetadataOffset + *puiCurrDescMetadataOffset; + Call(WriteWmpDE(pWS, poffPos, pwmpDE, (U8*)var.VT.pwszVal, &uiDataWrittenToOffset)); + break; + + case DPKVT_UI2: + CalcMetadataSizeUI2(var, &uiTemp, &uiMetadataOffsetSize); + pwmpDE->uCount = 1; + pwmpDE->uValueOrOffset = var.VT.uiVal; + Call(WriteWmpDE(pWS, poffPos, pwmpDE, NULL, NULL)); + break; + + case DPKVT_UI4: + CalcMetadataSizeUI4(var, &uiTemp, &uiMetadataOffsetSize); + pwmpDE->uCount = 1; + pwmpDE->uValueOrOffset = var.VT.ulVal; + Call(WriteWmpDE(pWS, poffPos, pwmpDE, NULL, NULL)); + break; + + default: + assert(FALSE); // This case is not handled + FailIf(TRUE, WMP_errNotYetImplemented); + break; + } + + *puiCurrDescMetadataOffset += uiDataWrittenToOffset; + + // Sanity check after + assert(*puiCurrDescMetadataOffset <= pDEMisc->uDescMetadataByteCount); // Can be equal + +Cleanup: + return err; +} + + + +//================================================================ +// PKImageEncode_WMP +//================================================================ +ERR WriteContainerPre( + PKImageEncode* pIE) +{ + ERR err = WMP_errSuccess; + const U32 OFFSET_OF_PFD = 0x20; + struct WMPStream* pWS = pIE->pStream; + WmpDEMisc* pDEMisc = &pIE->WMP.wmiDEMisc; + PKPixelInfo PI; + size_t offPos = 0; + + U8 IIMM[2] = { '\x49', '\x49' }; + // const U32 cbWmpDEMisc = OFFSET_OF_PFD; + U32 cbMetadataOffsetSize = 0; + U16 cInactiveMetadata = 0; + U32 uiCurrDescMetadataOffset = 0; + + static WmpDE wmpDEs[] = + { + {WMP_tagDocumentName, WMP_typASCII, 1, (U32)-1}, // Descriptive metadata + {WMP_tagImageDescription, WMP_typASCII, 1, (U32)-1}, // Descriptive metadata + {WMP_tagCameraMake, WMP_typASCII, 1, (U32)-1}, // Descriptive metadata + {WMP_tagCameraModel, WMP_typASCII, 1, (U32)-1}, // Descriptive metadata + {WMP_tagPageName, WMP_typASCII, 1, (U32)-1}, // Descriptive metadata + {WMP_tagPageNumber, WMP_typSHORT, 2, (U32)-1}, // Descriptive metadata + {WMP_tagSoftware, WMP_typASCII, 1, (U32)-1}, // Descriptive metadata + {WMP_tagDateTime, WMP_typASCII, 1, (U32)-1}, // Descriptive metadata + {WMP_tagArtist, WMP_typASCII, 1, (U32)-1}, // Descriptive metadata + {WMP_tagHostComputer, WMP_typASCII, 1, (U32)-1}, // Descriptive metadata + {WMP_tagRatingStars, WMP_typSHORT, 1, (U32)-1}, // Descriptive metadata + {WMP_tagRatingValue, WMP_typSHORT, 1, (U32)-1}, // Descriptive metadata + {WMP_tagCopyright, WMP_typASCII, 1, (U32)-1}, // Descriptive metadata + {WMP_tagCaption, WMP_typBYTE, 1, (U32)-1}, // Descriptive metadata + + {WMP_tagXMPMetadata, WMP_typBYTE, 1, (U32)-1}, + {WMP_tagIPTCNAAMetadata, WMP_typBYTE, 1, (U32)-1}, + {WMP_tagPhotoshopMetadata, WMP_typBYTE, 1, (U32)-1}, + {WMP_tagEXIFMetadata, WMP_typLONG, 1, (U32)-1}, + {WMP_tagIccProfile, WMP_typUNDEFINED, 1, (U32)-1}, + {WMP_tagGPSInfoMetadata, WMP_typLONG, 1, (U32)-1}, + + {WMP_tagPixelFormat, WMP_typBYTE, 16, (U32)-1}, + {WMP_tagTransformation, WMP_typLONG, 1, (U32)-1}, + {WMP_tagImageWidth, WMP_typLONG, 1, (U32)-1}, + {WMP_tagImageHeight, WMP_typLONG, 1, (U32)-1}, + {WMP_tagWidthResolution, WMP_typFLOAT, 1, (U32)-1}, + {WMP_tagHeightResolution, WMP_typFLOAT, 1, (U32)-1}, + {WMP_tagImageOffset, WMP_typLONG, 1, (U32)-1}, + {WMP_tagImageByteCount, WMP_typLONG, 1, (U32)-1}, + {WMP_tagAlphaOffset, WMP_typLONG, 1, (U32)-1}, + {WMP_tagAlphaByteCount, WMP_typLONG, 1, (U32)-1}, + }; + U16 cWmpDEs = sizeof(wmpDEs) / sizeof(wmpDEs[0]); + WmpDE wmpDE = { 0 }; + size_t i = 0; + + U8* pbEXIFMetadata = NULL; + U8* pbGPSInfoMetadata = NULL; + + // const unsigned char Zero[0x20] = { 0 }; + const unsigned char Zero[sizeof(struct IFDEntry) * sizeof(wmpDEs) / sizeof(wmpDEs[0]) + sizeof(U32)] = { 0 }; + assert(SizeofIFDEntry * sizeof(wmpDEs) / sizeof(wmpDEs[0]) + sizeof(U32) > 0x20); + + //================ + Call(pWS->GetPos(pWS, &offPos)); + FailIf(0 != offPos, WMP_errUnsupportedFormat); + + //================ + // Header (8 bytes) + Call(pWS->Write(pWS, IIMM, sizeof(IIMM))); offPos += 2; + Call(PutUShort(pWS, offPos, 0x01bc)); offPos += 2; + Call(PutULong(pWS, offPos, (U32)OFFSET_OF_PFD)); offPos += 4; + + //================ + // Write overflow area + pDEMisc->uOffPixelFormat = (U32)offPos; + PI.pGUIDPixFmt = &pIE->guidPixFormat; + PixelFormatLookup(&PI, LOOKUP_FORWARD); + + //Call(pWS->Write(pWS, PI.pGUIDPixFmt, sizeof(*PI.pGUIDPixFmt))); offPos += 16; + /** following code is endian-agnostic **/ + { + unsigned char* pGuid = (unsigned char*)&pIE->guidPixFormat; + Call(PutULong(pWS, offPos, ((U32*)pGuid)[0])); + Call(PutUShort(pWS, offPos + 4, ((U16*)(pGuid + 4))[0])); + Call(PutUShort(pWS, offPos + 6, ((U16*)(pGuid + 6))[0])); + Call(pWS->Write(pWS, pGuid + 8, 8)); + offPos += 16; + } + + //================ + // Tally up space required for descriptive metadata + Call(CalcMetadataOffsetSize(pIE, &cInactiveMetadata, &cbMetadataOffsetSize)); + cWmpDEs -= cInactiveMetadata; + + //================ + // PFD + assert(offPos <= OFFSET_OF_PFD); // otherwise stuff is overwritten + if (offPos < OFFSET_OF_PFD) + Call(pWS->Write(pWS, Zero, OFFSET_OF_PFD - offPos)); + offPos = (size_t)OFFSET_OF_PFD; + + if (!pIE->WMP.bHasAlpha || pIE->WMP.wmiSCP.uAlphaMode != 2) //no planar alpha + cWmpDEs -= 2; + + if (0 == pIE->cbXMPMetadataByteCount) + cWmpDEs -= 1; // No XMP metadata + + if (0 == pIE->cbIPTCNAAMetadataByteCount) + cWmpDEs -= 1; // No IPTCNAA metadata + + if (0 == pIE->cbPhotoshopMetadataByteCount) + cWmpDEs -= 1; // No Photoshop metadata + + if (0 == pIE->cbEXIFMetadataByteCount) + cWmpDEs -= 1; // No EXIF metadata + + if (0 == pIE->cbColorContext) + cWmpDEs -= 1; // No color context + + if (0 == pIE->cbGPSInfoMetadataByteCount) + cWmpDEs -= 1; // No GPSInfo metadata + + pDEMisc->uImageOffset = (U32)(offPos + sizeof(U16) + SizeofIFDEntry * cWmpDEs + sizeof(U32)); + + if (cbMetadataOffsetSize > 0) + { + pDEMisc->uDescMetadataByteCount = cbMetadataOffsetSize; + pDEMisc->uDescMetadataOffset = pDEMisc->uImageOffset; + pDEMisc->uImageOffset += cbMetadataOffsetSize; + } + + if (pIE->cbXMPMetadataByteCount > 0) + { + pDEMisc->uXMPMetadataOffset = pDEMisc->uImageOffset; + pDEMisc->uImageOffset += pIE->cbXMPMetadataByteCount; + } + + if (pIE->cbIPTCNAAMetadataByteCount > 0) + { + pDEMisc->uIPTCNAAMetadataOffset = pDEMisc->uImageOffset; + pDEMisc->uImageOffset += pIE->cbIPTCNAAMetadataByteCount; + } + + if (pIE->cbPhotoshopMetadataByteCount > 0) + { + pDEMisc->uPhotoshopMetadataOffset = pDEMisc->uImageOffset; + pDEMisc->uImageOffset += pIE->cbPhotoshopMetadataByteCount; + } + + if (pIE->cbEXIFMetadataByteCount > 0) + { + pDEMisc->uEXIFMetadataOffset = pDEMisc->uImageOffset; + pDEMisc->uImageOffset += (pDEMisc->uImageOffset & 1); + pDEMisc->uImageOffset += pIE->cbEXIFMetadataByteCount; + } + + if (pIE->cbColorContext > 0) + { + pDEMisc->uColorProfileOffset = pDEMisc->uImageOffset; + pDEMisc->uImageOffset += pIE->cbColorContext; + } + + if (pIE->cbGPSInfoMetadataByteCount > 0) + { + pDEMisc->uGPSInfoMetadataOffset = pDEMisc->uImageOffset; + pDEMisc->uImageOffset += (pDEMisc->uImageOffset & 1); + pDEMisc->uImageOffset += pIE->cbGPSInfoMetadataByteCount; + } + + Call(PutUShort(pWS, offPos, cWmpDEs)); offPos += 2; + Call(pWS->Write(pWS, Zero, SizeofIFDEntry * cWmpDEs + sizeof(U32))); + + //================ + wmpDE = wmpDEs[i++]; + assert(WMP_tagDocumentName == wmpDE.uTag); + Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarDocumentName, &wmpDE, + &uiCurrDescMetadataOffset, &offPos)); + + wmpDE = wmpDEs[i++]; + assert(WMP_tagImageDescription == wmpDE.uTag); + Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarImageDescription, &wmpDE, + &uiCurrDescMetadataOffset, &offPos)); + + wmpDE = wmpDEs[i++]; + assert(WMP_tagCameraMake == wmpDE.uTag); + Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarCameraMake, &wmpDE, + &uiCurrDescMetadataOffset, &offPos)); + + wmpDE = wmpDEs[i++]; + assert(WMP_tagCameraModel == wmpDE.uTag); + Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarCameraModel, &wmpDE, + &uiCurrDescMetadataOffset, &offPos)); + + wmpDE = wmpDEs[i++]; + assert(WMP_tagPageName == wmpDE.uTag); + Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarPageName, &wmpDE, + &uiCurrDescMetadataOffset, &offPos)); + + wmpDE = wmpDEs[i++]; + assert(WMP_tagPageNumber == wmpDE.uTag); + Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarPageNumber, &wmpDE, + &uiCurrDescMetadataOffset, &offPos)); + + wmpDE = wmpDEs[i++]; + assert(WMP_tagSoftware == wmpDE.uTag); + Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarSoftware, &wmpDE, + &uiCurrDescMetadataOffset, &offPos)); + + wmpDE = wmpDEs[i++]; + assert(WMP_tagDateTime == wmpDE.uTag); + Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarDateTime, &wmpDE, + &uiCurrDescMetadataOffset, &offPos)); + + wmpDE = wmpDEs[i++]; + assert(WMP_tagArtist == wmpDE.uTag); + Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarArtist, &wmpDE, + &uiCurrDescMetadataOffset, &offPos)); + + wmpDE = wmpDEs[i++]; + assert(WMP_tagHostComputer == wmpDE.uTag); + Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarHostComputer, &wmpDE, + &uiCurrDescMetadataOffset, &offPos)); + + wmpDE = wmpDEs[i++]; + assert(WMP_tagRatingStars == wmpDE.uTag); + Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarRatingStars, &wmpDE, + &uiCurrDescMetadataOffset, &offPos)); + + wmpDE = wmpDEs[i++]; + assert(WMP_tagRatingValue == wmpDE.uTag); + Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarRatingValue, &wmpDE, + &uiCurrDescMetadataOffset, &offPos)); + + wmpDE = wmpDEs[i++]; + assert(WMP_tagCopyright == wmpDE.uTag); + Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarCopyright, &wmpDE, + &uiCurrDescMetadataOffset, &offPos)); + + wmpDE = wmpDEs[i++]; + assert(WMP_tagCaption == wmpDE.uTag); + Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarCaption, &wmpDE, + &uiCurrDescMetadataOffset, &offPos)); + + // XMP Metadata + wmpDE = wmpDEs[i++]; + assert(WMP_tagXMPMetadata == wmpDE.uTag); + if (pIE->cbXMPMetadataByteCount > 0) + { + U32 uiTemp; + wmpDE.uCount = pIE->cbXMPMetadataByteCount; + wmpDE.uValueOrOffset = pDEMisc->uXMPMetadataOffset; + Call(WriteWmpDE(pWS, &offPos, &wmpDE, pIE->pbXMPMetadata, &uiTemp)); + } + + // IPTCNAA Metadata + wmpDE = wmpDEs[i++]; + assert(WMP_tagIPTCNAAMetadata == wmpDE.uTag); + if (pIE->cbIPTCNAAMetadataByteCount > 0) + { + U32 uiTemp; + wmpDE.uCount = pIE->cbIPTCNAAMetadataByteCount; + wmpDE.uValueOrOffset = pDEMisc->uIPTCNAAMetadataOffset; + Call(WriteWmpDE(pWS, &offPos, &wmpDE, pIE->pbIPTCNAAMetadata, &uiTemp)); + } + + // Photoshop Metadata + wmpDE = wmpDEs[i++]; + assert(WMP_tagPhotoshopMetadata == wmpDE.uTag); + if (pIE->cbPhotoshopMetadataByteCount > 0) + { + U32 uiTemp; + wmpDE.uCount = pIE->cbPhotoshopMetadataByteCount; + wmpDE.uValueOrOffset = pDEMisc->uPhotoshopMetadataOffset; + Call(WriteWmpDE(pWS, &offPos, &wmpDE, pIE->pbPhotoshopMetadata, &uiTemp)); + } + + // EXIF Metadata + wmpDE = wmpDEs[i++]; + assert(WMP_tagEXIFMetadata == wmpDE.uTag); + if (pIE->cbEXIFMetadataByteCount > 0) + { + U32 uiTemp; + if ((pDEMisc->uEXIFMetadataOffset & 1) != 0) + { + Call(pWS->SetPos(pWS, pDEMisc->uEXIFMetadataOffset)); + Call(pWS->Write(pWS, Zero, 1)); + } + pDEMisc->uEXIFMetadataOffset += (pDEMisc->uEXIFMetadataOffset & 1); + wmpDE.uValueOrOffset = pDEMisc->uEXIFMetadataOffset; + Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); + + Call(PKAlloc((void**)&pbEXIFMetadata, pIE->cbEXIFMetadataByteCount)); + uiTemp = pDEMisc->uEXIFMetadataOffset; + Call(BufferCopyIFD(pIE->pbEXIFMetadata, pIE->cbEXIFMetadataByteCount, 0, WMP_INTEL_ENDIAN, + pbEXIFMetadata - uiTemp, uiTemp + pIE->cbEXIFMetadataByteCount, &uiTemp)); + Call(pWS->SetPos(pWS, pDEMisc->uEXIFMetadataOffset)); + Call(pWS->Write(pWS, pbEXIFMetadata, pIE->cbEXIFMetadataByteCount)); + } + + // ICC Profile + wmpDE = wmpDEs[i++]; + assert(WMP_tagIccProfile == wmpDE.uTag); + if (pIE->cbColorContext > 0) + { + U32 uiTemp; + wmpDE.uCount = pIE->cbColorContext; + wmpDE.uValueOrOffset = pDEMisc->uColorProfileOffset; + Call(WriteWmpDE(pWS, &offPos, &wmpDE, pIE->pbColorContext, &uiTemp)); + } + + // GPSInfo Metadata + wmpDE = wmpDEs[i++]; + assert(WMP_tagGPSInfoMetadata == wmpDE.uTag); + if (pIE->cbGPSInfoMetadataByteCount > 0) + { + U32 uiTemp; + if ((pDEMisc->uGPSInfoMetadataOffset & 1) != 0) + { + Call(pWS->SetPos(pWS, pDEMisc->uGPSInfoMetadataOffset)); + Call(pWS->Write(pWS, Zero, 1)); + } + pDEMisc->uGPSInfoMetadataOffset += (pDEMisc->uGPSInfoMetadataOffset & 1); + wmpDE.uValueOrOffset = pDEMisc->uGPSInfoMetadataOffset; + Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); + + Call(PKAlloc((void**)&pbGPSInfoMetadata, pIE->cbGPSInfoMetadataByteCount)); + uiTemp = pDEMisc->uGPSInfoMetadataOffset; + Call(BufferCopyIFD(pIE->pbGPSInfoMetadata, pIE->cbGPSInfoMetadataByteCount, 0, WMP_INTEL_ENDIAN, + pbGPSInfoMetadata - uiTemp, uiTemp + pIE->cbGPSInfoMetadataByteCount, &uiTemp)); + Call(pWS->SetPos(pWS, pDEMisc->uGPSInfoMetadataOffset)); + Call(pWS->Write(pWS, pbGPSInfoMetadata, pIE->cbGPSInfoMetadataByteCount)); + } + + wmpDE = wmpDEs[i++]; + assert(WMP_tagPixelFormat == wmpDE.uTag); + wmpDE.uValueOrOffset = pDEMisc->uOffPixelFormat; + Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); + + wmpDE = wmpDEs[i++]; + assert(WMP_tagTransformation == wmpDE.uTag); + wmpDE.uValueOrOffset = pIE->WMP.oOrientation; + Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); + + wmpDE = wmpDEs[i++]; + assert(WMP_tagImageWidth == wmpDE.uTag); + wmpDE.uValueOrOffset = pIE->uWidth; + Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); + + wmpDE = wmpDEs[i++]; + assert(WMP_tagImageHeight == wmpDE.uTag); + wmpDE.uValueOrOffset = pIE->uHeight; + Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); + + wmpDE = wmpDEs[i++]; + assert(WMP_tagWidthResolution == wmpDE.uTag); + *((float*)&wmpDE.uValueOrOffset) = pIE->fResX; + Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); + + wmpDE = wmpDEs[i++]; + assert(WMP_tagHeightResolution == wmpDE.uTag); + *((float*)&wmpDE.uValueOrOffset) = pIE->fResY; + Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); + + wmpDE = wmpDEs[i++]; + assert(WMP_tagImageOffset == wmpDE.uTag); + wmpDE.uValueOrOffset = pDEMisc->uImageOffset; + Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); + + // fix up in WriteContainerPost() + wmpDE = wmpDEs[i++]; + assert(WMP_tagImageByteCount == wmpDE.uTag); + pDEMisc->uOffImageByteCount = (U32)offPos; + wmpDE.uValueOrOffset = 0; + Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); + + if (pIE->WMP.bHasAlpha && pIE->WMP.wmiSCP.uAlphaMode == 2) + { + // fix up in WriteContainerPost() + wmpDE = wmpDEs[i++]; + assert(WMP_tagAlphaOffset == wmpDE.uTag); + pDEMisc->uOffAlphaOffset = (U32)offPos; + wmpDE.uValueOrOffset = 0; + Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); + + // fix up in WriteContainerPost() + wmpDE = wmpDEs[i++]; + assert(WMP_tagAlphaByteCount == wmpDE.uTag); + pDEMisc->uOffAlphaByteCount = (U32)offPos; + wmpDE.uValueOrOffset = 0; + Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); + } + + //================ + Call(PutULong(pWS, offPos, 0)); offPos += 4; + + assert(0 == (offPos & 1)); + if (pDEMisc->uColorProfileOffset > 0 || pDEMisc->uDescMetadataOffset > 0 || + pDEMisc->uXMPMetadataOffset > 0 || pDEMisc->uIPTCNAAMetadataOffset > 0 || + pDEMisc->uPhotoshopMetadataOffset > 0 || pDEMisc->uEXIFMetadataOffset > 0 || + pDEMisc->uGPSInfoMetadataOffset > 0) + { + assert(pDEMisc->uColorProfileOffset == offPos || + pDEMisc->uDescMetadataOffset == offPos || + pDEMisc->uXMPMetadataOffset == offPos || + pDEMisc->uIPTCNAAMetadataOffset == offPos || + pDEMisc->uPhotoshopMetadataOffset == offPos || + pDEMisc->uEXIFMetadataOffset == offPos || + pDEMisc->uGPSInfoMetadataOffset == offPos); + + // OK, now skip to image offset + Call(pWS->SetPos(pWS, pDEMisc->uImageOffset)); + offPos = pDEMisc->uImageOffset; + } + assert(pDEMisc->uImageOffset == offPos); + +Cleanup: + if (pbEXIFMetadata != NULL) + PKFree((void**)&pbEXIFMetadata); + if (pbGPSInfoMetadata != NULL) + PKFree((void**)&pbGPSInfoMetadata); + return err; +} + + + +ERR WriteContainerPost( + PKImageEncode* pIE) +{ + ERR err = WMP_errSuccess; + + struct WMPStream* pWS = pIE->pStream; + WmpDEMisc* pDEMisc = &pIE->WMP.wmiDEMisc; + size_t offPos; + + WmpDE deImageByteCount = { WMP_tagImageByteCount, WMP_typLONG, 1, 0 }; + WmpDE deAlphaOffset = { WMP_tagAlphaOffset, WMP_typLONG, 1, 0 }; + WmpDE deAlphaByteCount = { WMP_tagAlphaByteCount, WMP_typLONG, 1, 0 }; + + deImageByteCount.uValueOrOffset = pIE->WMP.nCbImage; + offPos = pDEMisc->uOffImageByteCount; + Call(WriteWmpDE(pWS, &offPos, &deImageByteCount, NULL, NULL)); + + //Alpha + if (pIE->WMP.bHasAlpha && pIE->WMP.wmiSCP.uAlphaMode == 2) + { + deAlphaOffset.uValueOrOffset = pIE->WMP.nOffAlpha; + offPos = pDEMisc->uOffAlphaOffset; + Call(WriteWmpDE(pWS, &offPos, &deAlphaOffset, NULL, NULL)); + + deAlphaByteCount.uValueOrOffset = pIE->WMP.nCbAlpha + pIE->WMP.nOffAlpha; + offPos = pDEMisc->uOffAlphaByteCount; + Call(WriteWmpDE(pWS, &offPos, &deAlphaByteCount, NULL, NULL)); + } + +Cleanup: + return err; +} + + +//================================================ +ERR PKImageEncode_Initialize_WMP( + PKImageEncode* pIE, + struct WMPStream* pStream, + void* pvParam, + size_t cbParam) +{ + ERR err = WMP_errSuccess; + + FailIf(sizeof(pIE->WMP.wmiSCP) != cbParam, WMP_errInvalidArgument); + + pIE->WMP.wmiSCP = *(CWMIStrCodecParam*)pvParam; + pIE->WMP.wmiSCP_Alpha = *(CWMIStrCodecParam*)pvParam; + pIE->pStream = pStream; + + pIE->WMP.wmiSCP.pWStream = pIE->pStream; + pIE->WMP.wmiSCP_Alpha.pWStream = pIE->pStream; + +Cleanup: + return err; +} + +ERR PKImageEncode_Terminate_WMP( + PKImageEncode* pIE) +{ + ERR err = WMP_errSuccess; + UNREFERENCED_PARAMETER(pIE); + return err; +} + + +ERR PKImageEncode_EncodeContent_Init( + PKImageEncode* pIE, + PKPixelInfo PI, + U32 cLine, + U8* pbPixels, + U32 cbStride) +{ + ERR err = WMP_errSuccess; + + // init codec + pIE->WMP.wmiI.cWidth = pIE->uWidth; + pIE->WMP.wmiI.cHeight = pIE->uHeight; + pIE->WMP.wmiI.bdBitDepth = PI.bdBitDepth; + pIE->WMP.wmiI.cBitsPerUnit = PI.cbitUnit; + pIE->WMP.wmiI.bRGB = !(PI.grBit & PK_pixfmtBGR); + pIE->WMP.wmiI.cfColorFormat = PI.cfColorFormat; + pIE->WMP.wmiI.oOrientation = pIE->WMP.oOrientation; + + // Set the fPaddedUserBuffer if the following conditions are met + if (0 == ((size_t)pbPixels % 128) && // Frame buffer is aligned to 128-byte boundary + 0 == (pIE->uWidth % 16) && // Horizontal resolution is multiple of 16 + 0 == (cLine % 16) && // Vertical resolution is multiple of 16 + 0 == (cbStride % 128)) // Stride is a multiple of 128 bytes + { + pIE->WMP.wmiI.fPaddedUserBuffer = TRUE; + // Note that there are additional conditions in strenc_x86.c's strEncOpt + // which could prevent optimization from being engaged + } + + //if (pIE->WMP.bHasAlpha) + //{ + // pIE->WMP.wmiSCP.cChannel = PI.cChannel - 1; + // pIE->WMP.wmiI.cfColorFormat = PI.cfStripAlpha; + //} + //else + + if (PI.cfColorFormat == NCOMPONENT && (!(PI.grBit & PK_pixfmtHasAlpha)))//N-channel without Alpha + pIE->WMP.wmiSCP.cChannel = PI.cChannel; + else + pIE->WMP.wmiSCP.cChannel = PI.cChannel - 1;//other formats and (N-channel + Alpha) + + pIE->idxCurrentLine = 0; + + pIE->WMP.wmiSCP.fMeasurePerf = TRUE; + FailIf(ICERR_OK != ImageStrEncInit(&pIE->WMP.wmiI, &pIE->WMP.wmiSCP, &pIE->WMP.ctxSC), WMP_errFail); + +Cleanup: + return err; +} + +ERR PKImageEncode_EncodeContent_Encode( + PKImageEncode* pIE, + U32 cLine, + U8* pbPixels, + U32 cbStride) +{ + ERR err = WMP_errSuccess; + U32 i = 0; + + //================================ + for (i = 0; i < cLine; i += 16) + { + Bool f420 = (pIE->WMP.wmiI.cfColorFormat == YUV_420 || + (pIE->WMP.wmiSCP.bYUVData && pIE->WMP.wmiSCP.cfColorFormat == YUV_420)); + CWMImageBufferInfo wmiBI = { 0 }; + wmiBI.pv = pbPixels + cbStride * i / (f420 ? 2 : 1); + wmiBI.cLine = min(16, cLine - i); + wmiBI.cbStride = cbStride; + FailIf(ICERR_OK != ImageStrEncEncode(pIE->WMP.ctxSC, &wmiBI), WMP_errFail); + } + pIE->idxCurrentLine += cLine; + +Cleanup: + return err; +} + +ERR PKImageEncode_EncodeContent_Term(PKImageEncode* pIE) +{ + ERR err = WMP_errSuccess; + + FailIf(ICERR_OK != ImageStrEncTerm(pIE->WMP.ctxSC), WMP_errFail); + +Cleanup: + return err; +} + +ERR PKImageEncode_EncodeContent( + PKImageEncode* pIE, + PKPixelInfo PI, + U32 cLine, + U8* pbPixels, + U32 cbStride) +{ + ERR err = WMP_errSuccess; + size_t offPos = 0; + + Call(pIE->pStream->GetPos(pIE->pStream, &offPos)); + pIE->WMP.nOffImage = (Long)offPos; + + Call(PKImageEncode_EncodeContent_Init(pIE, PI, cLine, pbPixels, cbStride)); + Call(PKImageEncode_EncodeContent_Encode(pIE, cLine, pbPixels, cbStride)); + Call(PKImageEncode_EncodeContent_Term(pIE)); + + Call(pIE->pStream->GetPos(pIE->pStream, &offPos)); + pIE->WMP.nCbImage = (Long)offPos - pIE->WMP.nOffImage; + +Cleanup: + return err; +} + + +ERR PKImageEncode_EncodeAlpha_Init( + PKImageEncode* pIE, + PKPixelInfo PI, + U32 cLine, + U8* pbPixels, + U32 cbStride) +{ + ERR err = WMP_errSuccess; + + UNREFERENCED_PARAMETER(cLine); + UNREFERENCED_PARAMETER(pbPixels); + UNREFERENCED_PARAMETER(cbStride); + + pIE->WMP.wmiI_Alpha = pIE->WMP.wmiI; + + pIE->WMP.wmiI_Alpha.cWidth = pIE->uWidth; + pIE->WMP.wmiI_Alpha.cHeight = pIE->uHeight; + pIE->WMP.wmiI_Alpha.bdBitDepth = PI.bdBitDepth; + pIE->WMP.wmiI_Alpha.cBitsPerUnit = PI.cbitUnit; + pIE->WMP.wmiI_Alpha.bRGB = !(PI.grBit & PK_pixfmtBGR); + pIE->WMP.wmiI.oOrientation = pIE->WMP.oOrientation; + // pIE->WMP.wmiI_Alpha.cLeadingPadding += pIE->WMP.wmiSCP.cChannel; + // pIE->WMP.wmiI_Alpha.cLeadingPadding += PI.cChannel - 1; + + switch (pIE->WMP.wmiI.bdBitDepth) + { + case BD_8: + pIE->WMP.wmiI_Alpha.cLeadingPadding += (pIE->WMP.wmiI.cBitsPerUnit >> 3) - 1; + break; + + case BD_16: + case BD_16S: + case BD_16F: + pIE->WMP.wmiI_Alpha.cLeadingPadding += (pIE->WMP.wmiI.cBitsPerUnit >> 3) / sizeof(U16) - 1; + break; + + case BD_32: + case BD_32S: + case BD_32F: + pIE->WMP.wmiI_Alpha.cLeadingPadding += (pIE->WMP.wmiI.cBitsPerUnit >> 3) / sizeof(float) - 1; + break; + + case BD_5: + case BD_10: + case BD_565: + default: + break; + } + + // pIE->WMP.wmiSCP_Alpha.uAlphaMode = 1; + + + //assert(pIE->WMP.wmiI_Alpha.cfColorFormat == CF_RGB); // only RGBA is supported for now! + pIE->WMP.wmiI_Alpha.cfColorFormat = Y_ONLY; + + pIE->WMP.wmiSCP_Alpha.cfColorFormat = Y_ONLY; + + pIE->idxCurrentLine = 0; + pIE->WMP.wmiSCP_Alpha.fMeasurePerf = TRUE; + FailIf(ICERR_OK != ImageStrEncInit(&pIE->WMP.wmiI_Alpha, &pIE->WMP.wmiSCP_Alpha, &pIE->WMP.ctxSC_Alpha), WMP_errFail); + +Cleanup: + return err; +} + +ERR PKImageEncode_EncodeAlpha_Encode( + PKImageEncode* pIE, + U32 cLine, + U8* pbPixels, + U32 cbStride) +{ + ERR err = WMP_errSuccess; + U32 i = 0; + + //================================ + for (i = 0; i < cLine; i += 16) + { + CWMImageBufferInfo wmiBI = { 0 }; + wmiBI.pv = pbPixels + cbStride * i; + wmiBI.cLine = min(16, cLine - i); + wmiBI.cbStride = cbStride; + FailIf(ICERR_OK != ImageStrEncEncode(pIE->WMP.ctxSC_Alpha, &wmiBI), WMP_errFail); + } + pIE->idxCurrentLine += cLine; + +Cleanup: + return err; +} + +ERR PKImageEncode_EncodeAlpha_Term(PKImageEncode* pIE) +{ + ERR err = WMP_errSuccess; + + FailIf(ICERR_OK != ImageStrEncTerm(pIE->WMP.ctxSC_Alpha), WMP_errFail); + +Cleanup: + return err; +} + +ERR PKImageEncode_EncodeAlpha( + PKImageEncode* pIE, + PKPixelInfo PI, + U32 cLine, + U8* pbPixels, + U32 cbStride) +{ + ERR err = WMP_errSuccess; + size_t offPos = 0; + + Call(pIE->pStream->GetPos(pIE->pStream, &offPos)); + if ((offPos & 1) != 0) + { + // Make the mark even if it is odd by inserting a pad byte + char zero = 0; + Call(pIE->pStream->Write(pIE->pStream, &zero, 1)); + offPos++; + } + pIE->WMP.nOffAlpha = (Long)offPos; + + Call(PKImageEncode_EncodeAlpha_Init(pIE, PI, cLine, pbPixels, cbStride)); + Call(PKImageEncode_EncodeAlpha_Encode(pIE, cLine, pbPixels, cbStride)); + Call(PKImageEncode_EncodeAlpha_Term(pIE)); + + Call(pIE->pStream->GetPos(pIE->pStream, &offPos)); + pIE->WMP.nCbAlpha = (Long)offPos - pIE->WMP.nOffAlpha; + +Cleanup: + return err; +} + + + +static ERR SetMetadata(PKImageEncode* pIE, const U8* pbMetadata, U32 cbMetadata, U8** pbSet, U32* pcbSet) +{ + ERR err = WMP_errSuccess; + + // Fail if the caller called us after we've already written the header out + if (pIE->fHeaderDone) + { + assert(FALSE); // Message to programmer + err = WMP_errOutOfSequence; + goto Cleanup; + } + + // Make a copy of the metadata + PKFree((void**)pbSet); + *pcbSet = 0; + + Call(PKAlloc((void**)pbSet, cbMetadata)); + memcpy(*pbSet, pbMetadata, cbMetadata); + *pcbSet = cbMetadata; + +Cleanup: + return err; +} + + + +ERR PKImageEncode_SetColorContext_WMP(PKImageEncode* pIE, + const U8* pbColorContext, + U32 cbColorContext) +{ + return SetMetadata(pIE, pbColorContext, cbColorContext, &pIE->pbColorContext, &pIE->cbColorContext); +} + + + +ERR PKImageEncode_SetXMPMetadata_WMP(PKImageEncode* pIE, const U8* pbXMPMetadata, U32 cbXMPMetadata) +{ // same as the other Set's, but make sure dc:format is image/vnd.ms-photo + ERR err = WMP_errSuccess; + char* pbTemp = 0; + U32 cbTemp; + char* pszFormatBegin; + // const char* pszXMPMetadata = (const char*)pbXMPMetadata; + size_t cbBuffer; + + // Fail if the caller called us after we've already written the header out + FailIf(pIE->fHeaderDone, WMP_errOutOfSequence); + + // Free any previously set XMP metadata + PKFree((void**)&pIE->pbXMPMetadata); + pIE->cbXMPMetadataByteCount = 0; + + // allocate a block big enough for data passed in plus added trailing null plus added HD Photo dc:format + // there may already be a trailing null (but ps doesn't seem to) + // there may already be a dc:format we will replace with HD Photo's + // but anyway this block will be large enough guaranteed + cbBuffer = cbXMPMetadata + 1 + sizeof("") - 1 + sizeof("") - 1 + sizeof(szHDPhotoFormat) - 1; + Call(PKAlloc((void**)&pbTemp, cbBuffer)); + memcpy(pbTemp, pbXMPMetadata, cbXMPMetadata); // Make a copy of the metadata + pbTemp[cbXMPMetadata] = '\0'; + cbXMPMetadata = (U32)strlen(pbTemp); + pszFormatBegin = strstr(pbTemp, ""); + if (pszFormatBegin != 0) + { + char* pszFormatEnd; + const char* pszLessThan; + + pszFormatEnd = strstr(pszFormatBegin, ""); + FailIf(pszFormatEnd == 0, WMP_errFail); + pszLessThan = strchr(pszFormatBegin + sizeof("") - 1, '<'); + FailIf(pszLessThan != pszFormatEnd, WMP_errFail); + pszFormatEnd += sizeof("") - 1; + + // photoshop doesn't put a trailing null, so we don't either + // hd and tiff don't put a trailing null, so we don't either + cbTemp = cbXMPMetadata - (U32)(pszFormatEnd - pszFormatBegin) + sizeof(szHDPhotoFormat) - 1; + assert(cbTemp <= cbBuffer); + FailIf(0 != STRCPY_SAFE(pszFormatBegin, + cbBuffer - (pszFormatBegin - pbTemp), + szHDPhotoFormat), + WMP_errBufferOverflow); + memcpy(pszFormatBegin + sizeof(szHDPhotoFormat) - 1, pbXMPMetadata + (pszFormatEnd - pbTemp), + cbXMPMetadata - (pszFormatEnd - pbTemp)); + } + else + { + cbTemp = cbXMPMetadata; + } + + pIE->pbXMPMetadata = (U8*)pbTemp; + pIE->cbXMPMetadataByteCount = cbTemp; + return (err); + +Cleanup: + PKFree((void**)&pbTemp); + pIE->cbXMPMetadataByteCount = 0; + return err; +} + + + +ERR PKImageEncode_SetEXIFMetadata_WMP(PKImageEncode* pIE, const U8* pbEXIFMetadata, U32 cbEXIFMetadata) +{ + return SetMetadata(pIE, pbEXIFMetadata, cbEXIFMetadata, + &pIE->pbEXIFMetadata, &pIE->cbEXIFMetadataByteCount); +} + + + +ERR PKImageEncode_SetGPSInfoMetadata_WMP(PKImageEncode* pIE, const U8* pbGPSInfoMetadata, U32 cbGPSInfoMetadata) +{ + return SetMetadata(pIE, pbGPSInfoMetadata, cbGPSInfoMetadata, + &pIE->pbGPSInfoMetadata, &pIE->cbGPSInfoMetadataByteCount); +} + + + +ERR PKImageEncode_SetIPTCNAAMetadata_WMP(PKImageEncode* pIE, const U8* pbIPTCNAAMetadata, U32 cbIPTCNAAMetadata) +{ + return SetMetadata(pIE, pbIPTCNAAMetadata, cbIPTCNAAMetadata, + &pIE->pbIPTCNAAMetadata, &pIE->cbIPTCNAAMetadataByteCount); +} + + + +ERR PKImageEncode_SetPhotoshopMetadata_WMP(PKImageEncode* pIE, const U8* pbPhotoshopMetadata, U32 cbPhotoshopMetadata) +{ + return SetMetadata(pIE, pbPhotoshopMetadata, cbPhotoshopMetadata, + &pIE->pbPhotoshopMetadata, &pIE->cbPhotoshopMetadataByteCount); +} + + + +ERR PKImageEncode_SetDescriptiveMetadata_WMP(PKImageEncode* pIE, const DESCRIPTIVEMETADATA* pSrcMeta) +{ + ERR err = WMP_errSuccess; + DESCRIPTIVEMETADATA* pDstMeta = &pIE->sDescMetadata; + + // Fail if the caller called us after we've already written the header out + if (pIE->fHeaderDone) + { + assert(FALSE); // Message to programmer + FailIf(TRUE, WMP_errOutOfSequence); + } + + // Make a copy of the descriptive metadata + Call(CopyDescMetadata(&pDstMeta->pvarImageDescription, pSrcMeta->pvarImageDescription)); + Call(CopyDescMetadata(&pDstMeta->pvarCameraMake, pSrcMeta->pvarCameraMake)); + Call(CopyDescMetadata(&pDstMeta->pvarCameraModel, pSrcMeta->pvarCameraModel)); + Call(CopyDescMetadata(&pDstMeta->pvarSoftware, pSrcMeta->pvarSoftware)); + Call(CopyDescMetadata(&pDstMeta->pvarDateTime, pSrcMeta->pvarDateTime)); + Call(CopyDescMetadata(&pDstMeta->pvarArtist, pSrcMeta->pvarArtist)); + Call(CopyDescMetadata(&pDstMeta->pvarCopyright, pSrcMeta->pvarCopyright)); + Call(CopyDescMetadata(&pDstMeta->pvarRatingStars, pSrcMeta->pvarRatingStars)); + Call(CopyDescMetadata(&pDstMeta->pvarRatingValue, pSrcMeta->pvarRatingValue)); + Call(CopyDescMetadata(&pDstMeta->pvarCaption, pSrcMeta->pvarCaption)); + Call(CopyDescMetadata(&pDstMeta->pvarDocumentName, pSrcMeta->pvarDocumentName)); + Call(CopyDescMetadata(&pDstMeta->pvarPageName, pSrcMeta->pvarPageName)); + Call(CopyDescMetadata(&pDstMeta->pvarPageNumber, pSrcMeta->pvarPageNumber)); + Call(CopyDescMetadata(&pDstMeta->pvarHostComputer, pSrcMeta->pvarHostComputer)); + +Cleanup: + return err; +} + + + +ERR PKImageEncode_WritePixels_WMP( + PKImageEncode* pIE, + U32 cLine, + U8* pbPixels, + U32 cbStride) +{ + ERR err = WMP_errSuccess; + // U32 i = 0; + PKPixelInfo PI; + + // Performing non-banded encode + assert(BANDEDENCSTATE_UNINITIALIZED == pIE->WMP.eBandedEncState); + pIE->WMP.eBandedEncState = BANDEDENCSTATE_NONBANDEDENCODE; + + PI.pGUIDPixFmt = &pIE->guidPixFormat; + PixelFormatLookup(&PI, LOOKUP_FORWARD); + pIE->WMP.bHasAlpha = !!(PI.grBit & PK_pixfmtHasAlpha); + + if (!pIE->fHeaderDone) + { + // write metadata + Call(WriteContainerPre(pIE)); + + pIE->fHeaderDone = !FALSE; + } + + /* if (pIE->WMP.bHasAlpha && pIE->WMP.wmiSCP.uAlphaMode == 2){ + pIE->WMP.wmiSCP_Alpha = pIE->WMP.wmiSCP; + } + */ + Call(PKImageEncode_EncodeContent(pIE, PI, cLine, pbPixels, cbStride)); + if (pIE->WMP.bHasAlpha && pIE->WMP.wmiSCP.uAlphaMode == 2) {//planar alpha + Call(PKImageEncode_EncodeAlpha(pIE, PI, cLine, pbPixels, cbStride)); + } + + Call(WriteContainerPost(pIE)); + +Cleanup: + return err; +} + + +ERR PKImageEncode_WritePixelsBandedBegin_WMP(PKImageEncode* pIE, struct WMPStream* pPATempFile) +{ + ERR err = WMP_errSuccess; + + // Just make sure that we are in the correct state to begin a banded decode + assert(BANDEDENCSTATE_UNINITIALIZED == pIE->WMP.eBandedEncState); + pIE->WMP.eBandedEncState = BANDEDENCSTATE_INIT; + + // Save the planar alpha tempfile for future use + pIE->WMP.pPATempFile = pPATempFile; + + //Cleanup: + return err; +} + +ERR PKImageEncode_WritePixelsBanded_WMP(PKImageEncode* pIE, U32 cLine, U8* pbPixels, U32 cbStride, Bool fLastCall) +{ + ERR err = WMP_errSuccess; + PKPixelInfo PI = { 0 }; + Bool fPI = FALSE; + BANDEDENCSTATE eEncStateOrig = pIE->WMP.eBandedEncState; + struct WMPStream* pPATempFile = pIE->WMP.pPATempFile; + + // Unless this is the last call, reject inputs which are not multiples of 16 + FailIf(!fLastCall && 0 != cLine % 16, WMP_errMustBeMultipleOf16LinesUntilLastCall); + + if (!pIE->fHeaderDone || BANDEDENCSTATE_INIT == pIE->WMP.eBandedEncState) + { + PI.pGUIDPixFmt = &pIE->guidPixFormat; + PixelFormatLookup(&PI, LOOKUP_FORWARD); + pIE->WMP.bHasAlpha = !!(PI.grBit & PK_pixfmtHasAlpha); + fPI = TRUE; + + // Check if this is planar alpha: banded encode requires temp file + if (pIE->WMP.bHasAlpha && pIE->WMP.wmiSCP.uAlphaMode == 2) + { + FailIf(NULL == pPATempFile, WMP_errPlanarAlphaBandedEncRequiresTempFile); + } + } + + if (!pIE->fHeaderDone) + { + // write metadata + assert(fPI); + Call(WriteContainerPre(pIE)); + pIE->fHeaderDone = !FALSE; + } + + if (BANDEDENCSTATE_INIT == pIE->WMP.eBandedEncState) + { + // Record start of main content for future call to WriteContainerPost + size_t offPos; + Call(pIE->pStream->GetPos(pIE->pStream, &offPos)); + pIE->WMP.nOffImage = (Long)offPos; + + assert(fPI); + Call(PKImageEncode_EncodeContent_Init(pIE, PI, cLine, pbPixels, cbStride)); + pIE->WMP.eBandedEncState = BANDEDENCSTATE_ENCODING; + } + + Call(PKImageEncode_EncodeContent_Encode(pIE, cLine, pbPixels, cbStride)); + if (pIE->WMP.bHasAlpha && pIE->WMP.wmiSCP.uAlphaMode == 2) + { + //planar alpha + if (BANDEDENCSTATE_INIT == eEncStateOrig) + { + size_t offStart; + + // We assume the following which allows us to avoid saving state + Call(pPATempFile->GetPos(pPATempFile, &offStart)); + assert(0 == offStart); + assert(pIE->WMP.wmiSCP_Alpha.pWStream == pIE->WMP.wmiSCP.pWStream); + + // For planar alpha, we write the file to a temp file + pIE->WMP.wmiSCP_Alpha.pWStream = pPATempFile; + Call(PKImageEncode_EncodeAlpha_Init(pIE, PI, cLine, pbPixels, cbStride)); + } + + Call(PKImageEncode_EncodeAlpha_Encode(pIE, cLine, pbPixels, cbStride)); + } + +Cleanup: + return err; +} + +ERR PKImageEncode_WritePixelsBandedEnd_WMP(PKImageEncode* pIE) +{ + ERR err = WMP_errSuccess; + struct WMPStream* pMainStream = pIE->WMP.wmiSCP.pWStream; + size_t offAlpha; + + assert(BANDEDENCSTATE_ENCODING == pIE->WMP.eBandedEncState); + + // Finish off main content, update its length ptr for WriteContainerPost + Call(PKImageEncode_EncodeContent_Term(pIE)); + Call(pMainStream->GetPos(pIE->pStream, &offAlpha)); + pIE->WMP.nCbImage = (Long)offAlpha - pIE->WMP.nOffImage; + + if (pIE->WMP.bHasAlpha && pIE->WMP.wmiSCP.uAlphaMode == 2) + { + size_t cbAlpha; + size_t cbBytesCopied; + struct WMPStream* pAlphaStream = pIE->WMP.wmiSCP_Alpha.pWStream; + + assert(pAlphaStream != pMainStream); // Otherwise we didn't use a temp file + + // Close it up - this causes write to temp file + Call(PKImageEncode_EncodeAlpha_Term(pIE)); + + // Calculate size of alpha bitstream and its new offset + Call(pAlphaStream->GetPos(pAlphaStream, &cbAlpha)); + + // Copy alpha bitstream to end of main stream + cbBytesCopied = 0; + Call(pAlphaStream->SetPos(pAlphaStream, 0)); + while (cbBytesCopied < cbAlpha) + { + char rgbBuf[TEMPFILE_COPYBUF_SIZE]; + size_t cbCopy; + + cbCopy = min(sizeof(rgbBuf), cbAlpha - cbBytesCopied); + Call(pAlphaStream->Read(pAlphaStream, rgbBuf, cbCopy)); + Call(pMainStream->Write(pMainStream, rgbBuf, cbCopy)); + + cbBytesCopied += cbCopy; + } + assert(cbBytesCopied == cbAlpha); + + // Update alpha offset/length for WriteContainerPost + pIE->WMP.nOffAlpha = (Long)offAlpha; + pIE->WMP.nCbAlpha = (Long)cbAlpha; + } + + Call(WriteContainerPost(pIE)); + +Cleanup: + return err; +} + + +ERR PKImageEncode_Transcode_WMP( + PKImageEncode* pIE, + PKImageDecode* pID, + CWMTranscodingParam* pParam) +{ + ERR err = WMP_errSuccess; + Float fResX = 0, fResY = 0; + PKPixelFormatGUID pixGUID = { 0 }; + CWMTranscodingParam tcParamAlpha; + size_t offPos = 0; + Bool fPlanarAlpha; + PKPixelInfo PI; + + struct WMPStream* pWSDec = NULL; + struct WMPStream* pWSEnc = pIE->pStream; + + // pass through metadata + Call(pID->GetPixelFormat(pID, &pixGUID)); + Call(pIE->SetPixelFormat(pIE, pixGUID)); + + Call(pIE->SetSize(pIE, (I32)pParam->cWidth, (I32)pParam->cHeight)); + + Call(pID->GetResolution(pID, &fResX, &fResY)); + Call(pIE->SetResolution(pIE, fResX, fResY)); + + PI.pGUIDPixFmt = &pIE->guidPixFormat; + PixelFormatLookup(&PI, LOOKUP_FORWARD); + pIE->WMP.bHasAlpha = !!(PI.grBit & PK_pixfmtHasAlpha) && (2 == pParam->uAlphaMode); + assert(0 == pIE->WMP.bHasAlpha || (pParam->uAlphaMode == 2)); // Decode alpha mode does not match encode alpha mode! + + // Check for any situations where transcoder is being asked to convert alpha - we can't do this + // NOTE: Decoder's bHasAlpha parameter really means, "has PLANAR alpha" + PI.pGUIDPixFmt = &pixGUID; + PixelFormatLookup(&PI, LOOKUP_FORWARD); + FailIf(0 == (PI.grBit & PK_pixfmtHasAlpha) && pParam->uAlphaMode != 0, + WMP_errAlphaModeCannotBeTranscoded); // Destination is planar/interleaved, src has no alpha + FailIf(!!(PI.grBit & PK_pixfmtHasAlpha) && 2 == pParam->uAlphaMode && + FALSE == pID->WMP.bHasAlpha, WMP_errAlphaModeCannotBeTranscoded); // Destination is planar, src is interleaved + FailIf(!!(PI.grBit & PK_pixfmtHasAlpha) && 3 == pParam->uAlphaMode && + pID->WMP.bHasAlpha, WMP_errAlphaModeCannotBeTranscoded); // Destination is interleaved, src is planar + assert(/*pParam->uAlphaMode >= 0 &&*/ pParam->uAlphaMode <= 3); // All the above statements make this assumption + + fPlanarAlpha = pIE->WMP.bHasAlpha && (2 == pParam->uAlphaMode); + + // write matadata + Call(WriteContainerPre(pIE)); + + // Copy transcoding params for alpha (codec changes the struct) + if (fPlanarAlpha) + tcParamAlpha = *pParam; + + // write compressed bitstream + Call(pID->GetRawStream(pID, &pWSDec)); + + FailIf(ICERR_OK != WMPhotoTranscode(pWSDec, pWSEnc, pParam), WMP_errFail); + Call(pIE->pStream->GetPos(pIE->pStream, &offPos)); + pIE->WMP.nCbImage = (Long)offPos - pIE->WMP.nOffImage; + + if (fPlanarAlpha) + { + pIE->WMP.nOffAlpha = (Long)offPos; + + // Cue the stream to alpha block + assert(pID->WMP.wmiDEMisc.uAlphaOffset > 0); + Call(pWSDec->SetPos(pWSDec, pID->WMP.wmiDEMisc.uAlphaOffset)); + + FailIf(ICERR_OK != WMPhotoTranscode(pWSDec, pWSEnc, &tcParamAlpha), WMP_errFail); + Call(pIE->pStream->GetPos(pIE->pStream, &offPos)); + pIE->WMP.nCbAlpha = (Long)offPos - pIE->WMP.nOffAlpha; + } + + // fixup matadata + Call(WriteContainerPost(pIE)); + +Cleanup: + return err; +} + +ERR PKImageEncode_CreateNewFrame_WMP( + PKImageEncode* pIE, + void* pvParam, + size_t cbParam) +{ + ERR err = WMP_errSuccess; + + UNREFERENCED_PARAMETER(pIE); + UNREFERENCED_PARAMETER(pvParam); + UNREFERENCED_PARAMETER(cbParam); + + Call(WMP_errNotYetImplemented); + +Cleanup: + return err; +} + +ERR PKImageEncode_Release_WMP( + PKImageEncode** ppIE) +{ + ERR err = WMP_errSuccess; + + PKImageEncode* pIE = *ppIE; + pIE->pStream->Close(&pIE->pStream); + + PKFree((void**)&pIE->pbColorContext); + pIE->cbColorContext = 0; + PKFree((void**)&pIE->pbXMPMetadata); + pIE->cbXMPMetadataByteCount = 0; + PKFree((void**)&pIE->pbEXIFMetadata); + pIE->cbEXIFMetadataByteCount = 0; + PKFree((void**)&pIE->pbGPSInfoMetadata); + pIE->cbGPSInfoMetadataByteCount = 0; + PKFree((void**)&pIE->pbIPTCNAAMetadata); + pIE->cbIPTCNAAMetadataByteCount = 0; + PKFree((void**)&pIE->pbPhotoshopMetadata); + pIE->cbPhotoshopMetadataByteCount = 0; + + // Free descriptive metadata + FreeDescMetadata(&pIE->sDescMetadata.pvarImageDescription); + FreeDescMetadata(&pIE->sDescMetadata.pvarCameraMake); + FreeDescMetadata(&pIE->sDescMetadata.pvarCameraModel); + FreeDescMetadata(&pIE->sDescMetadata.pvarSoftware); + FreeDescMetadata(&pIE->sDescMetadata.pvarDateTime); + FreeDescMetadata(&pIE->sDescMetadata.pvarArtist); + FreeDescMetadata(&pIE->sDescMetadata.pvarCopyright); + FreeDescMetadata(&pIE->sDescMetadata.pvarRatingStars); + FreeDescMetadata(&pIE->sDescMetadata.pvarRatingValue); + FreeDescMetadata(&pIE->sDescMetadata.pvarCaption); + FreeDescMetadata(&pIE->sDescMetadata.pvarDocumentName); + FreeDescMetadata(&pIE->sDescMetadata.pvarPageName); + FreeDescMetadata(&pIE->sDescMetadata.pvarPageNumber); + FreeDescMetadata(&pIE->sDescMetadata.pvarHostComputer); + + Call(PKFree((void**)ppIE)); + +Cleanup: + return err; +} + +//---------------------------------------------------------------- +ERR PKImageEncode_Create_WMP(PKImageEncode** ppIE) +{ + ERR err = WMP_errSuccess; + + PKImageEncode* pIE = NULL; + + Call(PKImageEncode_Create(ppIE)); + + pIE = *ppIE; + pIE->Initialize = PKImageEncode_Initialize_WMP; + pIE->Terminate = PKImageEncode_Terminate_WMP; + pIE->SetColorContext = PKImageEncode_SetColorContext_WMP; + pIE->SetDescriptiveMetadata = PKImageEncode_SetDescriptiveMetadata_WMP; + pIE->WritePixels = PKImageEncode_WritePixels_WMP; + + pIE->WritePixelsBandedBegin = PKImageEncode_WritePixelsBandedBegin_WMP; + pIE->WritePixelsBanded = PKImageEncode_WritePixelsBanded_WMP; + pIE->WritePixelsBandedEnd = PKImageEncode_WritePixelsBandedEnd_WMP; + + pIE->Transcode = PKImageEncode_Transcode_WMP; + pIE->CreateNewFrame = PKImageEncode_CreateNewFrame_WMP; + pIE->Release = PKImageEncode_Release_WMP; + pIE->bWMP = TRUE; + +Cleanup: + return err; +} + + +//================================================================ +// PKImageDecode_WMP +//================================================================ +ERR ParsePFDEntry( + PKImageDecode* pID, + U16 uTag, + U16 uType, + U32 uCount, + U32 uValue) +{ + ERR err = WMP_errSuccess; + ERR errTmp = WMP_errSuccess; + PKPixelInfo PI; + struct WMPStream* pWS = pID->pStream; + // size_t offPos = 0; + + union uf { + U32 uVal; + Float fVal; + }ufValue = { 0 }; + + //================================ + switch (uTag) + { + case WMP_tagPixelFormat: + { + unsigned char* pGuid = (unsigned char*)&pID->guidPixFormat; + /** following code is endian-agnostic **/ + Call(GetULong(pWS, uValue, (U32*)pGuid)); + Call(GetUShort(pWS, uValue + 4, (unsigned short*)(pGuid + 4))); + Call(GetUShort(pWS, uValue + 6, (unsigned short*)(pGuid + 6))); + Call(pWS->Read(pWS, pGuid + 8, 8)); + + PI.pGUIDPixFmt = &pID->guidPixFormat; + PixelFormatLookup(&PI, LOOKUP_FORWARD); + + pID->WMP.bHasAlpha = !!(PI.grBit & PK_pixfmtHasAlpha); + pID->WMP.wmiI.cBitsPerUnit = PI.cbitUnit; + pID->WMP.wmiI.bRGB = !(PI.grBit & PK_pixfmtBGR); + + break; + } + + case WMP_tagTransformation: + FailIf(1 != uCount, WMP_errUnsupportedFormat); + assert(uValue < O_MAX); + pID->WMP.fOrientationFromContainer = TRUE; + pID->WMP.oOrientationFromContainer = uValue; + break; + + case WMP_tagImageWidth: + FailIf(0 == uValue, WMP_errUnsupportedFormat); + break; + + case WMP_tagImageHeight: + FailIf(0 == uValue, WMP_errUnsupportedFormat); + break; + + case WMP_tagImageOffset: + FailIf(1 != uCount, WMP_errUnsupportedFormat); + pID->WMP.wmiDEMisc.uImageOffset = uValue; + break; + + case WMP_tagImageByteCount: + FailIf(1 != uCount, WMP_errUnsupportedFormat); + pID->WMP.wmiDEMisc.uImageByteCount = uValue; + break; + + case WMP_tagAlphaOffset: + FailIf(1 != uCount, WMP_errUnsupportedFormat); + pID->WMP.wmiDEMisc.uAlphaOffset = uValue; + break; + + case WMP_tagAlphaByteCount: + FailIf(1 != uCount, WMP_errUnsupportedFormat); + pID->WMP.wmiDEMisc.uAlphaByteCount = uValue; + break; + + case WMP_tagWidthResolution: + FailIf(1 != uCount, WMP_errUnsupportedFormat); + ufValue.uVal = uValue; + pID->fResX = ufValue.fVal; + break; + + case WMP_tagHeightResolution: + FailIf(1 != uCount, WMP_errUnsupportedFormat); + ufValue.uVal = uValue; + pID->fResY = ufValue.fVal; + break; + + case WMP_tagIccProfile: + pID->WMP.wmiDEMisc.uColorProfileByteCount = uCount; + pID->WMP.wmiDEMisc.uColorProfileOffset = uValue; + break; + + case WMP_tagXMPMetadata: + pID->WMP.wmiDEMisc.uXMPMetadataByteCount = uCount; + pID->WMP.wmiDEMisc.uXMPMetadataOffset = uValue; + break; + + case WMP_tagEXIFMetadata: + pID->WMP.wmiDEMisc.uEXIFMetadataOffset = uValue; + CallIgnoreError(errTmp, StreamCalcIFDSize(pWS, uValue, &pID->WMP.wmiDEMisc.uEXIFMetadataByteCount)); + break; + + case WMP_tagGPSInfoMetadata: + pID->WMP.wmiDEMisc.uGPSInfoMetadataOffset = uValue; + CallIgnoreError(errTmp, StreamCalcIFDSize(pWS, uValue, &pID->WMP.wmiDEMisc.uGPSInfoMetadataByteCount)); + break; + + case WMP_tagIPTCNAAMetadata: + pID->WMP.wmiDEMisc.uIPTCNAAMetadataByteCount = uCount; + pID->WMP.wmiDEMisc.uIPTCNAAMetadataOffset = uValue; + break; + + case WMP_tagPhotoshopMetadata: + pID->WMP.wmiDEMisc.uPhotoshopMetadataByteCount = uCount; + pID->WMP.wmiDEMisc.uPhotoshopMetadataOffset = uValue; + break; + + case WMP_tagCompression: + case WMP_tagImageType: + case WMP_tagImageDataDiscard: + case WMP_tagAlphaDataDiscard: + break; + + // Descriptive Metadata + case WMP_tagImageDescription: + CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, + &pID->WMP.sDescMetadata.pvarImageDescription)); + assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarImageDescription.vt); + break; + + case WMP_tagCameraMake: + CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, + &pID->WMP.sDescMetadata.pvarCameraMake)); + assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarCameraMake.vt); + break; + + case WMP_tagCameraModel: + CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, + &pID->WMP.sDescMetadata.pvarCameraModel)); + assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarCameraModel.vt); + break; + + case WMP_tagSoftware: + CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, + &pID->WMP.sDescMetadata.pvarSoftware)); + assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarSoftware.vt); + break; + + case WMP_tagDateTime: + CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, + &pID->WMP.sDescMetadata.pvarDateTime)); + assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarDateTime.vt); + break; + + case WMP_tagArtist: + CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, + &pID->WMP.sDescMetadata.pvarArtist)); + assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarArtist.vt); + break; + + case WMP_tagCopyright: + CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, + &pID->WMP.sDescMetadata.pvarCopyright)); + assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarCopyright.vt); + break; + + case WMP_tagRatingStars: + CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, + &pID->WMP.sDescMetadata.pvarRatingStars)); + assert(DPKVT_UI2 == pID->WMP.sDescMetadata.pvarRatingStars.vt); + break; + + case WMP_tagRatingValue: + CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, + &pID->WMP.sDescMetadata.pvarRatingValue)); + assert(DPKVT_UI2 == pID->WMP.sDescMetadata.pvarRatingValue.vt); + break; + + case WMP_tagCaption: + CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, + &pID->WMP.sDescMetadata.pvarCaption)); + assert((DPKVT_BYREF | DPKVT_UI1) == pID->WMP.sDescMetadata.pvarCaption.vt); + + // Change type from C-style byte array to LPWSTR + assert((U8*)pID->WMP.sDescMetadata.pvarCaption.VT.pwszVal == + pID->WMP.sDescMetadata.pvarCaption.VT.pbVal); + assert(0 == pID->WMP.sDescMetadata.pvarCaption.VT.pwszVal[uCount / sizeof(U16) - 1]); // Confirm null-term + // make sure null term (ReadPropvar allocated enough space for this) + pID->WMP.sDescMetadata.pvarCaption.VT.pwszVal[uCount / sizeof(U16)] = 0; + pID->WMP.sDescMetadata.pvarCaption.vt = DPKVT_LPWSTR; + break; + + case WMP_tagDocumentName: + CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, + &pID->WMP.sDescMetadata.pvarDocumentName)); + assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarDocumentName.vt); + break; + + case WMP_tagPageName: + CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, + &pID->WMP.sDescMetadata.pvarPageName)); + assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarPageName.vt); + break; + + case WMP_tagPageNumber: + CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, + &pID->WMP.sDescMetadata.pvarPageNumber)); + assert(DPKVT_UI4 == pID->WMP.sDescMetadata.pvarPageNumber.vt); + break; + + case WMP_tagHostComputer: + CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, + &pID->WMP.sDescMetadata.pvarHostComputer)); + assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarHostComputer.vt); + break; + + default: + fprintf(stderr, "Unrecognized WMPTag: %d(%#x), %d, %d, %#x" CRLF, + (int)uTag, (int)uTag, (int)uType, (int)uCount, (int)uValue); + break; + } + +Cleanup: + return err; +} + +ERR ParsePFD( + PKImageDecode* pID, + size_t offPos, + U16 cEntry) +{ + ERR err = WMP_errSuccess; + struct WMPStream* pWS = pID->pStream; + U16 i = 0; + + for (i = 0; i < cEntry; ++i) + { + U16 uTag = 0; + U16 uType = 0; + U32 uCount = 0; + U32 uValue = 0; + + Call(GetUShort(pWS, offPos, &uTag)); offPos += 2; + Call(GetUShort(pWS, offPos, &uType)); offPos += 2; + Call(GetULong(pWS, offPos, &uCount)); offPos += 4; + Call(GetULong(pWS, offPos, &uValue)); offPos += 4; + + Call(ParsePFDEntry(pID, uTag, uType, uCount, uValue)); + } + + pID->WMP.bHasAlpha = ((pID->WMP.bHasAlpha) && (pID->WMP.wmiDEMisc.uAlphaOffset != 0) && (pID->WMP.wmiDEMisc.uAlphaByteCount != 0));//has planar alpha + +Cleanup: + return err; +} + +ERR ReadContainer( + PKImageDecode* pID) +{ + ERR err = WMP_errSuccess; + + struct WMPStream* pWS = pID->pStream; + size_t offPos = 0; + + char szSig[2] = { 0 }; + U16 uWmpID = 0; + U32 offPFD = 0; + U16 cPFDEntry = 0; + U8 bVersion; + + //================================ + Call(pWS->GetPos(pWS, &offPos)); + FailIf(0 != offPos, WMP_errUnsupportedFormat); + + //================================ + // Header + Call(pWS->Read(pWS, szSig, sizeof(szSig))); offPos += 2; + FailIf(szSig != strstr(szSig, "II"), WMP_errUnsupportedFormat); + + Call(GetUShort(pWS, offPos, &uWmpID)); offPos += 2; + FailIf(WMP_valWMPhotoID != (0x00FF & uWmpID), WMP_errUnsupportedFormat); + + // We accept version 00 and version 01 bitstreams - all others rejected + bVersion = (0xFF00 & uWmpID) >> 8; + FailIf(bVersion != 0 && bVersion != 1, WMP_errUnsupportedFormat); + + Call(GetULong(pWS, offPos, &offPFD)); offPos += 4; + + //================================ + // PFD + offPos = (size_t)offPFD; + Call(GetUShort(pWS, offPos, &cPFDEntry)); offPos += 2; + FailIf(0 == cPFDEntry || USHRT_MAX == cPFDEntry, WMP_errUnsupportedFormat); + Call(ParsePFD(pID, offPos, cPFDEntry)); + + //================================ + Call(pWS->SetPos(pWS, pID->WMP.wmiDEMisc.uImageOffset)); + +Cleanup: + return err; +} + + +//================================================ +ERR PKImageDecode_Initialize_WMP( + PKImageDecode* pID, + struct WMPStream* pWS) +{ + ERR err = WMP_errSuccess; + + CWMImageInfo* pII = NULL; + + //================================ + Call(PKImageDecode_Initialize(pID, pWS)); + + //================================ + Call(ReadContainer(pID)); + + //================================ + pID->WMP.wmiSCP.pWStream = pWS; + pID->WMP.DecoderCurrMBRow = 0; + pID->WMP.cLinesDecoded = 0; + pID->WMP.cLinesCropped = 0; + pID->WMP.fFirstNonZeroDecode = FALSE; + + FailIf(ICERR_OK != ImageStrDecGetInfo(&pID->WMP.wmiI, &pID->WMP.wmiSCP), WMP_errFail); + assert(Y_ONLY <= pID->WMP.wmiSCP.cfColorFormat && pID->WMP.wmiSCP.cfColorFormat < CFT_MAX); + assert(BD_SHORT == pID->WMP.wmiSCP.bdBitDepth || BD_LONG == pID->WMP.wmiSCP.bdBitDepth); + + // If HD Photo container provided an orientation, this should override bitstream orientation + // If container did NOT provide an orientation, force O_NONE. This is to be consistent with + // Vista behaviour, which is to ignore bitstream orientation (only looks at container). + if (pID->WMP.fOrientationFromContainer) + { + pID->WMP.wmiI.oOrientation = pID->WMP.oOrientationFromContainer; + } + else + { + // Force to O_NONE to match Vista decode behaviour + pID->WMP.wmiI.oOrientation = O_NONE; + } + + pII = &pID->WMP.wmiI; + pID->uWidth = (U32)pII->cWidth; + pID->uHeight = (U32)pII->cHeight; + +Cleanup: + return err; +} + + +ERR PKImageDecode_GetSize_WMP( + PKImageDecode* pID, + I32* piWidth, + I32* piHeight) +{ + if (pID->WMP.wmiI.oOrientation >= O_RCW) + { + *piWidth = (I32)pID->uHeight; + *piHeight = (I32)pID->uWidth; + } + else + { + *piWidth = (I32)pID->uWidth; + *piHeight = (I32)pID->uHeight; + } + return WMP_errSuccess; +} + + +ERR PKImageDecode_GetRawStream_WMP( + PKImageDecode* pID, + struct WMPStream** ppWS) +{ + ERR err = WMP_errSuccess; + struct WMPStream* pWS = pID->pStream; + + *ppWS = NULL; + Call(pWS->SetPos(pWS, pID->WMP.wmiDEMisc.uImageOffset)); + *ppWS = pWS; + +Cleanup: + return err; +} + +ERR PKImageDecode_Copy_WMP( + PKImageDecode* pID, + const PKRect* pRect, + U8* pb, + U32 cbStride) +{ + ERR err = WMP_errSuccess; + U32 cThumbnailScale; + U32 linesperMBRow; + CWMImageBufferInfo wmiBI = { 0 }; +#ifdef REENTRANT_MODE + U8* pbLowMemAdj = NULL; + U32 i, cMBRow; + U32 cMBRowStart; +#endif // REENTRANT_MODE + struct WMPStream* pWS = pID->pStream; + U8 tempAlphaMode = 0; + wmiBI.pv = pb; + wmiBI.cLine = pRect->Height; + wmiBI.cbStride = cbStride; +#ifdef REENTRANT_MODE + // In REENTRANT_MODE, we allow rectangles with any top left corner (not just (0,0)) +#else + FailIf(0 != pRect->X, WMP_errInvalidParameter); + FailIf(0 != pRect->Y, WMP_errInvalidParameter); +#endif // REENTRANT_MODE + + cThumbnailScale = 1; + if (pID->WMP.wmiI.cThumbnailWidth > 0) + { + while (cThumbnailScale * pID->WMP.wmiI.cThumbnailWidth < pID->uWidth) + cThumbnailScale <<= 1; + } + // note the following implementation can't handle fractional linesperMBRow limiting + // us to >= 1/256 thumbnail which is unfortunate, but all the PS plugin needs is 1/256 + // and I didn't care to get into floating point or a bunch of conditional tests or + // other rewrite for a case not needed nor tested by PS plugin. sorry. + linesperMBRow = 16 / cThumbnailScale; + +#ifdef REENTRANT_MODE + if (0 == pID->WMP.DecoderCurrMBRow) + { +#endif // REENTRANT_MODE + // Set the fPaddedUserBuffer if the following conditions are met + if (0 == ((size_t)pb % 128) && // Frame buffer is aligned to 128-byte boundary + 0 == (pRect->Height % 16) && // Horizontal resolution is multiple of 16 + 0 == (pRect->Width % 16) && // Vertical resolution is multiple of 16 + 0 == (cbStride % 128)) // Stride is a multiple of 128 bytes + { + pID->WMP.wmiI.fPaddedUserBuffer = TRUE; + // Note that there are additional conditions in strdec_x86.c's strDecOpt + // which could prevent optimization from being engaged + } +#ifdef REENTRANT_MODE + } +#endif // REENTRANT_MODE + //if(pID->WMP.wmiSCP.uAlphaMode != 1) + if ((!pID->WMP.bHasAlpha) || (pID->WMP.wmiSCP.uAlphaMode != 1)) + { + if (pID->WMP.bHasAlpha)//planar alpha + { + tempAlphaMode = pID->WMP.wmiSCP.uAlphaMode; + pID->WMP.wmiSCP.uAlphaMode = 0; + } + pID->WMP.wmiSCP.fMeasurePerf = TRUE; +#ifdef REENTRANT_MODE + if (0 == pID->WMP.DecoderCurrMBRow) + { + Call(pID->WMP.wmiSCP.pWStream->GetPos(pID->WMP.wmiSCP.pWStream, &(pID->WMP.cMarker))); + FailIf(ICERR_OK != ImageStrDecInit(&pID->WMP.wmiI, &pID->WMP.wmiSCP, &pID->WMP.ctxSC), WMP_errFail); + } + // Re-entrant mode incurs 1 MBR delay, so to get 0th MBR, we have to ask for 1st MBR + cMBRow = ((U32)pID->WMP.cLinesCropped + pRect->Y + pRect->Height + + (pRect->Y + pRect->Height >= (I32)pID->WMP.wmiI.cROIHeight ? linesperMBRow - 1 : 0)) / // round up if last MBR + linesperMBRow + 1; + cMBRowStart = ((U32)pID->WMP.cLinesCropped + pRect->Y) / linesperMBRow + 1; + // if current request starts before current state, then rewind. + if (cMBRowStart < pID->WMP.DecoderCurrMBRow) + { + pID->WMP.DecoderCurrMBRow = 0; + pID->WMP.cLinesDecoded = 0; + pID->WMP.cLinesCropped = 0; + pID->WMP.fFirstNonZeroDecode = FALSE; + FailIf(ICERR_OK != ImageStrDecTerm(pID->WMP.ctxSC), WMP_errFail); + Call(pID->WMP.wmiSCP.pWStream->SetPos(pID->WMP.wmiSCP.pWStream, pID->WMP.cMarker)); + FailIf(ICERR_OK != ImageStrDecInit(&pID->WMP.wmiI, &pID->WMP.wmiSCP, &pID->WMP.ctxSC), WMP_errFail); + } + + // In "Low Memory mode", we don't have full frame buffer. We therefore cannot rotate the image. + // We can flip H, V and HV, but no rotations. + FailIf(pID->WMP.wmiI.oOrientation >= O_RCW, WMP_errFail); + + // In low-memory mode, the full frame buffer is unavailable. This doesn't seem to + // matter in O_NONE and O_FLIPH, but for O_FLIPV and O_FLIPVH, outputMBRow tries to write to + // the bottom of full-frame buffer. Adjust the buffer pointer to compensate. + if (O_FLIPV == pID->WMP.wmiI.oOrientation || O_FLIPVH == pID->WMP.wmiI.oOrientation) + { + I32 iActualY2 = pRect->Y + pRect->Height; + pbLowMemAdj = pb - (pID->WMP.wmiI.cROIHeight - (iActualY2 - pID->WMP.cLinesCropped)) * cbStride; + } + else + { + pbLowMemAdj = pb - pRect->Y * cbStride; + } + wmiBI.pv = pbLowMemAdj; + + for (i = (U32)pID->WMP.DecoderCurrMBRow; i < cMBRow; i++) + { + size_t cLinesDecoded; + wmiBI.uiFirstMBRow = i; + wmiBI.uiLastMBRow = i; + FailIf(ICERR_OK != ImageStrDecDecode(pID->WMP.ctxSC, &wmiBI, &cLinesDecoded), WMP_errFail); + pID->WMP.cLinesDecoded = cLinesDecoded; + if (FALSE == pID->WMP.fFirstNonZeroDecode && cLinesDecoded > 0) + { + pID->WMP.cLinesCropped += (linesperMBRow - cLinesDecoded); + pID->WMP.fFirstNonZeroDecode = TRUE; + // update cMBRow if partial MB row cropped + cMBRow = ((U32)pID->WMP.cLinesCropped + pRect->Y + pRect->Height + + (pRect->Y + pRect->Height >= (I32)pID->WMP.wmiI.cROIHeight ? linesperMBRow - 1 : 0)) / // round up if last MBR + linesperMBRow + 1; + } + + if (0 == cLinesDecoded && i > 0) + { + pID->WMP.cLinesCropped += linesperMBRow; + // update cMBRow if whole MB row cropped + cMBRow++; + } + } + wmiBI.pv = pbLowMemAdj; + + // If we're past the top of the image, then we're done, so terminate. + if (linesperMBRow * (cMBRow - 1) >= (U32)pID->WMP.cLinesCropped + pID->WMP.wmiI.cROIHeight) { + FailIf(ICERR_OK != ImageStrDecTerm(pID->WMP.ctxSC), WMP_errFail); + } + pID->WMP.DecoderCurrMBRow = cMBRow; // Set to next possible MBRow that is decodable + +#else + FailIf(ICERR_OK != ImageStrDecInit(&pID->WMP.wmiI, &pID->WMP.wmiSCP, &pID->WMP.ctxSC), WMP_errFail); + FailIf(ICERR_OK != ImageStrDecDecode(pID->WMP.ctxSC, &wmiBI), WMP_errFail); + FailIf(ICERR_OK != ImageStrDecTerm(pID->WMP.ctxSC), WMP_errFail); +#endif //REENTRANT_MODE + + if (pID->WMP.bHasAlpha)//planar alpha + { + pID->WMP.wmiSCP.uAlphaMode = tempAlphaMode; + } + } + + // if(pID->WMP.bHasAlpha && pID->WMP.wmiSCP.uAlphaMode == 2) + // if(pID->WMP.bHasAlpha && pID->WMP.wmiSCP.uAlphaMode != 1) + if (pID->WMP.bHasAlpha && pID->WMP.wmiSCP.uAlphaMode != 0) + { + pID->WMP.wmiI_Alpha = pID->WMP.wmiI; + pID->WMP.wmiSCP_Alpha = pID->WMP.wmiSCP; + + // assert(pID->WMP.wmiI_Alpha.cfColorFormat == CF_RGB); // only RGBA is supported for now! + pID->WMP.wmiI_Alpha.cfColorFormat = Y_ONLY; + + switch (pID->WMP.wmiI.bdBitDepth) + { + case BD_8: + pID->WMP.wmiI_Alpha.cLeadingPadding += (pID->WMP.wmiI.cBitsPerUnit >> 3) - 1; + break; + + case BD_16: + case BD_16S: + case BD_16F: + pID->WMP.wmiI_Alpha.cLeadingPadding += (pID->WMP.wmiI.cBitsPerUnit >> 3) / sizeof(U16) - 1; + break; + + case BD_32: + case BD_32S: + case BD_32F: + pID->WMP.wmiI_Alpha.cLeadingPadding += (pID->WMP.wmiI.cBitsPerUnit >> 3) / sizeof(float) - 1; + break; + + case BD_5: + case BD_10: + case BD_565: + default: + break; + } + + pID->WMP.wmiSCP_Alpha.fMeasurePerf = TRUE; + Call(pWS->SetPos(pWS, pID->WMP.wmiDEMisc.uAlphaOffset)); +#ifdef REENTRANT_MODE + if (0 == pID->WMP.DecoderCurrAlphaMBRow) // add this to WMP struct! + { + FailIf(ICERR_OK != ImageStrDecInit(&pID->WMP.wmiI_Alpha, &pID->WMP.wmiSCP_Alpha, &pID->WMP.ctxSC_Alpha), WMP_errFail); + } + + // Re-entrant mode incurs 1 MBR delay, so to get 0th MBR, we have to ask for 1st MBR + cMBRow = ((U32)pID->WMP.cLinesCropped + pRect->Y + pRect->Height + + (pRect->Y + pRect->Height >= (I32)pID->WMP.wmiI.cROIHeight ? linesperMBRow - 1 : 0)) / // round up if last MBR + linesperMBRow + 1; + cMBRowStart = ((U32)pID->WMP.cLinesCropped + pRect->Y) / linesperMBRow + 1; + // if current request starts before current state, then rewind. + if (cMBRowStart < pID->WMP.DecoderCurrAlphaMBRow) + { + pID->WMP.DecoderCurrAlphaMBRow = 0; + FailIf(ICERR_OK != ImageStrDecTerm(pID->WMP.ctxSC_Alpha), WMP_errFail); + FailIf(ICERR_OK != ImageStrDecInit(&pID->WMP.wmiI_Alpha, &pID->WMP.wmiSCP_Alpha, &pID->WMP.ctxSC_Alpha), WMP_errFail); + } + + for (i = (U32)pID->WMP.DecoderCurrAlphaMBRow; i < cMBRow; i++) + { + size_t cLinesDecoded; + wmiBI.uiFirstMBRow = i; + wmiBI.uiLastMBRow = i; + FailIf(ICERR_OK != ImageStrDecDecode(pID->WMP.ctxSC_Alpha, &wmiBI, &cLinesDecoded), WMP_errFail); + } + + // If we're past the top of the image, then we're done, so terminate + if (linesperMBRow * (cMBRow - 1) >= (U32)pID->WMP.cLinesCropped + pID->WMP.wmiI.cROIHeight) { + FailIf(ICERR_OK != ImageStrDecTerm(pID->WMP.ctxSC_Alpha), WMP_errFail); + } + pID->WMP.DecoderCurrAlphaMBRow = cMBRow; // Set to next possible MBRow that is decodable + wmiBI.pv = pb; +#else + FailIf(ICERR_OK != ImageStrDecInit(&pID->WMP.wmiI_Alpha, &pID->WMP.wmiSCP_Alpha, &pID->WMP.ctxSC_Alpha), WMP_errFail); + FailIf(ICERR_OK != ImageStrDecDecode(pID->WMP.ctxSC_Alpha, &wmiBI), WMP_errFail); + FailIf(ICERR_OK != ImageStrDecTerm(pID->WMP.ctxSC_Alpha), WMP_errFail); +#endif //REENTRANT_MODE + } + + pID->idxCurrentLine += pRect->Height; + +Cleanup: + return err; +} + + +ERR PKImageDecode_GetMetadata_WMP(PKImageDecode* pID, U32 uOffset, U32 uByteCount, U8* pbGot, U32* pcbGot) +{ + ERR err = WMP_errSuccess; + + if (pbGot && uOffset) + { + struct WMPStream* pWS = pID->pStream; + size_t iCurrPos; + + FailIf(*pcbGot < uByteCount, WMP_errBufferOverflow); + Call(pWS->GetPos(pWS, &iCurrPos)); + Call(pWS->SetPos(pWS, uOffset)); + Call(pWS->Read(pWS, pbGot, uByteCount)); + Call(pWS->SetPos(pWS, iCurrPos)); + } + +Cleanup: + if (Failed(err)) + *pcbGot = 0; + else + *pcbGot = uByteCount; + + return err; +} + + + +ERR PKImageDecode_GetColorContext_WMP(PKImageDecode* pID, U8* pbColorContext, U32* pcbColorContext) +{ + return PKImageDecode_GetMetadata_WMP(pID, pID->WMP.wmiDEMisc.uColorProfileOffset, + pID->WMP.wmiDEMisc.uColorProfileByteCount, pbColorContext, pcbColorContext); +} + + +ERR PKImageDecode_GetXMPMetadata_WMP(PKImageDecode* pID, U8* pbXMPMetadata, U32* pcbXMPMetadata) +{ + return PKImageDecode_GetMetadata_WMP(pID, pID->WMP.wmiDEMisc.uXMPMetadataOffset, + pID->WMP.wmiDEMisc.uXMPMetadataByteCount, pbXMPMetadata, pcbXMPMetadata); +} + + +ERR PKImageDecode_GetEXIFMetadata_WMP(PKImageDecode* pID, U8* pbEXIFMetadata, U32* pcbEXIFMetadata) +{ + return PKImageDecode_GetMetadata_WMP(pID, pID->WMP.wmiDEMisc.uEXIFMetadataOffset, + pID->WMP.wmiDEMisc.uEXIFMetadataByteCount, pbEXIFMetadata, pcbEXIFMetadata); +} + + +ERR PKImageDecode_GetGPSInfoMetadata_WMP(PKImageDecode* pID, U8* pbGPSInfoMetadata, U32* pcbGPSInfoMetadata) +{ + return PKImageDecode_GetMetadata_WMP(pID, pID->WMP.wmiDEMisc.uGPSInfoMetadataOffset, + pID->WMP.wmiDEMisc.uGPSInfoMetadataByteCount, pbGPSInfoMetadata, pcbGPSInfoMetadata); +} + + +ERR PKImageDecode_GetIPTCNAAMetadata_WMP(PKImageDecode* pID, U8* pbIPTCNAAMetadata, U32* pcbIPTCNAAMetadata) +{ + return PKImageDecode_GetMetadata_WMP(pID, pID->WMP.wmiDEMisc.uIPTCNAAMetadataOffset, + pID->WMP.wmiDEMisc.uIPTCNAAMetadataByteCount, pbIPTCNAAMetadata, pcbIPTCNAAMetadata); +} + + +ERR PKImageDecode_GetPhotoshopMetadata_WMP(PKImageDecode* pID, U8* pbPhotoshopMetadata, U32* pcbPhotoshopMetadata) +{ + return PKImageDecode_GetMetadata_WMP(pID, pID->WMP.wmiDEMisc.uPhotoshopMetadataOffset, + pID->WMP.wmiDEMisc.uPhotoshopMetadataByteCount, pbPhotoshopMetadata, pcbPhotoshopMetadata); +} + + +ERR PKImageDecode_GetDescriptiveMetadata_WMP(PKImageDecode* pID, DESCRIPTIVEMETADATA* pDescMetadata) +{ + ERR err = WMP_errSuccess; + *pDescMetadata = pID->WMP.sDescMetadata; + return err; +} + + +ERR PKImageDecode_Release_WMP(PKImageDecode** ppID) +{ + ERR err = WMP_errSuccess; + PKImageDecode* pID; + + if (NULL == ppID) + goto Cleanup; + + pID = *ppID; + + // Free descriptive metadata + FreeDescMetadata(&pID->WMP.sDescMetadata.pvarImageDescription); + FreeDescMetadata(&pID->WMP.sDescMetadata.pvarCameraMake); + FreeDescMetadata(&pID->WMP.sDescMetadata.pvarCameraModel); + FreeDescMetadata(&pID->WMP.sDescMetadata.pvarSoftware); + FreeDescMetadata(&pID->WMP.sDescMetadata.pvarDateTime); + FreeDescMetadata(&pID->WMP.sDescMetadata.pvarArtist); + FreeDescMetadata(&pID->WMP.sDescMetadata.pvarCopyright); + FreeDescMetadata(&pID->WMP.sDescMetadata.pvarRatingStars); + FreeDescMetadata(&pID->WMP.sDescMetadata.pvarRatingValue); + FreeDescMetadata(&pID->WMP.sDescMetadata.pvarCaption); + FreeDescMetadata(&pID->WMP.sDescMetadata.pvarDocumentName); + FreeDescMetadata(&pID->WMP.sDescMetadata.pvarPageName); + FreeDescMetadata(&pID->WMP.sDescMetadata.pvarPageNumber); + FreeDescMetadata(&pID->WMP.sDescMetadata.pvarHostComputer); + + // Release base class + Call(PKImageDecode_Release(ppID)); + +Cleanup: + return err; +} + + + +ERR PKImageDecode_Create_WMP(PKImageDecode** ppID) +{ + ERR err = WMP_errSuccess; + PKImageDecode* pID = NULL; + + Call(PKImageDecode_Create(ppID)); + + pID = *ppID; + pID->Initialize = PKImageDecode_Initialize_WMP; + pID->GetSize = PKImageDecode_GetSize_WMP; + pID->GetRawStream = PKImageDecode_GetRawStream_WMP; + pID->Copy = PKImageDecode_Copy_WMP; + pID->GetColorContext = PKImageDecode_GetColorContext_WMP; + pID->GetDescriptiveMetadata = PKImageDecode_GetDescriptiveMetadata_WMP; + pID->Release = PKImageDecode_Release_WMP; + +Cleanup: + return err; +} + diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c new file mode 100644 index 00000000..ab975ff3 --- /dev/null +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c @@ -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; +} + diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h new file mode 100644 index 00000000..f64852d0 --- /dev/null +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h @@ -0,0 +1,260 @@ +//*@@@+++@@@@****************************************************************** +// +// 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 +#include "../image/sys/Windowsmediaphoto.h" +#ifndef WIN32 +//#include +#include "../common/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); diff --git a/Src/libCZI/decoder.cpp b/Src/libCZI/decoder.cpp index 25da6510..70b6e3df 100644 --- a/Src/libCZI/decoder.cpp +++ b/Src/libCZI/decoder.cpp @@ -5,6 +5,7 @@ #include "stdafx.h" #include "decoder.h" #include "../JxrDecode/JxrDecode.h" +#include "../JxrDecode/JxrDecode2.h" #include "bitmapData.h" #include "stdAllocator.h" #include "BitmapOperations.h" @@ -18,7 +19,60 @@ using namespace std; return make_shared(JxrDecode::Initialize()); } -/*virtual*/std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, size_t size, libCZI::PixelType pixelType, uint32_t width, uint32_t height) +std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, size_t size, libCZI::PixelType pixelType, uint32_t width, uint32_t height) +{ + std::shared_ptr bm; + JxrDecode2 decoder2; + decoder2.Decode(nullptr, + ptrData, + size, + nullptr, + [&](JxrDecode2::PixelFormat pixFmt, std::uint32_t width, std::uint32_t height, std::uint32_t linesCount, const void* ptrData, std::uint32_t stride)->void + { + /* if (GetSite()->IsEnabled(LOGLEVEL_CHATTYINFORMATION)) + { + stringstream ss; ss << "JxrDecode: decode done - pixelfmt=" << JxrDecode::PixelFormatAsInformalString(pixFmt) << " width=" << width << " height=" << height << " linesCount=" << linesCount << " stride=" << stride; + GetSite()->Log(LOGLEVEL_CHATTYINFORMATION, ss.str()); + }*/ + + // TODO: it seems feasible to directly decode to the buffer (saving us the copy) + PixelType px_type; + switch (pixFmt) + { + case JxrDecode2::PixelFormat::_24bppBGR: px_type = PixelType::Bgr24; break; + case JxrDecode2::PixelFormat::_8bppGray: px_type = PixelType::Gray8; break; + case JxrDecode2::PixelFormat::_48bppRGB: px_type = PixelType::Bgr48; break; + case JxrDecode2::PixelFormat::_16bppGray: px_type = PixelType::Gray16; break; + case JxrDecode2::PixelFormat::_32bppGrayFloat: px_type = PixelType::Gray32Float; break; + default: throw std::logic_error("need to look into these formats..."); + } + + bm = GetSite()->CreateBitmap(px_type, width, height); + auto bmLckInfo = ScopedBitmapLockerSP(bm); + if (bmLckInfo.stride != stride) + { + for (uint32_t i = 0; i < linesCount; ++i) + { + memcpy(static_cast(bmLckInfo.ptrDataRoi) + i * bmLckInfo.stride, static_cast(ptrData) + i * stride, stride); + } + } + else + { + memcpy(bmLckInfo.ptrDataRoi, ptrData, static_cast(stride) * linesCount); + } + + // since BGR48 is not available as output, we need to convert (#36) + if (px_type == PixelType::Bgr48) + { + CBitmapOperations::RGB48ToBGR48(width, height, (uint16_t*)bmLckInfo.ptrDataRoi, bmLckInfo.stride); + } + } + ); + + return bm; +} + +std::shared_ptr CJxrLibDecoder::Decode2(const void* ptrData, size_t size, libCZI::PixelType pixelType, uint32_t width, uint32_t height) { std::shared_ptr bm; diff --git a/Src/libCZI/decoder.h b/Src/libCZI/decoder.h index 5a7341a0..9f734d38 100644 --- a/Src/libCZI/decoder.h +++ b/Src/libCZI/decoder.h @@ -22,4 +22,5 @@ class CJxrLibDecoder : public libCZI::IDecoder public: std::shared_ptr Decode(const void* ptrData, size_t size, libCZI::PixelType, std::uint32_t width, std::uint32_t height) override; + std::shared_ptr Decode2(const void* ptrData, size_t size, libCZI::PixelType, std::uint32_t width, std::uint32_t height); }; From e360f7496c08579b928cfbb7671d0635c0894446 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Thu, 27 Jul 2023 16:02:49 +0200 Subject: [PATCH 03/98] update --- Src/JxrDecode/JxrDecode2.cpp | 10 ++++++---- Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h | 1 + Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Src/JxrDecode/JxrDecode2.cpp b/Src/JxrDecode/JxrDecode2.cpp index dabdecf3..7db0c08e 100644 --- a/Src/JxrDecode/JxrDecode2.cpp +++ b/Src/JxrDecode/JxrDecode2.cpp @@ -18,10 +18,10 @@ void JxrDecode2::Decode( //if (Failed(err)) { ThrowError("PKCreateFactory failed", err); } std::unique_ptr upFactory(pFactory, [](PKFactory* p)->void {p->Release(&p); }); - PKCodecFactory* pCodecFactory = NULL; + /*PKCodecFactory* pCodecFactory = NULL; err = PKCreateCodecFactory(&pCodecFactory, WMP_SDK_VERSION); //if (Failed(err)) { ThrowError("PKCreateCodecFactory failed", err); } - std::unique_ptr upCodecFactory(pCodecFactory, [](PKCodecFactory* p)->void {p->Release(&p); }); + std::unique_ptr upCodecFactory(pCodecFactory, [](PKCodecFactory* p)->void {p->Release(&p); });*/ /* const PKIID* pIID = NULL; @@ -30,10 +30,12 @@ void JxrDecode2::Decode( std::unique_ptr upDecoder(pDecoder, [](PKImageDecode* p)->void {p->Release(&p); });*/ WMPStream* pStream; - err = pFactory->CreateStreamFromMemory(&pStream, const_cast(ptrData), size); + err = CreateWS_Memory(&pStream, const_cast(ptrData), size); + //err = pFactory->CreateStreamFromMemory(&pStream, const_cast(ptrData), size); PKImageDecode* pDecoder; - upCodecFactory->CreateDecoderFromStream(pStream, &pDecoder); + //upCodecFactory->CreateDecoderFromStream(pStream, &pDecoder); + PKCodecFactory_CreateDecoderFromStream(pStream, &pDecoder); std::unique_ptr upDecoder(pDecoder, [](PKImageDecode* p)->void {p->Release(&p); }); diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h index 1b09b7b3..d35b8d45 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h @@ -587,6 +587,7 @@ extern "C" { ERR PKImageDecode_Create(PKImageDecode** ppID); ERR PKCodecFactory_CreateDecoderFromFile(const char* szFilename, PKImageDecode** ppDecoder); + ERR PKCodecFactory_CreateDecoderFromStream(struct WMPStream* pStream, PKImageDecode** ppDecoder); //================================================================ typedef struct tagPKFormatConverter diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h index f64852d0..c7b93c0c 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h @@ -28,7 +28,7 @@ #pragma once //#include -#include "../image/sys/Windowsmediaphoto.h" +#include "../image/sys/windowsmediaphoto.h" #ifndef WIN32 //#include #include "../common/include/wmspecstring.h" From 1bc1e9792e3963ecfe03125d32202bed4ece3d3c Mon Sep 17 00:00:00 2001 From: ptahmose Date: Fri, 28 Jul 2023 11:53:36 +0200 Subject: [PATCH 04/98] update --- Src/JxrDecode/CMakeLists.txt | 86 +- .../jxrlib/image/decode/JXRTranscode.c | 991 +++++++ .../jxrlib/image/decode/postprocess.c | 288 ++ Src/JxrDecode/jxrlib/image/encode/encode.c | 144 + Src/JxrDecode/jxrlib/image/encode/encode.h | 113 + Src/JxrDecode/jxrlib/image/encode/segenc.c | 1186 +++++++++ .../jxrlib/image/encode/strFwdTransform.c | 1111 ++++++++ .../jxrlib/image/encode/strPredQuantEnc.c | 511 ++++ Src/JxrDecode/jxrlib/image/encode/strenc.c | 2372 +++++++++++++++++ Src/JxrDecode/jxrlib/image/sys/adapthuff.c | 513 ++++ Src/JxrDecode/jxrlib/image/sys/image.c | 182 ++ Src/JxrDecode/jxrlib/image/sys/strPredQuant.c | 306 +++ Src/JxrDecode/jxrlib/image/sys/strTransform.c | 85 + Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c | 2338 ++++++++++++++++ 14 files changed, 10188 insertions(+), 38 deletions(-) create mode 100644 Src/JxrDecode/jxrlib/image/decode/JXRTranscode.c create mode 100644 Src/JxrDecode/jxrlib/image/decode/postprocess.c create mode 100644 Src/JxrDecode/jxrlib/image/encode/encode.c create mode 100644 Src/JxrDecode/jxrlib/image/encode/encode.h create mode 100644 Src/JxrDecode/jxrlib/image/encode/segenc.c create mode 100644 Src/JxrDecode/jxrlib/image/encode/strFwdTransform.c create mode 100644 Src/JxrDecode/jxrlib/image/encode/strPredQuantEnc.c create mode 100644 Src/JxrDecode/jxrlib/image/encode/strenc.c create mode 100644 Src/JxrDecode/jxrlib/image/sys/adapthuff.c create mode 100644 Src/JxrDecode/jxrlib/image/sys/image.c create mode 100644 Src/JxrDecode/jxrlib/image/sys/strPredQuant.c create mode 100644 Src/JxrDecode/jxrlib/image/sys/strTransform.c create mode 100644 Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c diff --git a/Src/JxrDecode/CMakeLists.txt b/Src/JxrDecode/CMakeLists.txt index 69bb1a38..fd3b97f7 100644 --- a/Src/JxrDecode/CMakeLists.txt +++ b/Src/JxrDecode/CMakeLists.txt @@ -6,60 +6,60 @@ # static libCIZ-library add_library(JxrDecodeStatic OBJECT JxrDecode.cpp - stdafx.cpp - JxrDecode.h - stdafx.h - targetver.h - Jxr/adapthuff.c + ##stdafx.cpp + ##JxrDecode.h + ##stdafx.h + ##targetver.h + ##Jxr/adapthuff.c #Jxr/decode.c - Jxr/encode.c - Jxr/image.c + ##Jxr/encode.c + ##Jxr/image.c #Jxr/JXRGlue.c #Jxr/JXRGlueJxr.c - Jxr/JXRGluePFC.c + ##Jxr/JXRGluePFC.c #Jxr/JXRMeta.c - Jxr/JXRTest.c - Jxr/JXRTestBmp.c - Jxr/JXRTestHdr.c - Jxr/JXRTestPnm.c - Jxr/JXRTestTif.c - Jxr/JXRTestWrapper.c - Jxr/JXRTestYUV.c - Jxr/JXRTranscode.c - Jxr/perfTimerANSI.c - Jxr/postprocess.c + ##Jxr/JXRTest.c + ##Jxr/JXRTestBmp.c + ##Jxr/JXRTestHdr.c + ##Jxr/JXRTestPnm.c + ##Jxr/JXRTestTif.c + ##Jxr/JXRTestWrapper.c + ##Jxr/JXRTestYUV.c + ##Jxr/JXRTranscode.c + ##Jxr/perfTimerANSI.c + ##Jxr/postprocess.c #Jxr/segdec.c - Jxr/segenc.c + ##Jxr/segenc.c #Jxr/strcodec.c #Jxr/strdec.c - Jxr/strdec_x86.c - Jxr/strenc.c - Jxr/strenc_x86.c - Jxr/strFwdTransform.c + ##Jxr/strdec_x86.c + ##Jxr/strenc.c + ##Jxr/strenc_x86.c + ##Jxr/strFwdTransform.c #Jxr/strInvTransform.c - Jxr/strPredQuant.c + ##Jxr/strPredQuant.c #Jxr/strPredQuantDec.c - Jxr/strPredQuantEnc.c - Jxr/strTransform.c + ##Jxr/strPredQuantEnc.c + ##Jxr/strTransform.c #Jxr/common.h #Jxr/decode.h - Jxr/encode.h + ##Jxr/encode.h #Jxr/JXRGlue.h #Jxr/JXRMeta.h - Jxr/JXRTest.h - Jxr/JXRTestWrapper.h - Jxr/perfTimer.h + ##Jxr/JXRTest.h + ##Jxr/JXRTestWrapper.h + ##Jxr/perfTimer.h #Jxr/strcodec.h #Jxr/strTransform.h #Jxr/windowsmediaphoto.h - Jxr/_x86/_x86.h - Jxr/priv_guiddef.h - Jxr/wmsal.h + ##Jxr/_x86/_x86.h + ##Jxr/priv_guiddef.h + ##Jxr/wmsal.h #Jxr/wmspecstring.h #Jxr/wmspecstrings_adt.h - Jxr/wmspecstrings_strict.h - Jxr/wmspecstrings_undef.h - Jxr/jxr_defines.h + ##Jxr/wmspecstrings_strict.h + ##Jxr/wmspecstrings_undef.h + ##Jxr/jxr_defines.h "JxrDecode2.h" "JxrDecode2.cpp" @@ -74,18 +74,28 @@ add_library(JxrDecodeStatic OBJECT "jxrlib/image/decode/strdec.c" "jxrlib/image/decode/strInvTransform.c" "jxrlib/image/decode/strPredQuantDec.c" + "jxrlib/image/decode/postprocess.c" + + "jxrlib/image/encode/strenc.c" + "jxrlib/image/encode/encode.h" + "jxrlib/image/encode/encode.c" "jxrlib/image/sys/strcodec.h" "jxrlib/image/sys/strcodec.c" "jxrlib/image/sys/windowsmediaphoto.h" "jxrlib/image/sys/common.h" - "jxrlib/image/sys/strTransform.h" + "jxrlib/image/sys/strTransform.h" + "jxrlib/image/sys/strTransform.c" + "jxrlib/image/sys/image.c" + "jxrlib/image/sys/adapthuff.c" + "jxrlib/image/sys/strPredQuant.c" "jxrlib/jxrgluelib/JXRGlue.h" "jxrlib/jxrgluelib/JXRGlue.c" "jxrlib/jxrgluelib/JXRGlueJxr.c" "jxrlib/jxrgluelib/JXRMeta.h" - "jxrlib/jxrgluelib/JXRMeta.c" ) + "jxrlib/jxrgluelib/JXRMeta.c" + "jxrlib/jxrgluelib/JXRGluePFC.c" "jxrlib/image/encode/segenc.c" "jxrlib/image/encode/strFwdTransform.c" "jxrlib/image/encode/strPredQuantEnc.c" "jxrlib/image/decode/JXRTranscode.c") set_target_properties(JxrDecodeStatic PROPERTIES CXX_STANDARD 11) diff --git a/Src/JxrDecode/jxrlib/image/decode/JXRTranscode.c b/Src/JxrDecode/jxrlib/image/decode/JXRTranscode.c new file mode 100644 index 00000000..d674d705 --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/decode/JXRTranscode.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 "../sys/windowsmediaphoto.h" +#include "../sys/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; +} diff --git a/Src/JxrDecode/jxrlib/image/decode/postprocess.c b/Src/JxrDecode/jxrlib/image/decode/postprocess.c new file mode 100644 index 00000000..aed51485 --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/decode/postprocess.c @@ -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 "../sys/windowsmediaphoto.h" +#include "../sys/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]); + } + } + } + } +} + diff --git a/Src/JxrDecode/jxrlib/image/encode/encode.c b/Src/JxrDecode/jxrlib/image/encode/encode.c new file mode 100644 index 00000000..d6c2bbed --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/encode/encode.c @@ -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 +#include +#include "encode.h" +#include "../sys/strcodec.h" +#include "../sys/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); + } +} + diff --git a/Src/JxrDecode/jxrlib/image/encode/encode.h b/Src/JxrDecode/jxrlib/image/encode/encode.h new file mode 100644 index 00000000..8b90eb8b --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/encode/encode.h @@ -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 "../sys/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 + diff --git a/Src/JxrDecode/jxrlib/image/encode/segenc.c b/Src/JxrDecode/jxrlib/image/encode/segenc.c new file mode 100644 index 00000000..b91c2668 --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/encode/segenc.c @@ -0,0 +1,1186 @@ +//*@@@+++@@@@****************************************************************** +// +// 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 +#include +#include "../sys/strcodec.h" +#include "encode.h" + +#ifdef MEM_TRACE +#define TRACE_MALLOC 1 +#define TRACE_NEW 0 +#define TRACE_HEAP 0 +#include "memtrace.h" +#endif + +/** local function definitions **/ +#ifdef X86OPT_INLINE +__forceinline +#endif +static Int EncodeBlock(Bool bChroma, const Int* aLocalCoef, Int iNumNonzero, + struct CAdaptiveHuffman** pAHexpt, + Int iContextOffset, BitIOInfo* pOut, UInt iLocation); + +/************************************************************************* + EncodeSignificantAbsLevel +*************************************************************************/ +#ifdef X86OPT_INLINE +//__forceinline +#endif +static Void EncodeSignificantAbsLevel(UInt iAbsLevel, struct CAdaptiveHuffman* pAHexpt, BitIOInfo* pOut) +{ + Int iIndex, iFixed, aIndex[] = { 0,1,2,2, 3,3,3,3, 4,4,4,4, 5,5,5,5 }; + Int aFixedLength[] = { 0, 0, 1, 2, 2, 2 }; + + assert(iAbsLevel > 0); + iAbsLevel--; + if (iAbsLevel >= 16) { + Int i = iAbsLevel; + iIndex = 6; + /** find leftmost bit **/ + i >>= 5; + iFixed = 4; + while (i) { /** caution - infinite loop if not careful **/ + iFixed++; + assert(iFixed < 30); + i >>= 1; + } + + pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex]; + putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1], pAHexpt->m_pTable[iIndex * 2 + 2]); + if (iFixed > 18) { + putBit16z(pOut, 15, 4); + if (iFixed > 21) { + putBit16z(pOut, 3, 2); + putBit16(pOut, iFixed - 22, 3); // 22 - 29 + } + else + putBit16z(pOut, iFixed - 19, 2); // 19 20 21 + } + else { + putBit16z(pOut, (iFixed - 4), 4); + } + putBit32(pOut, iAbsLevel, iFixed); + } + else { + iIndex = aIndex[iAbsLevel]; + iFixed = aFixedLength[iIndex]; + + pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex]; + putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1], pAHexpt->m_pTable[iIndex * 2 + 2]); + putBit32(pOut, iAbsLevel, iFixed); + } +} + +/************************************************************************* + EncodeMacroblockDC +*************************************************************************/ + +Void encodeQPIndex(BitIOInfo* pIO, U8 iIndex, U8 cBits) +{ + if (iIndex == 0) + putBit16z(pIO, 0, 1); + else { + putBit16z(pIO, 1, 1); + putBit16z(pIO, iIndex - 1, cBits); + } +} + +Int EncodeMacroblockDC(CWMImageStrCodec* pSC, CCodingContext* pContext, Int iMBX, Int iMBY) +{ + CWMITile* pTile = pSC->pTile + pSC->cTileColumn; + BitIOInfo* pIO = pContext->m_pIODC; + CWMIMBInfo* pMBInfo = &pSC->MBInfo; + Int iIndex, j = 0; + struct CAdaptiveHuffman* pAH; + Int aLaplacianMean[2] = { 0, 0 }, * pLM = aLaplacianMean; + Int iModelBits = pContext->m_aModelDC.m_iFlcBits[0]; + COLORFORMAT cf = pSC->m_param.cfColorFormat; + const Int iChannels = (Int)pSC->m_param.cNumChannels; + + UNREFERENCED_PARAMETER(iMBX); + UNREFERENCED_PARAMETER(iMBY); + + writeIS_L1(pSC, pIO); + + if (pSC->m_param.bTranscode == FALSE) { + pMBInfo->iQIndexLP = (U8)(pTile->cNumQPLP > 1 ? (rand() % pTile->cNumQPLP) : 0); + pMBInfo->iQIndexHP = (U8)(pTile->cNumQPHP > 1 ? (rand() % pTile->cNumQPHP) : 0); + } + if (pTile->cBitsHP == 0 && pTile->cNumQPHP > 1) // use LP QP + pMBInfo->iQIndexHP = pMBInfo->iQIndexLP; + + if (pSC->WMISCP.bfBitstreamFormat == SPATIAL && pSC->WMISCP.sbSubband != SB_DC_ONLY) { + if (pTile->cBitsLP > 0) // MB-based LP QP index + encodeQPIndex(pIO, pMBInfo->iQIndexLP, pTile->cBitsLP); + if (pSC->WMISCP.sbSubband != SB_NO_HIGHPASS && pTile->cBitsHP > 0) // MB-based HP QP index + encodeQPIndex(pIO, pMBInfo->iQIndexHP, pTile->cBitsHP); + } + + if (pSC->m_param.bTranscode == FALSE) + pSC->Quantize(pSC); + + predMacroblockEnc(pSC); + + /** code path for Y_ONLY, CMYK and N_CHANNEL DC **/ + if (cf == Y_ONLY || cf == CMYK || cf == NCOMPONENT) { + Int iQDC, iDC, iSign; + for (j = 0; j < iChannels; j++) { + iDC = pMBInfo->iBlockDC[j][0]; + iSign = (iDC < 0); + iDC = abs(iDC); + iQDC = iDC >> iModelBits; + + /** send luminance DC **/ + if (iQDC) { + putBit16z(pIO, 1, 1); + EncodeSignificantAbsLevel((UInt)iQDC, pContext->m_pAHexpt[3], pIO); + *pLM += 1; + } + else { + putBit16z(pIO, 0, 1); + } + + putBit16(pIO, iDC, iModelBits); + if (iDC) { + putBit16z(pIO, iSign, 1); + } + + pLM = aLaplacianMean + 1; + iModelBits = pContext->m_aModelDC.m_iFlcBits[1]; + } + } + else { /** code path for YUV DC **/ + Int iDCY, iDCU, iDCV, iQDCY, iQDCU, iQDCV; + + pAH = pContext->m_pAHexpt[2]; + iQDCY = abs(iDCY = pMBInfo->iBlockDC[0][0]); + iQDCU = abs(iDCU = pMBInfo->iBlockDC[1][0]); + iQDCV = abs(iDCV = pMBInfo->iBlockDC[2][0]); + if (iModelBits) { + iQDCY >>= iModelBits; + } + + iModelBits = pContext->m_aModelDC.m_iFlcBits[1]; + if (iModelBits) { + iQDCU >>= iModelBits; + iQDCV >>= iModelBits; + } + iModelBits = pContext->m_aModelDC.m_iFlcBits[0]; + + iIndex = (iQDCY != 0) * 4 + (iQDCU != 0) * 2 + (iQDCV != 0); + putBit16z(pIO, pAH->m_pTable[iIndex * 2 + 1], pAH->m_pTable[iIndex * 2 + 2]); + + /** send luminance DC **/ + if (iQDCY) { + EncodeSignificantAbsLevel((UInt)iQDCY, pContext->m_pAHexpt[3], pIO); + *pLM += 1; + } + putBit16(pIO, abs(iDCY), iModelBits); + if (iDCY) { + putBit16z(pIO, (iDCY < 0), 1); + } + + /** send chroma DC **/ + pLM = aLaplacianMean + 1; + iModelBits = pContext->m_aModelDC.m_iFlcBits[1]; + + if (iQDCU) { + EncodeSignificantAbsLevel((UInt)iQDCU, pContext->m_pAHexpt[4], pIO); + *pLM += 1; + } + putBit16(pIO, abs(iDCU), iModelBits); + if (iDCU) { + putBit16z(pIO, (iDCU < 0), 1); + } + + if (iQDCV) { + EncodeSignificantAbsLevel((UInt)iQDCV, pContext->m_pAHexpt[4], pIO); + *pLM += 1; + } + putBit16(pIO, abs(iDCV), iModelBits); + if (iDCV) { + putBit16z(pIO, (iDCV < 0), 1); + } + } + + UpdateModelMB(cf, iChannels, aLaplacianMean, &(pContext->m_aModelDC)); + + if (pSC->m_bResetContext && pSC->WMISCP.sbSubband == SB_DC_ONLY) { + AdaptDiscriminant(pContext->m_pAHexpt[2]); + AdaptDiscriminant(pContext->m_pAHexpt[3]); + AdaptDiscriminant(pContext->m_pAHexpt[4]); + } + + return ICERR_OK; +} + +/************************************************************************* + Scan block with zero model bits +*************************************************************************/ +#ifdef X86OPT_INLINE +__forceinline +#endif +static Int AdaptiveScanZero(const PixelI* pCoeffs, CAdaptiveScan* pScan, + Int* pRLCoeffs, const Int iCount) +{ + Int k, iRun = 1, iLevel, iNumNonzero = 0; + + iLevel = pCoeffs[pScan[1].uScan]; + if (iLevel) { + pScan[1].uTotal++; + pRLCoeffs[iNumNonzero * 2] = 0; + pRLCoeffs[iNumNonzero * 2 + 1] = iLevel; + iNumNonzero++; + iRun = 0; + } + for (k = 2; k < iCount; k++) { + iLevel = pCoeffs[pScan[k].uScan]; + iRun++; + if (iLevel) { + pScan[k].uTotal++; + if (pScan[k].uTotal > pScan[k - 1].uTotal) { + CAdaptiveScan cTemp = pScan[k]; + pScan[k] = pScan[k - 1]; + pScan[k - 1] = cTemp; + } + pRLCoeffs[iNumNonzero * 2] = iRun - 1; + pRLCoeffs[iNumNonzero * 2 + 1] = iLevel; + iNumNonzero++; + iRun = 0; + } + } + return iNumNonzero; +} + +/************************************************************************* + Scan block with nonzero model bits, all trimmed +*************************************************************************/ +#ifdef X86OPT_INLINE +__forceinline +#endif +static Int AdaptiveScanTrim(const PixelI* pCoeffs, CAdaptiveScan* pScan, + const Int iModelBits, Int* pRLCoeffs, const Int iCount) +{ + Int k, iRun = 1, iLevel, iNumNonzero = 0; + Int iTemp; + unsigned int iThOff = (1 << iModelBits) - 1, iTh = iThOff * 2 + 1; + + iLevel = pCoeffs[pScan[1].uScan]; + + if ((unsigned int)(iLevel + iThOff) >= iTh) { + iTemp = abs(iLevel) >> iModelBits; + pScan[1].uTotal++; + pRLCoeffs[iNumNonzero * 2] = 0; + pRLCoeffs[iNumNonzero * 2 + 1] = (iLevel < 0) ? -iTemp : iTemp; + iNumNonzero++; + iRun = 0; + } + for (k = 2; k < iCount; k++) { + iRun++; + iLevel = pCoeffs[pScan[k].uScan]; + if ((unsigned int)(iLevel + iThOff) >= iTh) { + iTemp = abs(iLevel) >> iModelBits; + pScan[k].uTotal++; + if (pScan[k].uTotal > pScan[k - 1].uTotal) { + CAdaptiveScan cTemp = pScan[k]; + pScan[k] = pScan[k - 1]; + pScan[k - 1] = cTemp; + } + pRLCoeffs[iNumNonzero * 2] = iRun - 1; + pRLCoeffs[iNumNonzero * 2 + 1] = (iLevel < 0) ? -iTemp : iTemp; + iNumNonzero++; + iRun = 0; + } + } + return iNumNonzero; +} + +/************************************************************************* + Scan block with nonzero model bits +*************************************************************************/ +/** saves around 1.5% at QP=1 (no SIMD opt) **/ +#define USE_GRES_LUT +#ifdef USE_GRES_LUT +static const Int gRes[] = { +65 * 2 + 1, 63 * 2 + 1, 61 * 2 + 1, 59 * 2 + 1, 57 * 2 + 1, 55 * 2 + 1, 53 * 2 + 1, 51 * 2 + 1, 49 * 2 + 1, 47 * 2 + 1, 45 * 2 + 1, 43 * 2 + 1, 41 * 2 + 1, +39 * 2 + 1, 37 * 2 + 1, 35 * 2 + 1, 33 * 2 + 1, 31 * 2 + 1, 29 * 2 + 1, 27 * 2 + 1, 25 * 2 + 1, 23 * 2 + 1, 21 * 2 + 1, 19 * 2 + 1, 17 * 2 + 1, 15 * 2 + 1, +13 * 2 + 1, 11 * 2 + 1, 9 * 2 + 1, 7 * 2 + 1, 5 * 2 + 1, 3 * 2 + 1, +0, +2 * 2 + 1, 4 * 2 + 1, 6 * 2 + 1, 8 * 2 + 1, 10 * 2 + 1, 12 * 2 + 1, 14 * 2 + 1, 16 * 2 + 1, 18 * 2 + 1, 20 * 2 + 1, 22 * 2 + 1, 24 * 2 + 1, +26 * 2 + 1, 28 * 2 + 1, 30 * 2 + 1, 32 * 2 + 1, 34 * 2 + 1, 36 * 2 + 1, 38 * 2 + 1, 40 * 2 + 1, 42 * 2 + 1, 44 * 2 + 1, 46 * 2 + 1, 48 * 2 + 1, 50 * 2 + 1, +52 * 2 + 1, 54 * 2 + 1, 56 * 2 + 1, 58 * 2 + 1, 60 * 2 + 1, 62 * 2 + 1, 64 * 2 + 1 }; +#endif // USE_GRES_LUT + +#ifdef X86OPT_INLINE +//__forceinline +#endif +static Int AdaptiveScan(const PixelI* pCoeffs, Int* pResidual, + CAdaptiveScan* pScan, + const Int iModelBits, const Int iTrimBits, + Int* pRLCoeffs, const Int iCount) +{ + if (iModelBits == 0) { + return AdaptiveScanZero(pCoeffs, pScan, pRLCoeffs, iCount); + } + else if (iModelBits <= iTrimBits) { + return AdaptiveScanTrim(pCoeffs, pScan, iModelBits, pRLCoeffs, iCount); + } + else if (iTrimBits == 0 +#ifdef USE_GRES_LUT + && iModelBits < 6 +#endif // USE_GRES_LUT + ) { + Int k, iRun = 0, iLevel, iNumNonzero = 0; + Int iTemp, iTemp1; + const unsigned int iThOff = (1 << iModelBits) - 1, iTh = iThOff * 2 + 1; + + iLevel = pCoeffs[pScan[1].uScan]; + + if ((unsigned int)(iLevel + iThOff) >= iTh) { + iTemp1 = abs(iLevel); + iTemp = iTemp1 >> iModelBits; + pResidual[pScan[1].uScan] = (iTemp1 & iThOff) * 2; + pScan[1].uTotal++; + pRLCoeffs[iNumNonzero * 2] = iRun; + pRLCoeffs[iNumNonzero * 2 + 1] = (iLevel < 0) ? -iTemp : iTemp; + iNumNonzero++; + iRun = 0; + } + else { + iRun++; +#ifdef USE_GRES_LUT + pResidual[pScan[1].uScan] = gRes[(iLevel + 32)]; +#else // USE_GRES_LUT + iTemp = -(iLevel < 0); + pResidual[pScan[1].uScan] = (iLevel ^ iTemp) * 4 + (6 & iTemp) + (iLevel != 0); +#endif // USE_GRES_LUT + } + for (k = 2; k < iCount; k++) { + const Int sk = pScan[k].uScan; + //pResidual++; + iLevel = pCoeffs[sk]; + if ((unsigned int)(iLevel + iThOff) >= iTh) { + const Int iSign = -(iLevel < 0); + iTemp1 = (iSign ^ iLevel) - iSign; + iTemp = iTemp1 >> iModelBits; + pResidual[sk] = (iTemp1 & iThOff) * 2; + pScan[k].uTotal++; + if (pScan[k].uTotal > pScan[k - 1].uTotal) { + CAdaptiveScan cTemp = pScan[k]; + pScan[k] = pScan[k - 1]; + pScan[k - 1] = cTemp; + } + pRLCoeffs[iNumNonzero * 2] = iRun; + pRLCoeffs[iNumNonzero * 2 + 1] = (iTemp ^ iSign) - iSign; + iNumNonzero++; + iRun = 0; + } + else { + iRun++; +#ifdef USE_GRES_LUT + pResidual[sk] = gRes[(iLevel + 32)]; +#else // USE_GRES_LUT + iTemp = -(iLevel < 0); + pResidual[sk] = (iLevel ^ iTemp) * 4 + (6 & iTemp) + (iLevel != 0); +#endif // USE_GRES_LUT + ////(abs(iLevel) * 4) + ((iLevel < 0) * 2) + (iLevel != 0); + } + } + return iNumNonzero; + } + else { + Int k, iRun = 0, iLevel, iNumNonzero = 0; + Int iTemp, iTemp1; + const unsigned int iThOff = (1 << iModelBits) - 1, iTh = iThOff * 2 + 1; + + iLevel = pCoeffs[pScan[1].uScan]; + //pResidual++; + if ((unsigned int)(iLevel + iThOff) >= iTh) { + iTemp1 = abs(iLevel); + iTemp = iTemp1 >> iModelBits; + pResidual[pScan[1].uScan] = ((iTemp1 & iThOff) >> iTrimBits) * 2; + pScan[1].uTotal++; + pRLCoeffs[iNumNonzero * 2] = iRun; + pRLCoeffs[iNumNonzero * 2 + 1] = (iLevel < 0) ? -iTemp : iTemp; + iNumNonzero++; + iRun = 0; + } + else { + iRun++; + iTemp = -(iLevel < 0); + iLevel = ((iLevel + iTemp) >> iTrimBits) - iTemp; // round towards zero + iTemp = -(iLevel < 0); + pResidual[pScan[1].uScan] = (iLevel ^ iTemp) * 4 + (6 & iTemp) + (iLevel != 0); + } + for (k = 2; k < iCount; k++) { + const Int sk = pScan[k].uScan; + //pResidual++; + iLevel = pCoeffs[sk]; + if ((unsigned int)(iLevel + iThOff) >= iTh) { + iTemp1 = abs(iLevel); + iTemp = iTemp1 >> iModelBits; + pResidual[sk] = ((iTemp1 & iThOff) >> iTrimBits) * 2; + pScan[k].uTotal++; + if (pScan[k].uTotal > pScan[k - 1].uTotal) { + CAdaptiveScan cTemp = pScan[k]; + pScan[k] = pScan[k - 1]; + pScan[k - 1] = cTemp; + } + pRLCoeffs[iNumNonzero * 2] = iRun; + pRLCoeffs[iNumNonzero * 2 + 1] = (iLevel < 0) ? -iTemp : iTemp; + iNumNonzero++; + iRun = 0; + } + else { + iRun++; + iTemp = -(iLevel < 0); + iLevel = ((iLevel + iTemp) >> iTrimBits) - iTemp; // round towards zero + iTemp = -(iLevel < 0); + pResidual[sk] = (iLevel ^ iTemp) * 4 + (6 & iTemp) + (iLevel != 0); + } + } + return iNumNonzero; + } +} + +/************************************************************************* + EncodeMacroblockLowpass +*************************************************************************/ +Int EncodeMacroblockLowpass(CWMImageStrCodec* pSC, CCodingContext* pContext, Int iMBX, Int iMBY) +{ + const COLORFORMAT cf = pSC->m_param.cfColorFormat; + const Int iChannels = (Int)pSC->m_param.cNumChannels; + Int iFullChannels = (cf == YUV_420 || cf == YUV_422) ? 1 : iChannels; + CWMIMBInfo* pMBInfo = &pSC->MBInfo; + BitIOInfo* pIO = pContext->m_pIOLP; + + CAdaptiveScan* pScan = pContext->m_aScanLowpass; + Int k, /*iPrevRun = -1,*/ iRun = 0;// iLastIndex = 0; + Int iModelBits = pContext->m_aModelLP.m_iFlcBits[0]; + PixelI aBuf[2][8]; + Int aLaplacianMean[2] = { 0, 0 }, * pLM = aLaplacianMean; + Int iChannel, iVal; + Int aRLCoeffs[MAX_CHANNELS][32], iNumCoeffs[MAX_CHANNELS]; + const I32* aDC[MAX_CHANNELS]; + Int aResidual[MAX_CHANNELS][16]; + Void(*putBits)(BitIOInfo * pIO, U32 uiBits, U32 cBits) = putBit16; + + UNREFERENCED_PARAMETER(iMBX); + UNREFERENCED_PARAMETER(iMBY); + + if (iChannels > MAX_CHANNELS) + return ICERR_ERROR; + + if ((pSC->WMISCP.bfBitstreamFormat != SPATIAL) && (pSC->pTile[pSC->cTileColumn].cBitsLP > 0)) // MB-based LP QP index + encodeQPIndex(pIO, pMBInfo->iQIndexLP, pSC->pTile[pSC->cTileColumn].cBitsLP); + + // set arrays + for (k = 0; k < iChannels; k++) { + aDC[k] = pMBInfo->iBlockDC[k]; + } + + /** reset adaptive scan totals **/ + if (pSC->m_bResetRGITotals) { + int iScale = 2; + int iWeight = iScale * 16; + pScan[0].uTotal = MAXTOTAL; + for (k = 1; k < 16; k++) { + pScan[k].uTotal = iWeight; + iWeight -= iScale; + } + } + + /** scan 4x4 transform **/ + for (iChannel = 0; iChannel < iFullChannels; iChannel++) { + iNumCoeffs[iChannel] = AdaptiveScan(aDC[iChannel], aResidual[iChannel], + pScan, iModelBits, 0, aRLCoeffs[iChannel], 16); + + iModelBits = pContext->m_aModelLP.m_iFlcBits[1]; + } + + if (cf == YUV_420 || cf == YUV_422) { /** interleave U and V **/ + static const Int aRemap[] = { 4, 1,2,3, 5,6,7 }; + const Int* pRemap = aRemap + (cf == YUV_420); + const Int iCount = (cf == YUV_420) ? 6 : 14; + Int iCoef = 0; + + iRun = 0; + iModelBits = pContext->m_aModelLP.m_iFlcBits[1]; + + for (k = 0; k < iCount; k++) { + Int iIndex = pRemap[k >> 1]; + Int iDC = aDC[(k & 1) + 1][iIndex]; + aBuf[k & 1][iIndex] = iVal = abs(iDC) >> iModelBits; + + if (iVal) { + aRLCoeffs[1][iCoef * 2] = iRun; + aRLCoeffs[1][iCoef * 2 + 1] = (iDC < 0) ? -iVal : iVal; + iCoef++; + iRun = 0; + } + else { + iRun++; + } + } + iNumCoeffs[1] = iCoef; + } + + /** in raw mode, this can take 6% of the bits in the extreme low rate case!!! **/ + if (cf == YUV_420 || cf == YUV_422) + iFullChannels = 2; + + if (cf == YUV_420 || cf == YUV_422 || cf == YUV_444) { + int iCBP, iMax = iFullChannels * 4 - 5; /* actually (1 << iNChannels) - 1 **/ + int iCountM = pContext->m_iCBPCountMax, iCountZ = pContext->m_iCBPCountZero; + iCBP = (iNumCoeffs[0] > 0) + (iNumCoeffs[1] > 0) * 2; + if (iFullChannels == 3) + iCBP += (iNumCoeffs[2] > 0) * 4; + + if (iCountZ <= 0 || iCountM < 0) { + iVal = iCBP; + if (iCountM < iCountZ) { + iVal = iMax - iCBP; + } + if (iVal == 0) + putBit16z(pIO, 0, 1); + else if (iVal == 1) + putBit16z(pIO, (iFullChannels + 1) & 0x6, iFullChannels); // 2 or 4 + else + putBit16z(pIO, iVal + iMax + 1, iFullChannels + 1); // cbp + 4 or cbp + 8 + } + else { + putBit16z(pIO, iCBP, iFullChannels); + } + + iCountM += 1 - 4 * (iCBP == iMax);//(b + c - 2*a); + iCountZ += 1 - 4 * (iCBP == 0);//(a + b - 2*c); + if (iCountM < -8) + iCountM = -8; + else if (iCountM > 7) + iCountM = 7; + pContext->m_iCBPCountMax = iCountM; + + if (iCountZ < -8) + iCountZ = -8; + else if (iCountZ > 7) + iCountZ = 7; + pContext->m_iCBPCountZero = iCountZ; + } + else { /** 1 or N channel **/ + for (iChannel = 0; iChannel < iChannels; iChannel++) { + putBit16z(pIO, (iNumCoeffs[iChannel] > 0), 1); + } + } + + // set appropriate function pointer + if (pContext->m_aModelLP.m_iFlcBits[0] > 14 || pContext->m_aModelLP.m_iFlcBits[1] > 14) { + putBits = putBit32; + } + + iModelBits = pContext->m_aModelLP.m_iFlcBits[0]; + + for (iChannel = 0; iChannel < iFullChannels; iChannel++) { + const Int* pRL = aRLCoeffs[iChannel]; + Int iCoef = iNumCoeffs[iChannel]; + + if (iCoef) { + (*pLM) += iCoef; + if (EncodeBlock(iChannel > 0, pRL, iCoef, pContext->m_pAHexpt, CTDC, + pIO, 1 + 9 * ((cf == YUV_420) && (iChannel == 1)) + ((cf == YUV_422) && (iChannel == 1))) != ICERR_OK) + return ICERR_ERROR; + } + + if (iModelBits) { + if ((cf == YUV_420 || cf == YUV_422) && iChannel) { // 420/422 chroma + for (k = 1; k < ((cf == YUV_420) ? 4 : 8); k++) { + putBits(pIO, abs(aDC[1][k]), iModelBits); + if (aBuf[0][k] == 0 && aDC[1][k]) { + putBit16z(pIO, (aDC[1][k] < 0), 1); + } + putBits(pIO, abs(aDC[2][k]), iModelBits); + if (aBuf[1][k] == 0 && aDC[2][k]) { + putBit16z(pIO, (aDC[2][k] < 0), 1); + } + } + } + else { // normal case + for (k = 1; k < 16; k++) { + putBit16z(pIO, aResidual[iChannel][k] >> 1, iModelBits + (aResidual[iChannel][k] & 1)); + } + } + } + + pLM = aLaplacianMean + 1; + iModelBits = pContext->m_aModelLP.m_iFlcBits[1]; + } + + writeIS_L1(pSC, pIO); + + UpdateModelMB(cf, iChannels, aLaplacianMean, &pContext->m_aModelLP); + + if (pSC->m_bResetContext) { + AdaptLowpassEnc(pContext); + } + + return ICERR_OK; +} + +/************************************************************************* + Adapt +*************************************************************************/ +Void AdaptLowpassEnc(CCodingContext* pSC) +{ + Int kk; + for (kk = 0; kk < CONTEXTX + CTDC; kk++) { /** adapt fixed code (index 0 and 1) as well **/ + AdaptDiscriminant(pSC->m_pAHexpt[kk]); + } +} + +Void AdaptHighpassEnc(CCodingContext* pSC) +{ + Int kk; + //Adapt (pSC->m_pAdaptHuffCBPCY, FALSE); + AdaptDiscriminant(pSC->m_pAdaptHuffCBPCY); + AdaptDiscriminant(pSC->m_pAdaptHuffCBPCY1); + for (kk = 0; kk < CONTEXTX; kk++) { /** adapt fixed code **/ + AdaptDiscriminant(pSC->m_pAHexpt[kk + CONTEXTX + CTDC]); + } +} + +/************************************************************************* + Experimental code -- encodeBlock + SR = <0 1 2> == + alphabet 12: + pAHexpt[0] == + alphabet 6: + pAHexpt[1] == + pAHexpt[2] == + alphabet 4: + pAHexpt[3] == (SR may be last or insignificant only) + alphabet f(run) (this can be extended to 6 contexts - SL and SR') + pAHexpt[4] == + alphabet f(lev) (this can be extended to 9 contexts) + pAHexpt[5-6] == first symbol + pAHexpt[7-8] == condition on SRn no use +*************************************************************************/ +#ifdef X86OPT_INLINE +__forceinline +#endif +static Void EncodeSignificantRun(Int iRun, Int iMaxRun, struct CAdaptiveHuffman* pAHexpt, BitIOInfo* pOut) +{ + Int iIndex, iFLC, iBin; + static const Int aIndex[] = { + 0,1,2,2,3,3,4,4,4,4,4,4,4,4, + 0,1,2,2,3,3,4,4,4,4,0,0,0,0, + 0,1,2,3,4,4 + }; + + if (iMaxRun < 5) { + //if (iMaxRun == 4) { + //static const Int gCode[] = { 0, 1, 1, 1 }; + static const Int gLen[] = { 3, 3, 2, 1 }; + if (iMaxRun > 1) + putBit16z(pOut, (iMaxRun != iRun), gLen[iMaxRun - iRun] - (4 - iMaxRun)); + //} + //else if (iMaxRun == 3) { + // if (iRun == 1) { + // putBit16z(pOut, 1, 1); + // } + // else { + // putBit16z(pOut, 3 ^ iRun, 2); + // } + //} + //else if (iMaxRun == 2) { + // putBit16z(pOut, 2 - iRun, 1); + //} + return; + } + + iBin = gSignificantRunBin[iMaxRun]; + iIndex = aIndex[iRun + iBin * 14 - 1]; + iFLC = gSignificantRunFixedLength[iIndex + iBin * 5]; + putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1], pAHexpt->m_pTable[iIndex * 2 + 2]); + //this always uses table 0 + //pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex]; + putBit16(pOut, iRun + 1, iFLC); +} + +#ifdef X86OPT_INLINE +__forceinline +#endif +static Void EncodeFirstIndex(Bool bChroma, Int iLoc, Int iCont, Int iIndex, Int iSign, + struct CAdaptiveHuffman** ppAHexpt, BitIOInfo* pOut) +{ + // Int iContext = iCont + 1 + bChroma * 3; + struct CAdaptiveHuffman* pAHexpt = ppAHexpt[bChroma * 3]; + UNREFERENCED_PARAMETER(iLoc); + UNREFERENCED_PARAMETER(iCont); + pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex]; + pAHexpt->m_iDiscriminant1 += pAHexpt->m_pDelta1[iIndex]; + putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1] * 2 + iSign, pAHexpt->m_pTable[iIndex * 2 + 2] + 1); + return; +} + +#ifdef X86OPT_INLINE +__forceinline +#endif +static Void EncodeIndex(Bool bChroma, Int iLoc, Int iCont, Int iIndex, Int iSign, + struct CAdaptiveHuffman** ppAHexpt, BitIOInfo* pOut) +{ + Int iContext = iCont + 1 + bChroma * 3; + + if (iLoc < 15) { + struct CAdaptiveHuffman* pAHexpt = ppAHexpt[iContext]; + pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex]; + pAHexpt->m_iDiscriminant1 += pAHexpt->m_pDelta1[iIndex]; + putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1] * 2 + iSign, pAHexpt->m_pTable[iIndex * 2 + 2] + 1); + } + else if (iLoc == 15) { + static const U32 gCode[] = { 0, 6, 2, 7 }; + static const U32 gLen[] = { 1, 3, 2, 3 }; + putBit16z(pOut, gCode[iIndex] * 2 + iSign, gLen[iIndex] + 1); + return; + } + else {//if (iLoc == 16) { + putBit16z(pOut, iIndex * 2 + iSign, 1 + 1); + return; + } +} + +#ifdef X86OPT_INLINE +__forceinline +#endif +static Int EncodeBlock(Bool bChroma, const Int* aLocalCoef, Int iNumNonzero, + struct CAdaptiveHuffman** pAHexpt, Int iContextOffset, + BitIOInfo* pOut, UInt iLocation) +{ + Int iSR, iSL, iSRn, iIndex, k, iCont, iLev; + + /** first symbol **/ + iLev = aLocalCoef[1]; + iSR = (aLocalCoef[0] == 0); + iSL = ((unsigned int)(iLev + 1) > 2U); + iSRn = 1; + if (iNumNonzero == 1) { + iSRn = 0; + } + else if (aLocalCoef[2] > 0) { + iSRn = 2; + } + iIndex = iSRn * 4 + iSL * 2 + iSR; + EncodeFirstIndex(bChroma, iLocation, 0, iIndex, (iLev < 0), pAHexpt + iContextOffset, pOut); + iCont = iSR & iSRn; + if (iSL) { + EncodeSignificantAbsLevel((UInt)(abs(iLev) - 1), pAHexpt[6 + iContextOffset + iCont], pOut); + } + if (iSR == 0) { + EncodeSignificantRun(aLocalCoef[0], 15 - iLocation, pAHexpt[0], pOut); + } + iLocation += aLocalCoef[0] + 1; + + for (k = 1; k < iNumNonzero; k++) { + if (iSRn == 2) { + EncodeSignificantRun(aLocalCoef[k * 2], 15 - iLocation, pAHexpt[0], pOut); + } + iLocation += aLocalCoef[k * 2] + 1; + iSRn = 1; + if (k == iNumNonzero - 1) { + iSRn = 0; + } + else if (aLocalCoef[k * 2 + 2] > 0) { + iSRn = 2; + } + //iSL = (abs(aLocalCoef[k * 2 + 1]) > 1); + iLev = aLocalCoef[k * 2 + 1]; + iSL = ((unsigned int)(iLev + 1) > 2U); + iIndex = iSRn * 2 + iSL; + EncodeIndex(bChroma, iLocation, iCont, iIndex, (iLev < 0), pAHexpt + iContextOffset, pOut); + + iCont &= iSRn; /** big difference! **/ + if (iSL) { + EncodeSignificantAbsLevel((UInt)(abs(iLev) - 1), pAHexpt[6 + iContextOffset + iCont], pOut); + } + //else { + // putBit16z(pOut, (iLev < 0), 1); + //} + } + + return ICERR_OK; +} + +/************************************************************************* + CodeCoeffs +*************************************************************************/ +#ifdef X86OPT_INLINE +__forceinline +#endif +static Int CodeCoeffs(CWMImageStrCodec* pSC, CCodingContext* pContext, + Int iMBX, Int iMBY, BitIOInfo* pIO, BitIOInfo* pIOFL) +{ + const COLORFORMAT cf = pSC->m_param.cfColorFormat; + const Int iChannels = (Int)pSC->m_param.cNumChannels; + const Int iPlanes = (cf == YUV_420 || cf == YUV_422) ? 1 : iChannels; + CWMIMBInfo* pMBInfo = &pSC->MBInfo; + CAdaptiveScan* pScan; + Int iBlock, iNBlocks = 4; + Int iSubblock, iIndex = 0; + Int i, k; + const Int iNumCoeffs = 16; + Int iModelBits = pContext->m_aModelAC.m_iFlcBits[0], iFlex = 0, iTrim = 0, iMask = 0; + Int aLaplacianMean[2] = { 0, 0 }, * pLM = aLaplacianMean; + Bool bChroma = FALSE; + + UNREFERENCED_PARAMETER(iMBX); + UNREFERENCED_PARAMETER(iMBY); + + assert(iModelBits < 16); + if (pContext->m_iTrimFlexBits <= iModelBits && pSC->WMISCP.sbSubband != SB_NO_FLEXBITS) { + iTrim = pContext->m_iTrimFlexBits; + iFlex = iModelBits - pContext->m_iTrimFlexBits; + iMask = (1 << iFlex) - 1; + } + + if (pSC->WMISCP.sbSubband != SB_NO_FLEXBITS) + writeIS_L1(pSC, pIOFL); + + /** set scan arrays **/ + if (pMBInfo->iOrientation == 1) { + pScan = pContext->m_aScanVert; + } + else { + pScan = pContext->m_aScanHoriz; + } + + /** write out coefficients **/ + for (i = 0; i < iPlanes; i++) { + Int iPattern = pMBInfo->iCBP[i]; + + if (cf == YUV_420) { + iNBlocks = 6; + iPattern += (pMBInfo->iCBP[1] << 16) + (pMBInfo->iCBP[2] << 20); + } + else if (cf == YUV_422) { + iNBlocks = 8; + iPattern += (pMBInfo->iCBP[1] << 16) + (pMBInfo->iCBP[2] << 24); + } + + for (iBlock = iIndex = 0; iBlock < iNBlocks; iBlock++) { + writeIS_L2(pSC, pIO); + if (pIO != pIOFL) + writeIS_L2(pSC, pIOFL); + + for (iSubblock = 0; iSubblock < 4; iSubblock++, iPattern >>= 1, iIndex++) { + const PixelI* pCoeffs = NULL; + + if (iBlock < 4) { + pCoeffs = pSC->pPlane[i] + blkOffset[iIndex]; + } + else if (cf == YUV_420) { + pCoeffs = pSC->pPlane[iBlock - 3] + blkOffsetUV[iSubblock]; + } + else if (cf == YUV_422) { + pCoeffs = pSC->pPlane[1 + ((iBlock - 4) >> 1)] + blkOffsetUV_422[(iBlock & 1) * 4 + iSubblock]; + } + + /** put AC bits **/ + + if ((iPattern & 1) == 0) { + if (iFlex) { + /** FLC only, all else is skipped **/ + for (k = 1; k < iNumCoeffs; k++) { + Int data = pCoeffs[dctIndex[0][k]]; + Int atdata = (abs(data) >> iTrim); + Int word = atdata & iMask, len = iFlex; + if (atdata) { + word += word + (data < 0); + len++; + } + putBit16z(pIOFL, word, len); + } + } + } + else { + // WARNING!!! interaction between lowpass coefficients and highpass scan ordering - may lead to break in decoding when model bits is nonzero! + // Fix is to use same scan order in model bits transmission, and defer update of scan order to end of block + /** collect coefficients **/ + Int aLocalCoef[32], iNumNonzero = 0; + Int aResidual[16]; + + iNumNonzero = AdaptiveScan(pCoeffs, aResidual, + pScan, iModelBits, iTrim, aLocalCoef, 16); + (*pLM) += iNumNonzero; + EncodeBlock(bChroma, aLocalCoef, iNumNonzero, pContext->m_pAHexpt, CTDC + CONTEXTX, pIO, 1); + + if (iFlex) { + for (k = 1; k < iNumCoeffs; k++) { + putBit16z(pIOFL, aResidual[dctIndex[0][k]] >> 1, iFlex + (aResidual[dctIndex[0][k]] & 1)); + } + } + } + } + if (iBlock == 3) { + iModelBits = pContext->m_aModelAC.m_iFlcBits[1]; + assert(iModelBits < 16); + pLM = aLaplacianMean + 1; + bChroma = TRUE; + iTrim = iFlex = iMask = 0; + if (pContext->m_iTrimFlexBits <= iModelBits && pSC->WMISCP.sbSubband != SB_NO_FLEXBITS) { + iTrim = pContext->m_iTrimFlexBits; + iFlex = iModelBits - iTrim; + iMask = (1 << iFlex) - 1; + } + } + } + } + + /** update model at end of MB **/ + UpdateModelMB(cf, iChannels, aLaplacianMean, &pContext->m_aModelAC); + + return ICERR_OK; +} + + +/************************************************************************* + CodeCBP +*************************************************************************/ +static Void CodeCBP(CWMImageStrCodec* pSC, CCodingContext* pContext, + Int iMBX, Int iMBY, BitIOInfo* pIO) +{ + const COLORFORMAT cf = pSC->m_param.cfColorFormat; + const Int iChannel = (cf == NCOMPONENT || cf == CMYK) ? (Int)pSC->m_param.cNumChannels : 1; + Int iDiffCBPCY, iDiffCBPCU = 0, iDiffCBPCV = 0, iDY; + Int iBlock, i, k; + static const Int aNumOnes[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; + static const Int aTabLen[] = { 0, 2, 2, 2, 2, 2, 3, 2, 2, 3, 3, 2, 3, 2, 2, 0 }; + static const Int aTabCode[] = { 0, 0, 1, 0, 2, 1, 4, 3, 3, 5, 6, 2, 7, 1, 0, 0 }; + CAdaptiveHuffman* pAH; + Int iCount, iPattern, iCode, iCodeU = 0, iCodeV = 0; + + UNREFERENCED_PARAMETER(iMBX); + UNREFERENCED_PARAMETER(iMBY); + + predCBPEnc(pSC, pContext); + writeIS_L1(pSC, pIO); + + iDiffCBPCU = pSC->MBInfo.iDiffCBP[1]; + iDiffCBPCV = pSC->MBInfo.iDiffCBP[2]; + + for (i = 0; i < iChannel; i++) { + iDiffCBPCY = pSC->MBInfo.iDiffCBP[i]; + + if (cf == YUV_420) { // PackCBP420 + iDiffCBPCY = (iDiffCBPCY & 0xf) + ((iDiffCBPCU & 1) << 4) + ((iDiffCBPCV & 1) << 5) + + ((iDiffCBPCY & 0x00f0) << 2) + ((iDiffCBPCU & 2) << 9) + ((iDiffCBPCV & 2) << 10) + + ((iDiffCBPCY & 0x0f00) << 4) + ((iDiffCBPCU & 4) << 14) + ((iDiffCBPCV & 4) << 15) + + ((iDiffCBPCY & 0xf000) << 6) + ((iDiffCBPCU & 8) << 19) + ((iDiffCBPCV & 8) << 20); + } + else if (cf == YUV_422) {// PackCBP422 + iDiffCBPCY = (iDiffCBPCY & 0xf) + ((iDiffCBPCU & 1) << 4) + ((iDiffCBPCU & 4) << 3) + + ((iDiffCBPCV & 1) << 6) + ((iDiffCBPCV & 4) << 5) + + ((iDiffCBPCY & 0x00f0) << 4) + ((iDiffCBPCU & 2) << 11) + ((iDiffCBPCU & 8) << 10) + + ((iDiffCBPCV & 2) << 13) + ((iDiffCBPCV & 8) << 12) + + ((iDiffCBPCY & 0x0f00) << 8) + ((iDiffCBPCU & 16) << 16) + ((iDiffCBPCU & 64) << 15) + + ((iDiffCBPCV & 16) << 18) + ((iDiffCBPCV & 64) << 17) + + ((iDiffCBPCY & 0xf000) << 12) + ((iDiffCBPCU & 32) << 23) + ((iDiffCBPCU & 128) << 22) + + ((iDiffCBPCV & 32) << 25) + ((iDiffCBPCV & 128) << 24); + } + + /** send CBPCY **/ + iPattern = 0; + iDY = iDiffCBPCY; + if (cf == YUV_444) { + iDY |= (iDiffCBPCU | iDiffCBPCV); + } + + for (iBlock = 0; iBlock < 4; iBlock++) { + if (cf == YUV_422) { + iPattern |= ((iDY & 0xff) != 0) * 0x10; + iDY >>= 8; + } + else if (cf == YUV_420) { + iPattern |= ((iDY & 0x3f) != 0) * 0x10; + iDY >>= 6; + } + else { + iPattern |= ((iDY & 0xf) != 0) * 0x10; + iDY >>= 4; + } + iPattern >>= 1; + } + + pAH = pContext->m_pAdaptHuffCBPCY1; + iCount = aNumOnes[iPattern]; + putBit16z(pIO, pAH->m_pTable[iCount * 2 + 1], pAH->m_pTable[iCount * 2 + 2]); + pAH->m_iDiscriminant += pAH->m_pDelta[iCount]; + if (aTabLen[iPattern]) { + putBit16z(pIO, aTabCode[iPattern], aTabLen[iPattern]); + } + + for (iBlock = 0; iBlock < 4; iBlock++) { + switch (cf) { + case YUV_444: + iCode = iDiffCBPCY & 0xf; + iCodeU = iDiffCBPCU & 0xf; + iCodeV = iDiffCBPCV & 0xf; + iCode |= ((iCodeU != 0) << 4); + iCode |= ((iCodeV != 0) << 5); + iDiffCBPCY >>= 4; + iDiffCBPCU >>= 4; + iDiffCBPCV >>= 4; + break; + + case YUV_422: + iCode = iDiffCBPCY & 0xff; + iDiffCBPCY >>= 8; + break; + + case YUV_420: + iCode = iDiffCBPCY & 0x3f; + iDiffCBPCY >>= 6; + break; + + default: + iCode = iDiffCBPCY & 0xf; + iDiffCBPCY >>= 4; + } + + if (iCode) { + static const Int gTab0[16] = { 0,1,1,2, 1,3,3,4, 1,3,3,4, 2,4,4,5 }; + static const Int gFL0[16] = { 0,2,2,1, 2,2,2,2, 2,2,2,2, 1,2,2,0 }; + static const Int gCode0[16] = { 0,0,1,0, 2,0,1,0, 3,2,3,1, 1,2,3,0 }; + int val, iChroma = (iCode >> 4); + iCode &= 0xf; + + if (cf == YUV_422) { + iCodeU = (iChroma & 3); + iCodeV = ((iChroma >> 2) & 3); + iChroma = (iCodeU == 0 ? 0 : 1); + if (iCodeV != 0) { + iChroma += 2; + } + } + + if (iChroma) { + if (gTab0[iCode] > 2) { + val = 8; + } + else { + val = gTab0[iCode] + 6 - 1; + } + } + else { + val = gTab0[iCode] - 1; + } + pAH = pContext->m_pAdaptHuffCBPCY; + putBit16z(pIO, pAH->m_pTable[val * 2 + 1], pAH->m_pTable[val * 2 + 2]); + pAH->m_iDiscriminant += pAH->m_pDelta[val]; + + if (iChroma) { + if (iChroma == 1) + putBit16z(pIO, 1, 1); + else + putBit16z(pIO, 3 - iChroma, 2); + } + if (val == 8) { + if (gTab0[iCode] == 3) { + putBit16z(pIO, 1, 1); + } + else { + putBit16z(pIO, 5 - gTab0[iCode], 2); + } + } + if (gFL0[iCode]) { + putBit16z(pIO, gCode0[iCode], gFL0[iCode]); + } + + if (cf == YUV_444) { + pAH = pContext->m_pAHexpt[1]; + iPattern = iCodeU; + for (k = 0; k < 2; k++) { + if (iPattern) { + iCount = aNumOnes[iPattern]; + iCount--; + putBit16z(pIO, pAH->m_pTable[iCount * 2 + 1], pAH->m_pTable[iCount * 2 + 2]); + if (aTabLen[iPattern]) { + putBit16z(pIO, aTabCode[iPattern], aTabLen[iPattern]); + } + } + iPattern = iCodeV; + } + } + else if (cf == YUV_422) { + iPattern = iCodeU; + for (k = 0; k < 2; k++) { + if (iPattern) { + if (iPattern == 1) + putBit16z(pIO, 1, 1); + else { + putBit16z(pIO, 3 - iPattern, 2); + } + } + iPattern = iCodeV; + } + } + } + } + } +} + +/************************************************************************* + macroblock encode function using 4x4 transforms +*************************************************************************/ +Int EncodeMacroblockHighpass(CWMImageStrCodec* pSC, CCodingContext* pContext, Int iMBX, Int iMBY) +{ + BitIOInfo* pIO = pContext->m_pIOAC; + BitIOInfo* pIOFL = pContext->m_pIOFL; + + if ((pSC->WMISCP.bfBitstreamFormat != SPATIAL) && (pSC->pTile[pSC->cTileColumn].cBitsHP > 0)) // MB-based HP QP index + encodeQPIndex(pIO, pSC->MBInfo.iQIndexHP, pSC->pTile[pSC->cTileColumn].cBitsHP); + + /** reset adaptive scan totals **/ + if (pSC->m_bResetRGITotals) { + Int iScale = 2; + Int iWeight = iScale * 16; + Int k; + pContext->m_aScanHoriz[0].uTotal = pContext->m_aScanVert[0].uTotal = MAXTOTAL; + for (k = 1; k < 16; k++) { + pContext->m_aScanHoriz[k].uTotal = pContext->m_aScanVert[k].uTotal = iWeight; + iWeight -= iScale; + } + } + CodeCBP(pSC, pContext, iMBX, iMBY, pIO); + if (CodeCoeffs(pSC, pContext, iMBX, iMBY, pIO, pIOFL) != ICERR_OK) + return ICERR_ERROR; + + if (pSC->m_bResetContext) { + AdaptHighpassEnc(pContext); + } + + return ICERR_OK; +} diff --git a/Src/JxrDecode/jxrlib/image/encode/strFwdTransform.c b/Src/JxrDecode/jxrlib/image/encode/strFwdTransform.c new file mode 100644 index 00000000..b4a2e5d4 --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/encode/strFwdTransform.c @@ -0,0 +1,1111 @@ +//*@@@+++@@@@****************************************************************** +// +// 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 "../sys/strTransform.h" +#include "encode.h" + +/** rotation by pi/8 **/ +#define ROTATE1(a, b) (b) -= (((a) + 1) >> 1), (a) += (((b) + 1) >> 1) // this works well too +#define ROTATE2(a, b) (b) -= (((a)*3 + 4) >> 3), (a) += (((b)*3 + 4) >> 3) // this works well too + +/** local functions **/ +static Void fwdOddOdd(PixelI*, PixelI*, PixelI*, PixelI*); +static Void fwdOddOddPre(PixelI*, PixelI*, PixelI*, PixelI*); +static Void fwdOdd(PixelI*, PixelI*, PixelI*, PixelI*); +static Void strDCT2x2alt(PixelI* a, PixelI* b, PixelI* c, PixelI* d); +static Void strHSTenc1(PixelI*, PixelI*); +static Void strHSTenc(PixelI*, PixelI*, PixelI*, PixelI*); +static Void strHSTenc1_edge(PixelI* pa, PixelI* pd); + +//static Void scaleDownUp0(PixelI *, PixelI *); +//static Void scaleDownUp1(PixelI *, PixelI *); +//static Void scaleDownUp2(PixelI *, PixelI *); +//#define FOURBUTTERFLY_ENC_ALT(p, i00, i01, i02, i03, i10, i11, i12, i13, \ +// i20, i21, i22, i23, i30, i31, i32, i33) \ +// strHSTenc(&p[i00], &p[i01], &p[i02], &p[i03]); \ +// strHSTenc(&p[i10], &p[i11], &p[i12], &p[i13]); \ +// strHSTenc(&p[i20], &p[i21], &p[i22], &p[i23]); \ +// strHSTenc(&p[i30], &p[i31], &p[i32], &p[i33]); \ +// strHSTenc1(&p[i00], &p[i03]); \ +// strHSTenc1(&p[i10], &p[i13]); \ +// strHSTenc1(&p[i20], &p[i23]); \ +// strHSTenc1(&p[i30], &p[i33]) + +/** DCT stuff **/ +/** data order before DCT **/ +/** 0 1 2 3 **/ +/** 4 5 6 7 **/ +/** 8 9 10 11 **/ +/** 12 13 14 15 **/ +/** data order after DCT **/ +/** 0 8 4 6 **/ +/** 2 10 14 12 **/ +/** 1 11 15 13 **/ +/** 9 3 7 5 **/ +/** reordering should be combined with zigzag scan **/ + +Void strDCT4x4Stage1(PixelI* p) +{ + /** butterfly **/ + //FOURBUTTERFLY(p, 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15); + FOURBUTTERFLY_HARDCODED1(p); + + /** top left corner, butterfly => butterfly **/ + strDCT2x2up(&p[0], &p[1], &p[2], &p[3]); + + /** bottom right corner, pi/8 rotation => pi/8 rotation **/ + fwdOddOdd(&p[15], &p[14], &p[13], &p[12]); + + /** top right corner, butterfly => pi/8 rotation **/ + fwdOdd(&p[5], &p[4], &p[7], &p[6]); + + /** bottom left corner, pi/8 rotation => butterfly **/ + fwdOdd(&p[10], &p[8], &p[11], &p[9]); +} + +Void strDCT4x4SecondStage(PixelI* p) +{ + /** butterfly **/ + FOURBUTTERFLY(p, 0, 192, 48, 240, 64, 128, 112, 176, 16, 208, 32, 224, 80, 144, 96, 160); + + /** top left corner, butterfly => butterfly **/ + strDCT2x2up(&p[0], &p[64], &p[16], &p[80]); + + /** bottom right corner, pi/8 rotation => pi/8 rotation **/ + fwdOddOdd(&p[160], &p[224], &p[176], &p[240]); + + /** top right corner, butterfly => pi/8 rotation **/ + fwdOdd(&p[128], &p[192], &p[144], &p[208]); + + /** bottom left corner, pi/8 rotation => butterfly **/ + fwdOdd(&p[32], &p[48], &p[96], &p[112]); +} + +Void strNormalizeEnc(PixelI* p, Bool bChroma) +{ + int i; + if (!bChroma) { + //for (i = 0; i < 256; i += 16) { + // p[i] = (p[i] + 1) >> 2; + //} + } + else { + for (i = 0; i < 256; i += 16) { + p[i] >>= 1; + } + } +} + +/** 2x2 DCT with pre-scaling - for use on encoder side **/ +Void strDCT2x2dnEnc(PixelI* pa, PixelI* pb, PixelI* pc, PixelI* pd) +{ + PixelI a, b, c, d, C, t; + a = (*pa + 0) >> 1; + b = (*pb + 0) >> 1; + C = (*pc + 0) >> 1; + d = (*pd + 0) >> 1; + //PixelI t1, t2; + + 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; +} + +/** pre filter stuff **/ +/** 2-point pre for boundaries **/ +Void strPre2(PixelI* pa, PixelI* pb) +{ + PixelI a, b; + a = *pa; + b = *pb; + + /** rotate **/ + b -= ((a + 2) >> 2); + a -= ((b + 1) >> 1); + + a -= (b >> 5); + a -= (b >> 9); + a -= (b >> 13); + + b -= ((a + 2) >> 2); + + *pa = a; + *pb = b; +} + +Void strPre2x2(PixelI* pa, PixelI* pb, PixelI* pc, PixelI* pd) +{ + PixelI a, b, c, d; + a = *pa; + b = *pb; + c = *pc; + d = *pd; + + /** butterflies **/ + a += d; + b += c; + d -= (a + 1) >> 1; + c -= (b + 1) >> 1; + + /** rotate **/ + b -= ((a + 2) >> 2); + a -= ((b + 1) >> 1); + a -= (b >> 5); + a -= (b >> 9); + a -= (b >> 13); + b -= ((a + 2) >> 2); + + /** butterflies **/ + d += (a + 1) >> 1; + c += (b + 1) >> 1; + a -= d; + b -= c; + + *pa = a; + *pb = b; + *pc = c; + *pd = d; +} + +/** 4-point pre for boundaries **/ +Void strPre4(PixelI* pa, PixelI* pb, PixelI* pc, PixelI* pd) +{ + PixelI a, b, c, d; + a = *pa; + b = *pb; + c = *pc; + d = *pd; + + a += d, b += c; + d -= ((a + 1) >> 1), c -= ((b + 1) >> 1); + + ROTATE1(c, d); + + strHSTenc1_edge(&a, &d); strHSTenc1_edge(&b, &c); + + d += ((a + 1) >> 1), c += ((b + 1) >> 1); + a -= d, b -= c; + + *pa = a; + *pb = b; + *pc = c; + *pd = d; +} + +/***************************************************************************************** + Input data offsets: + (15)(14)|(10+64)(11+64) p0 (15)(14)|(74)(75) + (13)(12)|( 8+64)( 9+64) (13)(12)|(72)(73) + --------+-------------- --------+-------- + ( 5)( 4)|( 0+64) (1+64) p1 ( 5)( 4)|(64)(65) + ( 7)( 6)|( 2+64) (3+64) ( 7)( 6)|(66)(67) +*****************************************************************************************/ +Void strPre4x4Stage1Split(PixelI* p0, PixelI* p1, Int iOffset) +{ + PixelI* p2 = p0 + 72 - iOffset; + PixelI* p3 = p1 + 64 - iOffset; + p0 += 12; + p1 += 4; + + /** butterfly & scaling **/ + strHSTenc(p0 + 0, p2 + 0, p1 + 0, p3 + 0); + strHSTenc(p0 + 1, p2 + 1, p1 + 1, p3 + 1); + strHSTenc(p0 + 2, p2 + 2, p1 + 2, p3 + 2); + strHSTenc(p0 + 3, p2 + 3, p1 + 3, p3 + 3); + strHSTenc1(p0 + 0, p3 + 0); + strHSTenc1(p0 + 1, p3 + 1); + strHSTenc1(p0 + 2, p3 + 2); + strHSTenc1(p0 + 3, p3 + 3); + + /** anti diagonal corners: rotation by pi/8 **/ + ROTATE1(p1[2], p1[3]); + ROTATE1(p1[0], p1[1]); + ROTATE1(p2[1], p2[3]); + ROTATE1(p2[0], p2[2]); + + /** bottom right corner: pi/8 rotation => pi/8 rotation **/ + fwdOddOddPre(p3 + 0, p3 + 1, p3 + 2, p3 + 3); + + /** butterfly **/ + strDCT2x2dn(p0 + 0, p2 + 0, p1 + 0, p3 + 0); + strDCT2x2dn(p0 + 1, p2 + 1, p1 + 1, p3 + 1); + strDCT2x2dn(p0 + 2, p2 + 2, p1 + 2, p3 + 2); + strDCT2x2dn(p0 + 3, p2 + 3, p1 + 3, p3 + 3); +} + +Void strPre4x4Stage1(PixelI* p, Int iOffset) +{ + strPre4x4Stage1Split(p, p + 16, iOffset); +} + +/***************************************************************************************** + Input data offsets: + (15)(14)|(10+32)(11+32) p0 (15)(14)|(42)(43) + (13)(12)|( 8+32)( 9+32) (13)(12)|(40)(41) + --------+-------------- --------+-------- + ( 5)( 4)|( 0+32)( 1+32) p1 ( 5)( 4)|(32)(33) + ( 7)( 6)|( 2+32)( 3+32) ( 7)( 6)|(34)(35) +*****************************************************************************************/ +Void strPre4x4Stage2Split(PixelI* p0, PixelI* p1) +{ + /** butterfly **/ + strHSTenc(p0 - 96, p0 + 96, p1 - 112, p1 + 80); + strHSTenc(p0 - 32, p0 + 32, p1 - 48, p1 + 16); + strHSTenc(p0 - 80, p0 + 112, p1 - 128, p1 + 64); + strHSTenc(p0 - 16, p0 + 48, p1 - 64, p1 + 0); + strHSTenc1(p0 - 96, p1 + 80); + strHSTenc1(p0 - 32, p1 + 16); + strHSTenc1(p0 - 80, p1 + 64); + strHSTenc1(p0 - 16, p1 + 0); + + /** anti diagonal corners: rotation **/ + ROTATE1(p1[-48], p1[-112]); + ROTATE1(p1[-64], p1[-128]); + ROTATE1(p0[112], p0[96]); + ROTATE1(p0[48], p0[32]); + + /** bottom right corner: pi/8 rotation => pi/8 rotation **/ + fwdOddOddPre(p1 + 0, p1 + 64, p1 + 16, p1 + 80); + + /** butterfly **/ + strDCT2x2dn(p0 - 96, p1 - 112, p0 + 96, p1 + 80); + strDCT2x2dn(p0 - 32, p1 - 48, p0 + 32, p1 + 16); + strDCT2x2dn(p0 - 80, p1 - 128, p0 + 112, p1 + 64); + strDCT2x2dn(p0 - 16, p1 - 64, p0 + 48, p1 + 0); +} + + +/** + Hadamard+Scale transform + for some strange reason, breaking up the function into two blocks, strHSTenc1 and strHSTenc + seems to work faster +**/ +static Void strHSTenc(PixelI* pa, PixelI* pb, PixelI* pc, PixelI* pd) +{ + /** different realization : does rescaling as well! **/ + PixelI a, b, c, d; + a = *pa; + b = *pb; + d = *pc; + c = *pd; + + a += c; + b -= d; + c = ((a - b) >> 1) - c; + d += (b >> 1); + b += c; + + a -= (d * 3 + 4) >> 3; + + *pa = a; + *pb = b; + *pc = c; + *pd = d; +} + +static Void strHSTenc1(PixelI* pa, PixelI* pd) +{ + /** different realization : does rescaling as well! **/ + PixelI a, d; + a = *pa; + d = *pd; + + d -= (a >> 7); + d += (a >> 10); + + //a -= (d * 3 + 4) >> 3; + d -= (a * 3 + 0) >> 4; + a -= (d * 3 + 0) >> 3; + d = (a >> 1) - d; + a -= d; + + *pa = a; + *pd = d; +} + +static Void strHSTenc1_edge(PixelI* pa, PixelI* pd) +{ + /** different realizion as compared to scaling operator for 2D case **/ + PixelI a, d; + a = *pa; + d = -(*pd); // Negative sign needed here for 1D scaling case to ensure correct scaling. + + a -= d; + d += (a >> 1); + a -= (d * 3 + 4) >> 3; + // End new operations + + //Scaling modification of adding 7/1024 in two steps (without multiplication by 7). + d -= (a >> 7); + d += (a >> 10); + + d -= (a * 3 + 0) >> 4; + a -= (d * 3 + 0) >> 3; + d = (a >> 1) - d; + a -= d; + + *pa = a; + *pd = d; +} + +/** Kron(Rotate(pi/8), Rotate(pi/8)) **/\ +static Void fwdOddOdd(PixelI* pa, PixelI* pb, PixelI* pc, PixelI* pd) +{ + PixelI a, b, c, d, t1, t2; + + a = *pa; + b = -*pb; + c = -*pc; + d = *pd; + + /** butterflies **/ + d += a; + c -= b; + a -= (t1 = d >> 1); + b += (t2 = c >> 1); + + /** rotate pi/4 **/ + a += (b * 3 + 4) >> 3; + b -= (a * 3 + 3) >> 2; + a += (b * 3 + 3) >> 3; + + /** butterflies **/ + b -= t2; + a += t1; + c += b; + d -= a; + + *pa = a; + *pb = b; + *pc = c; + *pd = d; +} +/** Kron(Rotate(pi/8), Rotate(pi/8)) **/ +static Void fwdOddOddPre(PixelI* pa, PixelI* pb, PixelI* pc, PixelI* pd) +{ + PixelI a, b, c, d, t1, t2; + a = *pa; + b = *pb; + c = *pc; + d = *pd; + + /** butterflies **/ + d += a; + c -= b; + a -= (t1 = d >> 1); + b += (t2 = c >> 1); + + /** rotate pi/4 **/ + a += (b * 3 + 4) >> 3; + b -= (a * 3 + 2) >> 2; + a += (b * 3 + 6) >> 3; + + /** butterflies **/ + b -= t2; + a += t1; + c += b; + d -= a; + + *pa = a; + *pb = b; + *pc = c; + *pd = d; +} + +/** Kron(Rotate(pi/8), [1 1; 1 -1]/sqrt(2)) **/ +/** [a b c d] => [D C A B] **/ +Void fwdOdd(PixelI* pa, PixelI* pb, PixelI* pc, PixelI* pd) +{ + PixelI a, b, c, d; + a = *pa; + b = *pb; + c = *pc; + d = *pd; + + /** butterflies **/ + b -= c; + a += d; + c += (b + 1) >> 1; + d = ((a + 1) >> 1) - d; + + /** rotate pi/8 **/ + ROTATE2(a, b); + ROTATE2(c, d); + + /** butterflies **/ + d += (b) >> 1; + c -= (a + 1) >> 1; + b -= d; + a += c; + + *pa = a; + *pb = b; + *pc = c; + *pd = d; +} + +/************************************************************************* + Top-level function to tranform possible part of a macroblock +*************************************************************************/ +Void transformMacroblock(CWMImageStrCodec* pSC) +{ + OVERLAP olOverlap = pSC->WMISCP.olOverlap; + COLORFORMAT cfColorFormat = pSC->m_param.cfColorFormat; + Bool left = (pSC->cColumn == 0), right = (pSC->cColumn == pSC->cmbWidth); + Bool top = (pSC->cRow == 0), bottom = (pSC->cRow == pSC->cmbHeight); + Bool leftORright = (left || right), topORbottom = (top || bottom); + Bool topORleft = (left || top);// rightORbottom = (right || bottom); + Bool leftAdjacentColumn = (pSC->cColumn == 1), rightAdjacentColumn = (pSC->cColumn == pSC->cmbWidth - 1); + // Bool topAdjacentRow = (pSC->cRow == 1), bottomAdjacentRow = (pSC->cRow == pSC->cmbHeight - 1); + PixelI* p = NULL;// * pt = NULL; + Int i, j; + Int iNumChromaFullPlanes = (Int)((YUV_420 == cfColorFormat || YUV_422 == cfColorFormat) ? + 1 : pSC->m_param.cNumChannels); + +#define mbX pSC->mbX +#define mbY pSC->mbY +#define tileX pSC->tileX +#define tileY pSC->tileY +#define bVertTileBoundary pSC->bVertTileBoundary +#define bHoriTileBoundary pSC->bHoriTileBoundary +#define bOneMBLeftVertTB pSC->bOneMBLeftVertTB +#define bOneMBRightVertTB pSC->bOneMBRightVertTB +#define iPredBefore pSC->iPredBefore +#define iPredAfter pSC->iPredAfter + + if (pSC->WMISCP.bUseHardTileBoundaries) { + //Add tile location information + if (pSC->cColumn == 0) { + bVertTileBoundary = FALSE; + tileY = 0; + } + bOneMBLeftVertTB = bOneMBRightVertTB = FALSE; + if (tileY > 0 && tileY <= pSC->WMISCP.cNumOfSliceMinus1H && (pSC->cColumn - 1) == pSC->WMISCP.uiTileY[tileY]) + bOneMBRightVertTB = TRUE; + if (tileY < pSC->WMISCP.cNumOfSliceMinus1H && pSC->cColumn == pSC->WMISCP.uiTileY[tileY + 1]) { + bVertTileBoundary = TRUE; + tileY++; + } + else + bVertTileBoundary = FALSE; + if (tileY < pSC->WMISCP.cNumOfSliceMinus1H && (pSC->cColumn + 1) == pSC->WMISCP.uiTileY[tileY + 1]) + bOneMBLeftVertTB = TRUE; + + if (pSC->cRow == 0) { + bHoriTileBoundary = FALSE; + tileX = 0; + } + else if (mbY != pSC->cRow && tileX < pSC->WMISCP.cNumOfSliceMinus1V && pSC->cRow == pSC->WMISCP.uiTileX[tileX + 1]) { + bHoriTileBoundary = TRUE; + tileX++; + } + else if (mbY != pSC->cRow) + bHoriTileBoundary = FALSE; + } + else { + bVertTileBoundary = FALSE; + bHoriTileBoundary = FALSE; + bOneMBLeftVertTB = FALSE; + bOneMBRightVertTB = FALSE; + } + mbX = pSC->cColumn, mbY = pSC->cRow; + + //================================================================ + // 400_Y, 444_YUV + for (i = 0; i < iNumChromaFullPlanes; ++i) + { + PixelI* const p0 = pSC->p0MBbuffer[i];//(0 == i ? pSC->pY0 : (1 == i ? pSC->pU0 : pSC->pV0)); + PixelI* const p1 = pSC->p1MBbuffer[i];//(0 == i ? pSC->pY1 : (1 == i ? pSC->pU1 : pSC->pV1)); + + //================================ + // first level overlap + if (OL_NONE != olOverlap) + { + /* Corner operations */ + if ((top || bHoriTileBoundary) && (left || bVertTileBoundary)) + strPre4(p1 + 0, p1 + 1, p1 + 2, p1 + 3); + if ((top || bHoriTileBoundary) && (right || bVertTileBoundary)) + strPre4(p1 - 59, p1 - 60, p1 - 57, p1 - 58); + if ((bottom || bHoriTileBoundary) && (left || bVertTileBoundary)) + strPre4(p0 + 48 + 10, p0 + 48 + 11, p0 + 48 + 8, p0 + 48 + 9); + if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary)) + strPre4(p0 - 1, p0 - 2, p0 - 3, p0 - 4); + if (!right && !bottom) + { + if (top || bHoriTileBoundary) + { + + for (j = ((left || bVertTileBoundary) ? 0 : -64); j < 192; j += 64) + { + p = p1 + j; + strPre4(p + 5, p + 4, p + 64, p + 65); + strPre4(p + 7, p + 6, p + 66, p + 67); + p = NULL; + } + } + else + { + for (j = ((left || bVertTileBoundary) ? 0 : -64); j < 192; j += 64) + { + strPre4x4Stage1Split(p0 + 48 + j, p1 + j, 0); + } + } + + if (left || bVertTileBoundary) + { + if (!top && !bHoriTileBoundary) + { + strPre4(p0 + 58, p0 + 56, p1 + 0, p1 + 2); + strPre4(p0 + 59, p0 + 57, p1 + 1, p1 + 3); + } + + for (j = -64; j < -16; j += 16) + { + p = p1 + j; + strPre4(p + 74, p + 72, p + 80, p + 82); + strPre4(p + 75, p + 73, p + 81, p + 83); + p = NULL; + } + } + else + { + for (j = -64; j < -16; j += 16) + { + strPre4x4Stage1(p1 + j, 0); + } + } + + strPre4x4Stage1(p1 + 0, 0); + strPre4x4Stage1(p1 + 16, 0); + strPre4x4Stage1(p1 + 32, 0); + strPre4x4Stage1(p1 + 64, 0); + strPre4x4Stage1(p1 + 80, 0); + strPre4x4Stage1(p1 + 96, 0); + strPre4x4Stage1(p1 + 128, 0); + strPre4x4Stage1(p1 + 144, 0); + strPre4x4Stage1(p1 + 160, 0); + } + + if (bottom || bHoriTileBoundary) + { + for (j = ((left || bVertTileBoundary) ? 48 : -16); j < (right ? -16 : 240); j += 64) + { + p = p0 + j; + strPre4(p + 15, p + 14, p + 74, p + 75); + strPre4(p + 13, p + 12, p + 72, p + 73); + p = NULL; + } + } + + if ((right || bVertTileBoundary) && !bottom) + { + if (!top && !bHoriTileBoundary) + { + strPre4(p0 - 1, p0 - 3, p1 - 59, p1 - 57); + strPre4(p0 - 2, p0 - 4, p1 - 60, p1 - 58); + } + for (j = -64; j < -16; j += 16) + { + p = p1 + j; + strPre4(p + 15, p + 13, p + 21, p + 23); + strPre4(p + 14, p + 12, p + 20, p + 22); + p = NULL; + } + } + } + + //================================ + // first level transform + if (!top) + { + for (j = (left ? 48 : -16); j < (right ? 48 : 240); j += 64) + { + strDCT4x4Stage1(p0 + j); + } + } + + if (!bottom) + { + for (j = (left ? 0 : -64); j < (right ? 0 : 192); j += 64) + { + strDCT4x4Stage1(p1 + j + 0); + strDCT4x4Stage1(p1 + j + 16); + strDCT4x4Stage1(p1 + j + 32); + } + } + + //================================ + // second level overlap + if (OL_TWO == olOverlap) + { + /* Corner operations */ + if ((top || bHoriTileBoundary) && (left || bVertTileBoundary)) + strPre4(p1 + 0, p1 + 64, p1 + 0 + 16, p1 + 64 + 16); + if ((top || bHoriTileBoundary) && (right || bVertTileBoundary)) + strPre4(p1 - 128, p1 - 64, p1 - 128 + 16, p1 - 64 + 16); + if ((bottom || bHoriTileBoundary) && (left || bVertTileBoundary)) + strPre4(p0 + 32, p0 + 96, p0 + 32 + 16, p0 + 96 + 16); + if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary)) + strPre4(p0 - 96, p0 - 32, p0 - 96 + 16, p0 - 32 + 16); + if ((leftORright || bVertTileBoundary) && (!topORbottom && !bHoriTileBoundary)) + { + if (left || bVertTileBoundary) { + j = 0; + strPre4(p0 + j + 32, p0 + j + 48, p1 + j + 0, p1 + j + 16); + strPre4(p0 + j + 96, p0 + j + 112, p1 + j + 64, p1 + j + 80); + } + if (right || bVertTileBoundary) { + j = -128; + strPre4(p0 + j + 32, p0 + j + 48, p1 + j + 0, p1 + j + 16); + strPre4(p0 + j + 96, p0 + j + 112, p1 + j + 64, p1 + j + 80); + } + } + + if (!leftORright && !bVertTileBoundary) + { + if (topORbottom || bHoriTileBoundary) + { + if (top || bHoriTileBoundary) { + p = p1; + strPre4(p - 128, p - 64, p + 0, p + 64); + strPre4(p - 112, p - 48, p + 16, p + 80); + p = NULL; + } + if (bottom || bHoriTileBoundary) { + p = p0 + 32; + strPre4(p - 128, p - 64, p + 0, p + 64); + strPre4(p - 112, p - 48, p + 16, p + 80); + p = NULL; + } + } + else + { + strPre4x4Stage2Split(p0, p1); + } + } + } + + //================================ + // second level transform + if (!topORleft) { + if (pSC->m_param.bScaledArith) { + strNormalizeEnc(p0 - 256, (i != 0)); + } + strDCT4x4SecondStage(p0 - 256); + } + } + + //================================================================ + // 420_UV + for (i = 0; i < (YUV_420 == cfColorFormat ? 2 : 0); ++i) + { + PixelI* const p0 = pSC->p0MBbuffer[1 + i];//(0 == i ? pSC->pU0 : pSC->pV0); + PixelI* const p1 = pSC->p1MBbuffer[1 + i];//(0 == i ? pSC->pU1 : pSC->pV1); + + //================================ + // first level overlap (420_UV) + if (OL_NONE != olOverlap) + { + /* Corner operations */ + if ((top || bHoriTileBoundary) && (left || bVertTileBoundary)) + strPre4(p1 + 0, p1 + 1, p1 + 2, p1 + 3); + if ((top || bHoriTileBoundary) && (right || bVertTileBoundary)) + strPre4(p1 - 27, p1 - 28, p1 - 25, p1 - 26); + if ((bottom || bHoriTileBoundary) && (left || bVertTileBoundary)) + strPre4(p0 + 16 + 10, p0 + 16 + 11, p0 + 16 + 8, p0 + 16 + 9); + if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary)) + strPre4(p0 - 1, p0 - 2, p0 - 3, p0 - 4); + if (!right && !bottom) + { + if (top || bHoriTileBoundary) + { + + for (j = ((left || bVertTileBoundary) ? 0 : -32); j < 32; j += 32) + { + p = p1 + j; + strPre4(p + 5, p + 4, p + 32, p + 33); + strPre4(p + 7, p + 6, p + 34, p + 35); + p = NULL; + } + } + else + { + for (j = ((left || bVertTileBoundary) ? 0 : -32); j < 32; j += 32) + { + strPre4x4Stage1Split(p0 + 16 + j, p1 + j, 32); + } + } + + if (left || bVertTileBoundary) + { + if (!top && !bHoriTileBoundary) + { + strPre4(p0 + 26, p0 + 24, p1 + 0, p1 + 2); + strPre4(p0 + 27, p0 + 25, p1 + 1, p1 + 3); + } + + strPre4(p1 + 10, p1 + 8, p1 + 16, p1 + 18); + strPre4(p1 + 11, p1 + 9, p1 + 17, p1 + 19); + } + else if (!bVertTileBoundary) + { + strPre4x4Stage1(p1 - 32, 32); + } + + strPre4x4Stage1(p1, 32); + } + + if (bottom || bHoriTileBoundary) + { + for (j = ((left || bVertTileBoundary) ? 16 : -16); j < (right ? -16 : 32); j += 32) + { + p = p0 + j; + strPre4(p + 15, p + 14, p + 42, p + 43); + strPre4(p + 13, p + 12, p + 40, p + 41); + p = NULL; + } + } + + if ((right || bVertTileBoundary) && !bottom) + { + if (!top && !bHoriTileBoundary) + { + strPre4(p0 - 1, p0 - 3, p1 - 27, p1 - 25); + strPre4(p0 - 2, p0 - 4, p1 - 28, p1 - 26); + } + + strPre4(p1 - 17, p1 - 19, p1 - 11, p1 - 9); + strPre4(p1 - 18, p1 - 20, p1 - 12, p1 - 10); + } + } + + //================================ + // first level transform (420_UV) + if (!top) + { + for (j = (left ? 16 : -16); j < (right ? 16 : 48); j += 32) + { + strDCT4x4Stage1(p0 + j); + } + } + + if (!bottom) + { + for (j = (left ? 0 : -32); j < (right ? 0 : 32); j += 32) + { + strDCT4x4Stage1(p1 + j); + } + } + + //================================ + // second level overlap (420_UV) + if (OL_TWO == olOverlap) + { + if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_DIFF(p1 - 64 + 0, *(p1 - 64 + 32)); + + if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary)) + iPredBefore[i][0] = *(p1 + 0); + if ((right || bVertTileBoundary) && (top || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_DIFF(p1 - 64 + 32, iPredBefore[i][0]); + + if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_DIFF(p0 - 64 + 16, *(p0 - 64 + 48)); + + if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) + iPredBefore[i][1] = *(p0 + 16); + if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_DIFF(p0 - 64 + 48, iPredBefore[i][1]); + + if ((leftORright || bVertTileBoundary) && !topORbottom && !bHoriTileBoundary) + { + if (left || bVertTileBoundary) + strPre2(p0 + 0 + 16, p1 + 0); + if (right || bVertTileBoundary) + strPre2(p0 + -32 + 16, p1 + -32); + } + + if (!leftORright) + { + if ((topORbottom || bHoriTileBoundary) && !bVertTileBoundary) + { + if (top || bHoriTileBoundary) + strPre2(p1 - 32, p1); + if (bottom || bHoriTileBoundary) + strPre2(p0 + 16 - 32, p0 + 16); + } + else if (!topORbottom && !bHoriTileBoundary && !bVertTileBoundary) + strPre2x2(p0 - 16, p0 + 16, p1 - 32, p1); + } + if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_ADD(p1 - 64 + 0, *(p1 - 64 + 32)); + if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary)) + iPredAfter[i][0] = *(p1 + 0); + if ((right || bVertTileBoundary) && (top || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_ADD(p1 - 64 + 32, iPredAfter[i][0]); + if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_ADD(p0 - 64 + 16, *(p0 - 64 + 48)); + if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) + iPredAfter[i][1] = *(p0 + 16); + if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_ADD(p0 - 64 + 48, iPredAfter[i][1]); + } + + //================================ + // second level transform (420_UV) + if (!topORleft) + { + if (!pSC->m_param.bScaledArith) { + strDCT2x2dn(p0 - 64, p0 - 32, p0 - 48, p0 - 16); + } + else { + strDCT2x2dnEnc(p0 - 64, p0 - 32, p0 - 48, p0 - 16); + } + } + } + + //================================================================ + // 422_UV + for (i = 0; i < (YUV_422 == cfColorFormat ? 2 : 0); ++i) + { + PixelI* const p0 = pSC->p0MBbuffer[1 + i];//(0 == i ? pSC->pU0 : pSC->pV0); + PixelI* const p1 = pSC->p1MBbuffer[1 + i];//(0 == i ? pSC->pU1 : pSC->pV1); + + //================================ + // first level overlap (422_UV) + if (OL_NONE != olOverlap) + { + /* Corner operations */ + if ((top || bHoriTileBoundary) && (left || bVertTileBoundary)) + strPre4(p1 + 0, p1 + 1, p1 + 2, p1 + 3); + if ((top || bHoriTileBoundary) && (right || bVertTileBoundary)) + strPre4(p1 - 59, p1 - 60, p1 - 57, p1 - 58); + if ((bottom || bHoriTileBoundary) && (left || bVertTileBoundary)) + strPre4(p0 + 48 + 10, p0 + 48 + 11, p0 + 48 + 8, p0 + 48 + 9); + if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary)) + strPre4(p0 - 1, p0 - 2, p0 - 3, p0 - 4); + if (!right && !bottom) + { + if (top || bHoriTileBoundary) + { + + for (j = ((left || bVertTileBoundary) ? 0 : -64); j < 64; j += 64) + { + p = p1 + j; + strPre4(p + 5, p + 4, p + 64, p + 65); + strPre4(p + 7, p + 6, p + 66, p + 67); + p = NULL; + } + } + else + { + for (j = ((left || bVertTileBoundary) ? 0 : -64); j < 64; j += 64) + { + strPre4x4Stage1Split(p0 + 48 + j, p1 + j, 0); + } + } + + if (left || bVertTileBoundary) + { + if (!top && !bHoriTileBoundary) + { + strPre4(p0 + 58, p0 + 56, p1 + 0, p1 + 2); + strPre4(p0 + 59, p0 + 57, p1 + 1, p1 + 3); + } + + for (j = 0; j < 48; j += 16) + { + p = p1 + j; + strPre4(p + 10, p + 8, p + 16, p + 18); + strPre4(p + 11, p + 9, p + 17, p + 19); + p = NULL; + } + } + else if (!bVertTileBoundary) + { + for (j = -64; j < -16; j += 16) + { + strPre4x4Stage1(p1 + j, 0); + } + } + + strPre4x4Stage1(p1 + 0, 0); + strPre4x4Stage1(p1 + 16, 0); + strPre4x4Stage1(p1 + 32, 0); + } + + if (bottom || bHoriTileBoundary) + { + for (j = ((left || bVertTileBoundary) ? 48 : -16); j < (right ? -16 : 112); j += 64) + { + p = p0 + j; + strPre4(p + 15, p + 14, p + 74, p + 75); + strPre4(p + 13, p + 12, p + 72, p + 73); + p = NULL; + } + } + + if ((right || bVertTileBoundary) && !bottom) + { + if (!top && !bHoriTileBoundary) + { + strPre4(p0 - 1, p0 - 3, p1 - 59, p1 - 57); + strPre4(p0 - 2, p0 - 4, p1 - 60, p1 - 58); + } + + for (j = -64; j < -16; j += 16) + { + p = p1 + j; + strPre4(p + 15, p + 13, p + 21, p + 23); + strPre4(p + 14, p + 12, p + 20, p + 22); + p = NULL; + } + } + } + + //================================ + // first level transform (422_UV) + if (!top) + { + for (j = (left ? 48 : -16); j < (right ? 48 : 112); j += 64) + { + strDCT4x4Stage1(p0 + j); + } + } + + if (!bottom) + { + for (j = (left ? 0 : -64); j < (right ? 0 : 64); j += 64) + { + strDCT4x4Stage1(p1 + j + 0); + strDCT4x4Stage1(p1 + j + 16); + strDCT4x4Stage1(p1 + j + 32); + } + } + + //================================ + // second level overlap (422_UV) + if (OL_TWO == olOverlap) + { + if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_DIFF(p1 - 128 + 0, *(p1 - 128 + 64)); + + if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary)) + iPredBefore[i][0] = *(p1 + 0); + if ((right || bVertTileBoundary) && (top || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_DIFF(p1 - 128 + 64, iPredBefore[i][0]); + + if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_DIFF(p0 - 128 + 48, *(p0 - 128 + 112)); + + if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) + iPredBefore[i][1] = *(p0 + 48); + if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_DIFF(p0 - 128 + 112, iPredBefore[i][1]); + + if (!bottom) + { + if (leftORright || bVertTileBoundary) + { + if (!top && !bHoriTileBoundary) + { + if (left || bVertTileBoundary) + strPre2(p0 + 48 + 0, p1 + 0); + + if (right || bVertTileBoundary) + strPre2(p0 + 48 + -64, p1 + -64); + } + + if (left || bVertTileBoundary) + strPre2(p1 + 16, p1 + 16 + 16); + + if (right || bVertTileBoundary) + strPre2(p1 + -48, p1 + -48 + 16); + } + + if (!leftORright && !bVertTileBoundary) + { + if (top || bHoriTileBoundary) + strPre2(p1 - 64, p1); + else + strPre2x2(p0 - 16, p0 + 48, p1 - 64, p1); + + strPre2x2(p1 - 48, p1 + 16, p1 - 32, p1 + 32); + } + } + + if ((bottom || bHoriTileBoundary) && (!leftORright && !bVertTileBoundary)) + strPre2(p0 - 16, p0 + 48); + + if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_ADD(p1 - 128 + 0, *(p1 - 128 + 64)); + + if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary)) + iPredAfter[i][0] = *(p1 + 0); + if ((right || bVertTileBoundary) && (top || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_ADD(p1 - 128 + 64, iPredAfter[i][0]); + + if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_ADD(p0 - 128 + 48, *(p0 - 128 + 112)); + + if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) + iPredAfter[i][1] = *(p0 + 48); + if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary)) + COMPUTE_CORNER_PRED_ADD(p0 - 128 + 112, iPredAfter[i][1]); + } + + //================================ + // second level transform (422_UV) + if (!topORleft) + { + if (!pSC->m_param.bScaledArith) { + strDCT2x2dn(p0 - 128, p0 - 64, p0 - 112, p0 - 48); + strDCT2x2dn(p0 - 96, p0 - 32, p0 - 80, p0 - 16); + } + else { + strDCT2x2dnEnc(p0 - 128, p0 - 64, p0 - 112, p0 - 48); + strDCT2x2dnEnc(p0 - 96, p0 - 32, p0 - 80, p0 - 16); + } + + // 1D lossless HT + p0[-96] -= p0[-128]; + p0[-128] += ((p0[-96] + 1) >> 1); + } + } + assert(NULL == p); +} + diff --git a/Src/JxrDecode/jxrlib/image/encode/strPredQuantEnc.c b/Src/JxrDecode/jxrlib/image/encode/strPredQuantEnc.c new file mode 100644 index 00000000..23a05879 --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/encode/strPredQuantEnc.c @@ -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 "../sys/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); + } + } +} + diff --git a/Src/JxrDecode/jxrlib/image/encode/strenc.c b/Src/JxrDecode/jxrlib/image/encode/strenc.c new file mode 100644 index 00000000..ee556138 --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/encode/strenc.c @@ -0,0 +1,2372 @@ +//*@@@+++@@@@****************************************************************** +// +// 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 "../sys/strcodec.h" +#include "encode.h" +#include "../sys/strTransform.h" +#include +//#include "perfTimer.h" + +#ifdef MEM_TRACE +#define TRACE_MALLOC 1 +#define TRACE_NEW 0 +#define TRACE_HEAP 0 +#include "memtrace.h" +#endif + +#ifdef ADI_SYS_OPT +extern char L1WW[]; +#endif + +#ifdef X86OPT_INLINE +#define _FORCEINLINE __forceinline +#else // X86OPT_INLINE +#define _FORCEINLINE +#endif // X86OPT_INLINE + +Int inputMBRow(CWMImageStrCodec*); + +#if defined(WMP_OPT_SSE2) || defined(WMP_OPT_CC_ENC) || defined(WMP_OPT_TRFM_ENC) +void StrEncOpt(CWMImageStrCodec* pSC); +#endif // OPT defined + +#define MINIMUM_PACKET_LENGTH 4 // as long as packet header - skipped if data is not accessed (happens only for flexbits) + +Void writeQuantizer(CWMIQuantizer* pQuantizer[MAX_CHANNELS], BitIOInfo* pIO, U8 cChMode, size_t cChannel, size_t iPos) +{ + if (cChMode > 2) + cChMode = 2; + + if (cChannel > 1) + putBit16(pIO, cChMode, 2); // Channel mode + else + cChMode = 0; + + putBit16(pIO, pQuantizer[0][iPos].iIndex, 8); // Y + + if (cChMode == 1) // MIXED + putBit16(pIO, pQuantizer[1][iPos].iIndex, 8); // UV + else if (cChMode > 0) { // INDEPENDENT + size_t i; + + for (i = 1; i < cChannel; i++) + putBit16(pIO, pQuantizer[i][iPos].iIndex, 8); // UV + } +} + +// packet header: 00000000 00000000 00000001 ?????xxx +// xxx: 000(spatial) 001(DC) 010(AD) 011(AC) 100(FL) 101-111(reserved) +// ?????: (iTileY * cNumOfSliceV + iTileX) +Void writePacketHeader(BitIOInfo* pIO, U8 ptPacketType, U8 pID) +{ + putBit16(pIO, 0, 8); + putBit16(pIO, 0, 8); + putBit16(pIO, 1, 8); + putBit16(pIO, (pID << 3) + (ptPacketType & 7), 8); +} + +Int writeTileHeaderDC(CWMImageStrCodec* pSC, BitIOInfo* pIO) +{ + size_t iTile, j = (pSC->m_pNextSC == NULL ? 1U : 2U); + + for (; j > 0; j--) { + if ((pSC->m_param.uQPMode & 1) != 0) { // not DC uniform + CWMITile* pTile = pSC->pTile + pSC->cTileColumn; + size_t i; + + pTile->cChModeDC = (U8)(rand() & 3); // channel mode, just for concept proofing! + + if (pSC->cTileRow + pSC->cTileColumn == 0) // allocate DC QP info + for (iTile = 0; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile++) + if (allocateQuantizer(pSC->pTile[iTile].pQuantizerDC, pSC->m_param.cNumChannels, 1) != ICERR_OK) + return ICERR_ERROR; + + for (i = 0; i < pSC->m_param.cNumChannels; i++) + pTile->pQuantizerDC[i]->iIndex = (U8)((rand() & 0x2f) + 1); // QP indexes, just for concept proofing! + + formatQuantizer(pTile->pQuantizerDC, pTile->cChModeDC, pSC->m_param.cNumChannels, 0, TRUE, pSC->m_param.bScaledArith); + + for (i = 0; i < pSC->m_param.cNumChannels; i++) + pTile->pQuantizerDC[i]->iOffset = (pTile->pQuantizerDC[i]->iQP >> 1); + + writeQuantizer(pTile->pQuantizerDC, pIO, pTile->cChModeDC, pSC->m_param.cNumChannels, 0); + } + + pSC = pSC->m_pNextSC; + } + + return ICERR_OK; +} + +Int writeTileHeaderLP(CWMImageStrCodec* pSC, BitIOInfo* pIO) +{ + size_t k = (pSC->m_pNextSC == NULL ? 1U : 2U); + + for (; k > 0; k--) { + if (pSC->WMISCP.sbSubband != SB_DC_ONLY && (pSC->m_param.uQPMode & 2) != 0) { // not LP uniform + CWMITile* pTile = pSC->pTile + pSC->cTileColumn; + U8 i, j; + + pTile->bUseDC = ((rand() & 1) == 0 ? TRUE : FALSE); // use DC quantizer? + putBit16(pIO, pTile->bUseDC == TRUE ? 1 : 0, 1); + pTile->cBitsLP = 0; + + pTile->cNumQPLP = (pTile->bUseDC == TRUE ? 1 : (U8)((rand() & 0xf) + 1)); // # of LP QPs + + if (pSC->cTileRow > 0) + freeQuantizer(pTile->pQuantizerLP); + + if (allocateQuantizer(pTile->pQuantizerLP, pSC->m_param.cNumChannels, pTile->cNumQPLP) != ICERR_OK) + return ICERR_ERROR; + + if (pTile->bUseDC == TRUE) + useDCQuantizer(pSC, pSC->cTileColumn); + else { + putBit16(pIO, pTile->cNumQPLP - 1, 4); + + pTile->cBitsLP = dquantBits(pTile->cNumQPLP); + + for (i = 0; i < pTile->cNumQPLP; i++) { + pTile->cChModeLP[i] = (U8)(rand() & 3); // channel mode, just for concept proofing! + + for (j = 0; j < pSC->m_param.cNumChannels; j++) + pTile->pQuantizerLP[j][i].iIndex = (U8)((rand() & 0xfe) + 1); // QP indexes, just for concept proofing! + formatQuantizer(pTile->pQuantizerLP, pTile->cChModeLP[i], pSC->m_param.cNumChannels, i, TRUE, pSC->m_param.bScaledArith); + writeQuantizer(pTile->pQuantizerLP, pIO, pTile->cChModeLP[i], pSC->m_param.cNumChannels, i); + } + } + } + pSC = pSC->m_pNextSC; + } + + return ICERR_OK; +} + +Int writeTileHeaderHP(CWMImageStrCodec* pSC, BitIOInfo* pIO) +{ + size_t k = (pSC->m_pNextSC == NULL ? 1U : 2U); + + for (; k > 0; k--) { + if (pSC->WMISCP.sbSubband != SB_DC_ONLY && pSC->WMISCP.sbSubband != SB_NO_HIGHPASS && (pSC->m_param.uQPMode & 4) != 0) { // not HP uniform + CWMITile* pTile = pSC->pTile + pSC->cTileColumn; + U8 i, j; + + pTile->bUseLP = ((rand() & 1) == 0 ? TRUE : FALSE); // use LP quantizer? + putBit16(pIO, pTile->bUseLP == TRUE ? 1 : 0, 1); + pTile->cBitsHP = 0; + + pTile->cNumQPHP = (pTile->bUseLP == TRUE ? pTile->cNumQPLP : (U8)((rand() & 0xf) + 1)); // # of LP QPs + + if (pSC->cTileRow > 0) + freeQuantizer(pTile->pQuantizerHP); + + if (allocateQuantizer(pTile->pQuantizerHP, pSC->m_param.cNumChannels, pTile->cNumQPHP) != ICERR_OK) + return ICERR_ERROR; + + if (pTile->bUseLP == TRUE) + useLPQuantizer(pSC, pTile->cNumQPHP, pSC->cTileColumn); + else { + putBit16(pIO, pTile->cNumQPHP - 1, 4); + pTile->cBitsHP = dquantBits(pTile->cNumQPHP); + + for (i = 0; i < pTile->cNumQPHP; i++) { + pTile->cChModeHP[i] = (U8)(rand() & 3); // channel mode, just for concept proofing! + + for (j = 0; j < pSC->m_param.cNumChannels; j++) + pTile->pQuantizerHP[j][i].iIndex = (U8)((rand() & 0xfe) + 1); // QP indexes, just for concept proofing! + formatQuantizer(pTile->pQuantizerHP, pTile->cChModeHP[i], pSC->m_param.cNumChannels, i, FALSE, pSC->m_param.bScaledArith); + writeQuantizer(pTile->pQuantizerHP, pIO, pTile->cChModeHP[i], pSC->m_param.cNumChannels, i); + } + } + } + pSC = pSC->m_pNextSC; + } + + return ICERR_OK; +} + +Int encodeMB(CWMImageStrCodec* pSC, Int iMBX, Int iMBY) +{ + CCodingContext* pContext = &pSC->m_pCodingContext[pSC->cTileColumn]; + + if (pSC->m_bCtxLeft && pSC->m_bCtxTop && pSC->m_bSecondary == FALSE && pSC->m_param.bTranscode == FALSE) { // write packet headers + U8 pID = (U8)((pSC->cTileRow * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + pSC->cTileColumn) & 0x1F); + + if (pSC->WMISCP.bfBitstreamFormat == SPATIAL) { + writePacketHeader(pContext->m_pIODC, 0, pID); + if (pSC->m_param.bTrimFlexbitsFlag) + putBit16(pContext->m_pIODC, pContext->m_iTrimFlexBits, 4); + writeTileHeaderDC(pSC, pContext->m_pIODC); + writeTileHeaderLP(pSC, pContext->m_pIODC); + writeTileHeaderHP(pSC, pContext->m_pIODC); + } + else { + writePacketHeader(pContext->m_pIODC, 1, pID); + writeTileHeaderDC(pSC, pContext->m_pIODC); + if (pSC->cSB > 1) { + writePacketHeader(pContext->m_pIOLP, 2, pID); + writeTileHeaderLP(pSC, pContext->m_pIOLP); + } + if (pSC->cSB > 2) { + writePacketHeader(pContext->m_pIOAC, 3, pID); + writeTileHeaderHP(pSC, pContext->m_pIOAC); + } + if (pSC->cSB > 3) { + writePacketHeader(pContext->m_pIOFL, 4, pID); + if (pSC->m_param.bTrimFlexbitsFlag) + putBit16(pContext->m_pIOFL, pContext->m_iTrimFlexBits, 4); + } + } + } + + if (EncodeMacroblockDC(pSC, pContext, iMBX, iMBY) != ICERR_OK) + return ICERR_ERROR; + + if (pSC->WMISCP.sbSubband != SB_DC_ONLY) + if (EncodeMacroblockLowpass(pSC, pContext, iMBX, iMBY) != ICERR_OK) + return ICERR_ERROR; + + if (pSC->WMISCP.sbSubband != SB_DC_ONLY && pSC->WMISCP.sbSubband != SB_NO_HIGHPASS) + if (EncodeMacroblockHighpass(pSC, pContext, iMBX, iMBY) != ICERR_OK) + return ICERR_ERROR; + + if (iMBX + 1 == (int)pSC->cmbWidth && (iMBY + 1 == (int)pSC->cmbHeight || + (pSC->cTileRow < pSC->WMISCP.cNumOfSliceMinus1H && iMBY == (int)pSC->WMISCP.uiTileY[pSC->cTileRow + 1] - 1))) + { // end of a horizontal slice + size_t k, l; + + // get sizes of each packet and update index table + if (pSC->m_pNextSC == NULL || pSC->m_bSecondary) { + for (k = 0; k < pSC->cNumBitIO; k++) { + fillToByte(pSC->m_ppBitIO[k]); + pSC->ppWStream[k]->GetPos(pSC->ppWStream[k], &l); + pSC->pIndexTable[pSC->cNumBitIO * pSC->cTileRow + k] = l + getSizeWrite(pSC->m_ppBitIO[k]); // offset + } + } + + // reset coding contexts + if (iMBY + 1 != (int)pSC->cmbHeight) { + for (k = 0; k <= pSC->WMISCP.cNumOfSliceMinus1V; k++) + ResetCodingContextEnc(&pSC->m_pCodingContext[k]); + } + } + + return ICERR_OK; +} + +/************************************************************************* + Top level function for processing a macroblock worth of input +*************************************************************************/ +Int processMacroblock(CWMImageStrCodec* pSC) +{ + Bool topORleft = (pSC->cColumn == 0 || pSC->cRow == 0); + ERR_CODE result = ICERR_OK; + size_t j, jend = (pSC->m_pNextSC != NULL); + + for (j = 0; j <= jend; j++) { + transformMacroblock(pSC); + if (!topORleft) { + getTilePos(pSC, (Int)pSC->cColumn - 1, (Int)pSC->cRow - 1); + if (jend) { + pSC->m_pNextSC->cTileRow = pSC->cTileRow; + pSC->m_pNextSC->cTileColumn = pSC->cTileColumn; + } + if ((result = encodeMB(pSC, (Int)pSC->cColumn - 1, (Int)pSC->cRow - 1)) != ICERR_OK) + return result; + } + + if (jend) { + pSC->m_pNextSC->cRow = pSC->cRow; + pSC->m_pNextSC->cColumn = pSC->cColumn; + pSC = pSC->m_pNextSC; + } + } + + return ICERR_OK; +} + +/************************************************************************* + forwardRGBE: forward conversion from RGBE to RGB +*************************************************************************/ +static _FORCEINLINE PixelI forwardRGBE(PixelI RGB, PixelI E) +{ + PixelI iResult = 0, iAppend = 1; + + if (E == 0) + return 0; + + assert(E != 0); + + E--; + while (((RGB & 0x80) == 0) && (E > 0)) { + RGB = (RGB << 1) + iAppend; + iAppend = 0; + E--; + } + + // result will always be one of 3 cases + // E RGB convert to + // 0 [0.x] [0 x] + // 0 [1.x] [1 x] + // e [1.x] [e+1 x] + if (E == 0) { + iResult = RGB; + } + else { + E++; + iResult = (RGB & 0x7f) + (E << 7); + } + + return iResult; +} + +/************************************************************************* + convert float-32 into float with (c, lm)!! +*************************************************************************/ +static _FORCEINLINE PixelI float2pixel(float f, const char _c, const unsigned char _lm) +{ + union uif + { + I32 i; + float f; + } x; + + PixelI _h, e, e1, m, s; + + if (f == 0) + { + _h = 0; + } + else + { + x.f = f; + + e = (x.i >> 23) & 0x000000ff;//here set e as e, not s! e includes s: [s e] 9 bits [31..23] + m = (x.i & 0x007fffff) | 0x800000; // actual mantissa, with normalizer + if (e == 0) { // denormal-land + m ^= 0x800000; // actual mantissa, removing normalizer + e++; // actual exponent -126 + } + + e1 = e - 127 + _c; // this is basically a division or quantization to a different exponent + // note: _c cannot be greater than 127, so e1 cannot be greater than e +//assert (_c <= 127); + if (e1 <= 1) { // denormal-land + if (e1 < 1) + m >>= (1 - e1); // shift mantissa right to make exponent 1 + e1 = 1; + if ((m & 0x800000) == 0) // if denormal, set e1 to zero else to 1 + e1 = 0; + } + m &= 0x007fffff; + + //for float-22: + _h = (e1 << _lm) + ((m + (1 << (23 - _lm - 1))) >> (23 - _lm));//take 23-bit m, shift (23-lm), get lm-bit m for float22 + s = ((PixelI)x.i) >> 31; + //padding to int-32: + _h = (_h ^ s) - s; + } + + return _h; +} + +/************************************************************************* + convert Half-16 to internal format, only need to handle sign bit +*************************************************************************/ +static _FORCEINLINE PixelI forwardHalf(PixelI hHalf) +{ + PixelI s; + s = hHalf >> 31; + hHalf = ((hHalf & 0x7fff) ^ s) - s; + return hHalf; +} + + +//================================================================ +// Color Conversion +// functions to get image data from input buffer +// this inlcudes necessary color conversion and boundary padding +//================================================================ +#define _CC(r, g, b) (b -= r, r += ((b + 1) >> 1) - g, g += ((r + 0) >> 1)) +#define _CC_CMYK(c, m, y, k) (y -= c, c += ((y + 1) >> 1) - m, m += (c >> 1) - k, k += ((m + 1) >> 1)) + +//================================================================ +// BitIOInfo init/term for encoding +const size_t MAX_MEMORY_SIZE_IN_WORDS = 64 << 20; // 1 << 20 \approx 1 million + +Int StrIOEncInit(CWMImageStrCodec* pSC) +{ + pSC->m_param.bIndexTable = !(pSC->WMISCP.bfBitstreamFormat == SPATIAL && pSC->WMISCP.cNumOfSliceMinus1H + pSC->WMISCP.cNumOfSliceMinus1V == 0); + if (allocateBitIOInfo(pSC) != ICERR_OK) { + return ICERR_ERROR; + } + + attachISWrite(pSC->pIOHeader, pSC->WMISCP.pWStream); + + if (pSC->cNumBitIO > 0) { + size_t i; +#if defined(_WINDOWS_) || defined(UNDER_CE) // tmpnam does not exist in VS2005 WinCE CRT + TCHAR szPath[MAX_PATH]; + DWORD cSize, j, k; +#endif + char* pFilename; + + pSC->ppWStream = (struct WMPStream**)malloc(pSC->cNumBitIO * sizeof(struct WMPStream*)); + if (pSC->ppWStream == NULL) return ICERR_ERROR; + memset(pSC->ppWStream, 0, pSC->cNumBitIO * sizeof(struct WMPStream*)); + + if (pSC->cmbHeight * pSC->cmbWidth * pSC->WMISCP.cChannel >= MAX_MEMORY_SIZE_IN_WORDS) { +#ifdef _WINDOWS_ + pSC->ppTempFile = (TCHAR**)malloc(pSC->cNumBitIO * sizeof(TCHAR*)); + if (pSC->ppTempFile == NULL) return ICERR_ERROR; + memset(pSC->ppTempFile, 0, pSC->cNumBitIO * sizeof(TCHAR*)); +#else + pSC->ppTempFile = (char**)malloc(pSC->cNumBitIO * sizeof(char*)); + if (pSC->ppTempFile == NULL) return ICERR_ERROR; + memset(pSC->ppTempFile, 0, pSC->cNumBitIO * sizeof(char*)); +#endif + } + + for (i = 0; i < pSC->cNumBitIO; i++) { + if (pSC->cmbHeight * pSC->cmbWidth * pSC->WMISCP.cChannel >= MAX_MEMORY_SIZE_IN_WORDS) { +#if defined(_WINDOWS_) || defined(UNDER_CE) // tmpnam does not exist in VS2005 WinCE CRT + Bool bUnicode = sizeof(TCHAR) == 2; + pSC->ppTempFile[i] = (TCHAR*)malloc(MAX_PATH * sizeof(TCHAR)); + if (pSC->ppTempFile[i] == NULL) return ICERR_ERROR; + + pFilename = (char*)pSC->ppTempFile[i]; + + cSize = GetTempPath(MAX_PATH, szPath); + if (cSize == 0 || cSize >= MAX_PATH) + return ICERR_ERROR; + if (!GetTempFileName(szPath, TEXT("wdp"), 0, pSC->ppTempFile[i])) + return ICERR_ERROR; + + if (bUnicode) { // unicode file name + for (k = j = cSize = 0; cSize < MAX_PATH; cSize++, j += 2) { + if (pSC->ppTempFile[i][cSize] == '\0') + break; + if (pFilename[j] != '\0') + pFilename[k++] = pFilename[j]; + if (pFilename[j + 1] != '\0') + pFilename[k++] = pFilename[j + 1]; + } + pFilename[cSize] = '\0'; + } + +#else //DPK needs to support ANSI + pSC->ppTempFile[i] = (char*)malloc(FILENAME_MAX * sizeof(char)); + if (pSC->ppTempFile[i] == NULL) return ICERR_ERROR; + + char tmpnambuf[] = { 'f', 'i', 'l', 'e', 'X', 'X', 'X', 'X', 'X', 'X', '\0' }; + if (mkstemp(tmpnambuf) == -1) + return ICERR_ERROR; + pFilename = tmpnambuf; + strcpy(pSC->ppTempFile[i], pFilename); +#endif + if (CreateWS_File(pSC->ppWStream + i, pFilename, "w+b") != ICERR_OK) return ICERR_ERROR; + + } + else { + if (CreateWS_List(pSC->ppWStream + i) != ICERR_OK) return ICERR_ERROR; + } + attachISWrite(pSC->m_ppBitIO[i], pSC->ppWStream[i]); + } + } + + return ICERR_OK; +} + +#define PUTBITS putBit16 +/************************************************************************* + Write variable length byte aligned integer +*************************************************************************/ +static Void PutVLWordEsc(BitIOInfo* pIO, Int iEscape, size_t s) +{ + if (iEscape) { + assert(iEscape <= 0xff && iEscape > 0xfc); // fd,fe,ff are the only valid escapes + PUTBITS(pIO, iEscape, 8); + } + else if (s < 0xfb00) { + PUTBITS(pIO, (U32)s, 16); + } + else { + size_t t = s >> 16; + if ((t >> 16) == 0) { + PUTBITS(pIO, 0xfb, 8); + } + else { + t >>= 16; + PUTBITS(pIO, 0xfc, 8); + PUTBITS(pIO, (U32)(t >> 16) & 0xffff, 16); + PUTBITS(pIO, (U32)t & 0xffff, 16); + } + PUTBITS(pIO, (U32)t & 0xffff, 16); + PUTBITS(pIO, (U32)s & 0xffff, 16); + } +} + +/************************************************************************* + Write index table at start (null index table) +*************************************************************************/ +Int writeIndexTableNull(CWMImageStrCodec* pSC) +{ + if (pSC->cNumBitIO == 0) { + BitIOInfo* pIO = pSC->pIOHeader; + fillToByte(pIO); + + /* Profile / Level info */ + PutVLWordEsc(pIO, 0, 4); // 4 bytes + PUTBITS(pIO, 111, 8); // default profile idc + PUTBITS(pIO, 255, 8); // default level idc + PUTBITS(pIO, 1, 16); // LAST_FLAG + } + + return ICERR_OK; +} + +/************************************************************************* + Write index table +*************************************************************************/ +Int writeIndexTable(CWMImageStrCodec* pSC) +{ + if (pSC->cNumBitIO > 0) { + BitIOInfo* pIO = pSC->pIOHeader; + size_t* pTable = pSC->pIndexTable, iSize[4] = { 0 }; + I32 iEntry = (I32)pSC->cNumBitIO * (pSC->WMISCP.cNumOfSliceMinus1H + 1), i, k, l; + + // write index table header [0x0001] - 2 bytes + PUTBITS(pIO, 1, 16); + + for (i = pSC->WMISCP.cNumOfSliceMinus1H; i >= 0 && pSC->bTileExtraction == FALSE; i--) { + for (k = 0; k < (int)pSC->cNumBitIO; ) { + for (l = 0; l < (pSC->WMISCP.bfBitstreamFormat == FREQUENCY && pSC->WMISCP.bProgressiveMode ? pSC->cSB : 1); l++, k++) + { + if (i > 0) + pTable[pSC->cNumBitIO * i + k] -= pSC->pIndexTable[pSC->cNumBitIO * (i - 1) + k]; // packet length + iSize[l] += pTable[pSC->cNumBitIO * i + k]; + } + } + } + + iSize[3] = iSize[2] + iSize[1] + iSize[0]; + iSize[2] = iSize[1] + iSize[0]; + iSize[1] = iSize[0]; + iSize[0] = 0; + + for (i = 0; i < iEntry; ) { + for (l = 0; l < (pSC->WMISCP.bfBitstreamFormat == FREQUENCY && pSC->WMISCP.bProgressiveMode ? pSC->cSB : 1); l++, i++) + { + writeIS_L1(pSC, pIO); + PutVLWordEsc(pIO, (pTable[i] <= MINIMUM_PACKET_LENGTH) ? 0xff : 0, iSize[l]); + iSize[l] += (pTable[i] <= MINIMUM_PACKET_LENGTH) ? 0 : pTable[i]; + } + } + + writeIS_L1(pSC, pIO); + PutVLWordEsc(pIO, 0xff, 0); // escape to end + fillToByte(pIO); + } + + return ICERR_OK; +} + +Int copyTo(struct WMPStream* pSrc, struct WMPStream* pDst, size_t iBytes) +{ + char pData[PACKETLENGTH]; + + if (iBytes <= MINIMUM_PACKET_LENGTH) { + pSrc->Read(pSrc, pData, iBytes); + return ICERR_OK; + } + + while (iBytes > PACKETLENGTH) { + pSrc->Read(pSrc, pData, PACKETLENGTH); + pDst->Write(pDst, pData, PACKETLENGTH); + iBytes -= PACKETLENGTH; + } + pSrc->Read(pSrc, pData, iBytes); + pDst->Write(pDst, pData, iBytes); + + return ICERR_OK; +} + +Int StrIOEncTerm(CWMImageStrCodec* pSC) +{ + BitIOInfo* pIO = pSC->pIOHeader; + + fillToByte(pIO); + + if (pSC->WMISCP.bVerbose) { + U32 i, j; + + printf("\n%d horizontal tiles:\n", pSC->WMISCP.cNumOfSliceMinus1H + 1); + for (i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1H; i++) { + printf(" offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileY[i]); + } + + printf("\n%d vertical tiles:\n", pSC->WMISCP.cNumOfSliceMinus1V + 1); + for (i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i++) { + printf(" offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileX[i]); + } + + if (pSC->WMISCP.bfBitstreamFormat == SPATIAL) { + printf("\nSpatial order bitstream\n"); + } + else { + printf("\nFrequency order bitstream\n"); + } + + if (!pSC->m_param.bIndexTable) { + printf("\nstreaming mode, no index table.\n"); + } + else if (pSC->WMISCP.bfBitstreamFormat == SPATIAL) { + for (j = 0; j <= pSC->WMISCP.cNumOfSliceMinus1H; j++) { + for (i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i++) { + printf("bitstream size for tile (%d, %d): %d.\n", j, i, (int)pSC->pIndexTable[j * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + i]); + } + } + } + else { + for (j = 0; j <= pSC->WMISCP.cNumOfSliceMinus1H; j++) { + for (i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i++) { + size_t* p = &pSC->pIndexTable[(j * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + i) * 4]; + printf("bitstream size of (DC, LP, AC, FL) for tile (%d, %d): %d %d %d %d.\n", j, i, + (int)p[0], (int)p[1], (int)p[2], (int)p[3]); + } + } + } + } + + writeIndexTable(pSC); // write index table to the header + + detachISWrite(pSC, pIO); + + if (pSC->cNumBitIO > 0) { + size_t i, j, k, l; + struct WMPStream* pDst = pSC->WMISCP.pWStream; + size_t* pTable = pSC->pIndexTable; + + for (i = 0; i < pSC->cNumBitIO; i++) { + detachISWrite(pSC, pSC->m_ppBitIO[i]); + } + + for (i = 0; i < pSC->cNumBitIO; i++) { + pSC->ppWStream[i]->SetPos(pSC->ppWStream[i], 0); // seek back for read + } + + for (l = 0; l < (size_t)(pSC->WMISCP.bfBitstreamFormat == FREQUENCY && pSC->WMISCP.bProgressiveMode ? pSC->cSB : 1); l++) { + for (i = 0, k = l; i <= pSC->WMISCP.cNumOfSliceMinus1H; i++) { // loop through tiles + for (j = 0; j <= pSC->WMISCP.cNumOfSliceMinus1V; j++) { + + if (pSC->WMISCP.bfBitstreamFormat == SPATIAL) + copyTo(pSC->ppWStream[j], pDst, pTable[k++]); + else if (!pSC->WMISCP.bProgressiveMode) { + copyTo(pSC->ppWStream[j * pSC->cSB + 0], pDst, pTable[k++]); + if (pSC->cSB > 1) + copyTo(pSC->ppWStream[j * pSC->cSB + 1], pDst, pTable[k++]); + if (pSC->cSB > 2) + copyTo(pSC->ppWStream[j * pSC->cSB + 2], pDst, pTable[k++]); + if (pSC->cSB > 3) + copyTo(pSC->ppWStream[j * pSC->cSB + 3], pDst, pTable[k++]); + } + else { + copyTo(pSC->ppWStream[j * pSC->cSB + l], pDst, pTable[k]); + k += pSC->cSB; + } + } + } + } + + if (pSC->cmbHeight * pSC->cmbWidth * pSC->WMISCP.cChannel >= MAX_MEMORY_SIZE_IN_WORDS) { + for (i = 0; i < pSC->cNumBitIO; i++) { + if (pSC->ppWStream && pSC->ppWStream[i]) { + if ((*(pSC->ppWStream + i))->state.file.pFile) { + fclose((*(pSC->ppWStream + i))->state.file.pFile); +#ifdef _WINDOWS_ + if (DeleteFileA((LPCSTR)pSC->ppTempFile[i]) == 0) + return ICERR_ERROR; +#else + if (remove(pSC->ppTempFile[i]) == -1) + return ICERR_ERROR; +#endif + } + + if (*(pSC->ppWStream + i)) + free(*(pSC->ppWStream + i)); + } + if (pSC->ppTempFile) { + if (pSC->ppTempFile[i]) + free(pSC->ppTempFile[i]); + } + } + + if (pSC->ppTempFile) + free(pSC->ppTempFile); + } + else { + for (i = 0; i < pSC->cNumBitIO; i++) { + if (pSC->ppWStream && pSC->ppWStream[i]) + pSC->ppWStream[i]->Close(pSC->ppWStream + i); + } + } + + free(pSC->ppWStream); + + free(pSC->m_ppBitIO); + free(pSC->pIndexTable); + } + + return 0; +} + +/************************************************************************* + Write header of image plane +*************************************************************************/ +Int WriteImagePlaneHeader(CWMImageStrCodec* pSC) +{ + CWMImageInfo* pII = &pSC->WMII; + CWMIStrCodecParam* pSCP = &pSC->WMISCP; + BitIOInfo* pIO = pSC->pIOHeader; + + PUTBITS(pIO, (Int)pSC->m_param.cfColorFormat, 3); // internal color format + PUTBITS(pIO, (Int)pSC->m_param.bScaledArith, 1); // lossless mode + + // subbands + PUTBITS(pIO, (U32)pSCP->sbSubband, 4); + + // color parameters + switch (pSC->m_param.cfColorFormat) { + case YUV_420: + case YUV_422: + case YUV_444: + PUTBITS(pIO, 0, 4); + PUTBITS(pIO, 0, 4); + break; + case NCOMPONENT: + PUTBITS(pIO, (Int)pSC->m_param.cNumChannels - 1, 4); + PUTBITS(pIO, 0, 4); + break; + default: + break; + } + + // float and 32s additional parameters + switch (pII->bdBitDepth) { + case BD_16: + case BD_16S: + PUTBITS(pIO, pSCP->nLenMantissaOrShift, 8); + break; + case BD_32: + case BD_32S: + if (pSCP->nLenMantissaOrShift == 0) + pSCP->nLenMantissaOrShift = 10;//default + PUTBITS(pIO, pSCP->nLenMantissaOrShift, 8); + break; + case BD_32F: + if (pSCP->nLenMantissaOrShift == 0) + pSCP->nLenMantissaOrShift = 13;//default + PUTBITS(pIO, pSCP->nLenMantissaOrShift, 8);//float conversion parameters + PUTBITS(pIO, pSCP->nExpBias, 8); + break; + default: + break; + } + + // quantization + PUTBITS(pIO, (pSC->m_param.uQPMode & 1) == 1 ? 0 : 1, 1); // DC frame uniform quantization? + if ((pSC->m_param.uQPMode & 1) == 0) + writeQuantizer(pSC->pTile[0].pQuantizerDC, pIO, (pSC->m_param.uQPMode >> 3) & 3, pSC->m_param.cNumChannels, 0); + if (pSC->WMISCP.sbSubband != SB_DC_ONLY) { + PUTBITS(pIO, (pSC->m_param.uQPMode & 0x200) == 0 ? 1 : 0, 1); // use DC quantization? + if ((pSC->m_param.uQPMode & 0x200) != 0) { + PUTBITS(pIO, (pSC->m_param.uQPMode & 2) == 2 ? 0 : 1, 1); // LP frame uniform quantization? + if ((pSC->m_param.uQPMode & 2) == 0) + writeQuantizer(pSC->pTile[0].pQuantizerLP, pIO, (pSC->m_param.uQPMode >> 5) & 3, pSC->m_param.cNumChannels, 0); + } + + if (pSC->WMISCP.sbSubband != SB_NO_HIGHPASS) { + PUTBITS(pIO, (pSC->m_param.uQPMode & 0x400) == 0 ? 1 : 0, 1); // use LP quantization? + if ((pSC->m_param.uQPMode & 0x400) != 0) { + PUTBITS(pIO, (pSC->m_param.uQPMode & 4) == 4 ? 0 : 1, 1); // HP frame uniform quantization? + if ((pSC->m_param.uQPMode & 4) == 0) + writeQuantizer(pSC->pTile[0].pQuantizerHP, pIO, (pSC->m_param.uQPMode >> 7) & 3, pSC->m_param.cNumChannels, 0); + } + } + } + + fillToByte(pIO); // remove this later + return ICERR_OK; +} + +/************************************************************************* + Write header to buffer +*************************************************************************/ +Int WriteWMIHeader(CWMImageStrCodec* pSC) +{ + CWMImageInfo* pII = &pSC->WMII; + CWMIStrCodecParam* pSCP = &pSC->WMISCP; + CCoreParameters* pCoreParam = &pSC->m_param; + BitIOInfo* pIO = pSC->pIOHeader; + U32 /*iSizeOfSize = 2,*/ i; + // temporary assignments / reserved words + // const Int HEADERSIZE = 0; + Bool bInscribed = FALSE; + Bool bAbbreviatedHeader = (((pII->cWidth + 15) / 16 > 255 || (pII->cHeight + 15) / 16 > 255) ? FALSE : TRUE); + + if (pCoreParam->bTranscode == FALSE) + pCoreParam->cExtraPixelsTop = pCoreParam->cExtraPixelsLeft = pCoreParam->cExtraPixelsRight = pCoreParam->cExtraPixelsBottom = 0; + + // num of extra boundary pixels due to compressed domain processing + bInscribed = (pCoreParam->cExtraPixelsTop || pCoreParam->cExtraPixelsLeft || pCoreParam->cExtraPixelsBottom || pCoreParam->cExtraPixelsRight); + + // 0 + /** signature **/ + for (i = 0; i < 8; PUTBITS(pSC->pIOHeader, gGDISignature[i++], 8)); + + // 8 + /** codec version and subversion **/ + PUTBITS(pIO, CODEC_VERSION, 4); // this should be changed to "profile" in RTM + if (pSC->WMISCP.bUseHardTileBoundaries) + PUTBITS(pIO, CODEC_SUBVERSION_NEWSCALING_HARD_TILES, 4); + else + PUTBITS(pIO, CODEC_SUBVERSION_NEWSCALING_SOFT_TILES, 4); + + // 9 primary parameters + PUTBITS(pIO, (pSCP->cNumOfSliceMinus1V || pSCP->cNumOfSliceMinus1H) ? 1 : 0, 1); // tiling present + PUTBITS(pIO, (Int)pSCP->bfBitstreamFormat, 1); // bitstream layout + PUTBITS(pIO, pII->oOrientation, 3); // m_iRotateFlip + PUTBITS(pIO, pSC->m_param.bIndexTable, 1); // index table present + PUTBITS(pIO, pSCP->olOverlap, 2); // overlap + + // 10 + PUTBITS(pIO, bAbbreviatedHeader, 1); // short words for size and tiles + PUTBITS(pIO, 1, 1); // long word length (use intelligence later) + PUTBITS(pIO, bInscribed, 1); // windowing + PUTBITS(pIO, pSC->m_param.bTrimFlexbitsFlag, 1); // trim flexbits flag sent + PUTBITS(pIO, 0, 1); // tile stretching parameters (not enabled) + PUTBITS(pIO, 0, 2); // reserved bits + PUTBITS(pIO, (Int)pSC->m_param.bAlphaChannel, 1); // alpha channel present + + // 11 - informational + PUTBITS(pIO, (Int)pII->cfColorFormat, 4); // source color format + if (BD_1 == pII->bdBitDepth && pSCP->bBlackWhite) + PUTBITS(pIO, (Int)BD_1alt, 4); // source bit depth + else + PUTBITS(pIO, (Int)pII->bdBitDepth, 4); // source bit depth + + // 12 - Variable length fields + // size + putBit32(pIO, (U32)(pII->cWidth - 1), bAbbreviatedHeader ? 16 : 32); + putBit32(pIO, (U32)(pII->cHeight - 1), bAbbreviatedHeader ? 16 : 32); + + // tiling + if (pSCP->cNumOfSliceMinus1V || pSCP->cNumOfSliceMinus1H) { + PUTBITS(pIO, pSCP->cNumOfSliceMinus1V, LOG_MAX_TILES); // # of vertical slices + PUTBITS(pIO, pSCP->cNumOfSliceMinus1H, LOG_MAX_TILES); // # of horizontal slices + } + + // tile sizes + for (i = 0; i < pSCP->cNumOfSliceMinus1V; i++) { // width in MB of vertical slices, not needed for last slice! + PUTBITS(pIO, pSCP->uiTileX[i + 1] - pSCP->uiTileX[i], bAbbreviatedHeader ? 8 : 16); + } + for (i = 0; i < pSCP->cNumOfSliceMinus1H; i++) { // width in MB of horizontal slices, not needed for last slice! + PUTBITS(pIO, pSCP->uiTileY[i + 1] - pSCP->uiTileY[i], bAbbreviatedHeader ? 8 : 16); + } + + // window due to compressed domain processing + if (bInscribed) { + PUTBITS(pIO, (U32)pCoreParam->cExtraPixelsTop, 6); + PUTBITS(pIO, (U32)pCoreParam->cExtraPixelsLeft, 6); + PUTBITS(pIO, (U32)pCoreParam->cExtraPixelsBottom, 6); + PUTBITS(pIO, (U32)pCoreParam->cExtraPixelsRight, 6); + } + fillToByte(pIO); // redundant + + // write image plane headers + WriteImagePlaneHeader(pSC); + + return ICERR_OK; +} + +// streaming codec init/term +Int StrEncInit(CWMImageStrCodec* pSC) +{ + COLORFORMAT cf = pSC->m_param.cfColorFormat; + COLORFORMAT cfE = pSC->WMII.cfColorFormat; + U16 iQPIndexY = 0, iQPIndexYLP = 0, iQPIndexYHP = 0; + U16 iQPIndexU = 0, iQPIndexULP = 0, iQPIndexUHP = 0; + U16 iQPIndexV = 0, iQPIndexVLP = 0, iQPIndexVHP = 0; + size_t i; + Bool b32bit = sizeof(size_t) == 4; + + /** color transcoding with resolution change **/ + pSC->m_bUVResolutionChange = (((cfE == CF_RGB || cfE == YUV_444 || cfE == CMYK || cfE == CF_RGBE) && + (cf == YUV_422 || cf == YUV_420)) + || (cfE == YUV_422 && cf == YUV_420)) && !pSC->WMISCP.bYUVData; + + if (pSC->m_bUVResolutionChange) { + size_t cSize = ((cfE == YUV_422 ? 128 : 256) + (cf == YUV_420 ? 32 : 0)) * pSC->cmbWidth + 256; + + if (b32bit) { // integer overlow/underflow check for 32-bit system + if (((pSC->cmbWidth >> 16) * ((cfE == YUV_422 ? 128 : 256) + (cf == YUV_420 ? 32 : 0))) & 0xffff0000) + return ICERR_ERROR; + if (cSize >= 0x3fffffff) + return ICERR_ERROR; + } + pSC->pResU = (PixelI*)malloc(cSize * sizeof(PixelI)); + pSC->pResV = (PixelI*)malloc(cSize * sizeof(PixelI)); + if (pSC->pResU == NULL || pSC->pResV == NULL) { + return ICERR_ERROR; + } + } + + pSC->cTileColumn = pSC->cTileRow = 0; + + if (allocateTileInfo(pSC) != ICERR_OK) + return ICERR_ERROR; + + if (pSC->m_param.bTranscode == FALSE) { + pSC->m_param.uQPMode = 0x150; // 101010 000 + // 000 == uniform (not per tile) DC, LP, HP + // 101010 == cChMode == 2 == independent (not same) DC, LP, HP + +/** lossless or Y component lossless condition: all subbands present, uniform quantization with QPIndex 1 **/ + pSC->m_param.bScaledArith = !((pSC->m_param.uQPMode & 7) == 0 && + 1 == pSC->WMISCP.uiDefaultQPIndex <= 1 && + pSC->WMISCP.sbSubband == SB_ALL && + pSC->m_bUVResolutionChange == FALSE) && + !pSC->WMISCP.bUnscaledArith; + if (BD_32 == pSC->WMII.bdBitDepth || BD_32S == pSC->WMII.bdBitDepth || BD_32F == pSC->WMII.bdBitDepth) { + pSC->m_param.bScaledArith = FALSE; + } + pSC->m_param.uQPMode |= 0x600; // don't use DC QP for LP, LP QP for HP + + // default QPs + iQPIndexY = pSC->m_param.bAlphaChannel && pSC->m_param.cNumChannels == 1 ? + pSC->WMISCP.uiDefaultQPIndexAlpha : pSC->WMISCP.uiDefaultQPIndex; + + // determine the U,V index + iQPIndexU = pSC->WMISCP.uiDefaultQPIndexU != 0 ? + pSC->WMISCP.uiDefaultQPIndexU : iQPIndexY; + iQPIndexV = pSC->WMISCP.uiDefaultQPIndexV != 0 ? + pSC->WMISCP.uiDefaultQPIndexV : iQPIndexY; + + // determine the QPIndexYLP + iQPIndexYLP = pSC->m_param.bAlphaChannel && pSC->m_param.cNumChannels == 1 ? + pSC->WMISCP.uiDefaultQPIndexAlpha : + (pSC->WMISCP.uiDefaultQPIndexYLP == 0 ? + pSC->WMISCP.uiDefaultQPIndex : pSC->WMISCP.uiDefaultQPIndexYLP); // default to QPIndex if not set + + // determine the QPIndexYHP + iQPIndexYHP = pSC->m_param.bAlphaChannel && pSC->m_param.cNumChannels == 1 ? + pSC->WMISCP.uiDefaultQPIndexAlpha : + (pSC->WMISCP.uiDefaultQPIndexYHP == 0 ? + pSC->WMISCP.uiDefaultQPIndex : pSC->WMISCP.uiDefaultQPIndexYHP); // default to QPIndex if not set + + // determine the U,V LP index + iQPIndexULP = pSC->WMISCP.uiDefaultQPIndexULP != 0 ? + pSC->WMISCP.uiDefaultQPIndexULP : iQPIndexU; + iQPIndexVLP = pSC->WMISCP.uiDefaultQPIndexVLP != 0 ? + pSC->WMISCP.uiDefaultQPIndexVLP : iQPIndexV; + + // determine the U,V HP index + iQPIndexUHP = pSC->WMISCP.uiDefaultQPIndexUHP != 0 ? + pSC->WMISCP.uiDefaultQPIndexUHP : iQPIndexU; + iQPIndexVHP = pSC->WMISCP.uiDefaultQPIndexVHP != 0 ? + pSC->WMISCP.uiDefaultQPIndexVHP : iQPIndexV; + + // clamp the QPIndex - 0 is lossless mode + if (iQPIndexY < 2) + iQPIndexY = 0; + if (iQPIndexYLP < 2) + iQPIndexYLP = 0; + if (iQPIndexYHP < 2) + iQPIndexYHP = 0; + if (iQPIndexU < 2) + iQPIndexU = 0; + if (iQPIndexULP < 2) + iQPIndexULP = 0; + if (iQPIndexUHP < 2) + iQPIndexUHP = 0; + if (iQPIndexV < 2) + iQPIndexV = 0; + if (iQPIndexVLP < 2) + iQPIndexVLP = 0; + if (iQPIndexVHP < 2) + iQPIndexVHP = 0; + } + + if ((pSC->m_param.uQPMode & 1) == 0) { // DC frame uniform quantization + if (allocateQuantizer(pSC->pTile[0].pQuantizerDC, pSC->m_param.cNumChannels, 1) != ICERR_OK) + return ICERR_ERROR; + setUniformQuantizer(pSC, 0); + for (i = 0; i < pSC->m_param.cNumChannels; i++) + if (pSC->m_param.bTranscode) + pSC->pTile[0].pQuantizerDC[i]->iIndex = pSC->m_param.uiQPIndexDC[i]; + else + pSC->pTile[0].pQuantizerDC[i]->iIndex = pSC->m_param.uiQPIndexDC[i] = (U8)(((i == 0 ? iQPIndexY : (i == 1) ? iQPIndexU : iQPIndexV)) & 0xff); + formatQuantizer(pSC->pTile[0].pQuantizerDC, (pSC->m_param.uQPMode >> 3) & 3, pSC->m_param.cNumChannels, 0, TRUE, pSC->m_param.bScaledArith); + + for (i = 0; i < pSC->m_param.cNumChannels; i++) + pSC->pTile[0].pQuantizerDC[i]->iOffset = (pSC->pTile[0].pQuantizerDC[i]->iQP >> 1); + } + + if (pSC->WMISCP.sbSubband != SB_DC_ONLY) { + if ((pSC->m_param.uQPMode & 2) == 0) { // LP frame uniform quantization + if (allocateQuantizer(pSC->pTile[0].pQuantizerLP, pSC->m_param.cNumChannels, 1) != ICERR_OK) + return ICERR_ERROR; + setUniformQuantizer(pSC, 1); + for (i = 0; i < pSC->m_param.cNumChannels; i++) + if (pSC->m_param.bTranscode) + pSC->pTile[0].pQuantizerLP[i]->iIndex = pSC->m_param.uiQPIndexLP[i]; + else + pSC->pTile[0].pQuantizerLP[i]->iIndex = pSC->m_param.uiQPIndexLP[i] = (U8)(((i == 0 ? iQPIndexYLP : (i == 1) ? iQPIndexULP : iQPIndexVLP)) & 0xff); + formatQuantizer(pSC->pTile[0].pQuantizerLP, (pSC->m_param.uQPMode >> 5) & 3, pSC->m_param.cNumChannels, 0, TRUE, pSC->m_param.bScaledArith); + } + + if (pSC->WMISCP.sbSubband != SB_NO_HIGHPASS) { + if ((pSC->m_param.uQPMode & 4) == 0) { // HP frame uniform quantization + if (allocateQuantizer(pSC->pTile[0].pQuantizerHP, pSC->m_param.cNumChannels, 1) != ICERR_OK) + return ICERR_ERROR; + setUniformQuantizer(pSC, 2); + for (i = 0; i < pSC->m_param.cNumChannels; i++) + if (pSC->m_param.bTranscode) + pSC->pTile[0].pQuantizerHP[i]->iIndex = pSC->m_param.uiQPIndexHP[i]; + else + pSC->pTile[0].pQuantizerHP[i]->iIndex = pSC->m_param.uiQPIndexHP[i] = (U8)(((i == 0 ? iQPIndexYHP : (i == 1) ? iQPIndexUHP : iQPIndexVHP)) & 0xff); + formatQuantizer(pSC->pTile[0].pQuantizerHP, (pSC->m_param.uQPMode >> 7) & 3, pSC->m_param.cNumChannels, 0, FALSE, pSC->m_param.bScaledArith); + } + } + } + + if (allocatePredInfo(pSC) != ICERR_OK) { + return ICERR_ERROR; + } + + if (pSC->WMISCP.cNumOfSliceMinus1V >= MAX_TILES || AllocateCodingContextEnc(pSC, pSC->WMISCP.cNumOfSliceMinus1V + 1, pSC->WMISCP.uiTrimFlexBits) != ICERR_OK) { + return ICERR_ERROR; + } + + if (pSC->m_bSecondary) { + pSC->pIOHeader = pSC->m_pNextSC->pIOHeader; + pSC->m_ppBitIO = pSC->m_pNextSC->m_ppBitIO; + pSC->cNumBitIO = pSC->m_pNextSC->cNumBitIO; + pSC->cSB = pSC->m_pNextSC->cSB; + pSC->ppWStream = pSC->m_pNextSC->ppWStream; + pSC->pIndexTable = pSC->m_pNextSC->pIndexTable; + setBitIOPointers(pSC); + } + else { + StrIOEncInit(pSC); + setBitIOPointers(pSC); + WriteWMIHeader(pSC); + } + + return ICERR_OK; +} + +static Int StrEncTerm(CTXSTRCODEC ctxSC) +{ + CWMImageStrCodec* pSC = (CWMImageStrCodec*)ctxSC; + size_t j, jend = (pSC->m_pNextSC != NULL); + + for (j = 0; j <= jend; j++) { + if (sizeof(*pSC) != pSC->cbStruct) { + return ICERR_ERROR; + } + + if (pSC->m_bUVResolutionChange) { + if (pSC->pResU != NULL) + free(pSC->pResU); + if (pSC->pResV != NULL) + free(pSC->pResV); + } + + freePredInfo(pSC); + + if (j == 0) + StrIOEncTerm(pSC); + + FreeCodingContextEnc(pSC); + + freeTileInfo(pSC); + + pSC->WMISCP.nExpBias -= 128; // reset + + pSC = pSC->m_pNextSC; + } + + return 0; +} + +U32 setUniformTiling(U32* pTile, U32 cNumTile, U32 cNumMB) +{ + U32 i, j; + + while ((cNumMB + cNumTile - 1) / cNumTile > 65535) // too few tiles + cNumTile++; + + for (i = cNumTile, j = cNumMB; i > 1; i--) { + pTile[cNumTile - i] = (j + i - 1) / i; + j -= pTile[cNumTile - i]; + } + + return cNumTile; +} + +U32 validateTiling(U32* pTile, U32 cNumTile, U32 cNumMB) +{ + U32 i, cMBs; + + if (cNumTile == 0) + cNumTile = 1; + if (cNumTile > cNumMB) // too many tiles + cNumTile = 1; + if (cNumTile > MAX_TILES) + cNumTile = MAX_TILES; + + for (i = cMBs = 0; i + 1 < cNumTile; i++) { + if (pTile[i] == 0 || pTile[i] > 65535) { // invalid tile setting, resetting to uniform tiling + cNumTile = setUniformTiling(pTile, cNumTile, cNumMB); + break; + } + + cMBs += pTile[i]; + + if (cMBs >= cNumMB) { + cNumTile = i + 1; + break; + } + } + + // last tile + if (cNumMB - cMBs > 65536) + cNumTile = setUniformTiling(pTile, cNumTile, cNumMB); + + for (i = 1; i < cNumTile; i++) + pTile[i] += pTile[i - 1]; + for (i = cNumTile - 1; i > 0; i--) + pTile[i] = pTile[i - 1]; + pTile[0] = 0; + + return cNumTile; +} + +/************************************************************************* + Validate and adjust input params here +*************************************************************************/ +Int ValidateArgs(CWMImageInfo* pII, CWMIStrCodecParam* pSCP) +{ + int i; + Bool bTooNarrowTile = FALSE; + + if (pII->cWidth > (1 << 28) || pII->cHeight > (1 << 28) || pII->cWidth == 0 || pII->cHeight == 0) { + printf("Unsurpported image size!\n"); + return ICERR_ERROR; // unsurpported image size + } + + if (((pSCP->cfColorFormat == YUV_420) || (pSCP->cfColorFormat == YUV_422)) && (pSCP->olOverlap == OL_TWO) && ((Int)(((U32)pII->cWidth + 15) >> 4) < 2)) { + printf("Image width must be at least 2 MB wide for subsampled chroma and two levels of overlap!\n"); + return ICERR_ERROR; + } + + if (pSCP->sbSubband == SB_ISOLATED || pSCP->sbSubband >= SB_MAX) // not allowed + pSCP->sbSubband = SB_ALL; + + if (pII->bdBitDepth == BD_5 && (pII->cfColorFormat != CF_RGB || pII->cBitsPerUnit != 16 || pII->cLeadingPadding != 0)) { + printf("Unsupported BD_5 image format!\n"); + return ICERR_ERROR; // BD_5 must be compact RGB! + } + if (pII->bdBitDepth == BD_565 && (pII->cfColorFormat != CF_RGB || pII->cBitsPerUnit != 16 || pII->cLeadingPadding != 0)) { + printf("Unsupported BD_565 image format!\n"); + return ICERR_ERROR; // BD_5 must be compact RGB! + } + if (pII->bdBitDepth == BD_10 && (pII->cfColorFormat != CF_RGB || pII->cBitsPerUnit != 32 || pII->cLeadingPadding != 0)) { + printf("Unsupported BD_10 image format!\n"); + return ICERR_ERROR; // BD_10 must be compact RGB! + } + + if ((pII->bdBitDepth == BD_5 || pII->bdBitDepth == BD_565 || pII->bdBitDepth == BD_10) && + (pSCP->cfColorFormat != YUV_420 && pSCP->cfColorFormat != YUV_422 && pSCP->cfColorFormat != Y_ONLY)) + pSCP->cfColorFormat = YUV_444; + + if (BD_1 == pII->bdBitDepth) { // binary image + if (pII->cfColorFormat != Y_ONLY) { + printf("BD_1 image must be black-and white!\n"); + return ICERR_ERROR; + } + pSCP->cfColorFormat = Y_ONLY; // can only be black white + } + + if (pSCP->bdBitDepth != BD_LONG) + pSCP->bdBitDepth = BD_LONG; // currently only support 32 bit internally + + if (pSCP->uAlphaMode > 1 && (pII->cfColorFormat == YUV_420 || pII->cfColorFormat == YUV_422 + || pII->bdBitDepth == BD_5 || pII->bdBitDepth == BD_10 + || pII->bdBitDepth == BD_1)) + { + printf("Alpha is not supported for this pixel format!\n"); + return ICERR_ERROR; + } + + if ((pSCP->cfColorFormat == YUV_420 || pSCP->cfColorFormat == YUV_422) && (pII->bdBitDepth == BD_16F || pII->bdBitDepth == BD_32F || pII->cfColorFormat == CF_RGBE)) + { + printf("Float or RGBE images must be encoded with YUV 444!\n"); + return ICERR_ERROR; + } + + // adjust tiling + pSCP->cNumOfSliceMinus1V = validateTiling(pSCP->uiTileX, pSCP->cNumOfSliceMinus1V + 1, (((U32)pII->cWidth + 15) >> 4)) - 1; + pSCP->cNumOfSliceMinus1H = validateTiling(pSCP->uiTileY, pSCP->cNumOfSliceMinus1H + 1, (((U32)pII->cHeight + 15) >> 4)) - 1; + + if (pSCP->bUseHardTileBoundaries && ((pSCP->cfColorFormat == YUV_420) || (pSCP->cfColorFormat == YUV_422)) && (pSCP->olOverlap == OL_TWO)) { + for (i = 1; i < (int)(pSCP->cNumOfSliceMinus1H + 1); i++) { + if ((Int)(pSCP->uiTileY[i] - pSCP->uiTileY[i - 1]) < 2) { + bTooNarrowTile = TRUE; + break; + } + } + if ((Int)((((U32)pII->cWidth + 15) >> 4) - pSCP->uiTileY[pSCP->cNumOfSliceMinus1H]) < 2) + bTooNarrowTile = TRUE; + } + if (bTooNarrowTile) { + printf("Tile width must be at least 2 MB wide for hard tiles, subsampled chroma, and two levels of overlap!\n"); + return ICERR_ERROR; + } + + if (pSCP->cChannel > MAX_CHANNELS) + return ICERR_ERROR; + + /** supported color transcoding **/ + /** ARGB, RGB => YUV_444, YUV_422, YUV_420, Y_ONLY **/ + /** YUV_444 => YUV_422, YUV_420, Y_ONLY **/ + /** YUV_422 => YUV_420, Y_ONLY **/ + /** YUV_420 => Y_ONLY **/ + + /** unsupported color transcoding **/ + /** Y_ONLY, YUV_420, YUV_422 => YUV_444 **/ + /** Y_ONLY, YUV_420 => YUV_422 **/ + /** Y_ONLY => YUV_420 **/ + if ((pII->cfColorFormat == Y_ONLY && pSCP->cfColorFormat != Y_ONLY) || + (pSCP->cfColorFormat == YUV_422 && (pII->cfColorFormat == YUV_420 || pII->cfColorFormat == Y_ONLY)) || + (pSCP->cfColorFormat == YUV_444 && (pII->cfColorFormat == YUV_422 || pII->cfColorFormat == YUV_420 || pII->cfColorFormat == Y_ONLY))) { + pSCP->cfColorFormat = pII->cfColorFormat; // force not to do color transcoding! + } + else if (pII->cfColorFormat == NCOMPONENT) { + pSCP->cfColorFormat = NCOMPONENT; // force not to do color transcoding! + } + if (CMYK == pII->cfColorFormat && pSCP->cfColorFormat == NCOMPONENT) + { + pSCP->cfColorFormat = CMYK; + } + + if (pSCP->cfColorFormat != NCOMPONENT) { + if (pSCP->cfColorFormat == Y_ONLY) + pSCP->cChannel = 1; + else if (pSCP->cfColorFormat == CMYK) + pSCP->cChannel = 4; + else + pSCP->cChannel = 3; + } + + if (pSCP->sbSubband >= SB_MAX) + pSCP->sbSubband = SB_ALL; + + + pII->cChromaCenteringX = 0; + pII->cChromaCenteringY = 0; + + return ICERR_OK; +} + +/************************************************************************* + Initialization of CWMImageStrCodec struct +*************************************************************************/ +static Void InitializeStrEnc(CWMImageStrCodec* pSC, + const CWMImageInfo* pII, const CWMIStrCodecParam* pSCP) +{ + pSC->cbStruct = sizeof(*pSC); + pSC->WMII = *pII; + pSC->WMISCP = *pSCP; + + // set nExpBias + if (pSC->WMISCP.nExpBias == 0) + pSC->WMISCP.nExpBias = 4 + 128;//default + pSC->WMISCP.nExpBias += 128; // rollover arithmetic + + pSC->cRow = 0; + pSC->cColumn = 0; + + pSC->cmbWidth = (pSC->WMII.cWidth + 15) / 16; + pSC->cmbHeight = (pSC->WMII.cHeight + 15) / 16; + + pSC->Load = inputMBRow; + pSC->Quantize = quantizeMacroblock; + pSC->ProcessTopLeft = processMacroblock; + pSC->ProcessTop = processMacroblock; + pSC->ProcessTopRight = processMacroblock; + pSC->ProcessLeft = processMacroblock; + pSC->ProcessCenter = processMacroblock; + pSC->ProcessRight = processMacroblock; + pSC->ProcessBottomLeft = processMacroblock; + pSC->ProcessBottom = processMacroblock; + pSC->ProcessBottomRight = processMacroblock; + + pSC->m_pNextSC = NULL; + pSC->m_bSecondary = FALSE; +} + +/************************************************************************* + Streaming API init +*************************************************************************/ +Int ImageStrEncInit( + CWMImageInfo* pII, + CWMIStrCodecParam* pSCP, + CTXSTRCODEC* pctxSC) +{ + static size_t cbChannels[BD_MAX] = { 2, 4 }; + + size_t cbChannel = 0, cblkChroma = 0, i; + size_t cbMacBlockStride = 0, cbMacBlockChroma = 0, cMacBlock = 0; + + CWMImageStrCodec* pSC = NULL, * pNextSC = NULL; + char* pb = NULL; + size_t cb = 0; + Bool b32bit = sizeof(size_t) == 4; + + Int err; + + if (ValidateArgs(pII, pSCP) != ICERR_OK) { + goto ErrorExit; + } + + //================================================ + *pctxSC = NULL; + + //================================================ + cbChannel = cbChannels[pSCP->bdBitDepth]; + cblkChroma = cblkChromas[pSCP->cfColorFormat]; + cbMacBlockStride = cbChannel * 16 * 16; + cbMacBlockChroma = cbChannel * 16 * cblkChroma; + cMacBlock = (pII->cWidth + 15) / 16; + + //================================================ + cb = sizeof(*pSC) + (128 - 1) + (PACKETLENGTH * 4 - 1) + (PACKETLENGTH * 2) + sizeof(*pSC->pIOHeader); + i = cbMacBlockStride + cbMacBlockChroma * (pSCP->cChannel - 1); + if (b32bit) // integer overlow/underflow check for 32-bit system + if (((cMacBlock >> 15) * i) & 0xffff0000) + return ICERR_ERROR; + i *= cMacBlock * 2; + cb += i; + + pb = malloc(cb); + if (NULL == pb) + { + goto ErrorExit; + } + memset(pb, 0, cb); + + //================================================ + pSC = (CWMImageStrCodec*)pb; pb += sizeof(*pSC); + + //// Set up perf timers + //PERFTIMER_ONLY(pSC->m_fMeasurePerf = pSCP->fMeasurePerf); + //PERFTIMER_NEW(pSC->m_fMeasurePerf, &pSC->m_ptEndToEndPerf); + //PERFTIMER_NEW(pSC->m_fMeasurePerf, &pSC->m_ptEncDecPerf); + //PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEndToEndPerf); + //PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); + //PERFTIMER_COPYSTARTTIME(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf, pSC->m_ptEndToEndPerf); + + pSC->m_param.cfColorFormat = pSCP->cfColorFormat; + pSC->m_param.bAlphaChannel = (pSCP->uAlphaMode == 3); + pSC->m_param.cNumChannels = pSCP->cChannel; + pSC->m_param.cExtraPixelsTop = pSC->m_param.cExtraPixelsBottom + = pSC->m_param.cExtraPixelsLeft = pSC->m_param.cExtraPixelsRight = 0; + + pSC->cbChannel = cbChannel; + + pSC->m_param.bTranscode = pSC->bTileExtraction = FALSE; + + //================================================ + InitializeStrEnc(pSC, pII, pSCP); + + //================================================ + // 2 Macro Row buffers for each channel + pb = ALIGNUP(pb, 128); + for (i = 0; i < pSC->m_param.cNumChannels; i++) { + pSC->a0MBbuffer[i] = (PixelI*)pb; pb += cbMacBlockStride * pSC->cmbWidth; + pSC->a1MBbuffer[i] = (PixelI*)pb; pb += cbMacBlockStride * pSC->cmbWidth; + cbMacBlockStride = cbMacBlockChroma; + } + + //================================================ + // lay 2 aligned IO buffers just below pIO struct + pb = (char*)ALIGNUP(pb, PACKETLENGTH * 4) + PACKETLENGTH * 2; + pSC->pIOHeader = (BitIOInfo*)pb; + + //================================================ + err = StrEncInit(pSC); + if (ICERR_OK != err) + goto ErrorExit; + + // if interleaved alpha is needed + if (pSC->m_param.bAlphaChannel) { + cbMacBlockStride = cbChannel * 16 * 16; + // 1. allocate new pNextSC info + //================================================ + cb = sizeof(*pNextSC) + (128 - 1) + cbMacBlockStride * cMacBlock * 2; + pb = malloc(cb); + if (NULL == pb) + { + goto ErrorExit; + } + memset(pb, 0, cb); + //================================================ + pNextSC = (CWMImageStrCodec*)pb; pb += sizeof(*pNextSC); + + // 2. initialize pNextSC + pNextSC->m_param.cfColorFormat = Y_ONLY; + pNextSC->m_param.cNumChannels = 1; + pNextSC->m_param.bAlphaChannel = TRUE; + pNextSC->cbChannel = cbChannel; + //================================================ + + // 3. initialize arrays + InitializeStrEnc(pNextSC, pII, pSCP); + //================================================ + + // 2 Macro Row buffers for each channel + pb = ALIGNUP(pb, 128); + pNextSC->a0MBbuffer[0] = (PixelI*)pb; pb += cbMacBlockStride * pNextSC->cmbWidth; + pNextSC->a1MBbuffer[0] = (PixelI*)pb; pb += cbMacBlockStride * pNextSC->cmbWidth; + //================================================ + pNextSC->pIOHeader = pSC->pIOHeader; + //================================================ + + // 4. link pSC->pNextSC = pNextSC + pNextSC->m_pNextSC = pSC; + pNextSC->m_bSecondary = TRUE; + + // 5. StrEncInit + StrEncInit(pNextSC); + + // 6. Write header of image plane + WriteImagePlaneHeader(pNextSC); + } + + pSC->m_pNextSC = pNextSC; + //================================================ + *pctxSC = (CTXSTRCODEC)pSC; + + writeIndexTableNull(pSC); +#if defined(WMP_OPT_SSE2) || defined(WMP_OPT_CC_ENC) || defined(WMP_OPT_TRFM_ENC) + StrEncOpt(pSC); +#endif // OPT defined + +// PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); + return ICERR_OK; + +ErrorExit: + return ICERR_ERROR; +} + +/************************************************************************* + Streaming API encode +*************************************************************************/ +Int ImageStrEncEncode( + CTXSTRCODEC ctxSC, + const CWMImageBufferInfo* pBI) +{ + CWMImageStrCodec* pSC = (CWMImageStrCodec*)ctxSC; + CWMImageStrCodec* pNextSC = pSC->m_pNextSC; + ImageDataProc ProcessLeft, ProcessCenter, ProcessRight; + + if (sizeof(*pSC) != pSC->cbStruct) + { + return ICERR_ERROR; + } + + //================================ + // PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); + + pSC->WMIBI = *pBI; + pSC->cColumn = 0; + initMRPtr(pSC); + if (pNextSC) + pNextSC->WMIBI = *pBI; + + if (0 == pSC->cRow) { + ProcessLeft = pSC->ProcessTopLeft; + ProcessCenter = pSC->ProcessTop; + ProcessRight = pSC->ProcessTopRight; + } + else { + ProcessLeft = pSC->ProcessLeft; + ProcessCenter = pSC->ProcessCenter; + ProcessRight = pSC->ProcessRight; + } + + if (pSC->Load(pSC) != ICERR_OK) + return ICERR_ERROR; + if (ProcessLeft(pSC) != ICERR_OK) + return ICERR_ERROR; + advanceMRPtr(pSC); + + //================================ + for (pSC->cColumn = 1; pSC->cColumn < pSC->cmbWidth; ++pSC->cColumn) { + if (ProcessCenter(pSC) != ICERR_OK) + return ICERR_ERROR; + advanceMRPtr(pSC); + } + + //================================ + if (ProcessRight(pSC) != ICERR_OK) + return ICERR_ERROR; + if (pSC->cRow) + advanceOneMBRow(pSC); + + ++pSC->cRow; + swapMRPtr(pSC); + +// PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); + return ICERR_OK; +} + +/************************************************************************* + Streaming API term +*************************************************************************/ +Int ImageStrEncTerm( + CTXSTRCODEC ctxSC) +{ + CWMImageStrCodec* pSC = (CWMImageStrCodec*)ctxSC; + // CWMImageStrCodec *pNextSC = pSC->m_pNextSC; + + if (sizeof(*pSC) != pSC->cbStruct) + { + return ICERR_ERROR; + } + + //================================ +// PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); + pSC->cColumn = 0; + initMRPtr(pSC); + + pSC->ProcessBottomLeft(pSC); + advanceMRPtr(pSC); + + //================================ + for (pSC->cColumn = 1; pSC->cColumn < pSC->cmbWidth; ++pSC->cColumn) { + pSC->ProcessBottom(pSC); + advanceMRPtr(pSC); + } + + //================================ + pSC->ProcessBottomRight(pSC); + + //================================ + StrEncTerm(pSC); + + //PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); + //PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEndToEndPerf); + //PERFTIMER_REPORT(pSC->m_fMeasurePerf, pSC); + //PERFTIMER_DELETE(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); + //PERFTIMER_DELETE(pSC->m_fMeasurePerf, pSC->m_ptEndToEndPerf); + + free(pSC); + return ICERR_OK; +} + +// centralized UV downsampling +#define DF_ODD ((((d1 + d2 + d3) << 2) + (d2 << 1) + d0 + d4 + 8) >> 4) +Void downsampleUV(CWMImageStrCodec* pSC) +{ + const COLORFORMAT cfInt = pSC->m_param.cfColorFormat; + const COLORFORMAT cfExt = pSC->WMII.cfColorFormat; + PixelI* pSrc, * pDst; + PixelI d0, d1, d2, d3, d4; + size_t iChannel, iRow, iColumn; + + for (iChannel = 1; iChannel < 3; iChannel++) { + if (cfExt != YUV_422) { // need to do horizontal downsampling, 444 => 422 + const size_t cShift = (cfInt == YUV_422 ? 1 : 0); + + pSrc = (iChannel == 1 ? pSC->pResU : pSC->pResV); + pDst = (cfInt == YUV_422 ? pSC->p1MBbuffer[iChannel] : pSrc); + + for (iRow = 0; iRow < 16; iRow++) { + d0 = d4 = pSrc[idxCC[iRow][2]], d1 = d3 = pSrc[idxCC[iRow][1]], d2 = pSrc[idxCC[iRow][0]]; // left boundary + + for (iColumn = 0; iColumn + 2 < pSC->cmbWidth * 16; iColumn += 2) { + pDst[((iColumn >> 4) << (8 - cShift)) + idxCC[iRow][(iColumn & 15) >> cShift]] = DF_ODD; + d0 = d2, d1 = d3, d2 = d4; + d3 = pSrc[(((iColumn + 3) >> 4) << 8) + idxCC[iRow][(iColumn + 3) & 0xf]]; + d4 = pSrc[(((iColumn + 4) >> 4) << 8) + idxCC[iRow][(iColumn + 4) & 0xf]]; + } + + d4 = d2; // right boundary + pDst[((iColumn >> 4) << (8 - cShift)) + idxCC[iRow][(iColumn & 15) >> cShift]] = DF_ODD; + } + } + + if (cfInt == YUV_420) { // need to do vertical downsampling + const size_t cShift = (cfExt == YUV_422 ? 0 : 1); + PixelI* pBuf[4]; + size_t mbOff, pxOff; + + pDst = pSC->p1MBbuffer[iChannel]; + pSrc = (iChannel == 1 ? pSC->pResU : pSC->pResV); + pBuf[0] = pSrc + (pSC->cmbWidth << (cfExt == YUV_422 ? 7 : 8)); + pBuf[1] = pBuf[0] + pSC->cmbWidth * 8, pBuf[2] = pBuf[1] + pSC->cmbWidth * 8, pBuf[3] = pBuf[2] + pSC->cmbWidth * 8; + + for (iColumn = 0; iColumn < pSC->cmbWidth * 8; iColumn++) { + mbOff = (iColumn >> 3) << (7 + cShift); + pxOff = (iColumn & 7) << cShift; + + if (pSC->cRow == 0) // top image boundary + d0 = d4 = pSrc[mbOff + idxCC[2][pxOff]], d1 = d3 = pSrc[mbOff + idxCC[1][pxOff]], d2 = pSrc[mbOff + idxCC[0][pxOff]]; // top MB boundary + else { + // last row of previous MB row + d0 = pBuf[0][iColumn], d1 = pBuf[1][iColumn], d2 = pBuf[2][iColumn], d3 = pBuf[3][iColumn], d4 = pSrc[mbOff + idxCC[0][pxOff]]; + pSC->p0MBbuffer[iChannel][((iColumn >> 3) << 6) + idxCC_420[7][iColumn & 7]] = DF_ODD; + + // for first row of current MB + d0 = pBuf[2][iColumn], d1 = pBuf[3][iColumn]; + d2 = pSrc[mbOff + idxCC[0][pxOff]], d3 = pSrc[mbOff + idxCC[1][pxOff]], d4 = pSrc[mbOff + idxCC[2][pxOff]]; + } + + for (iRow = 0; iRow < 12; iRow += 2) { + pDst[((iColumn >> 3) << 6) + idxCC_420[iRow >> 1][iColumn & 7]] = DF_ODD; + d0 = d2, d1 = d3, d2 = d4; + d3 = pSrc[mbOff + idxCC[iRow + 3][pxOff]]; + d4 = pSrc[mbOff + idxCC[iRow + 4][pxOff]]; + } + + //last row of current MB + pDst[((iColumn >> 3) << 6) + idxCC_420[6][iColumn & 7]] = DF_ODD; + d0 = d2, d1 = d3, d2 = d4; + d3 = pSrc[mbOff + idxCC[iRow + 3][pxOff]]; + + if (pSC->cRow + 1 == pSC->cmbHeight) { // bottom image boundary + d4 = d2; + pDst[((iColumn >> 3) << 6) + idxCC_420[7][iColumn & 7]] = DF_ODD; + } + else { + for (iRow = 0; iRow < 4; iRow++) + pBuf[iRow][iColumn] = pSrc[mbOff + idxCC[iRow + 12][pxOff]]; + } + } + } + } +} + +// centralized horizontal padding +Void padHorizontally(CWMImageStrCodec* pSC) +{ + if (pSC->WMII.cWidth != pSC->cmbWidth * 16) { // horizontal padding is necessary! + const COLORFORMAT cfExt = pSC->WMISCP.bYUVData ? + pSC->m_param.cfColorFormat : pSC->WMII.cfColorFormat; + size_t cFullChannel = pSC->WMISCP.cChannel; + size_t iLast = pSC->WMII.cWidth - 1; + PixelI* pCh[16]; + size_t iChannel, iColumn, iRow; + + if (cfExt == YUV_420 || cfExt == YUV_422 || cfExt == Y_ONLY) + cFullChannel = 1; + + assert(cFullChannel <= 16); + + assert(pSC->WMISCP.cChannel <= 16); + for (iChannel = 0; iChannel < pSC->WMISCP.cChannel; iChannel++) + pCh[iChannel & 15] = pSC->p1MBbuffer[iChannel & 15]; + + if (pSC->m_bUVResolutionChange) + pCh[1] = pSC->pResU, pCh[2] = pSC->pResV; + + // pad full resoluton channels + for (iRow = 0; iRow < 16; iRow++) { + const size_t iPosLast = ((iLast >> 4) << 8) + idxCC[iRow][iLast & 0xf]; + for (iColumn = iLast + 1; iColumn < pSC->cmbWidth * 16; iColumn++) { + const size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + for (iChannel = 0; iChannel < cFullChannel; iChannel++) + pCh[iChannel & 15][iPos] = pCh[iChannel & 15][iPosLast]; + } + } + + if (cfExt == YUV_422) // pad YUV_422 UV + for (iLast >>= 1, iRow = 0; iRow < 16; iRow++) { + const size_t iPosLast = ((iLast >> 3) << 7) + idxCC[iRow][iLast & 7]; + for (iColumn = iLast + 1; iColumn < pSC->cmbWidth * 8; iColumn++) { + const size_t iPos = ((iColumn >> 3) << 7) + idxCC[iRow][iColumn & 7]; + for (iChannel = 1; iChannel < 3; iChannel++) + pCh[iChannel][iPos] = pCh[iChannel][iPosLast]; + } + } + else if (cfExt == YUV_420) // pad YUV_420 UV + for (iLast >>= 1, iRow = 0; iRow < 8; iRow++) { + const size_t iPosLast = ((iLast >> 3) << 6) + idxCC_420[iRow][iLast & 7]; + for (iColumn = iLast + 1; iColumn < pSC->cmbWidth * 8; iColumn++) { + const size_t iPos = ((iColumn >> 3) << 6) + idxCC_420[iRow][iColumn & 7]; + for (iChannel = 1; iChannel < 3; iChannel++) + pCh[iChannel][iPos] = pCh[iChannel][iPosLast]; + } + } + } +} + +// centralized alpha channel color conversion, small perf penalty +Int inputMBRowAlpha(CWMImageStrCodec* pSC) +{ + if (pSC->m_bSecondary == FALSE && pSC->m_pNextSC != NULL) { // alpha channel is present + const size_t cShift = (pSC->m_pNextSC->m_param.bScaledArith ? (SHIFTZERO + QPFRACBITS) : 0); + const BITDEPTH_BITS bdExt = pSC->WMII.bdBitDepth; + const size_t iAlphaPos = pSC->WMII.cLeadingPadding + (pSC->WMII.cfColorFormat == CMYK ? 4 : 3);//only RGB and CMYK may have interleaved alpha + const size_t cRow = pSC->WMIBI.cLine; + const size_t cColumn = pSC->WMII.cWidth; + const U8* pSrc0 = (U8*)pSC->WMIBI.pv; + PixelI* pA = pSC->m_pNextSC->p1MBbuffer[0]; + size_t iRow, iColumn; + + for (iRow = 0; iRow < 16; iRow++) { + if (bdExt == BD_8) { + const size_t cStride = (pSC->WMII.cBitsPerUnit >> 3); + const U8* pSrc = pSrc0; + + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cStride) + pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] = ((PixelI)pSrc[iAlphaPos] - (1 << 7)) << cShift; + } + else if (bdExt == BD_16) { + const size_t cStride = (pSC->WMII.cBitsPerUnit >> 3) / sizeof(U16); + const U8 nLenMantissaOrShift = pSC->m_pNextSC->WMISCP.nLenMantissaOrShift; + const U16* pSrc = (U16*)pSrc0; + + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cStride) + pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] = ((((PixelI)pSrc[iAlphaPos] - (1 << 15)) >> nLenMantissaOrShift) << cShift); + } + else if (bdExt == BD_16S) { + const size_t cStride = (pSC->WMII.cBitsPerUnit >> 3) / sizeof(I16); + const U8 nLenMantissaOrShift = pSC->m_pNextSC->WMISCP.nLenMantissaOrShift; + const I16* pSrc = (I16*)pSrc0; + + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cStride) + pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] = (((PixelI)pSrc[iAlphaPos] >> nLenMantissaOrShift) << cShift); + } + else if (bdExt == BD_16F) { + const size_t cStride = (pSC->WMII.cBitsPerUnit >> 3) / sizeof(U16); + const I16* pSrc = (I16*)pSrc0; + + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cStride) + pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] = forwardHalf(pSrc[iAlphaPos]) << cShift; + } + else if (bdExt == BD_32S) { + const size_t cStride = (pSC->WMII.cBitsPerUnit >> 3) / sizeof(I32); + const U8 nLenMantissaOrShift = pSC->m_pNextSC->WMISCP.nLenMantissaOrShift; + const I32* pSrc = (I32*)pSrc0; + + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cStride) + pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] = (((PixelI)pSrc[iAlphaPos] >> nLenMantissaOrShift) << cShift); + } + else if (bdExt == BD_32F) { + const size_t cStride = (pSC->WMII.cBitsPerUnit >> 3) / sizeof(float); + const U8 nLen = pSC->m_pNextSC->WMISCP.nLenMantissaOrShift; + const I8 nExpBias = pSC->m_pNextSC->WMISCP.nExpBias; + const float* pSrc = (float*)pSrc0; + + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cStride) + pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] = float2pixel(pSrc[iAlphaPos], nExpBias, nLen) << cShift; + } + else // not supported + return ICERR_ERROR; + + if (iRow + 1 < cRow) // vertical padding! + pSrc0 += pSC->WMIBI.cbStride; + + for (iColumn = cColumn; iColumn < pSC->cmbWidth * 16; iColumn++) // horizontal padding + pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] = pA[(((cColumn - 1) >> 4) << 8) + idxCC[iRow][(cColumn - 1) & 0xf]]; + } + } + + return ICERR_OK; +} + +// input one MB row of image data from input buffer +Int inputMBRow(CWMImageStrCodec* pSC) +{ + const size_t cShift = (pSC->m_param.bScaledArith ? (SHIFTZERO + QPFRACBITS) : 0); + const BITDEPTH_BITS bdExt = pSC->WMII.bdBitDepth; + COLORFORMAT cfExt = pSC->WMII.cfColorFormat; + const COLORFORMAT cfInt = pSC->m_param.cfColorFormat; + const size_t cPixelStride = (pSC->WMII.cBitsPerUnit >> 3); + const size_t iRowStride = + (cfExt == YUV_420 || (pSC->WMISCP.bYUVData && pSC->m_param.cfColorFormat == YUV_420)) ? 2 : 1; + const size_t cRow = pSC->WMIBI.cLine; + const size_t cColumn = pSC->WMII.cWidth; + const size_t iB = (pSC->WMII.bRGB ? 2 : 0); + const size_t iR = 2 - iB; + const U8* pSrc0 = (U8*)pSC->WMIBI.pv; + const U8 nLen = pSC->WMISCP.nLenMantissaOrShift; + const I8 nExpBias = pSC->WMISCP.nExpBias; + + PixelI* pY = pSC->p1MBbuffer[0], * pU = pSC->p1MBbuffer[1], * pV = pSC->p1MBbuffer[2]; + size_t iRow, iColumn, iPos; + + // guard input buffer + if (checkImageBuffer(pSC, cColumn, cRow) != ICERR_OK) + return ICERR_ERROR; + + if (pSC->m_bUVResolutionChange) // will do downsampling somewhere else! + pU = pSC->pResU, pV = pSC->pResV; + else if (cfInt == Y_ONLY) // xxx to Y_ONLY transcoding! + pU = pV = pY; // write pY AFTER pU and pV so Y will overwrite U&V + + for (iRow = 0; iRow < 16; iRow += iRowStride) { + if (pSC->WMISCP.bYUVData) { + I32* pSrc = (I32*)pSrc0 + pSC->WMII.cLeadingPadding; + + switch (pSC->m_param.cfColorFormat) { + case Y_ONLY: + case YUV_444: + case NCOMPONENT: + { + const size_t cChannel = pSC->m_param.cNumChannels; + PixelI* pChannel[16]; + size_t iChannel; + + assert(cChannel <= 16); + for (iChannel = 0; iChannel < cChannel; iChannel++) + pChannel[iChannel & 15] = pSC->p1MBbuffer[iChannel & 15]; + if (pSC->m_bUVResolutionChange) + pChannel[1] = pSC->pResU, pChannel[2] = pSC->pResV; + + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cChannel) { + iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + for (iChannel = 0; iChannel < cChannel; iChannel++) + pChannel[iChannel & 15][iPos] = (PixelI)pSrc[iChannel & 15]; + } + } + break; + + case YUV_422: + for (iColumn = 0; iColumn < cColumn; iColumn += 2, pSrc += 4) { + if (cfInt != Y_ONLY) { + iPos = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7]; + pU[iPos] = (PixelI)pSrc[0]; + pV[iPos] = (PixelI)pSrc[2]; + } + + pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] = (PixelI)pSrc[1]; + pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] = (PixelI)pSrc[3]; + } + break; + + case YUV_420: + for (iColumn = 0; iColumn < cColumn; iColumn += 2, pSrc += 6) { + if (cfInt != Y_ONLY) { + iPos = ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7]; + pU[iPos] = (PixelI)pSrc[4]; + pV[iPos] = (PixelI)pSrc[5]; + } + + pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] = (PixelI)pSrc[0]; + pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] = (PixelI)pSrc[1]; + pY[((iColumn >> 4) << 8) + idxCC[iRow + 1][iColumn & 15]] = (PixelI)pSrc[2]; + pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow + 1][(iColumn + 1) & 15]] = (PixelI)pSrc[3]; + } + break; + + default: + assert(0); + break; + } + } + else if (bdExt == BD_8) { + const U8* pSrc = pSrc0 + pSC->WMII.cLeadingPadding; + const PixelI iOffset = (128 << cShift); + + switch (cfExt) { + case CF_RGB: + assert(pSC->m_bSecondary == FALSE); + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cPixelStride) { + PixelI r = ((PixelI)pSrc[iR]) << cShift, g = ((PixelI)pSrc[1]) << cShift, b = ((PixelI)pSrc[iB]) << cShift; + + _CC(r, g, b); // color conversion + + iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g - iOffset; + } + break; + + case Y_ONLY: + case YUV_444: + case NCOMPONENT: + { + const size_t cChannel = pSC->m_param.cNumChannels; + PixelI* pChannel[16]; + size_t iChannel; + + assert(cChannel <= 16); + for (iChannel = 0; iChannel < cChannel; iChannel++) + pChannel[iChannel & 15] = pSC->p1MBbuffer[iChannel & 15]; + if (pSC->m_bUVResolutionChange) + pChannel[1] = pSC->pResU, pChannel[2] = pSC->pResV; + + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cPixelStride) { + iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + for (iChannel = 0; iChannel < cChannel; iChannel++) + pChannel[iChannel & 15][iPos] = (((PixelI)pSrc[iChannel & 15]) << cShift) - iOffset; + } + break; + } + + case CF_RGBE: + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cPixelStride) { + PixelI iExp = (PixelI)pSrc[3]; + PixelI r = forwardRGBE(pSrc[0], iExp) << cShift; + PixelI g = forwardRGBE(pSrc[1], iExp) << cShift; + PixelI b = forwardRGBE(pSrc[2], iExp) << cShift; + + _CC(r, g, b); + + iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g; + } + break; + + case CMYK: + { + PixelI* pK = (cfInt == CMYK ? pSC->p1MBbuffer[3] : pY); // CMYK -> YUV_xxx transcoding! + + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cPixelStride) { + PixelI c = ((PixelI)pSrc[0]) << cShift; + PixelI m = ((PixelI)pSrc[1]) << cShift; + PixelI y = ((PixelI)pSrc[2]) << cShift; + PixelI k = ((PixelI)pSrc[3]) << cShift; + + _CC_CMYK(c, m, y, k); + + iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + pU[iPos] = c, pV[iPos] = -y, pK[iPos] = k, pY[iPos] = iOffset - m; + } + break; + } + + case YUV_422: + for (iColumn = 0; iColumn < cColumn; iColumn += 2, pSrc += cPixelStride) { + if (cfInt != Y_ONLY) { + iPos = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7]; + pU[iPos] = (((PixelI)pSrc[0]) << cShift) - iOffset; + pV[iPos] = (((PixelI)pSrc[2]) << cShift) - iOffset; + } + + pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] = (((PixelI)pSrc[1]) << cShift) - iOffset; + pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] = (((PixelI)pSrc[3]) << cShift) - iOffset; + } + break; + + case YUV_420: + for (iColumn = 0; iColumn < cColumn; iColumn += 2, pSrc += cPixelStride) { + if (cfInt != Y_ONLY) { + iPos = ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7]; + pU[iPos] = (((PixelI)pSrc[4]) << cShift) - iOffset; + pV[iPos] = (((PixelI)pSrc[5]) << cShift) - iOffset; + } + + pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] = (((PixelI)pSrc[0]) << cShift) - iOffset; + pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] = (((PixelI)pSrc[1]) << cShift) - iOffset; + pY[((iColumn >> 4) << 8) + idxCC[iRow + 1][iColumn & 15]] = (((PixelI)pSrc[2]) << cShift) - iOffset; + pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow + 1][(iColumn + 1) & 15]] = (((PixelI)pSrc[3]) << cShift) - iOffset; + } + break; + + default: + assert(0); + break; + } + } + else if (bdExt == BD_16) { + const U16* pSrc = (U16*)pSrc0 + pSC->WMII.cLeadingPadding; + const size_t cStride = cPixelStride / sizeof(U16); + const PixelI iOffset = ((1 << 15) >> nLen) << cShift; + + switch (cfExt) { + case CF_RGB: + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cStride) { + PixelI r = ((PixelI)pSrc[0] >> nLen) << cShift, g = ((PixelI)pSrc[1] >> nLen) << cShift, b = ((PixelI)pSrc[2] >> nLen) << cShift; + + _CC(r, g, b); // color conversion + + iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g - iOffset; + } + break; + + case Y_ONLY: + case YUV_444: + case NCOMPONENT: + { + const size_t cChannel = pSC->WMISCP.cChannel; + size_t iChannel; + + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cStride) { + iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + for (iChannel = 0; iChannel < cChannel; iChannel++) + pSC->p1MBbuffer[iChannel][iPos] = (((PixelI)pSrc[iChannel] >> nLen) << cShift) - iOffset; + } + break; + } + + case CMYK: + { + PixelI* pK = (cfInt == CMYK ? pSC->p1MBbuffer[3] : pY); // CMYK -> YUV_xxx transcoding! + + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cStride) { + PixelI c = ((PixelI)pSrc[0] >> nLen) << cShift; + PixelI m = ((PixelI)pSrc[1] >> nLen) << cShift; + PixelI y = ((PixelI)pSrc[2] >> nLen) << cShift; + PixelI k = ((PixelI)pSrc[3] >> nLen) << cShift; + + _CC_CMYK(c, m, y, k); + + iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + pU[iPos] = c, pV[iPos] = -y, pK[iPos] = k, pY[iPos] = iOffset - m; + } + break; + } + + case YUV_422: + for (iColumn = 0; iColumn < cColumn; iColumn += 2, pSrc += cStride) { + if (cfInt != Y_ONLY) { + iPos = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7]; + pU[iPos] = (((PixelI)pSrc[0]) << cShift) - iOffset; + pV[iPos] = (((PixelI)pSrc[2]) << cShift) - iOffset; + } + + pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] = (((PixelI)pSrc[1]) << cShift) - iOffset; + pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] = (((PixelI)pSrc[3]) << cShift) - iOffset; + } + break; + + case YUV_420: + for (iColumn = 0; iColumn < cColumn; iColumn += 2, pSrc += cStride) { + if (cfInt != Y_ONLY) { + iPos = ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7]; + pU[iPos] = (((PixelI)pSrc[4]) << cShift) - iOffset; + pV[iPos] = (((PixelI)pSrc[5]) << cShift) - iOffset; + } + + pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] = (((PixelI)pSrc[0]) << cShift) - iOffset; + pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] = (((PixelI)pSrc[1]) << cShift) - iOffset; + pY[((iColumn >> 4) << 8) + idxCC[iRow + 1][iColumn & 15]] = (((PixelI)pSrc[2]) << cShift) - iOffset; + pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow + 1][(iColumn + 1) & 15]] = (((PixelI)pSrc[3]) << cShift) - iOffset; + } + break; + + default: + assert(0); + break; + } + } + else if (bdExt == BD_16S) { + const I16* pSrc = (I16*)pSrc0 + pSC->WMII.cLeadingPadding; + const size_t cStride = cPixelStride / sizeof(I16); + + switch (cfExt) { + case CF_RGB: + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cStride) { + PixelI r = ((PixelI)pSrc[0] >> nLen) << cShift, g = ((PixelI)pSrc[1] >> nLen) << cShift, b = ((PixelI)pSrc[2] >> nLen) << cShift; + + _CC(r, g, b); // color conversion + + iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g; + } + break; + + case Y_ONLY: + case YUV_444: + case NCOMPONENT: + { + const size_t cChannel = pSC->WMISCP.cChannel; + size_t iChannel; + + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cStride) { + iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + for (iChannel = 0; iChannel < cChannel; iChannel++) + pSC->p1MBbuffer[iChannel][iPos] = (((PixelI)pSrc[iChannel] >> nLen) << cShift); + } + } + break; + + case CMYK: + { + PixelI* pK = (cfInt == CMYK ? pSC->p1MBbuffer[3] : pY); // CMYK -> YUV_xxx transcoding! + + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cStride) { + PixelI c = ((PixelI)pSrc[0] >> nLen) << cShift; + PixelI m = ((PixelI)pSrc[1] >> nLen) << cShift; + PixelI y = ((PixelI)pSrc[2] >> nLen) << cShift; + PixelI k = ((PixelI)pSrc[3] >> nLen) << cShift; + + _CC_CMYK(c, m, y, k); + + iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + pU[iPos] = c, pV[iPos] = -y, pK[iPos] = k, pY[iPos] = -m; + } + } + break; + + default: + assert(0); + break; + } + } + else if (bdExt == BD_16F) { + const I16* pSrc = (I16*)pSrc0 + pSC->WMII.cLeadingPadding; + const size_t cStride = cPixelStride / sizeof(U16); + + switch (cfExt) { + case CF_RGB: + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cStride) { + PixelI r = forwardHalf(pSrc[0]) << cShift; + PixelI g = forwardHalf(pSrc[1]) << cShift; + PixelI b = forwardHalf(pSrc[2]) << cShift; + + _CC(r, g, b); // color conversion + + iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g; + } + break; + + case Y_ONLY: + case YUV_444: + case NCOMPONENT: + { + const size_t cChannel = pSC->WMISCP.cChannel; // check xxx => Y_ONLY transcoding! + size_t iChannel; + + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cStride) { + iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + for (iChannel = 0; iChannel < cChannel; iChannel++) + pSC->p1MBbuffer[iChannel][iPos] = forwardHalf(pSrc[iChannel]) << cShift; + } + } + break; + + default: + assert(0); + break; + } + } + else if (bdExt == BD_32) { + const U32* pSrc = (U32*)pSrc0 + pSC->WMII.cLeadingPadding; + const size_t cStride = cPixelStride / sizeof(U32); + const PixelI iOffset = ((1 << 31) >> nLen) << cShift; + + switch (cfExt) { + case CF_RGB: + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cStride) { + PixelI r = (pSrc[0] >> nLen) << cShift, g = (pSrc[1] >> nLen) << cShift, b = (pSrc[2] >> nLen) << cShift; + + _CC(r, g, b); // color conversion + + iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g - iOffset; + } + break; + + case Y_ONLY: + case YUV_444: + case NCOMPONENT: + { + const size_t cChannel = pSC->WMISCP.cChannel; + size_t iChannel; + + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cStride) { + iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + for (iChannel = 0; iChannel < cChannel; iChannel++) + pSC->p1MBbuffer[iChannel][iPos] = (pSrc[iChannel] >> nLen) << cShift; + } + break; + } + + default: + assert(0); + break; + } + } + else if (bdExt == BD_32S) { + const I32* pSrc = (I32*)pSrc0 + pSC->WMII.cLeadingPadding; + const size_t cStride = cPixelStride / sizeof(I32); + + switch (cfExt) { + case CF_RGB: + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cStride) { + PixelI r = (pSrc[0] >> nLen) << cShift, g = (pSrc[1] >> nLen) << cShift, b = (pSrc[2] >> nLen) << cShift; + + _CC(r, g, b); // color conversion + + iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g; + } + break; + + case Y_ONLY: + case YUV_444: + case NCOMPONENT: + { + const size_t cChannel = pSC->WMISCP.cChannel; // check xxx => Y_ONLY transcoding! + size_t iChannel; + + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cStride) { + iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + for (iChannel = 0; iChannel < cChannel; iChannel++) + pSC->p1MBbuffer[iChannel][iPos] = (pSrc[iChannel] >> nLen) << cShift; + } + } + break; + + default: + assert(0); + break; + } + } + else if (bdExt == BD_32F) { + const float* pSrc = (float*)pSrc0 + pSC->WMII.cLeadingPadding; + const size_t cStride = cPixelStride / sizeof(float); + + switch (cfExt) { + case CF_RGB: + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cStride) { + PixelI r = float2pixel(pSrc[0], nExpBias, nLen) << cShift; + PixelI g = float2pixel(pSrc[1], nExpBias, nLen) << cShift; + PixelI b = float2pixel(pSrc[2], nExpBias, nLen) << cShift; + + _CC(r, g, b); // color conversion + + iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g; + } + break; + + case Y_ONLY: + case YUV_444: + case NCOMPONENT: + { + const size_t cChannel = pSC->WMISCP.cChannel; + size_t iChannel; + + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cStride) { + iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + for (iChannel = 0; iChannel < cChannel; iChannel++) + pSC->p1MBbuffer[iChannel][iPos] = float2pixel(pSrc[iChannel], nExpBias, nLen) << cShift; + } + } + break; + default: + assert(0); + break; + } + } + else if (bdExt == BD_5) { // RGB 555, work for both big endian and small endian! + const U8* pSrc = pSrc0; + const PixelI iOffset = (16 << cShift); + + assert(cfExt == CF_RGB); + + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cPixelStride) { + PixelI r = (PixelI)pSrc[0], g = (PixelI)pSrc[1], b = ((g >> 2) & 0x1F) << cShift; + + g = ((r >> 5) + ((g & 3) << 3)) << cShift, r = (r & 0x1F) << cShift; + + _CC(r, g, b); // color conversion + + iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g - iOffset; + } + } + else if (bdExt == BD_565) { // RGB 555, work for both big endian and small endian! + const U8* pSrc = pSrc0; + const PixelI iOffset = (32 << cShift); + + assert(cfExt == CF_RGB); + + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cPixelStride) { + PixelI r = (PixelI)pSrc[0], g = (PixelI)pSrc[1], b = (g >> 3) << (cShift + 1); + + g = ((r >> 5) + ((g & 7) << 3)) << cShift, r = (r & 0x1F) << (cShift + 1); + + _CC(r, g, b); // color conversion + + iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g - iOffset; + } + } + else if (bdExt == BD_10) { //RGB 101010, work for both big endian and small endian! + const U8* pSrc = pSrc0; + const PixelI iOffset = (512 << cShift); + + assert(cfExt == CF_RGB); + + for (iColumn = 0; iColumn < cColumn; iColumn++, pSrc += cPixelStride) { + PixelI r = (PixelI)pSrc[0], g = (PixelI)pSrc[1], b = (PixelI)pSrc[2]; + + r = (r + ((g & 3) << 8)) << cShift, g = ((g >> 2) + ((b & 0xF) << 6)) << cShift; + b = ((b >> 4) + (((PixelI)pSrc[3] & 0x3F) << 4)) << cShift; + + _CC(r, g, b); // color conversion + + iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; + pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g - iOffset; + } + } + else if (bdExt == BD_1) { + assert(cfExt == Y_ONLY); + for (iColumn = 0; iColumn < cColumn; iColumn++) { + pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] = ((pSC->WMISCP.bBlackWhite + (pSrc0[iColumn >> 3] >> (7 - (iColumn & 7)))) & 1) << cShift; + } + } + + if (iRow + iRowStride < cRow) // centralized vertical padding! + pSrc0 += pSC->WMIBI.cbStride; + } + + padHorizontally(pSC); // centralized horizontal padding + + // centralized down-sampling + if (pSC->m_bUVResolutionChange) + downsampleUV(pSC); + + // centralized alpha channel handdling + if (pSC->WMISCP.uAlphaMode == 3) + if (inputMBRowAlpha(pSC) != ICERR_OK) + return ICERR_ERROR; + + return ICERR_OK; +} + + diff --git a/Src/JxrDecode/jxrlib/image/sys/adapthuff.c b/Src/JxrDecode/jxrlib/image/sys/adapthuff.c new file mode 100644 index 00000000..b3e06586 --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/sys/adapthuff.c @@ -0,0 +1,513 @@ +//*@@@+++@@@@****************************************************************** +// +// 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 + +#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) ? INT_MIN : -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; +} + diff --git a/Src/JxrDecode/jxrlib/image/sys/image.c b/Src/JxrDecode/jxrlib/image/sys/image.c new file mode 100644 index 00000000..86858a23 --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/sys/image.c @@ -0,0 +1,182 @@ +//*@@@+++@@@@****************************************************************** +// +// 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 + +#include +#include + +#if !(defined(__ANSI__)) +// Desktop +#include +#else +// ANSI +#include +#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]]; + } + } +} diff --git a/Src/JxrDecode/jxrlib/image/sys/strPredQuant.c b/Src/JxrDecode/jxrlib/image/sys/strPredQuant.c new file mode 100644 index 00000000..d265f0b8 --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/sys/strPredQuant.c @@ -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!!! + } + } +} diff --git a/Src/JxrDecode/jxrlib/image/sys/strTransform.c b/Src/JxrDecode/jxrlib/image/sys/strTransform.c new file mode 100644 index 00000000..c35b0b6c --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/sys/strTransform.c @@ -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]); +} diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c new file mode 100644 index 00000000..a11fef5f --- /dev/null +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c @@ -0,0 +1,2338 @@ +//*@@@+++@@@@****************************************************************** +// +// 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 + +#include "JXRGlue.h" +#include + +//================================================================ +// PKFormatConverter +//================================================================ +#define HLF_MIN 0.00006103515625f +#define HLF_MAX 65504.0f + +#define HLF_MIN_BITS 0x0400 +#define HLF_MAX_BITS 0x7bff + +#define HLF_MIN_BITS_NEG (HLF_MIN_BITS | 0x8000) +#define HLF_MAX_BITS_NEG (HLF_MAX_BITS | 0x8000) + +#define HLF_QNaN_BITZS 0x7fff + +// simple and slow implementation of half <-> float conversion +static U32 Convert_Half_To_Float(U16 u16) +{ + // 1s5e10m -> 1s8e23m + const U32 s = (u16 >> 15) & 0x0001; + const U32 e = (u16 >> 10) & 0x001f; + const U32 m = (u16 >> 0) & 0x03ff; + + if (0 == e) // 0, denorm + { + return s << 31; + } + else if (~(~0 << 5) == e) // inf, snan, qnan + { + return (s << 31) | ~(~0 << 8) << 23 | (m << 13); + } + + return (s << 31) | ((e - 15 + 127) << 23) | (m << 13); // norm +} + + +static U16 Convert_Float_To_Half(float f) +{ + // 1s5e10m -> 1s8e23m + const U32 iFloat = *(U32*)&f; // Convert float to U32 + + if (f != f) + { + return (U16)(iFloat | HLF_QNaN_BITZS); // +QNaN, -QNaN + } + else if (f < -HLF_MAX) + { + return HLF_MAX_BITS_NEG; + } + else if (HLF_MAX < f) + { + return HLF_MAX_BITS; + } + else if (-HLF_MIN < f && f < HLF_MIN) + { + return (U16)((iFloat >> 16) & 0x8000); // +0, -0 + } + + // Cut-and-paste from C++, introduce scope so we can decl more vars + { + const U32 s = (iFloat >> 31) & 0x00000001; + const U32 e = (iFloat >> 23) & 0x000000ff; + const U32 m = (iFloat >> 0) & 0x007fffff; + + return (U16)((s << 15) | ((e - 127 + 15) << 10) | (m >> 13)); + } +} + + +static U8 Convert_Float_To_U8(float f) +{ + // convert from linear scRGB to non-linear sRGB + if (f <= 0) + { + return 0; + } + else if (f <= 0.0031308f) + { + return (U8)((255.0f * f * 12.92f) + 0.5f); + } + else if (f < 1.0f) + { + return (U8)((255.0f * ((1.055f * (float)pow(f, 1.0 / 2.4)) - 0.055f)) + 0.5f); + } + else + { + return 255; + } +} + +static U8 Convert_AlphaFloat_To_U8(float f) +{ + // alpha is converted differently than RGB in scRGB + if (f <= 0) + { + return 0; + } + else if (f < 1.0f) + { + return (U8)((255.0f * f) + 0.5f); + } + else + { + return 255; + } +} + + +ERR RGB24_BGR24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + I32 i = 0, j = 0; + + UNREFERENCED_PARAMETER(pFC); + + for (i = 0; i < pRect->Height; ++i) + { + for (j = 0; j < pRect->Width * 3; j += 3) + { + // swap red with blue + U8 t = pb[j]; + pb[j] = pb[j + 2]; + pb[j + 2] = t; + } + + pb += cbStride; + } + + return WMP_errSuccess; +} + +ERR BGR24_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + return RGB24_BGR24(pFC, pRect, pb, cbStride); +} + +ERR RGB24_BGR32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + I32 i = 0, j = 0; + + UNREFERENCED_PARAMETER(pFC); + + for (i = 0; i < pRect->Height; ++i) + { + for (j = 0; j < pRect->Width; j++) + { + // swap red with blue + U8 t = pb[3 * j]; + pb[4 * j] = pb[3 * j + 2]; + pb[4 * j + 1] = pb[3 * j + 1]; + pb[4 * j + 2] = t; + } + + pb += cbStride; + } + + return WMP_errSuccess; +} + +ERR BGR32_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + I32 i = 0, j = 0; + + UNREFERENCED_PARAMETER(pFC); + + for (i = 0; i < pRect->Height; ++i) + { + for (j = 0; j < pRect->Width; j++) + { + // swap red with blue + U8 t = pb[4 * j]; + pb[3 * j] = pb[4 * j + 2]; + pb[3 * j + 1] = pb[4 * j + 1]; + pb[3 * j + 2] = t; + } + + pb += cbStride; + } + + return WMP_errSuccess; +} + +ERR RGB24_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + I32 i = 0, j = 0, k = 0; + + UNREFERENCED_PARAMETER(pFC); + + for (i = 0; i < pRect->Height; ++i) + { + for (j = 0, k = 0; j < pRect->Width * 3; j += 3, ++k) + { + U8 r = pb[j]; + U8 g = pb[j + 1]; + U8 b = pb[j + 2]; + + pb[k] = r / 4 + g / 2 + b / 8 + 16; + } + + pb += cbStride; + } + + return WMP_errSuccess; +} + +ERR BGR24_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + ERR err = WMP_errSuccess; + + Call(BGR24_RGB24(pFC, pRect, pb, cbStride)); + Call(RGB24_Gray8(pFC, pRect, pb, cbStride)); + +Cleanup: + return err; +} + +ERR Gray8_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + I32 i = 0, j = 0, k = 0; + + UNREFERENCED_PARAMETER(pFC); + + for (i = 0; i < pRect->Height; ++i) + { + for (j = pRect->Width - 1, k = 3 * j; 0 <= j; j--, k -= 3) + { + U8 v = pb[j]; + + pb[k] = v; + pb[k + 1] = v; + pb[k + 2] = v; + } + + pb += cbStride; + } + + return WMP_errSuccess; +} + +ERR Gray8_BGR24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + return Gray8_RGB24(pFC, pRect, pb, cbStride); +} + +#if 0 +ERR RGB48_BGR48(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + ERR err = WMP_errSuccess; + + I32 i = 0, j = 0; + + UNREFERENCED_PARAMETER(pFC); + + Call(PKFormatConverter_Copy(pFC, pRect, pb, cbStride)); + + for (i = 0; i < pRect->Height; ++i) + { + for (j = 0; j < pRect->Width; j += 3) + { + U16* ps = (U16*)pb; + + // swap red with blue + U16 t = ps[j]; + ps[j] = ps[j + 2]; + ps[j + 2] = t; + } + + pb += cbStride; + } + +Cleanup: + return err; +} + +ERR BGR48_RGB48(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + return RGB48_BGR48(pFC, pRect, pb, cbStride); +} + +ERR RGB48_Gray16(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + ERR err = WMP_errSuccess; + + I32 i = 0, j = 0, k = 0; + + UNREFERENCED_PARAMETER(pFC); + + Call(PKFormatConverter_Copy(pFC, pRect, pb, cbStride)); + + for (i = 0; i < pRect->Height; ++i) + { + for (j = 0, k = 0; j < pRect->Width; j += 3, ++k) + { + U16* ps = (U16*)pb; + + // Y = r / 4 + g / 2 + b / 8 + 16 + U16 r = ps[j]; + U16 g = ps[j + 1]; + U16 b = ps[j + 2]; + + ps[k] = r / 4 + g / 2 + b / 8 + 16; + } + + pb += cbStride; + } + +Cleanup: + return err; +} +#endif + +ERR RGBA128Fixed_RGBA128Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidthX4 = 4 * pRect->Width; // 4 == R, G, B, A + const float fltCvtFactor = 1.0F / (1 << 24); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + for (y = 0; y < iHeight; y++) + { + I32 x; + float* pfltDstPixel = (float*)(pb + cbStride * y); + const I32* piSrcPixel = (I32*)pfltDstPixel; + + for (x = 0; x < iWidthX4; x++) + pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor; + } + + return WMP_errSuccess; +} + + +ERR RGBA128Float_RGBA128Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidthX4 = 4 * pRect->Width; // 4 == R, G, B, A + const float fltCvtFactor = (float)(1 << 24); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + for (y = 0; y < iHeight; y++) + { + I32 x; + I32* piDstPixel = (I32*)(pb + cbStride * y); + const float* pfltSrcPixel = (float*)piDstPixel; + + for (x = 0; x < iWidthX4; x++) + piDstPixel[x] = (I32)(pfltSrcPixel[x] * fltCvtFactor + 0.5F); + } + + return WMP_errSuccess; +} + + + +ERR RGB96Fixed_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidthX3 = 3 * pRect->Width; // 3 == R, G, B + const float fltCvtFactor = 1.0F / (1 << 24); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + for (y = 0; y < iHeight; y++) + { + I32 x; + float* pfltDstPixel = (float*)(pb + cbStride * y); + const I32* piSrcPixel = (I32*)pfltDstPixel; + + for (x = 0; x < iWidthX3; x++) + pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor; + } + + return WMP_errSuccess; +} + + +ERR RGB128Fixed_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + const float fltCvtFactor = 1.0F / (1 << 24); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + for (y = 0; y < iHeight; y++) + { + I32 x; + float* pfltDstPixel = (float*)(pb + cbStride * y); + const I32* piSrcPixel = (I32*)pfltDstPixel; + + for (x = 0; x < iWidth; x++) + { + pfltDstPixel[3 * x] = piSrcPixel[4 * x] * fltCvtFactor; + pfltDstPixel[3 * x + 1] = piSrcPixel[4 * x + 1] * fltCvtFactor; + pfltDstPixel[3 * x + 2] = piSrcPixel[4 * x + 2] * fltCvtFactor; + } + } + + return WMP_errSuccess; +} + + + +ERR RGB96Float_RGB96Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidthX3 = 3 * pRect->Width; // 3 == R, G, B + const float fltCvtFactor = (float)(1 << 24); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + for (y = 0; y < iHeight; y++) + { + I32 x; + I32* piDstPixel = (I32*)(pb + cbStride * y); + const float* pfltSrcPixel = (float*)piDstPixel; + + for (x = 0; x < iWidthX3; x++) + piDstPixel[x] = (I32)(pfltSrcPixel[x] * fltCvtFactor + 0.5F); + } + + return WMP_errSuccess; +} + + +ERR RGB96Float_RGB128Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + const float fltCvtFactor = (float)(1 << 24); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + assert(iWidth > 2); // Otherwise, we corrupt source data in inner loop + for (y = iHeight - 1; y >= 0; y--) + { + I32 x; + I32* piDstPixel = (I32*)(pb + cbStride * y); + const float* pfltSrcPixel = (float*)piDstPixel; + + for (x = iWidth - 1; x >= 0; x--) + { + piDstPixel[4 * x] = (I32)(pfltSrcPixel[3 * x] * fltCvtFactor + 0.5F); + piDstPixel[4 * x + 1] = (I32)(pfltSrcPixel[3 * x + 1] * fltCvtFactor + 0.5F); + piDstPixel[4 * x + 2] = (I32)(pfltSrcPixel[3 * x + 2] * fltCvtFactor + 0.5F); + piDstPixel[4 * x + 3] = 0; // Zero out the alpha channel + } + } + + return WMP_errSuccess; +} + + +ERR RGB96Float_RGB128Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + assert(iWidth > 2); // Otherwise, we corrupt source data in inner loop + for (y = iHeight - 1; y >= 0; y--) + { + I32 x; + float* pfltDstPixel = (float*)(pb + cbStride * y); + const float* pfltSrcPixel = (float*)pfltDstPixel; + + for (x = iWidth - 1; x >= 0; x--) + { + pfltDstPixel[4 * x] = pfltSrcPixel[3 * x]; + pfltDstPixel[4 * x + 1] = pfltSrcPixel[3 * x + 1]; + pfltDstPixel[4 * x + 2] = pfltSrcPixel[3 * x + 2]; + pfltDstPixel[4 * x + 3] = 0.0F; // Zero out the alpha channel + } + } + + return WMP_errSuccess; +} + + +ERR RGB128Float_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + for (y = 0; y < iHeight; y++) + { + I32 x; + float* pfltDstPixel = (float*)(pb + cbStride * y); + const float* pfltSrcPixel = (float*)pfltDstPixel; + + for (x = 0; x < iWidth; x++) + { + pfltDstPixel[3 * x] = pfltSrcPixel[4 * x]; + pfltDstPixel[3 * x + 1] = pfltSrcPixel[4 * x + 1]; + pfltDstPixel[3 * x + 2] = pfltSrcPixel[4 * x + 2]; + } + } + + return WMP_errSuccess; +} + + +ERR RGB48Half_RGB64Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + assert(iWidth > 2); // Otherwise, we corrupt source data in inner loop + for (y = iHeight - 1; y >= 0; y--) + { + I32 x; + I16* piDstPixel = (I16*)(pb + cbStride * y); + const I16* piSrcPixel = (I16*)piDstPixel; + + for (x = iWidth - 1; x >= 0; x--) + { + piDstPixel[4 * x] = piSrcPixel[3 * x]; + piDstPixel[4 * x + 1] = piSrcPixel[3 * x + 1]; + piDstPixel[4 * x + 2] = piSrcPixel[3 * x + 2]; + piDstPixel[4 * x + 3] = 0; // Zero out the alpha channel + } + } + + return WMP_errSuccess; +} + + +ERR RGB64Half_RGB48Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + for (y = 0; y < iHeight; y++) + { + I32 x; + I16* piDstPixel = (I16*)(pb + cbStride * y); + const short* piSrcPixel = (I16*)piDstPixel; + + for (x = 0; x < iWidth; x++) + { + piDstPixel[3 * x] = piSrcPixel[4 * x]; + piDstPixel[3 * x + 1] = piSrcPixel[4 * x + 1]; + piDstPixel[3 * x + 2] = piSrcPixel[4 * x + 2]; + } + } + + return WMP_errSuccess; +} + + +ERR BGR24_BGR32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + assert(iWidth > 2); // Otherwise, we corrupt source data in inner loop + for (y = iHeight - 1; y >= 0; y--) + { + I32 x; + U8* piDstPixel = pb + cbStride * y; + const U8* piSrcPixel = piDstPixel; + + for (x = iWidth - 1; x >= 0; x--) + { + piDstPixel[4 * x] = piSrcPixel[3 * x]; + piDstPixel[4 * x + 1] = piSrcPixel[3 * x + 1]; + piDstPixel[4 * x + 2] = piSrcPixel[3 * x + 2]; + piDstPixel[4 * x + 3] = 0; // Zero out the alpha channel + } + } + + return WMP_errSuccess; +} + + +ERR BGR32_BGR24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + for (y = 0; y < iHeight; y++) + { + I32 x; + U8* piDstPixel = pb + cbStride * y; + const U8* piSrcPixel = piDstPixel; + + for (x = 0; x < iWidth; x++) + { + piDstPixel[3 * x] = piSrcPixel[4 * x]; + piDstPixel[3 * x + 1] = piSrcPixel[4 * x + 1]; + piDstPixel[3 * x + 2] = piSrcPixel[4 * x + 2]; + } + } + + return WMP_errSuccess; +} + + +ERR Gray32Fixed_Gray32Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + const float fltCvtFactor = 1.0F / (1 << 24); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + for (y = 0; y < iHeight; y++) + { + I32 x; + float* pfltDstPixel = (float*)(pb + cbStride * y); + const I32* piSrcPixel = (I32*)pfltDstPixel; + + for (x = 0; x < iWidth; x++) + pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor; + } + + return WMP_errSuccess; +} + + +ERR Gray32Float_Gray32Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + const float fltCvtFactor = (float)(1 << 24); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + for (y = 0; y < iHeight; y++) + { + I32 x; + I32* piDstPixel = (I32*)(pb + cbStride * y); + const float* pfltSrcPixel = (float*)piDstPixel; + + for (x = 0; x < iWidth; x++) + piDstPixel[x] = (I32)(pfltSrcPixel[x] * fltCvtFactor + 0.5F); + } + + return WMP_errSuccess; +} + + + +ERR Gray16Fixed_Gray32Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + const float fltCvtFactor = 1.0F / (1 << 13); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = iHeight - 1; y >= 0; y--) + { + I32 x; + float* pfltDstPixel = (float*)(pb + cbStride * y); + const I16* piSrcPixel = (I16*)pfltDstPixel; + + for (x = iWidth - 1; x >= 0; x--) + pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor; + } + + return WMP_errSuccess; +} + + +ERR Gray32Float_Gray16Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + const float fltCvtFactor = (float)(1 << 13); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = 0; y < iHeight; y++) + { + I32 x; + I16* piDstPixel = (I16*)(pb + cbStride * y); + const float* pfltSrcPixel = (float*)piDstPixel; + + for (x = 0; x < iWidth; x++) + piDstPixel[x] = (I16)(pfltSrcPixel[x] * fltCvtFactor + 0.5F); + } + + return WMP_errSuccess; +} + + +ERR RGB48Fixed_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidthX3 = 3 * pRect->Width; + const float fltCvtFactor = 1.0F / (1 << 13); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = iHeight - 1; y >= 0; y--) + { + I32 x; + float* pfltDstPixel = (float*)(pb + cbStride * y); + const I16* piSrcPixel = (I16*)pfltDstPixel; + + for (x = iWidthX3 - 1; x >= 0; x--) + pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor; + } + + return WMP_errSuccess; +} + + +ERR RGB96Float_RGB48Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidthX3 = 3 * pRect->Width; + const float fltCvtFactor = (float)(1 << 13); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = 0; y < iHeight; y++) + { + I32 x; + I16* piDstPixel = (I16*)(pb + cbStride * y); + const float* pfltSrcPixel = (float*)piDstPixel; + + for (x = 0; x < iWidthX3; x++) + piDstPixel[x] = (I16)(pfltSrcPixel[x] * fltCvtFactor + 0.5F); + } + + return WMP_errSuccess; +} + + +ERR RGB64Fixed_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + const float fltCvtFactor = 1.0F / (1 << 13); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = iHeight - 1; y >= 0; y--) + { + I32 x; + float* pfltDstPixel = (float*)(pb + cbStride * y); + const I16* piSrcPixel = (I16*)pfltDstPixel; + + for (x = iWidth - 1; x >= 0; x--) + { + pfltDstPixel[3 * x] = piSrcPixel[4 * x] * fltCvtFactor; + pfltDstPixel[3 * x + 1] = piSrcPixel[4 * x + 1] * fltCvtFactor; + pfltDstPixel[3 * x + 2] = piSrcPixel[4 * x + 2] * fltCvtFactor; + } + } + + return WMP_errSuccess; +} + + +ERR RGB96Float_RGB64Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + const float fltCvtFactor = (float)(1 << 13); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = 0; y < iHeight; y++) + { + I32 x; + I16* piDstPixel = (I16*)(pb + cbStride * y); + const float* pfltSrcPixel = (float*)piDstPixel; + + for (x = 0; x < iWidth; x++) + { + piDstPixel[4 * x] = (I16)(pfltSrcPixel[3 * x] * fltCvtFactor + 0.5F); + piDstPixel[4 * x + 1] = (I16)(pfltSrcPixel[3 * x + 1] * fltCvtFactor + 0.5F); + piDstPixel[4 * x + 2] = (I16)(pfltSrcPixel[3 * x + 2] * fltCvtFactor + 0.5F); + piDstPixel[4 * x + 3] = 0; // Zero out the alpha channel + } + } + + return WMP_errSuccess; +} + + +ERR RGBA64Fixed_RGBA128Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidthX4 = 4 * pRect->Width; + const float fltCvtFactor = 1.0F / (1 << 13); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = iHeight - 1; y >= 0; y--) + { + I32 x; + float* pfltDstPixel = (float*)(pb + cbStride * y); + const I16* piSrcPixel = (I16*)pfltDstPixel; + + for (x = iWidthX4 - 1; x >= 0; x--) + pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor; + } + + return WMP_errSuccess; +} + + + +ERR RGBA128Float_RGBA64Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidthX4 = 4 * pRect->Width; + const float fltCvtFactor = (float)(1 << 13); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = 0; y < iHeight; y++) + { + I32 x; + I16* piDstPixel = (I16*)(pb + cbStride * y); + const float* pfltSrcPixel = (float*)piDstPixel; + + for (x = 0; x < iWidthX4; x++) + piDstPixel[x] = (I16)(pfltSrcPixel[x] * fltCvtFactor + 0.5F); + } + + return WMP_errSuccess; +} + + + +ERR RGBE_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = iHeight - 1; y >= 0; y--) + { + I32 x; + float* pfltDstPixel = (float*)(pb + cbStride * y); + const U8* piSrcPixel = (U8*)pfltDstPixel; + + for (x = iWidth - 1; x >= 0; x--) + { + // First read the exponent + const U8 rawExp = piSrcPixel[4 * x + 3]; + + if (0 == rawExp) + { + pfltDstPixel[3 * x] = 0.0F; + pfltDstPixel[3 * x + 1] = 0.0F; + pfltDstPixel[3 * x + 2] = 0.0F; + } + else + { + const I32 adjExp = (I32)rawExp - 128 - 8; // Can be negative + float fltExp; + + if (adjExp > -32 && adjExp < 32) + { + fltExp = (float)(((U32)1) << abs(adjExp)); + if (adjExp < 0) + fltExp = 1.0F / fltExp; + } + else + { + fltExp = (float)ldexp(1.0F, adjExp); + } + + pfltDstPixel[3 * x] = piSrcPixel[4 * x] * fltExp; + pfltDstPixel[3 * x + 1] = piSrcPixel[4 * x + 1] * fltExp; + pfltDstPixel[3 * x + 2] = piSrcPixel[4 * x + 2] * fltExp; + } + } + } + + return WMP_errSuccess; +} + + +ERR RGB96Float_RGBE(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + assert(iWidth > 2); // Otherwise, we corrupt source data in inner loop + + // Stride is assumed to be same for src/dst + for (y = 0; y < iHeight; y++) + { + I32 x; + U8* piDstPixel = (U8*)(pb + cbStride * y); + const float* pfltSrcPixel = (float*)piDstPixel; + + for (x = 0; x < iWidth; x++) + { + // We clamp source RGB values at zero (don't allow negative numbers) + const float fltRed = max(pfltSrcPixel[3 * x], 0.0F); + const float fltGreen = max(pfltSrcPixel[3 * x + 1], 0.0F); + const float fltBlue = max(pfltSrcPixel[3 * x + 2], 0.0F); + float fltMaxPos = fltRed; + + if (fltGreen > fltMaxPos) + fltMaxPos = fltGreen; + + if (fltBlue > fltMaxPos) + fltMaxPos = fltBlue; + + if (fltMaxPos < 1e-32) + { + piDstPixel[4 * x] = 0; // R + piDstPixel[4 * x + 1] = 0; // G + piDstPixel[4 * x + 2] = 0; // B + piDstPixel[4 * x + 3] = 0; // E + } + else + { + int e; + const float fltScale = (float)frexp(fltMaxPos, &e) * 256 / fltMaxPos; + + // rounding SHOULD NOT be added - it has the potential to roll over to zero (and yes, 256 is the correct multiplier above) + piDstPixel[4 * x] = (U8)(fltRed * fltScale); // R + piDstPixel[4 * x + 1] = (U8)(fltGreen * fltScale); // G + piDstPixel[4 * x + 2] = (U8)(fltBlue * fltScale); // B + piDstPixel[4 * x + 3] = (U8)(e + 128); // E + } + } + } + + return WMP_errSuccess; +} + + +ERR RGBA64Half_RGBA128Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidthX4 = 4 * pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = iHeight - 1; y >= 0; y--) + { + I32 x; + U32* pfltDstPixel = (U32*)(pb + cbStride * y); // It's really float, but use U32 ptr + const I16* piSrcPixel = (I16*)pfltDstPixel; + + for (x = iWidthX4 - 1; x >= 0; x--) + pfltDstPixel[x] = Convert_Half_To_Float(piSrcPixel[x]); + } + + return WMP_errSuccess; +} + + +ERR RGBA128Float_RGBA64Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidthX4 = 4 * pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = 0; y < iHeight; y++) + { + I32 x; + I16* piDstPixel = (I16*)(pb + cbStride * y); + const float* pfltSrcPixel = (float*)piDstPixel; + + for (x = 0; x < iWidthX4; x++) + piDstPixel[x] = Convert_Float_To_Half(pfltSrcPixel[x]); + } + + return WMP_errSuccess; +} + + +ERR RGB64Half_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = iHeight - 1; y >= 0; y--) + { + I32 x; + U32* pfltDstPixel = (U32*)(pb + cbStride * y); // It's really float, but use U32 ptr + const I16* piSrcPixel = (I16*)pfltDstPixel; + + for (x = iWidth - 1; x >= 0; x--) + { + pfltDstPixel[3 * x] = Convert_Half_To_Float(piSrcPixel[4 * x]); + pfltDstPixel[3 * x + 1] = Convert_Half_To_Float(piSrcPixel[4 * x + 1]); + pfltDstPixel[3 * x + 2] = Convert_Half_To_Float(piSrcPixel[4 * x + 2]); + } + } + + return WMP_errSuccess; +} + + +ERR RGB96Float_RGB64Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = 0; y < iHeight; y++) + { + I32 x; + I16* piDstPixel = (I16*)(pb + cbStride * y); + const float* pfltSrcPixel = (float*)piDstPixel; + + for (x = 0; x < iWidth; x++) + { + piDstPixel[4 * x] = Convert_Float_To_Half(pfltSrcPixel[3 * x]); + piDstPixel[4 * x + 1] = Convert_Float_To_Half(pfltSrcPixel[3 * x + 1]); + piDstPixel[4 * x + 2] = Convert_Float_To_Half(pfltSrcPixel[3 * x + 2]); + piDstPixel[4 * x + 3] = 0; // Zero out the alpha channel + } + } + + return WMP_errSuccess; +} + + +ERR RGB48Half_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidthX3 = 3 * pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = iHeight - 1; y >= 0; y--) + { + I32 x; + U32* pfltDstPixel = (U32*)(pb + cbStride * y); // It's really float, but use U32 ptr + const I16* piSrcPixel = (I16*)pfltDstPixel; + + for (x = iWidthX3 - 1; x >= 0; x--) + pfltDstPixel[x] = Convert_Half_To_Float(piSrcPixel[x]); + } + + return WMP_errSuccess; +} + + +ERR RGB96Float_RGB48Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidthX3 = 3 * pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = 0; y < iHeight; y++) + { + I32 x; + I16* piDstPixel = (I16*)(pb + cbStride * y); + const float* pfltSrcPixel = (float*)piDstPixel; + + for (x = 0; x < iWidthX3; x++) + piDstPixel[x] = Convert_Float_To_Half(pfltSrcPixel[x]); + } + + return WMP_errSuccess; +} + + +ERR Gray16Half_Gray32Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = iHeight - 1; y >= 0; y--) + { + I32 x; + U32* pfltDstPixel = (U32*)(pb + cbStride * y); // It's really float, but use U32 ptr + const I16* piSrcPixel = (I16*)pfltDstPixel; + + for (x = iWidth - 1; x >= 0; x--) + pfltDstPixel[x] = Convert_Half_To_Float(piSrcPixel[x]); + } + + return WMP_errSuccess; +} + + +ERR Gray32Float_Gray16Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = 0; y < iHeight; y++) + { + I32 x; + I16* piDstPixel = (I16*)(pb + cbStride * y); + const float* pfltSrcPixel = (float*)piDstPixel; + + for (x = 0; x < iWidth; x++) + piDstPixel[x] = Convert_Float_To_Half(pfltSrcPixel[x]); + } + + return WMP_errSuccess; +} + +ERR RGB555_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = iHeight - 1; y >= 0; y--) + { + I32 x; + U8* piDstPixel = (pb + cbStride * y); + const U16* piSrcPixel = (U16*)piDstPixel; + + for (x = iWidth - 1; x >= 0; x--) + { + const U16 v = piSrcPixel[x]; + const unsigned int r = ((v >> 10) & 0x1f); + const unsigned int g = ((v >> 5) & 0x1f); + const unsigned int b = (v & 0x1f); + + piDstPixel[3 * x] = (U8)(r << 3); // R + piDstPixel[3 * x + 1] = (U8)(g << 3); // G + piDstPixel[3 * x + 2] = (U8)(b << 3); // B + } + } + + return WMP_errSuccess; +} + + +ERR RGB101010_RGB48(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = iHeight - 1; y >= 0; y--) + { + I32 x; + U16* piDstPixel = (U16*)(pb + cbStride * y); + const U32* piSrcPixel = (U32*)piDstPixel; + + for (x = iWidth - 1; x >= 0; x--) + { + const U32 v = piSrcPixel[x]; + const unsigned int r = ((v >> 20) & 0x3FF); + const unsigned int g = ((v >> 10) & 0x3FF); + const unsigned int b = (v & 0x3FF); + + piDstPixel[3 * x] = (U16)(r << 6); // R + piDstPixel[3 * x + 1] = (U16)(g << 6); // G + piDstPixel[3 * x + 2] = (U16)(b << 6); // B + } + } + + return WMP_errSuccess; +} + + +ERR RGB24_RGB555(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = 0; y < iHeight; y++) + { + I32 x; + U16* piDstPixel = (U16*)(pb + cbStride * y); + const U8* piSrcPixel = (U8*)piDstPixel; + + for (x = 0; x < iWidth; x++) + { + const unsigned int r = piSrcPixel[3 * x]; + const unsigned int g = piSrcPixel[3 * x + 1]; + const unsigned int b = piSrcPixel[3 * x + 2]; + + piDstPixel[x] = (U16)( + ((r & 0xF8) << 7) | + ((g & 0xF8) << 2) | + (b >> 3)); + } + } + + return WMP_errSuccess; +} + + + +ERR RGB48_RGB101010(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = 0; y < iHeight; y++) + { + I32 x; + U32* piDstPixel = (U32*)(pb + cbStride * y); + const U16* piSrcPixel = (U16*)piDstPixel; + + for (x = 0; x < iWidth; x++) + { + const unsigned int r = piSrcPixel[3 * x]; + const unsigned int g = piSrcPixel[3 * x + 1]; + const unsigned int b = piSrcPixel[3 * x + 2]; + + piDstPixel[x] = (3 << 30) | // For compatibility with D3D's 2-10-10-10 format. + ((r & 0x0000FFC0) << 14) | + ((g & 0x0000FFC0) << 4) | + (b >> 6); + } + } + + return WMP_errSuccess; +} + + + +ERR RGB565_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = iHeight - 1; y >= 0; y--) + { + I32 x; + U8* piDstPixel = (pb + cbStride * y); + const U16* piSrcPixel = (U16*)piDstPixel; + + for (x = iWidth - 1; x >= 0; x--) + { + const U16 v = piSrcPixel[x]; + const unsigned int r = ((v >> 11) & 0x1f); + const unsigned int g = ((v >> 5) & 0x3f); + const unsigned int b = (v & 0x1f); + + piDstPixel[3 * x] = (U8)(r << 3); // R + piDstPixel[3 * x + 1] = (U8)(g << 2); // G + piDstPixel[3 * x + 2] = (U8)(b << 3); // B + } + } + + return WMP_errSuccess; +} + + + +ERR RGB24_RGB565(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = 0; y < iHeight; y++) + { + I32 x; + U16* piDstPixel = (U16*)(pb + cbStride * y); + const U8* piSrcPixel = (U8*)piDstPixel; + + for (x = 0; x < iWidth; x++) + { + const unsigned int r = piSrcPixel[3 * x]; + const unsigned int g = piSrcPixel[3 * x + 1]; + const unsigned int b = piSrcPixel[3 * x + 2]; + + piDstPixel[x] = (U16)( + ((r & 0xF8) << 8) | + ((g & 0xFC) << 3) | + (b >> 3)); + } + } + + return WMP_errSuccess; +} + + +ERR RGBA32_BGRA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidthX4 = 4 * pRect->Width; // 4 == R, G, B, A + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + for (y = 0; y < iHeight; y++) + { + I32 x; + U8* piPixel = (U8*)(pb + cbStride * y); + + for (x = 0; x < iWidthX4; x += 4) + { + // Swap R and B + U8 bTemp = piPixel[x]; + piPixel[x] = piPixel[x + 2]; + piPixel[x + 2] = bTemp; + } + } + + return WMP_errSuccess; +} + + +ERR BGRA32_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + return RGBA32_BGRA32(pFC, pRect, pb, cbStride); +} + + +ERR BlackWhite_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + Bool bBlackWhite = pFC->pDecoder->WMP.wmiSCP.bBlackWhite; + I32 y; + + // Stride is assumed to be same for src/dst + for (y = iHeight - 1; y >= 0; y--) + { + I32 x; + I32 n; + U8* piDstPixel = (pb + cbStride * y); + const U8* piSrcPixel = (U8*)piDstPixel; + + if (iWidth % 8 != 0) + { + const U8 v = piSrcPixel[iWidth / 8]; + + for (n = 0; n < iWidth % 8; n++) + { + piDstPixel[iWidth / 8 * 8 + n] = (((v >> (7 - n)) & 0x1) != 0) ^ bBlackWhite ? 0xFF : 0x00; + } + } + + for (x = iWidth / 8 - 1; x >= 0; x--) + { + const U8 v = piSrcPixel[x]; + + for (n = 0; n < 8; n++) + { + piDstPixel[8 * x + n] = (((v >> (7 - n)) & 0x1) != 0) ^ bBlackWhite ? 0xFF : 0x00; + } + } + } + + return WMP_errSuccess; +} + + +ERR Gray16_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + I32 i = 0, j = 0; + + UNREFERENCED_PARAMETER(pFC); + + for (i = 0; i < pRect->Height; ++i) + { + for (j = 0; j < pRect->Width; ++j) + { + U16 v = ((U16*)pb)[j]; + + pb[j] = v >> 8; + } + + pb += cbStride; + } + + return WMP_errSuccess; +} + +ERR RGB48_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = 0; y < iHeight; y++) + { + I32 x; + U8* piDstPixel = (U8*)(pb + cbStride * y); + const U16* piSrcPixel = (U16*)piDstPixel; + + for (x = 0; x < iWidth; x++) + { + const U16 r = piSrcPixel[3 * x]; + const U16 g = piSrcPixel[3 * x + 1]; + const U16 b = piSrcPixel[3 * x + 2]; + + piDstPixel[3 * x] = r >> 8; + piDstPixel[3 * x + 1] = g >> 8; + piDstPixel[3 * x + 2] = b >> 8; + } + } + + return WMP_errSuccess; +} + +ERR RGBA64_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = 0; y < iHeight; y++) + { + I32 x; + U8* piDstPixel = (U8*)(pb + cbStride * y); + const U16* piSrcPixel = (U16*)piDstPixel; + + for (x = 0; x < iWidth; x++) + { + const U16 r = piSrcPixel[4 * x]; + const U16 g = piSrcPixel[4 * x + 1]; + const U16 b = piSrcPixel[4 * x + 2]; + const U16 a = piSrcPixel[4 * x + 3]; + + piDstPixel[4 * x] = r >> 8; + piDstPixel[4 * x + 1] = g >> 8; + piDstPixel[4 * x + 2] = b >> 8; + piDstPixel[4 * x + 3] = a >> 8; + } + } + + return WMP_errSuccess; +} + +ERR Gray32Float_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = 0; y < iHeight; y++) + { + I32 x; + U8* piDstPixel = (U8*)(pb + cbStride * y); + const float* piSrcPixel = (float*)piDstPixel; + + for (x = 0; x < iWidth; x++) + { + const float v = piSrcPixel[x]; + + piDstPixel[x] = Convert_Float_To_U8(v); + } + } + + return WMP_errSuccess; +} + +ERR RGB96Float_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = 0; y < iHeight; y++) + { + I32 x; + U8* piDstPixel = (U8*)(pb + cbStride * y); + const float* piSrcPixel = (float*)piDstPixel; + + for (x = 0; x < iWidth; x++) + { + const float r = piSrcPixel[3 * x]; + const float g = piSrcPixel[3 * x + 1]; + const float b = piSrcPixel[3 * x + 2]; + + piDstPixel[3 * x] = Convert_Float_To_U8(r); + piDstPixel[3 * x + 1] = Convert_Float_To_U8(g); + piDstPixel[3 * x + 2] = Convert_Float_To_U8(b); + } + } + + return WMP_errSuccess; +} + +ERR RGB128Float_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = 0; y < iHeight; y++) + { + I32 x; + U8* piDstPixel = (U8*)(pb + cbStride * y); + const float* piSrcPixel = (float*)piDstPixel; + + for (x = 0; x < iWidth; x++) + { + const float r = piSrcPixel[4 * x]; + const float g = piSrcPixel[4 * x + 1]; + const float b = piSrcPixel[4 * x + 2]; + + piDstPixel[3 * x] = Convert_Float_To_U8(r); + piDstPixel[3 * x + 1] = Convert_Float_To_U8(g); + piDstPixel[3 * x + 2] = Convert_Float_To_U8(b); + } + } + + return WMP_errSuccess; +} + +ERR RGBA128Float_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = 0; y < iHeight; y++) + { + I32 x; + U8* piDstPixel = (U8*)(pb + cbStride * y); + const float* piSrcPixel = (float*)piDstPixel; + + for (x = 0; x < iWidth; x++) + { + const float r = piSrcPixel[4 * x]; + const float g = piSrcPixel[4 * x + 1]; + const float b = piSrcPixel[4 * x + 2]; + const float a = piSrcPixel[4 * x + 3]; + + piDstPixel[4 * x] = Convert_Float_To_U8(r); + piDstPixel[4 * x + 1] = Convert_Float_To_U8(g); + piDstPixel[4 * x + 2] = Convert_Float_To_U8(b); + piDstPixel[4 * x + 3] = Convert_AlphaFloat_To_U8(a); + } + } + + return WMP_errSuccess; +} + +ERR Gray16Fixed_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + const float fltCvtFactor = 1.0F / (1 << 13); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = 0; y < iHeight; y++) + { + I32 x; + U8* piDstPixel = (U8*)(pb + cbStride * y); + const I16* piSrcPixel = (I16*)piDstPixel; + + for (x = 0; x < iWidth; x++) + { + piDstPixel[x] = Convert_Float_To_U8(piSrcPixel[x] * fltCvtFactor); + } + } + + return WMP_errSuccess; +} + +ERR Gray32Fixed_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + const float fltCvtFactor = 1.0F / (1 << 24); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = 0; y < iHeight; y++) + { + I32 x; + U8* piDstPixel = (U8*)(pb + cbStride * y); + const I32* piSrcPixel = (I32*)piDstPixel; + + for (x = 0; x < iWidth; x++) + { + piDstPixel[x] = Convert_Float_To_U8(piSrcPixel[x] * fltCvtFactor); + } + } + + return WMP_errSuccess; +} + +ERR RGB48Fixed_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + const float fltCvtFactor = 1.0F / (1 << 13); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + for (y = 0; y < iHeight; y++) + { + I32 x; + U8* pfltDstPixel = (U8*)(pb + cbStride * y); + const I16* piSrcPixel = (I16*)pfltDstPixel; + + for (x = 0; x < iWidth; x++) + { + pfltDstPixel[3 * x] = Convert_Float_To_U8(piSrcPixel[3 * x] * fltCvtFactor); + pfltDstPixel[3 * x + 1] = Convert_Float_To_U8(piSrcPixel[3 * x + 1] * fltCvtFactor); + pfltDstPixel[3 * x + 2] = Convert_Float_To_U8(piSrcPixel[3 * x + 2] * fltCvtFactor); + } + } + + return WMP_errSuccess; +} + +ERR RGB64Fixed_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + const float fltCvtFactor = 1.0F / (1 << 13); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + for (y = 0; y < iHeight; y++) + { + I32 x; + U8* pfltDstPixel = (U8*)(pb + cbStride * y); + const I16* piSrcPixel = (I16*)pfltDstPixel; + + for (x = 0; x < iWidth; x++) + { + pfltDstPixel[3 * x] = Convert_Float_To_U8(piSrcPixel[4 * x] * fltCvtFactor); + pfltDstPixel[3 * x + 1] = Convert_Float_To_U8(piSrcPixel[4 * x + 1] * fltCvtFactor); + pfltDstPixel[3 * x + 2] = Convert_Float_To_U8(piSrcPixel[4 * x + 2] * fltCvtFactor); + } + } + + return WMP_errSuccess; +} + +ERR RGB96Fixed_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + const float fltCvtFactor = 1.0F / (1 << 24); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + for (y = 0; y < iHeight; y++) + { + I32 x; + U8* pfltDstPixel = (U8*)(pb + cbStride * y); + const I32* piSrcPixel = (I32*)pfltDstPixel; + + for (x = 0; x < iWidth; x++) + { + pfltDstPixel[3 * x] = Convert_Float_To_U8(piSrcPixel[3 * x] * fltCvtFactor); + pfltDstPixel[3 * x + 1] = Convert_Float_To_U8(piSrcPixel[3 * x + 1] * fltCvtFactor); + pfltDstPixel[3 * x + 2] = Convert_Float_To_U8(piSrcPixel[3 * x + 2] * fltCvtFactor); + } + } + + return WMP_errSuccess; +} + +ERR RGB128Fixed_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + const float fltCvtFactor = 1.0F / (1 << 24); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + for (y = 0; y < iHeight; y++) + { + I32 x; + U8* pfltDstPixel = (U8*)(pb + cbStride * y); + const I32* piSrcPixel = (I32*)pfltDstPixel; + + for (x = 0; x < iWidth; x++) + { + pfltDstPixel[3 * x] = Convert_Float_To_U8(piSrcPixel[4 * x] * fltCvtFactor); + pfltDstPixel[3 * x + 1] = Convert_Float_To_U8(piSrcPixel[4 * x + 1] * fltCvtFactor); + pfltDstPixel[3 * x + 2] = Convert_Float_To_U8(piSrcPixel[4 * x + 2] * fltCvtFactor); + } + } + + return WMP_errSuccess; +} + +ERR RGBA64Fixed_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + const float fltCvtFactor = 1.0F / (1 << 13); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + for (y = 0; y < iHeight; y++) + { + I32 x; + U8* pfltDstPixel = (U8*)(pb + cbStride * y); + const I16* piSrcPixel = (I16*)pfltDstPixel; + + for (x = 0; x < iWidth; x++) + { + pfltDstPixel[4 * x] = Convert_Float_To_U8(piSrcPixel[4 * x] * fltCvtFactor); + pfltDstPixel[4 * x + 1] = Convert_Float_To_U8(piSrcPixel[4 * x + 1] * fltCvtFactor); + pfltDstPixel[4 * x + 2] = Convert_Float_To_U8(piSrcPixel[4 * x + 2] * fltCvtFactor); + pfltDstPixel[4 * x + 3] = Convert_AlphaFloat_To_U8(piSrcPixel[4 * x + 3] * fltCvtFactor); + } + } + + return WMP_errSuccess; +} + +ERR RGBA128Fixed_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + const float fltCvtFactor = 1.0F / (1 << 24); + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + for (y = 0; y < iHeight; y++) + { + I32 x; + U8* pfltDstPixel = (U8*)(pb + cbStride * y); + const I32* piSrcPixel = (I32*)pfltDstPixel; + + for (x = 0; x < iWidth; x++) + { + pfltDstPixel[4 * x] = Convert_Float_To_U8(piSrcPixel[4 * x] * fltCvtFactor); + pfltDstPixel[4 * x + 1] = Convert_Float_To_U8(piSrcPixel[4 * x + 1] * fltCvtFactor); + pfltDstPixel[4 * x + 2] = Convert_Float_To_U8(piSrcPixel[4 * x + 2] * fltCvtFactor); + pfltDstPixel[4 * x + 3] = Convert_AlphaFloat_To_U8(piSrcPixel[4 * x + 3] * fltCvtFactor); + } + } + + return WMP_errSuccess; +} + +ERR Gray16Half_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = 0; y < iHeight; y++) + { + I32 x; + U8* piDstPixel = (U8*)(pb + cbStride * y); + const U16* piSrcPixel = (U16*)piDstPixel; + + for (x = 0; x < iWidth; x++) + { + const U32 v = Convert_Half_To_Float(piSrcPixel[x]); + + piDstPixel[x] = Convert_Float_To_U8(*(float*)&v); + } + } + + return WMP_errSuccess; +} + +ERR RGB48Half_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + for (y = 0; y < iHeight; y++) + { + I32 x; + U8* pfltDstPixel = (U8*)(pb + cbStride * y); + const U16* piSrcPixel = (U16*)pfltDstPixel; + + for (x = 0; x < iWidth; x++) + { + const U32 r = Convert_Half_To_Float(piSrcPixel[3 * x]); + const U32 g = Convert_Half_To_Float(piSrcPixel[3 * x + 1]); + const U32 b = Convert_Half_To_Float(piSrcPixel[3 * x + 2]); + + pfltDstPixel[3 * x] = Convert_Float_To_U8(*(float*)&r); + pfltDstPixel[3 * x + 1] = Convert_Float_To_U8(*(float*)&g); + pfltDstPixel[3 * x + 2] = Convert_Float_To_U8(*(float*)&b); + } + } + + return WMP_errSuccess; +} + +ERR RGB64Half_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + for (y = 0; y < iHeight; y++) + { + I32 x; + U8* pfltDstPixel = (U8*)(pb + cbStride * y); + const U16* piSrcPixel = (U16*)pfltDstPixel; + + for (x = 0; x < iWidth; x++) + { + const U32 r = Convert_Half_To_Float(piSrcPixel[4 * x]); + const U32 g = Convert_Half_To_Float(piSrcPixel[4 * x + 1]); + const U32 b = Convert_Half_To_Float(piSrcPixel[4 * x + 2]); + + pfltDstPixel[3 * x] = Convert_Float_To_U8(*(float*)&r); + pfltDstPixel[3 * x + 1] = Convert_Float_To_U8(*(float*)&g); + pfltDstPixel[3 * x + 2] = Convert_Float_To_U8(*(float*)&b); + } + } + + return WMP_errSuccess; +} + +ERR RGBA64Half_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + for (y = 0; y < iHeight; y++) + { + I32 x; + U8* pfltDstPixel = (U8*)(pb + cbStride * y); + const U16* piSrcPixel = (U16*)pfltDstPixel; + + for (x = 0; x < iWidth; x++) + { + const U32 r = Convert_Half_To_Float(piSrcPixel[4 * x]); + const U32 g = Convert_Half_To_Float(piSrcPixel[4 * x + 1]); + const U32 b = Convert_Half_To_Float(piSrcPixel[4 * x + 2]); + const U32 a = Convert_Half_To_Float(piSrcPixel[4 * x + 3]); + + pfltDstPixel[4 * x] = Convert_Float_To_U8(*(float*)&r); + pfltDstPixel[4 * x + 1] = Convert_Float_To_U8(*(float*)&g); + pfltDstPixel[4 * x + 2] = Convert_Float_To_U8(*(float*)&b); + pfltDstPixel[4 * x + 3] = Convert_AlphaFloat_To_U8(*(float*)&a); + } + } + + return WMP_errSuccess; +} + +ERR RGB101010_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + const I32 iHeight = pRect->Height; + const I32 iWidth = pRect->Width; + I32 y; + + UNREFERENCED_PARAMETER(pFC); + + // Stride is assumed to be same for src/dst + for (y = 0; y < iHeight; y++) + { + I32 x; + U8* piDstPixel = (U8*)(pb + cbStride * y); + const U32* piSrcPixel = (U32*)piDstPixel; + + for (x = 0; x < iWidth; x++) + { + const U32 v = piSrcPixel[x]; + const unsigned int r = ((v >> 20) & 0x3FF); + const unsigned int g = ((v >> 10) & 0x3FF); + const unsigned int b = (v & 0x3FF); + + piDstPixel[3 * x] = (U8)(r >> 2); + piDstPixel[3 * x + 1] = (U8)(g >> 2); + piDstPixel[3 * x + 2] = (U8)(b >> 2); + } + } + + return WMP_errSuccess; +} + +ERR RGBE_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + I32 i = 0, j = 0; + + UNREFERENCED_PARAMETER(pFC); + + for (i = 0; i < pRect->Height; ++i) + { + for (j = 0; j < pRect->Width; j++) + { + // First read the exponent + const U8 rawExp = pb[4 * j + 3]; + + if (0 == rawExp) + { + pb[3 * j] = 0; + pb[3 * j + 1] = 0; + pb[3 * j + 2] = 0; + } + else + { + const I32 adjExp = (I32)rawExp - 128 - 8; // Can be negative + float fltExp; + + if (adjExp > -32 && adjExp < 32) + { + fltExp = (float)(((U32)1) << abs(adjExp)); + if (adjExp < 0) + fltExp = 1.0F / fltExp; + } + else + { + fltExp = (float)ldexp(1.0F, adjExp); + } + + pb[3 * j] = Convert_Float_To_U8(pb[4 * j] * fltExp); + pb[3 * j + 1] = Convert_Float_To_U8(pb[4 * j + 1] * fltExp); + pb[3 * j + 2] = Convert_Float_To_U8(pb[4 * j + 2] * fltExp); + } + } + + pb += cbStride; + } + + return WMP_errSuccess; +} + +//================================================================ +typedef struct tagPKPixelConverterInfo +{ + const PKPixelFormatGUID* pGUIDPixFmtFrom; + const PKPixelFormatGUID* pGUIDPixFmtTo; + + ERR(*Convert)(PKFormatConverter*, const PKRect*, U8*, U32); +} PKPixelConverterInfo; + +static PKPixelConverterInfo s_pcInfo[] = { + {&GUID_PKPixelFormat24bppRGB, &GUID_PKPixelFormat24bppBGR, RGB24_BGR24}, // Fwd + {&GUID_PKPixelFormat24bppBGR, &GUID_PKPixelFormat24bppRGB, BGR24_RGB24}, // Rev + {&GUID_PKPixelFormat24bppRGB, &GUID_PKPixelFormat32bppBGR, RGB24_BGR32}, // Fwd + {&GUID_PKPixelFormat32bppBGR, &GUID_PKPixelFormat24bppRGB, BGR32_RGB24}, // Rev + + // The following are not to be exposed when building the Adobe Photoshop plugin +#ifndef ADOBE_PS_PLUGIN + {&GUID_PKPixelFormat24bppRGB, &GUID_PKPixelFormat8bppGray, RGB24_Gray8}, // Fwd + {&GUID_PKPixelFormat8bppGray, &GUID_PKPixelFormat24bppRGB, Gray8_RGB24}, // Rev + {&GUID_PKPixelFormat24bppBGR, &GUID_PKPixelFormat8bppGray, BGR24_Gray8}, // Fwd + {&GUID_PKPixelFormat8bppGray, &GUID_PKPixelFormat24bppBGR, Gray8_BGR24}, // Rev +#endif // ADOBE_PS_PLUGIN + + {&GUID_PKPixelFormat128bppRGBAFixedPoint, &GUID_PKPixelFormat128bppRGBAFloat, RGBA128Fixed_RGBA128Float}, // Fwd + {&GUID_PKPixelFormat128bppRGBAFloat, &GUID_PKPixelFormat128bppRGBAFixedPoint, RGBA128Float_RGBA128Fixed}, // Rev + {&GUID_PKPixelFormat96bppRGBFixedPoint, &GUID_PKPixelFormat96bppRGBFloat, RGB96Fixed_RGB96Float}, // Fwd + {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat96bppRGBFixedPoint, RGB96Float_RGB96Fixed}, // Rev + {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat128bppRGBFloat, RGB96Float_RGB128Float}, // Fwd + {&GUID_PKPixelFormat128bppRGBFloat, &GUID_PKPixelFormat96bppRGBFloat, RGB128Float_RGB96Float}, // Rev + {&GUID_PKPixelFormat96bppRGBFixedPoint, &GUID_PKPixelFormat128bppRGBFixedPoint, RGB96Float_RGB128Float}, // Fwd + {&GUID_PKPixelFormat128bppRGBFixedPoint, &GUID_PKPixelFormat96bppRGBFixedPoint, RGB128Float_RGB96Float}, // Rev + {&GUID_PKPixelFormat64bppRGBHalf, &GUID_PKPixelFormat48bppRGBHalf, RGB64Half_RGB48Half}, // Fwd + {&GUID_PKPixelFormat48bppRGBHalf, &GUID_PKPixelFormat64bppRGBHalf, RGB48Half_RGB64Half}, // Rev + {&GUID_PKPixelFormat64bppRGBFixedPoint, &GUID_PKPixelFormat48bppRGBFixedPoint, RGB64Half_RGB48Half}, // Fwd + {&GUID_PKPixelFormat48bppRGBFixedPoint, &GUID_PKPixelFormat64bppRGBFixedPoint, RGB48Half_RGB64Half}, // Rev + {&GUID_PKPixelFormat32bppBGR, &GUID_PKPixelFormat24bppBGR, BGR32_BGR24}, // Fwd + {&GUID_PKPixelFormat24bppBGR, &GUID_PKPixelFormat32bppBGR, BGR24_BGR32}, // Rev + {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat128bppRGBFixedPoint, RGB96Float_RGB128Fixed}, // Fwd + {&GUID_PKPixelFormat128bppRGBFixedPoint, &GUID_PKPixelFormat96bppRGBFloat, RGB128Fixed_RGB96Float}, // Rev + {&GUID_PKPixelFormat32bppGrayFixedPoint, &GUID_PKPixelFormat32bppGrayFloat, Gray32Fixed_Gray32Float}, // Fwd + {&GUID_PKPixelFormat32bppGrayFloat, &GUID_PKPixelFormat32bppGrayFixedPoint, Gray32Float_Gray32Fixed}, // Rev + {&GUID_PKPixelFormat16bppGrayFixedPoint, &GUID_PKPixelFormat32bppGrayFloat, Gray16Fixed_Gray32Float}, // Fwd + {&GUID_PKPixelFormat32bppGrayFloat, &GUID_PKPixelFormat16bppGrayFixedPoint, Gray32Float_Gray16Fixed}, // Rev + {&GUID_PKPixelFormat48bppRGBFixedPoint, &GUID_PKPixelFormat96bppRGBFloat, RGB48Fixed_RGB96Float}, // Fwd + {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat48bppRGBFixedPoint, RGB96Float_RGB48Fixed}, // Rev + {&GUID_PKPixelFormat64bppRGBFixedPoint, &GUID_PKPixelFormat96bppRGBFloat, RGB64Fixed_RGB96Float}, // Fwd + {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat64bppRGBFixedPoint, RGB96Float_RGB64Fixed}, // Rev + {&GUID_PKPixelFormat64bppRGBAFixedPoint, &GUID_PKPixelFormat128bppRGBAFloat, RGBA64Fixed_RGBA128Float}, // Fwd + {&GUID_PKPixelFormat128bppRGBAFloat, &GUID_PKPixelFormat64bppRGBAFixedPoint, RGBA128Float_RGBA64Fixed}, // Rev + {&GUID_PKPixelFormat32bppRGBE, &GUID_PKPixelFormat96bppRGBFloat, RGBE_RGB96Float}, // Fwd + {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat32bppRGBE, RGB96Float_RGBE}, // Rev + {&GUID_PKPixelFormat64bppRGBAHalf, &GUID_PKPixelFormat128bppRGBAFloat, RGBA64Half_RGBA128Float}, // Fwd + {&GUID_PKPixelFormat128bppRGBAFloat, &GUID_PKPixelFormat64bppRGBAHalf, RGBA128Float_RGBA64Half}, // Rev + {&GUID_PKPixelFormat64bppRGBHalf, &GUID_PKPixelFormat96bppRGBFloat, RGB64Half_RGB96Float}, // Fwd + {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat64bppRGBHalf, RGB96Float_RGB64Half}, // Rev + {&GUID_PKPixelFormat48bppRGBHalf, &GUID_PKPixelFormat96bppRGBFloat, RGB48Half_RGB96Float}, // Fwd + {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat48bppRGBHalf, RGB96Float_RGB48Half}, // Rev + {&GUID_PKPixelFormat16bppGrayHalf, &GUID_PKPixelFormat32bppGrayFloat, Gray16Half_Gray32Float}, // Fwd + {&GUID_PKPixelFormat32bppGrayFloat, &GUID_PKPixelFormat16bppGrayHalf, Gray32Float_Gray16Half}, // Rev + {&GUID_PKPixelFormat16bppRGB555, &GUID_PKPixelFormat24bppRGB, RGB555_RGB24}, // Fwd + {&GUID_PKPixelFormat24bppRGB, &GUID_PKPixelFormat16bppRGB555, RGB24_RGB555}, // Rev + {&GUID_PKPixelFormat16bppRGB565, &GUID_PKPixelFormat24bppRGB, RGB565_RGB24}, // Fwd + {&GUID_PKPixelFormat24bppRGB, &GUID_PKPixelFormat16bppRGB565, RGB24_RGB565}, // Rev + {&GUID_PKPixelFormat32bppRGB101010, &GUID_PKPixelFormat48bppRGB, RGB101010_RGB48}, // Fwd + {&GUID_PKPixelFormat48bppRGB, &GUID_PKPixelFormat32bppRGB101010, RGB48_RGB101010}, // Rev + {&GUID_PKPixelFormat32bppRGBA, &GUID_PKPixelFormat32bppBGRA, RGBA32_BGRA32}, // Fwd + {&GUID_PKPixelFormat32bppBGRA, &GUID_PKPixelFormat32bppRGBA, BGRA32_RGBA32}, // Rev + {&GUID_PKPixelFormat32bppPRGBA, &GUID_PKPixelFormat32bppPBGRA, RGBA32_BGRA32}, // Fwd + {&GUID_PKPixelFormat32bppPBGRA, &GUID_PKPixelFormat32bppPRGBA, BGRA32_RGBA32}, // Rev + + // conversions to 8bppGray / 24bppRGB / 32bppRGBA + {&GUID_PKPixelFormatBlackWhite, &GUID_PKPixelFormat8bppGray, BlackWhite_Gray8}, + {&GUID_PKPixelFormat16bppGray, &GUID_PKPixelFormat8bppGray, Gray16_Gray8}, + {&GUID_PKPixelFormat48bppRGB, &GUID_PKPixelFormat24bppRGB, RGB48_RGB24}, + {&GUID_PKPixelFormat64bppRGBA, &GUID_PKPixelFormat32bppRGBA, RGBA64_RGBA32}, + {&GUID_PKPixelFormat32bppGrayFloat, &GUID_PKPixelFormat8bppGray, Gray32Float_Gray8}, + {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat24bppRGB, RGB96Float_RGB24}, + {&GUID_PKPixelFormat128bppRGBFloat, &GUID_PKPixelFormat24bppRGB, RGB128Float_RGB24}, + {&GUID_PKPixelFormat128bppRGBAFloat, &GUID_PKPixelFormat32bppRGBA, RGBA128Float_RGBA32}, + {&GUID_PKPixelFormat16bppGrayFixedPoint, &GUID_PKPixelFormat8bppGray, Gray16Fixed_Gray8}, + {&GUID_PKPixelFormat32bppGrayFixedPoint, &GUID_PKPixelFormat8bppGray, Gray32Fixed_Gray8}, + {&GUID_PKPixelFormat48bppRGBFixedPoint, &GUID_PKPixelFormat24bppRGB, RGB48Fixed_RGB24}, + {&GUID_PKPixelFormat64bppRGBFixedPoint, &GUID_PKPixelFormat24bppRGB, RGB64Fixed_RGB24}, + {&GUID_PKPixelFormat96bppRGBFixedPoint, &GUID_PKPixelFormat24bppRGB, RGB96Fixed_RGB24}, + {&GUID_PKPixelFormat128bppRGBFixedPoint, &GUID_PKPixelFormat24bppRGB, RGB128Fixed_RGB24}, + {&GUID_PKPixelFormat64bppRGBAFixedPoint, &GUID_PKPixelFormat32bppRGBA, RGBA64Fixed_RGBA32}, + {&GUID_PKPixelFormat128bppRGBAFixedPoint, &GUID_PKPixelFormat32bppRGBA, RGBA128Fixed_RGBA32}, + {&GUID_PKPixelFormat16bppGrayHalf, &GUID_PKPixelFormat8bppGray, Gray16Half_Gray8}, + {&GUID_PKPixelFormat48bppRGBHalf, &GUID_PKPixelFormat24bppRGB, RGB48Half_RGB24}, + {&GUID_PKPixelFormat64bppRGBHalf, &GUID_PKPixelFormat24bppRGB, RGB64Half_RGB24}, + {&GUID_PKPixelFormat64bppRGBAHalf, &GUID_PKPixelFormat32bppRGBA, RGBA64Half_RGBA32}, + {&GUID_PKPixelFormat32bppRGB101010, &GUID_PKPixelFormat24bppRGB, RGB101010_RGB24}, + {&GUID_PKPixelFormat32bppRGBE, &GUID_PKPixelFormat24bppRGB, RGBE_RGB24} +}; + +/* auxiliary data structure and hack to support valid encoding from/to configurations that +// don't actually require any color conversion. This is a conservative approach, where we +// include as few formats as necessary to encode situations that we're currently aware of. +*/ +typedef struct tagPKPixelConverter2Info +{ + const PKPixelFormatGUID* pGUIDPixFmtFrom; + const PKPixelFormatGUID* pGUIDPixFmtTo; + +} PKPixelConverter2Info; + +static PKPixelConverter2Info s_pcInfo2[] = { + // This allows us to view an RGBA input file as RGB, for when we create a planar alpha file + {&GUID_PKPixelFormat128bppRGBFloat, &GUID_PKPixelFormat128bppRGBAFloat}, + // 16- and 32-bpp RGB input files are given the "DontCare" GUID, so the next three + // from/to combinations are ok, and allowed on encoding: + {&GUID_PKPixelFormatDontCare, &GUID_PKPixelFormat16bppRGB555}, + {&GUID_PKPixelFormatDontCare, &GUID_PKPixelFormat16bppRGB565}, + {&GUID_PKPixelFormatDontCare, &GUID_PKPixelFormat32bppBGRA} +}; + +ERR PKFormatConverter_Initialize(PKFormatConverter* pFC, PKImageDecode* pID, char* pExt, PKPixelFormatGUID enPF) +{ + ERR err; + PKPixelFormatGUID enPFFrom; + + Call(pID->GetPixelFormat(pID, &enPFFrom)); + Call(PKFormatConverter_InitializeConvert(pFC, enPFFrom, pExt, enPF)); + + pFC->pDecoder = pID; + +Cleanup: + return err; +} + + +extern int PKStrnicmp(const char* s1, const char* s2, size_t c); + +ERR PKFormatConverter_InitializeConvert(PKFormatConverter* pFC, const PKPixelFormatGUID enPFFrom, + char* pExt, PKPixelFormatGUID enPFTo) +{ + ERR err = WMP_errSuccess; + + //================================ + pFC->enPixelFormat = enPFTo; + + if (pExt != NULL && IsEqualGUID(&enPFTo, &GUID_PKPixelFormat24bppRGB) && + 0 == PKStrnicmp(pExt, ".bmp", strlen(pExt))) + enPFTo = GUID_PKPixelFormat24bppBGR; + if (pExt != NULL && (0 == PKStrnicmp(pExt, ".tif", strlen(pExt)) || 0 == PKStrnicmp(pExt, ".tiff", strlen(pExt)))) + { + if (IsEqualGUID(&enPFTo, &GUID_PKPixelFormat32bppBGRA)) + enPFTo = GUID_PKPixelFormat32bppRGBA; + if (IsEqualGUID(&enPFTo, &GUID_PKPixelFormat32bppPBGRA)) + enPFTo = GUID_PKPixelFormat32bppPRGBA; + } + + //================================ + if (!IsEqualGUID(&enPFFrom, &enPFTo)) + { + size_t i = 0; + for (i = 0; i < sizeof2(s_pcInfo); ++i) + { + PKPixelConverterInfo* pPCI = s_pcInfo + i; + + if (IsEqualGUID(&enPFFrom, pPCI->pGUIDPixFmtFrom) && IsEqualGUID(&enPFTo, pPCI->pGUIDPixFmtTo)) + { + pFC->Convert = pPCI->Convert; + goto Cleanup; + } + } + // Bugfix to allow legitimate encoding from/to combinations that don't actually + // involve color conversions. + for (i = 0; i < sizeof2(s_pcInfo2); ++i) + { + PKPixelConverter2Info* pPCI = s_pcInfo2 + i; + + if (IsEqualGUID(&enPFFrom, pPCI->pGUIDPixFmtFrom) && IsEqualGUID(&enPFTo, pPCI->pGUIDPixFmtTo)) + { + goto Cleanup; + } + } + // If we failed the original check, and this bugfix check, then exit with error + Call(WMP_errUnsupportedFormat); + } + +Cleanup: + return err; +} + +ERR PKFormatConverter_EnumConversions(const PKPixelFormatGUID* pguidSourcePF, + const U32 iIndex, + const PKPixelFormatGUID** ppguidTargetPF) +{ + U32 iCurrIdx = 0; + U32 i; + ERR errResult = WMP_errIndexNotFound; + + *ppguidTargetPF = &GUID_PKPixelFormatDontCare; // Init return value + for (i = 0; i < sizeof2(s_pcInfo); i++) + { + if (IsEqualGUID(s_pcInfo[i].pGUIDPixFmtFrom, pguidSourcePF)) + { + if (iCurrIdx == iIndex) + { + // Found our target + errResult = WMP_errSuccess; + *ppguidTargetPF = s_pcInfo[i].pGUIDPixFmtTo; + break; + } + iCurrIdx += 1; + } + } + + return errResult; +} + +ERR PKFormatConverter_GetPixelFormat(PKFormatConverter* pFC, PKPixelFormatGUID* pPF) +{ + *pPF = pFC->enPixelFormat; + + return WMP_errSuccess; +} + +ERR PKFormatConverter_GetSourcePixelFormat(PKFormatConverter* pFC, PKPixelFormatGUID* pPF) +{ + return pFC->pDecoder->GetPixelFormat(pFC->pDecoder, pPF); +} + +ERR PKFormatConverter_GetSize(PKFormatConverter* pFC, I32* piWidth, I32* piHeight) +{ + return pFC->pDecoder->GetSize(pFC->pDecoder, piWidth, piHeight); +} + +ERR PKFormatConverter_GetResolution(PKFormatConverter* pFC, Float* pfrX, Float* pfrY) +{ + return pFC->pDecoder->GetResolution(pFC->pDecoder, pfrX, pfrY); +} + +ERR PKFormatConverter_Copy(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + ERR err = WMP_errSuccess; + + Call(pFC->pDecoder->Copy(pFC->pDecoder, pRect, pb, cbStride)); + Call(pFC->Convert(pFC, pRect, pb, cbStride)); + +Cleanup: + return err; +} + +ERR PKFormatConverter_Convert(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) +{ + UNREFERENCED_PARAMETER(pFC); + UNREFERENCED_PARAMETER(pRect); + UNREFERENCED_PARAMETER(pb); + UNREFERENCED_PARAMETER(cbStride); + + return WMP_errSuccess; +} + +ERR PKFormatConverter_Release(PKFormatConverter** ppFC) +{ + ERR err = WMP_errSuccess; + + Call(PKFree((void**)ppFC)); + +Cleanup: + return err; +} + From fb8df020af1322e67dd4d81a0ba6385425b7bb74 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Fri, 28 Jul 2023 12:38:13 +0200 Subject: [PATCH 05/98] cleanup unsused files --- Src/JxrDecode/CMakeLists.txt | 28 +- Src/JxrDecode/Jxr/JXRGlue.c | 964 ------ Src/JxrDecode/Jxr/JXRGlue.h | 659 ---- Src/JxrDecode/Jxr/JXRGlueJxr.c | 2284 -------------- Src/JxrDecode/Jxr/JXRGluePFC.c | 2338 -------------- Src/JxrDecode/Jxr/JXRMeta.c | 912 ------ Src/JxrDecode/Jxr/JXRMeta.h | 258 -- Src/JxrDecode/Jxr/JXRTest.c | 503 --- Src/JxrDecode/Jxr/JXRTest.h | 189 -- Src/JxrDecode/Jxr/JXRTestBmp.c | 404 --- Src/JxrDecode/Jxr/JXRTestHdr.c | 245 -- Src/JxrDecode/Jxr/JXRTestPnm.c | 336 -- Src/JxrDecode/Jxr/JXRTestTif.c | 940 ------ Src/JxrDecode/Jxr/JXRTestWrapper.c | 52 - Src/JxrDecode/Jxr/JXRTestWrapper.h | 30 - Src/JxrDecode/Jxr/JXRTestYUV.c | 722 ----- Src/JxrDecode/Jxr/JXRTranscode.c | 991 ------ Src/JxrDecode/Jxr/_x86/_x86.h | 58 - Src/JxrDecode/Jxr/adapthuff.c | 502 --- Src/JxrDecode/Jxr/ansi.h | 61 - Src/JxrDecode/Jxr/common.h | 131 - Src/JxrDecode/Jxr/decode.c | 200 -- Src/JxrDecode/Jxr/decode.h | 143 - Src/JxrDecode/Jxr/encode.c | 144 - Src/JxrDecode/Jxr/encode.h | 113 - Src/JxrDecode/Jxr/image.c | 182 -- Src/JxrDecode/Jxr/jxr_defines.h | 3 - Src/JxrDecode/Jxr/perfTimer.h | 117 - Src/JxrDecode/Jxr/perfTimerANSI.c | 276 -- Src/JxrDecode/Jxr/postprocess.c | 288 -- Src/JxrDecode/Jxr/priv_guiddef.h | 232 -- Src/JxrDecode/Jxr/segdec.c | 1227 -------- Src/JxrDecode/Jxr/segenc.c | 1186 ------- Src/JxrDecode/Jxr/strFwdTransform.c | 1111 ------- Src/JxrDecode/Jxr/strInvTransform.c | 1888 ----------- Src/JxrDecode/Jxr/strPredQuant.c | 306 -- Src/JxrDecode/Jxr/strPredQuantDec.c | 547 ---- Src/JxrDecode/Jxr/strPredQuantEnc.c | 511 --- Src/JxrDecode/Jxr/strTransform.c | 85 - Src/JxrDecode/Jxr/strTransform.h | 50 - Src/JxrDecode/Jxr/strcodec.c | 1293 -------- Src/JxrDecode/Jxr/strcodec.h | 678 ---- Src/JxrDecode/Jxr/strdec.c | 3628 ---------------------- Src/JxrDecode/Jxr/strdec_x86.c | 1641 ---------- Src/JxrDecode/Jxr/strenc.c | 2371 -------------- Src/JxrDecode/Jxr/strenc_x86.c | 409 --- Src/JxrDecode/Jxr/windowsmediaphoto.h | 515 --- Src/JxrDecode/Jxr/wmsal.h | 758 ----- Src/JxrDecode/Jxr/wmspecstring.h | 337 -- Src/JxrDecode/Jxr/wmspecstrings_adt.h | 72 - Src/JxrDecode/Jxr/wmspecstrings_strict.h | 1091 ------- Src/JxrDecode/Jxr/wmspecstrings_undef.h | 406 --- Src/JxrDecode/JxrDecode_Config.h.in | 13 + Src/JxrDecode/stdafx.cpp | 12 - Src/JxrDecode/stdafx.h | 18 - Src/JxrDecode/targetver.h | 14 - 56 files changed, 39 insertions(+), 34433 deletions(-) delete mode 100644 Src/JxrDecode/Jxr/JXRGlue.c delete mode 100644 Src/JxrDecode/Jxr/JXRGlue.h delete mode 100644 Src/JxrDecode/Jxr/JXRGlueJxr.c delete mode 100644 Src/JxrDecode/Jxr/JXRGluePFC.c delete mode 100644 Src/JxrDecode/Jxr/JXRMeta.c delete mode 100644 Src/JxrDecode/Jxr/JXRMeta.h delete mode 100644 Src/JxrDecode/Jxr/JXRTest.c delete mode 100644 Src/JxrDecode/Jxr/JXRTest.h delete mode 100644 Src/JxrDecode/Jxr/JXRTestBmp.c delete mode 100644 Src/JxrDecode/Jxr/JXRTestHdr.c delete mode 100644 Src/JxrDecode/Jxr/JXRTestPnm.c delete mode 100644 Src/JxrDecode/Jxr/JXRTestTif.c delete mode 100644 Src/JxrDecode/Jxr/JXRTestWrapper.c delete mode 100644 Src/JxrDecode/Jxr/JXRTestWrapper.h delete mode 100644 Src/JxrDecode/Jxr/JXRTestYUV.c delete mode 100644 Src/JxrDecode/Jxr/JXRTranscode.c delete mode 100644 Src/JxrDecode/Jxr/_x86/_x86.h delete mode 100644 Src/JxrDecode/Jxr/adapthuff.c delete mode 100644 Src/JxrDecode/Jxr/ansi.h delete mode 100644 Src/JxrDecode/Jxr/common.h delete mode 100644 Src/JxrDecode/Jxr/decode.c delete mode 100644 Src/JxrDecode/Jxr/decode.h delete mode 100644 Src/JxrDecode/Jxr/encode.c delete mode 100644 Src/JxrDecode/Jxr/encode.h delete mode 100644 Src/JxrDecode/Jxr/image.c delete mode 100644 Src/JxrDecode/Jxr/jxr_defines.h delete mode 100644 Src/JxrDecode/Jxr/perfTimer.h delete mode 100644 Src/JxrDecode/Jxr/perfTimerANSI.c delete mode 100644 Src/JxrDecode/Jxr/postprocess.c delete mode 100644 Src/JxrDecode/Jxr/priv_guiddef.h delete mode 100644 Src/JxrDecode/Jxr/segdec.c delete mode 100644 Src/JxrDecode/Jxr/segenc.c delete mode 100644 Src/JxrDecode/Jxr/strFwdTransform.c delete mode 100644 Src/JxrDecode/Jxr/strInvTransform.c delete mode 100644 Src/JxrDecode/Jxr/strPredQuant.c delete mode 100644 Src/JxrDecode/Jxr/strPredQuantDec.c delete mode 100644 Src/JxrDecode/Jxr/strPredQuantEnc.c delete mode 100644 Src/JxrDecode/Jxr/strTransform.c delete mode 100644 Src/JxrDecode/Jxr/strTransform.h delete mode 100644 Src/JxrDecode/Jxr/strcodec.c delete mode 100644 Src/JxrDecode/Jxr/strcodec.h delete mode 100644 Src/JxrDecode/Jxr/strdec.c delete mode 100644 Src/JxrDecode/Jxr/strdec_x86.c delete mode 100644 Src/JxrDecode/Jxr/strenc.c delete mode 100644 Src/JxrDecode/Jxr/strenc_x86.c delete mode 100644 Src/JxrDecode/Jxr/windowsmediaphoto.h delete mode 100644 Src/JxrDecode/Jxr/wmsal.h delete mode 100644 Src/JxrDecode/Jxr/wmspecstring.h delete mode 100644 Src/JxrDecode/Jxr/wmspecstrings_adt.h delete mode 100644 Src/JxrDecode/Jxr/wmspecstrings_strict.h delete mode 100644 Src/JxrDecode/Jxr/wmspecstrings_undef.h create mode 100644 Src/JxrDecode/JxrDecode_Config.h.in delete mode 100644 Src/JxrDecode/stdafx.cpp delete mode 100644 Src/JxrDecode/stdafx.h delete mode 100644 Src/JxrDecode/targetver.h diff --git a/Src/JxrDecode/CMakeLists.txt b/Src/JxrDecode/CMakeLists.txt index fd3b97f7..ceebe7c9 100644 --- a/Src/JxrDecode/CMakeLists.txt +++ b/Src/JxrDecode/CMakeLists.txt @@ -75,10 +75,14 @@ add_library(JxrDecodeStatic OBJECT "jxrlib/image/decode/strInvTransform.c" "jxrlib/image/decode/strPredQuantDec.c" "jxrlib/image/decode/postprocess.c" + "jxrlib/image/decode/JXRTranscode.c" "jxrlib/image/encode/strenc.c" "jxrlib/image/encode/encode.h" "jxrlib/image/encode/encode.c" + "jxrlib/image/encode/segenc.c" + "jxrlib/image/encode/strFwdTransform.c" + "jxrlib/image/encode/strPredQuantEnc.c" "jxrlib/image/sys/strcodec.h" "jxrlib/image/sys/strcodec.c" @@ -95,17 +99,37 @@ add_library(JxrDecodeStatic OBJECT "jxrlib/jxrgluelib/JXRGlueJxr.c" "jxrlib/jxrgluelib/JXRMeta.h" "jxrlib/jxrgluelib/JXRMeta.c" - "jxrlib/jxrgluelib/JXRGluePFC.c" "jxrlib/image/encode/segenc.c" "jxrlib/image/encode/strFwdTransform.c" "jxrlib/image/encode/strPredQuantEnc.c" "jxrlib/image/decode/JXRTranscode.c") + "jxrlib/jxrgluelib/JXRGluePFC.c" ) + + +# prepare the configuration-file "JxrDecode_Config.h" +if (IS_BIG_ENDIAN) + set(jxrdecode_ISBIGENDIANHOST 1) +else() + set(jxrdecode_ISBIGENDIANHOST 0) +endif() +if (CRASH_ON_UNALIGNED_ACCESS) + set (jxrdecode_CrashOnUnalignedIntegers 1) +else() + set (jxrdecode_CrashOnUnalignedIntegers 0) +endif() +configure_file ( + "${CMAKE_CURRENT_SOURCE_DIR}/JxrDecode_Config.h.in" + "${CMAKE_CURRENT_BINARY_DIR}/JxrDecode_Config.h" + ESCAPE_QUOTES @ONLY) +target_include_directories(JxrDecodeStatic PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") # for JxrDecode_Config.h to be found set_target_properties(JxrDecodeStatic PROPERTIES CXX_STANDARD 11) # shared libraries need PIC set_property(TARGET JxrDecodeStatic PROPERTY POSITION_INDEPENDENT_CODE ON) +#[[ if (IS_BIG_ENDIAN) target_compile_definitions(JxrDecodeStatic PRIVATE _BIG__ENDIAN_) endif(IS_BIG_ENDIAN) if (CRASH_ON_UNALIGNED_ACCESS) target_compile_definitions(JxrDecodeStatic PRIVATE _NO_UNALIGNED_LOAD_) -endif() \ No newline at end of file +endif() +]]# diff --git a/Src/JxrDecode/Jxr/JXRGlue.c b/Src/JxrDecode/Jxr/JXRGlue.c deleted file mode 100644 index 687bc11e..00000000 --- a/Src/JxrDecode/Jxr/JXRGlue.c +++ /dev/null @@ -1,964 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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 -#include - -#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) -{ - for (int 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}, - }; - - *ppInfo = NULL; - for (size_t 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_CreateDecoderFromStream(struct WMPStream* pStream, 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")); - pIID = &IID_PKImageWmpDecode; - - // 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->CreateDecoderFromStream = PKCodecFactory_CreateDecoderFromStream; - 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, (size_t)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, (size_t)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; - if (pIE->pStream != NULL) - { - 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; -} - diff --git a/Src/JxrDecode/Jxr/JXRGlue.h b/Src/JxrDecode/Jxr/JXRGlue.h deleted file mode 100644 index 2d895451..00000000 --- a/Src/JxrDecode/Jxr/JXRGlue.h +++ /dev/null @@ -1,659 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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 - -#if defined(_MSC_VER) -#include -#else -#include "priv_guiddef.h" -#endif -#include "JXRMeta.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 - -#if !defined(_MSC_VER) -#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 - - -//================================================================ -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; - -#include "JXRTestWrapper.h" - -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 (*CreateDecoderFromStream)(struct WMPStream*, 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; - - struct - { - JxrTestWrapperInitializeInfo info; - } WRAPPER; - -#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 - diff --git a/Src/JxrDecode/Jxr/JXRGlueJxr.c b/Src/JxrDecode/Jxr/JXRGlueJxr.c deleted file mode 100644 index f5e1f36a..00000000 --- a/Src/JxrDecode/Jxr/JXRGlueJxr.c +++ /dev/null @@ -1,2284 +0,0 @@ - -//*@@@+++@@@@****************************************************************** -// -// 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 -#include -#include "JXRGlue.h" - - -static const char szHDPhotoFormat[] = "image/vnd.ms-photo"; -const U32 IFDEntryTypeSizes[] = { 0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8 }; -const U32 SizeofIFDEntry = sizeof(struct IFDEntry); - - -void CalcMetadataSizeLPSTR(const DPKPROPVARIANT var, - U16 *pcInactiveMetadata, - U32 *pcbOffsetSize, - U32 *pcbCount) -{ - if (DPKVT_EMPTY != var.vt) - { - U32 uiLenWithNull = (U32)strlen(var.VT.pszVal) + 1; // +1 for NULL; - assert(DPKVT_LPSTR == var.vt); - - // We only use offset if size > 4 - if (uiLenWithNull > 4) - *pcbOffsetSize += uiLenWithNull; - - if (pcbCount) - *pcbCount = uiLenWithNull; - } - else - *pcInactiveMetadata += 1; -} - -void CalcMetadataSizeLPWSTR(const DPKPROPVARIANT var, - U16 *pcInactiveMetadata, - U32 *pcbOffsetSize, - U32 *pcbCount) -{ - if (DPKVT_EMPTY != var.vt) - { - U32 uiCBWithNull = sizeof(U16) * ((U32)wcslen((wchar_t *) var.VT.pwszVal) + 1); // +1 for NULL term; - assert(DPKVT_LPWSTR == var.vt); - - // We only use offset if size > 4 - if (uiCBWithNull > 4) - *pcbOffsetSize += uiCBWithNull; - - if (pcbCount) - *pcbCount = uiCBWithNull; - } - else - *pcInactiveMetadata += 1; -} - -void CalcMetadataSizeUI2(const DPKPROPVARIANT var, - U16 *pcInactiveMetadata, - U32 *pcbMetadataSize) -{ -// UNREFERENCED_PARAMETER( pcbMetadataSize ); - if (DPKVT_EMPTY != var.vt) - { - assert(DPKVT_UI2 == var.vt); - // This is a single UI2, so it will not be written via offset, but rather as value - } - else - *pcInactiveMetadata += 1; -} - -void CalcMetadataSizeUI4(const DPKPROPVARIANT var, - U16 *pcInactiveMetadata, - U32 *pcbContainer) -{ -// UNREFERENCED_PARAMETER( pcbContainer ); - if (DPKVT_EMPTY != var.vt) - { - assert(DPKVT_UI4 == var.vt); - // This is a single UI4, so it will not be written via offset, but rather as value - } - else - *pcInactiveMetadata += 1; -} - -ERR CalcMetadataOffsetSize(PKImageEncode* pIE, - U16 *pcInactiveMetadata, - U32 *pcbMetadataSize) -{ - ERR err = WMP_errSuccess; - - CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarImageDescription, pcInactiveMetadata, pcbMetadataSize, NULL); - CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarCameraMake, pcInactiveMetadata, pcbMetadataSize, NULL); - CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarCameraModel, pcInactiveMetadata, pcbMetadataSize, NULL); - CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarSoftware, pcInactiveMetadata, pcbMetadataSize, NULL); - CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarDateTime, pcInactiveMetadata, pcbMetadataSize, NULL); - CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarArtist, pcInactiveMetadata, pcbMetadataSize, NULL); - CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarCopyright, pcInactiveMetadata, pcbMetadataSize, NULL); - CalcMetadataSizeUI2(pIE->sDescMetadata.pvarRatingStars, pcInactiveMetadata, pcbMetadataSize); - CalcMetadataSizeUI2(pIE->sDescMetadata.pvarRatingValue, pcInactiveMetadata, pcbMetadataSize); - CalcMetadataSizeLPWSTR(pIE->sDescMetadata.pvarCaption, pcInactiveMetadata, pcbMetadataSize, NULL); - CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarDocumentName, pcInactiveMetadata, pcbMetadataSize, NULL); - CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarPageName, pcInactiveMetadata, pcbMetadataSize, NULL); - CalcMetadataSizeUI4(pIE->sDescMetadata.pvarPageNumber, pcInactiveMetadata, pcbMetadataSize); - CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarHostComputer, pcInactiveMetadata, pcbMetadataSize, NULL); - - return err; -} - - -ERR CopyDescMetadata(DPKPROPVARIANT *pvarDst, - const DPKPROPVARIANT varSrc) -{ - ERR err = WMP_errSuccess; - size_t uiSize; - - pvarDst->vt = varSrc.vt; - switch (varSrc.vt) - { - case DPKVT_LPSTR: - pvarDst->vt = DPKVT_LPSTR; - uiSize = strlen(varSrc.VT.pszVal) + 1; - Call(PKAlloc((void **) &pvarDst->VT.pszVal, uiSize)); - memcpy(pvarDst->VT.pszVal, varSrc.VT.pszVal, uiSize); - break; - - case DPKVT_LPWSTR: - pvarDst->vt = DPKVT_LPWSTR; - uiSize = sizeof(U16) * (wcslen((wchar_t *) varSrc.VT.pwszVal) + 1); // +1 for NULL term - Call(PKAlloc((void **) &pvarDst->VT.pszVal, uiSize)); - memcpy(pvarDst->VT.pwszVal, varSrc.VT.pwszVal, uiSize); - break; - - case DPKVT_UI2: - pvarDst->VT.uiVal = varSrc.VT.uiVal; - break; - - case DPKVT_UI4: - pvarDst->VT.ulVal = varSrc.VT.ulVal; - break; - - default: - assert(FALSE); // This case is not handled - FailIf(TRUE, WMP_errNotYetImplemented); - - // *** FALL THROUGH *** - - case DPKVT_EMPTY: - memset(pvarDst, 0, sizeof(*pvarDst)); - assert(DPKVT_EMPTY == pvarDst->vt); - break; - } - -Cleanup: - return err; -} - - -void FreeDescMetadata(DPKPROPVARIANT *pvar) -{ - switch (pvar->vt) - { - case DPKVT_LPSTR: - PKFree((void **) &pvar->VT.pszVal); - break; - - case DPKVT_LPWSTR: - PKFree((void **) &pvar->VT.pwszVal); - break; - - default: - assert(FALSE); // This case is not handled - break; - - case DPKVT_EMPTY: - case DPKVT_UI2: - case DPKVT_UI4: - break; - } -} - - -ERR WriteDescMetadata(PKImageEncode *pIE, - const DPKPROPVARIANT var, - WmpDE *pwmpDE, - U32 *puiCurrDescMetadataOffset, - size_t *poffPos) -{ - ERR err = WMP_errSuccess; - WmpDEMisc* pDEMisc = &pIE->WMP.wmiDEMisc; - struct WMPStream* pWS = pIE->pStream; - U32 uiMetadataOffsetSize = 0; - U32 uiCount = 0; - U32 uiDataWrittenToOffset = 0; - U16 uiTemp = 0; - - if (0 == pDEMisc->uDescMetadataOffset || 0 == pDEMisc->uDescMetadataByteCount) - goto Cleanup; // Nothing to do here - - // Sanity check before - can be equal due to remaining metadata being DPKVT_EMPTY - assert(*puiCurrDescMetadataOffset <= pDEMisc->uDescMetadataByteCount); - - switch (var.vt) - { - case DPKVT_EMPTY: - break; - - case DPKVT_LPSTR: - CalcMetadataSizeLPSTR(var, &uiTemp, &uiMetadataOffsetSize, &uiCount); - pwmpDE->uCount = uiCount; - pwmpDE->uValueOrOffset = pDEMisc->uDescMetadataOffset + *puiCurrDescMetadataOffset; - Call(WriteWmpDE(pWS, poffPos, pwmpDE, (U8*)var.VT.pszVal, &uiDataWrittenToOffset)); - break; - - case DPKVT_LPWSTR: - CalcMetadataSizeLPWSTR(var, &uiTemp, &uiMetadataOffsetSize, &uiCount); - pwmpDE->uCount = uiCount; - pwmpDE->uValueOrOffset = pDEMisc->uDescMetadataOffset + *puiCurrDescMetadataOffset; - Call(WriteWmpDE(pWS, poffPos, pwmpDE, (U8*)var.VT.pwszVal, &uiDataWrittenToOffset)); - break; - - case DPKVT_UI2: - CalcMetadataSizeUI2(var, &uiTemp, &uiMetadataOffsetSize); - pwmpDE->uCount = 1; - pwmpDE->uValueOrOffset = var.VT.uiVal; - Call(WriteWmpDE(pWS, poffPos, pwmpDE, NULL, NULL)); - break; - - case DPKVT_UI4: - CalcMetadataSizeUI4(var, &uiTemp, &uiMetadataOffsetSize); - pwmpDE->uCount = 1; - pwmpDE->uValueOrOffset = var.VT.ulVal; - Call(WriteWmpDE(pWS, poffPos, pwmpDE, NULL, NULL)); - break; - - default: - assert(FALSE); // This case is not handled - FailIf(TRUE, WMP_errNotYetImplemented); - break; - } - - *puiCurrDescMetadataOffset += uiDataWrittenToOffset; - - // Sanity check after - assert(*puiCurrDescMetadataOffset <= pDEMisc->uDescMetadataByteCount); // Can be equal - -Cleanup: - return err; -} - - - -//================================================================ -// PKImageEncode_WMP -//================================================================ -ERR WriteContainerPre( - PKImageEncode* pIE) -{ - ERR err = WMP_errSuccess; - const U32 OFFSET_OF_PFD = 0x20; - struct WMPStream* pWS = pIE->pStream; - WmpDEMisc* pDEMisc = &pIE->WMP.wmiDEMisc; - PKPixelInfo PI; - size_t offPos = 0; - - U8 IIMM[2] = {'\x49', '\x49'}; - // const U32 cbWmpDEMisc = OFFSET_OF_PFD; - U32 cbMetadataOffsetSize = 0; - U16 cInactiveMetadata = 0; - U32 uiCurrDescMetadataOffset = 0; - - static WmpDE wmpDEs[] = - { - {WMP_tagDocumentName, WMP_typASCII, 1, (U32) -1}, // Descriptive metadata - {WMP_tagImageDescription, WMP_typASCII, 1, (U32) -1}, // Descriptive metadata - {WMP_tagCameraMake, WMP_typASCII, 1, (U32) -1}, // Descriptive metadata - {WMP_tagCameraModel, WMP_typASCII, 1, (U32) -1}, // Descriptive metadata - {WMP_tagPageName, WMP_typASCII, 1, (U32) -1}, // Descriptive metadata - {WMP_tagPageNumber, WMP_typSHORT, 2, (U32) -1}, // Descriptive metadata - {WMP_tagSoftware, WMP_typASCII, 1, (U32) -1}, // Descriptive metadata - {WMP_tagDateTime, WMP_typASCII, 1, (U32) -1}, // Descriptive metadata - {WMP_tagArtist, WMP_typASCII, 1, (U32) -1}, // Descriptive metadata - {WMP_tagHostComputer, WMP_typASCII, 1, (U32) -1}, // Descriptive metadata - {WMP_tagRatingStars, WMP_typSHORT, 1, (U32) -1}, // Descriptive metadata - {WMP_tagRatingValue, WMP_typSHORT, 1, (U32) -1}, // Descriptive metadata - {WMP_tagCopyright, WMP_typASCII, 1, (U32) -1}, // Descriptive metadata - {WMP_tagCaption, WMP_typBYTE, 1, (U32) -1}, // Descriptive metadata - - {WMP_tagXMPMetadata, WMP_typBYTE, 1, (U32) -1}, - {WMP_tagIPTCNAAMetadata, WMP_typBYTE, 1, (U32) -1}, - {WMP_tagPhotoshopMetadata, WMP_typBYTE, 1, (U32) -1}, - {WMP_tagEXIFMetadata, WMP_typLONG, 1, (U32) -1}, - {WMP_tagIccProfile, WMP_typUNDEFINED, 1, (U32) -1}, - {WMP_tagGPSInfoMetadata, WMP_typLONG, 1, (U32) -1}, - - {WMP_tagPixelFormat, WMP_typBYTE, 16, (U32) -1}, - {WMP_tagTransformation, WMP_typLONG, 1, (U32) -1}, - {WMP_tagImageWidth, WMP_typLONG, 1, (U32) -1}, - {WMP_tagImageHeight, WMP_typLONG, 1, (U32) -1}, - {WMP_tagWidthResolution, WMP_typFLOAT, 1, (U32) -1}, - {WMP_tagHeightResolution, WMP_typFLOAT, 1, (U32) -1}, - {WMP_tagImageOffset, WMP_typLONG, 1, (U32) -1}, - {WMP_tagImageByteCount, WMP_typLONG, 1, (U32) -1}, - {WMP_tagAlphaOffset, WMP_typLONG, 1, (U32) -1}, - {WMP_tagAlphaByteCount, WMP_typLONG, 1, (U32) -1}, - }; - U16 cWmpDEs = sizeof(wmpDEs) / sizeof(wmpDEs[0]); - WmpDE wmpDE = {0}; - size_t i = 0; - - U8* pbEXIFMetadata = NULL; - U8* pbGPSInfoMetadata = NULL; - - // const unsigned char Zero[0x20] = { 0 }; - const unsigned char Zero[sizeof(struct IFDEntry) * sizeof(wmpDEs) / sizeof(wmpDEs[0]) + sizeof(U32)] = { 0 }; - assert(SizeofIFDEntry * sizeof(wmpDEs) / sizeof(wmpDEs[0]) + sizeof(U32) > 0x20); - - //================ - Call(pWS->GetPos(pWS, &offPos)); - FailIf(0 != offPos, WMP_errUnsupportedFormat); - - //================ - // Header (8 bytes) - Call(pWS->Write(pWS, IIMM, sizeof(IIMM))); offPos += 2; - Call(PutUShort(pWS, offPos, 0x01bc)); offPos += 2; - Call(PutULong(pWS, offPos, (U32)OFFSET_OF_PFD)); offPos += 4; - - //================ - // Write overflow area - pDEMisc->uOffPixelFormat = (U32)offPos; - PI.pGUIDPixFmt = &pIE->guidPixFormat; - PixelFormatLookup(&PI, LOOKUP_FORWARD); - - //Call(pWS->Write(pWS, PI.pGUIDPixFmt, sizeof(*PI.pGUIDPixFmt))); offPos += 16; - /** following code is endian-agnostic **/ - { - unsigned char *pGuid = (unsigned char *) &pIE->guidPixFormat; - Call(PutULong(pWS, offPos, ((U32 *)pGuid)[0])); - Call(PutUShort(pWS, offPos + 4, ((U16 *)(pGuid + 4))[0])); - Call(PutUShort(pWS, offPos + 6, ((U16 *)(pGuid + 6))[0])); - Call(pWS->Write(pWS, pGuid + 8, 8)); - offPos += 16; - } - - //================ - // Tally up space required for descriptive metadata - Call(CalcMetadataOffsetSize(pIE, &cInactiveMetadata, &cbMetadataOffsetSize)); - cWmpDEs -= cInactiveMetadata; - - //================ - // PFD - assert (offPos <= OFFSET_OF_PFD); // otherwise stuff is overwritten - if (offPos < OFFSET_OF_PFD) - { - Call(pWS->Write(pWS, Zero, OFFSET_OF_PFD - offPos)); - } - - offPos = (size_t)OFFSET_OF_PFD; - - if (!pIE->WMP.bHasAlpha || pIE->WMP.wmiSCP.uAlphaMode != 2) //no planar alpha - cWmpDEs -= 2; - - if (0 == pIE->cbXMPMetadataByteCount) - cWmpDEs -= 1; // No XMP metadata - - if (0 == pIE->cbIPTCNAAMetadataByteCount) - cWmpDEs -= 1; // No IPTCNAA metadata - - if (0 == pIE->cbPhotoshopMetadataByteCount) - cWmpDEs -= 1; // No Photoshop metadata - - if (0 == pIE->cbEXIFMetadataByteCount) - cWmpDEs -= 1; // No EXIF metadata - - if (0 == pIE->cbColorContext) - cWmpDEs -= 1; // No color context - - if (0 == pIE->cbGPSInfoMetadataByteCount) - cWmpDEs -= 1; // No GPSInfo metadata - - pDEMisc->uImageOffset = (U32)(offPos + sizeof(U16) + SizeofIFDEntry * cWmpDEs + sizeof(U32)); - - if (cbMetadataOffsetSize > 0) - { - pDEMisc->uDescMetadataByteCount = cbMetadataOffsetSize; - pDEMisc->uDescMetadataOffset = pDEMisc->uImageOffset; - pDEMisc->uImageOffset += cbMetadataOffsetSize; - } - - if (pIE->cbXMPMetadataByteCount > 0) - { - pDEMisc->uXMPMetadataOffset = pDEMisc->uImageOffset; - pDEMisc->uImageOffset += pIE->cbXMPMetadataByteCount; - } - - if (pIE->cbIPTCNAAMetadataByteCount > 0) - { - pDEMisc->uIPTCNAAMetadataOffset = pDEMisc->uImageOffset; - pDEMisc->uImageOffset += pIE->cbIPTCNAAMetadataByteCount; - } - - if (pIE->cbPhotoshopMetadataByteCount > 0) - { - pDEMisc->uPhotoshopMetadataOffset = pDEMisc->uImageOffset; - pDEMisc->uImageOffset += pIE->cbPhotoshopMetadataByteCount; - } - - if (pIE->cbEXIFMetadataByteCount > 0) - { - pDEMisc->uEXIFMetadataOffset = pDEMisc->uImageOffset; - pDEMisc->uImageOffset += (pDEMisc->uImageOffset & 1); - pDEMisc->uImageOffset += pIE->cbEXIFMetadataByteCount; - } - - if (pIE->cbColorContext > 0) - { - pDEMisc->uColorProfileOffset = pDEMisc->uImageOffset; - pDEMisc->uImageOffset += pIE->cbColorContext; - } - - if (pIE->cbGPSInfoMetadataByteCount > 0) - { - pDEMisc->uGPSInfoMetadataOffset = pDEMisc->uImageOffset; - pDEMisc->uImageOffset += (pDEMisc->uImageOffset & 1); - pDEMisc->uImageOffset += pIE->cbGPSInfoMetadataByteCount; - } - - Call(PutUShort(pWS, offPos, cWmpDEs)); offPos += 2; - Call(pWS->Write(pWS, Zero, SizeofIFDEntry * cWmpDEs + sizeof(U32))); - - //================ - wmpDE = wmpDEs[i++]; - assert(WMP_tagDocumentName == wmpDE.uTag); - Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarDocumentName, &wmpDE, - &uiCurrDescMetadataOffset, &offPos)); - - wmpDE = wmpDEs[i++]; - assert(WMP_tagImageDescription == wmpDE.uTag); - Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarImageDescription, &wmpDE, - &uiCurrDescMetadataOffset, &offPos)); - - wmpDE = wmpDEs[i++]; - assert(WMP_tagCameraMake == wmpDE.uTag); - Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarCameraMake, &wmpDE, - &uiCurrDescMetadataOffset, &offPos)); - - wmpDE = wmpDEs[i++]; - assert(WMP_tagCameraModel == wmpDE.uTag); - Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarCameraModel, &wmpDE, - &uiCurrDescMetadataOffset, &offPos)); - - wmpDE = wmpDEs[i++]; - assert(WMP_tagPageName == wmpDE.uTag); - Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarPageName, &wmpDE, - &uiCurrDescMetadataOffset, &offPos)); - - wmpDE = wmpDEs[i++]; - assert(WMP_tagPageNumber == wmpDE.uTag); - Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarPageNumber, &wmpDE, - &uiCurrDescMetadataOffset, &offPos)); - - wmpDE = wmpDEs[i++]; - assert(WMP_tagSoftware == wmpDE.uTag); - Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarSoftware, &wmpDE, - &uiCurrDescMetadataOffset, &offPos)); - - wmpDE = wmpDEs[i++]; - assert(WMP_tagDateTime == wmpDE.uTag); - Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarDateTime, &wmpDE, - &uiCurrDescMetadataOffset, &offPos)); - - wmpDE = wmpDEs[i++]; - assert(WMP_tagArtist == wmpDE.uTag); - Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarArtist, &wmpDE, - &uiCurrDescMetadataOffset, &offPos)); - - wmpDE = wmpDEs[i++]; - assert(WMP_tagHostComputer == wmpDE.uTag); - Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarHostComputer, &wmpDE, - &uiCurrDescMetadataOffset, &offPos)); - - wmpDE = wmpDEs[i++]; - assert(WMP_tagRatingStars == wmpDE.uTag); - Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarRatingStars, &wmpDE, - &uiCurrDescMetadataOffset, &offPos)); - - wmpDE = wmpDEs[i++]; - assert(WMP_tagRatingValue == wmpDE.uTag); - Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarRatingValue, &wmpDE, - &uiCurrDescMetadataOffset, &offPos)); - - wmpDE = wmpDEs[i++]; - assert(WMP_tagCopyright == wmpDE.uTag); - Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarCopyright, &wmpDE, - &uiCurrDescMetadataOffset, &offPos)); - - wmpDE = wmpDEs[i++]; - assert(WMP_tagCaption == wmpDE.uTag); - Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarCaption, &wmpDE, - &uiCurrDescMetadataOffset, &offPos)); - - // XMP Metadata - wmpDE = wmpDEs[i++]; - assert(WMP_tagXMPMetadata == wmpDE.uTag); - if (pIE->cbXMPMetadataByteCount > 0) - { - U32 uiTemp; - wmpDE.uCount = pIE->cbXMPMetadataByteCount; - wmpDE.uValueOrOffset = pDEMisc->uXMPMetadataOffset; - Call(WriteWmpDE(pWS, &offPos, &wmpDE, pIE->pbXMPMetadata, &uiTemp)); - } - - // IPTCNAA Metadata - wmpDE = wmpDEs[i++]; - assert(WMP_tagIPTCNAAMetadata == wmpDE.uTag); - if (pIE->cbIPTCNAAMetadataByteCount > 0) - { - U32 uiTemp; - wmpDE.uCount = pIE->cbIPTCNAAMetadataByteCount; - wmpDE.uValueOrOffset = pDEMisc->uIPTCNAAMetadataOffset; - Call(WriteWmpDE(pWS, &offPos, &wmpDE, pIE->pbIPTCNAAMetadata, &uiTemp)); - } - - // Photoshop Metadata - wmpDE = wmpDEs[i++]; - assert(WMP_tagPhotoshopMetadata == wmpDE.uTag); - if (pIE->cbPhotoshopMetadataByteCount > 0) - { - U32 uiTemp; - wmpDE.uCount = pIE->cbPhotoshopMetadataByteCount; - wmpDE.uValueOrOffset = pDEMisc->uPhotoshopMetadataOffset; - Call(WriteWmpDE(pWS, &offPos, &wmpDE, pIE->pbPhotoshopMetadata, &uiTemp)); - } - - // EXIF Metadata - wmpDE = wmpDEs[i++]; - assert(WMP_tagEXIFMetadata == wmpDE.uTag); - if (pIE->cbEXIFMetadataByteCount > 0) - { - U32 uiTemp; - if ((pDEMisc->uEXIFMetadataOffset & 1) != 0) - { - Call(pWS->SetPos(pWS, pDEMisc->uEXIFMetadataOffset)); - Call(pWS->Write(pWS, Zero, 1)); - } - pDEMisc->uEXIFMetadataOffset += (pDEMisc->uEXIFMetadataOffset & 1); - wmpDE.uValueOrOffset = pDEMisc->uEXIFMetadataOffset; - Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); - - Call(PKAlloc((void **) &pbEXIFMetadata, pIE->cbEXIFMetadataByteCount)); - uiTemp = pDEMisc->uEXIFMetadataOffset; - Call(BufferCopyIFD(pIE->pbEXIFMetadata, pIE->cbEXIFMetadataByteCount, 0, WMP_INTEL_ENDIAN, - pbEXIFMetadata - uiTemp, uiTemp + pIE->cbEXIFMetadataByteCount, &uiTemp)); - Call(pWS->SetPos(pWS, pDEMisc->uEXIFMetadataOffset)); - Call(pWS->Write(pWS, pbEXIFMetadata, pIE->cbEXIFMetadataByteCount)); - } - - // ICC Profile - wmpDE = wmpDEs[i++]; - assert(WMP_tagIccProfile == wmpDE.uTag); - if (pIE->cbColorContext > 0) - { - U32 uiTemp; - wmpDE.uCount = pIE->cbColorContext; - wmpDE.uValueOrOffset = pDEMisc->uColorProfileOffset; - Call(WriteWmpDE(pWS, &offPos, &wmpDE, pIE->pbColorContext, &uiTemp)); - } - - // GPSInfo Metadata - wmpDE = wmpDEs[i++]; - assert(WMP_tagGPSInfoMetadata == wmpDE.uTag); - if (pIE->cbGPSInfoMetadataByteCount > 0) - { - U32 uiTemp; - if ((pDEMisc->uGPSInfoMetadataOffset & 1) != 0) - { - Call(pWS->SetPos(pWS, pDEMisc->uGPSInfoMetadataOffset)); - Call(pWS->Write(pWS, Zero, 1)); - } - pDEMisc->uGPSInfoMetadataOffset += (pDEMisc->uGPSInfoMetadataOffset & 1); - wmpDE.uValueOrOffset = pDEMisc->uGPSInfoMetadataOffset; - Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); - - Call(PKAlloc((void **) &pbGPSInfoMetadata, pIE->cbGPSInfoMetadataByteCount)); - uiTemp = pDEMisc->uGPSInfoMetadataOffset; - Call(BufferCopyIFD(pIE->pbGPSInfoMetadata, pIE->cbGPSInfoMetadataByteCount, 0, WMP_INTEL_ENDIAN, - pbGPSInfoMetadata - uiTemp, uiTemp + pIE->cbGPSInfoMetadataByteCount, &uiTemp)); - Call(pWS->SetPos(pWS, pDEMisc->uGPSInfoMetadataOffset)); - Call(pWS->Write(pWS, pbGPSInfoMetadata, pIE->cbGPSInfoMetadataByteCount)); - } - - wmpDE = wmpDEs[i++]; - assert(WMP_tagPixelFormat == wmpDE.uTag); - wmpDE.uValueOrOffset = pDEMisc->uOffPixelFormat; - Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); - - wmpDE = wmpDEs[i++]; - assert(WMP_tagTransformation == wmpDE.uTag); - wmpDE.uValueOrOffset = pIE->WMP.oOrientation; - Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); - - wmpDE = wmpDEs[i++]; - assert(WMP_tagImageWidth == wmpDE.uTag); - wmpDE.uValueOrOffset = pIE->uWidth; - Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); - - wmpDE = wmpDEs[i++]; - assert(WMP_tagImageHeight == wmpDE.uTag); - wmpDE.uValueOrOffset = pIE->uHeight; - Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); - - wmpDE = wmpDEs[i++]; - assert(WMP_tagWidthResolution == wmpDE.uTag); - *((float *) &wmpDE.uValueOrOffset) = pIE->fResX; - Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); - - wmpDE = wmpDEs[i++]; - assert(WMP_tagHeightResolution == wmpDE.uTag); - *((float *) &wmpDE.uValueOrOffset) = pIE->fResY; - Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); - - wmpDE = wmpDEs[i++]; - assert(WMP_tagImageOffset == wmpDE.uTag); - wmpDE.uValueOrOffset = pDEMisc->uImageOffset; - Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); - - // fix up in WriteContainerPost() - wmpDE = wmpDEs[i++]; - assert(WMP_tagImageByteCount == wmpDE.uTag); - pDEMisc->uOffImageByteCount = (U32)offPos; - wmpDE.uValueOrOffset = 0; - Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); - - if (pIE->WMP.bHasAlpha && pIE->WMP.wmiSCP.uAlphaMode == 2) - { - // fix up in WriteContainerPost() - wmpDE = wmpDEs[i++]; - assert(WMP_tagAlphaOffset == wmpDE.uTag); - pDEMisc->uOffAlphaOffset = (U32)offPos; - wmpDE.uValueOrOffset = 0; - Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); - - // fix up in WriteContainerPost() - wmpDE = wmpDEs[i++]; - assert(WMP_tagAlphaByteCount == wmpDE.uTag); - pDEMisc->uOffAlphaByteCount = (U32)offPos; - wmpDE.uValueOrOffset = 0; - Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL)); - } - - //================ - Call(PutULong(pWS, offPos, 0)); offPos += 4; - - assert(0 == (offPos & 1)); - if (pDEMisc->uColorProfileOffset > 0 || pDEMisc->uDescMetadataOffset > 0 || - pDEMisc->uXMPMetadataOffset > 0 || pDEMisc->uIPTCNAAMetadataOffset > 0 || - pDEMisc->uPhotoshopMetadataOffset > 0 || pDEMisc->uEXIFMetadataOffset > 0 || - pDEMisc->uGPSInfoMetadataOffset > 0) - { - assert(pDEMisc->uColorProfileOffset == offPos || - pDEMisc->uDescMetadataOffset == offPos || - pDEMisc->uXMPMetadataOffset == offPos || - pDEMisc->uIPTCNAAMetadataOffset == offPos || - pDEMisc->uPhotoshopMetadataOffset == offPos || - pDEMisc->uEXIFMetadataOffset == offPos || - pDEMisc->uGPSInfoMetadataOffset == offPos); - - // OK, now skip to image offset - Call(pWS->SetPos(pWS, pDEMisc->uImageOffset)); - offPos = pDEMisc->uImageOffset; - } - assert(pDEMisc->uImageOffset == offPos); - -Cleanup: - if (pbEXIFMetadata != NULL) - PKFree((void **) &pbEXIFMetadata); - if (pbGPSInfoMetadata != NULL) - PKFree((void **) &pbGPSInfoMetadata); - return err; -} - - - -ERR WriteContainerPost( - PKImageEncode* pIE) -{ - ERR err = WMP_errSuccess; - - struct WMPStream* pWS = pIE->pStream; - WmpDEMisc* pDEMisc = &pIE->WMP.wmiDEMisc; - size_t offPos; - - WmpDE deImageByteCount = {WMP_tagImageByteCount, WMP_typLONG, 1, 0}; - WmpDE deAlphaOffset = {WMP_tagAlphaOffset, WMP_typLONG, 1, 0}; - WmpDE deAlphaByteCount = {WMP_tagAlphaByteCount, WMP_typLONG, 1, 0}; - - deImageByteCount.uValueOrOffset = pIE->WMP.nCbImage; - offPos = pDEMisc->uOffImageByteCount; - Call(WriteWmpDE(pWS, &offPos, &deImageByteCount, NULL, NULL)); - - //Alpha - if (pIE->WMP.bHasAlpha && pIE->WMP.wmiSCP.uAlphaMode == 2) - { - deAlphaOffset.uValueOrOffset = pIE->WMP.nOffAlpha; - offPos = pDEMisc->uOffAlphaOffset; - Call(WriteWmpDE(pWS, &offPos, &deAlphaOffset, NULL, NULL)); - - deAlphaByteCount.uValueOrOffset = pIE->WMP.nCbAlpha + pIE->WMP.nOffAlpha; - offPos = pDEMisc->uOffAlphaByteCount; - Call(WriteWmpDE(pWS, &offPos, &deAlphaByteCount, NULL, NULL)); - } - -Cleanup: - return err; -} - - -//================================================ -ERR PKImageEncode_Initialize_WMP( - PKImageEncode* pIE, - struct WMPStream* pStream, - void* pvParam, - size_t cbParam) -{ - ERR err = WMP_errSuccess; - - FailIf(sizeof(pIE->WMP.wmiSCP) != cbParam, WMP_errInvalidArgument); - - pIE->WMP.wmiSCP = *(CWMIStrCodecParam*)pvParam; - pIE->WMP.wmiSCP_Alpha = *(CWMIStrCodecParam*)pvParam; - pIE->pStream = pStream; - - pIE->WMP.wmiSCP.pWStream = pIE->pStream; - pIE->WMP.wmiSCP_Alpha.pWStream = pIE->pStream; - -Cleanup: - return err; -} - -ERR PKImageEncode_Terminate_WMP( - PKImageEncode* pIE) -{ - ERR err = WMP_errSuccess; -// UNREFERENCED_PARAMETER( pIE ); - return err; -} - - -ERR PKImageEncode_EncodeContent_Init( - PKImageEncode* pIE, - PKPixelInfo PI, - U32 cLine, - U8* pbPixels, - U32 cbStride) -{ - ERR err = WMP_errSuccess; - - // init codec - pIE->WMP.wmiI.cWidth = pIE->uWidth; - pIE->WMP.wmiI.cHeight = pIE->uHeight; - pIE->WMP.wmiI.bdBitDepth = PI.bdBitDepth; - pIE->WMP.wmiI.cBitsPerUnit = PI.cbitUnit; - pIE->WMP.wmiI.bRGB = !(PI.grBit & PK_pixfmtBGR); - pIE->WMP.wmiI.cfColorFormat = PI.cfColorFormat; - pIE->WMP.wmiI.oOrientation = pIE->WMP.oOrientation; - - // Set the fPaddedUserBuffer if the following conditions are met - if (0 == ((size_t)pbPixels % 128) && // Frame buffer is aligned to 128-byte boundary - 0 == (pIE->uWidth % 16) && // Horizontal resolution is multiple of 16 - 0 == (cLine % 16) && // Vertical resolution is multiple of 16 - 0 == (cbStride % 128)) // Stride is a multiple of 128 bytes - { - pIE->WMP.wmiI.fPaddedUserBuffer = TRUE; - // Note that there are additional conditions in strenc_x86.c's strEncOpt - // which could prevent optimization from being engaged - } - - //if (pIE->WMP.bHasAlpha) - //{ - // pIE->WMP.wmiSCP.cChannel = PI.cChannel - 1; - // pIE->WMP.wmiI.cfColorFormat = PI.cfStripAlpha; - //} - //else - - if(PI.cfColorFormat == NCOMPONENT && (!(PI.grBit & PK_pixfmtHasAlpha)))//N-channel without Alpha - pIE->WMP.wmiSCP.cChannel = PI.cChannel; - else - pIE->WMP.wmiSCP.cChannel = PI.cChannel - 1;//other formats and (N-channel + Alpha) - - pIE->idxCurrentLine = 0; - - pIE->WMP.wmiSCP.fMeasurePerf = TRUE; - FailIf(ICERR_OK != ImageStrEncInit(&pIE->WMP.wmiI, &pIE->WMP.wmiSCP, &pIE->WMP.ctxSC), WMP_errFail); - -Cleanup: - return err; -} - -ERR PKImageEncode_EncodeContent_Encode( - PKImageEncode* pIE, - U32 cLine, - U8* pbPixels, - U32 cbStride) -{ - ERR err = WMP_errSuccess; - U32 i = 0; - - //================================ - for (i = 0; i < cLine; i += 16) - { - Bool f420 = ( pIE->WMP.wmiI.cfColorFormat == YUV_420 || - (pIE->WMP.wmiSCP.bYUVData && pIE->WMP.wmiSCP.cfColorFormat==YUV_420) ); - CWMImageBufferInfo wmiBI = { 0 }; - wmiBI.pv = pbPixels + cbStride * i / (f420 ? 2 : 1); - wmiBI.cLine = MIN(16, cLine - i); - wmiBI.cbStride = cbStride; - FailIf(ICERR_OK != ImageStrEncEncode(pIE->WMP.ctxSC, &wmiBI), WMP_errFail); - } - pIE->idxCurrentLine += cLine; - -Cleanup: - return err; -} - -ERR PKImageEncode_EncodeContent_Term(PKImageEncode* pIE) -{ - ERR err = WMP_errSuccess; - - FailIf(ICERR_OK != ImageStrEncTerm(pIE->WMP.ctxSC), WMP_errFail); - -Cleanup: - return err; -} - -ERR PKImageEncode_EncodeContent( - PKImageEncode* pIE, - PKPixelInfo PI, - U32 cLine, - U8* pbPixels, - U32 cbStride) -{ - ERR err = WMP_errSuccess; - size_t offPos = 0; - - Call(pIE->pStream->GetPos(pIE->pStream, &offPos)); - pIE->WMP.nOffImage = (Long)offPos; - - Call(PKImageEncode_EncodeContent_Init(pIE, PI, cLine, pbPixels, cbStride)); - Call(PKImageEncode_EncodeContent_Encode(pIE, cLine, pbPixels, cbStride)); - Call(PKImageEncode_EncodeContent_Term(pIE)); - - Call(pIE->pStream->GetPos(pIE->pStream, &offPos)); - pIE->WMP.nCbImage = (Long)offPos - pIE->WMP.nOffImage; - -Cleanup: - return err; -} - - -ERR PKImageEncode_EncodeAlpha_Init( - PKImageEncode* pIE, - PKPixelInfo PI, - U32 cLine, - U8* pbPixels, - U32 cbStride) -{ - ERR err = WMP_errSuccess; - - //UNREFERENCED_PARAMETER( cLine ); - //UNREFERENCED_PARAMETER( pbPixels ); - //UNREFERENCED_PARAMETER( cbStride ); - - pIE->WMP.wmiI_Alpha = pIE->WMP.wmiI; - - pIE->WMP.wmiI_Alpha.cWidth = pIE->uWidth; - pIE->WMP.wmiI_Alpha.cHeight = pIE->uHeight; - pIE->WMP.wmiI_Alpha.bdBitDepth = PI.bdBitDepth; - pIE->WMP.wmiI_Alpha.cBitsPerUnit = PI.cbitUnit; - pIE->WMP.wmiI_Alpha.bRGB = !(PI.grBit & PK_pixfmtBGR); - pIE->WMP.wmiI.oOrientation = pIE->WMP.oOrientation; -// pIE->WMP.wmiI_Alpha.cLeadingPadding += pIE->WMP.wmiSCP.cChannel; -// pIE->WMP.wmiI_Alpha.cLeadingPadding += PI.cChannel - 1; - - switch (pIE->WMP.wmiI.bdBitDepth) - { - case BD_8: - pIE->WMP.wmiI_Alpha.cLeadingPadding += (pIE->WMP.wmiI.cBitsPerUnit >> 3) - 1; - break; - - case BD_16: - case BD_16S: - case BD_16F: - pIE->WMP.wmiI_Alpha.cLeadingPadding += (pIE->WMP.wmiI.cBitsPerUnit >> 3) / sizeof(U16) - 1; - break; - - case BD_32: - case BD_32S: - case BD_32F: - pIE->WMP.wmiI_Alpha.cLeadingPadding += (pIE->WMP.wmiI.cBitsPerUnit >> 3) / sizeof(float) - 1; - break; - - case BD_5: - case BD_10: - case BD_565: - default: - break; - } - -// pIE->WMP.wmiSCP_Alpha.uAlphaMode = 1; - - - //assert(pIE->WMP.wmiI_Alpha.cfColorFormat == CF_RGB); // only RGBA is supported for now! - pIE->WMP.wmiI_Alpha.cfColorFormat = Y_ONLY; - - pIE->WMP.wmiSCP_Alpha.cfColorFormat = Y_ONLY; - - pIE->idxCurrentLine = 0; - pIE->WMP.wmiSCP_Alpha.fMeasurePerf = TRUE; - FailIf(ICERR_OK != ImageStrEncInit(&pIE->WMP.wmiI_Alpha, &pIE->WMP.wmiSCP_Alpha, &pIE->WMP.ctxSC_Alpha), WMP_errFail); - -Cleanup: - return err; -} - -ERR PKImageEncode_EncodeAlpha_Encode( - PKImageEncode* pIE, - U32 cLine, - U8* pbPixels, - U32 cbStride) -{ - ERR err = WMP_errSuccess; - U32 i = 0; - - //================================ - for (i = 0; i < cLine; i += 16) - { - CWMImageBufferInfo wmiBI = { 0 }; - wmiBI.pv = pbPixels + cbStride * i; - wmiBI.cLine = MIN(16, cLine - i); - wmiBI.cbStride = cbStride; - FailIf(ICERR_OK != ImageStrEncEncode(pIE->WMP.ctxSC_Alpha, &wmiBI), WMP_errFail); - } - pIE->idxCurrentLine += cLine; - -Cleanup: - return err; -} - -ERR PKImageEncode_EncodeAlpha_Term(PKImageEncode* pIE) -{ - ERR err = WMP_errSuccess; - - FailIf(ICERR_OK != ImageStrEncTerm(pIE->WMP.ctxSC_Alpha), WMP_errFail); - -Cleanup: - return err; -} - -ERR PKImageEncode_EncodeAlpha( - PKImageEncode* pIE, - PKPixelInfo PI, - U32 cLine, - U8* pbPixels, - U32 cbStride) -{ - ERR err = WMP_errSuccess; - size_t offPos = 0; - - Call(pIE->pStream->GetPos(pIE->pStream, &offPos)); - if ((offPos & 1) != 0) - { - // Make the mark even if it is odd by inserting a pad byte - char zero = 0; - Call(pIE->pStream->Write(pIE->pStream, &zero, 1)); - offPos++; - } - pIE->WMP.nOffAlpha = (Long)offPos; - - Call(PKImageEncode_EncodeAlpha_Init(pIE, PI, cLine, pbPixels, cbStride)); - Call(PKImageEncode_EncodeAlpha_Encode(pIE, cLine, pbPixels, cbStride)); - Call(PKImageEncode_EncodeAlpha_Term(pIE)); - - Call(pIE->pStream->GetPos(pIE->pStream, &offPos)); - pIE->WMP.nCbAlpha = (Long)offPos - pIE->WMP.nOffAlpha; - -Cleanup: - return err; -} - - - -static ERR SetMetadata(PKImageEncode *pIE, const U8 *pbMetadata, U32 cbMetadata, U8** pbSet, U32* pcbSet) -{ - ERR err = WMP_errSuccess; - - // Fail if the caller called us after we've already written the header out - if (pIE->fHeaderDone) - { - assert(FALSE); // Message to programmer - err = WMP_errOutOfSequence; - goto Cleanup; - } - - // Make a copy of the metadata - PKFree((void **) pbSet); - *pcbSet = 0; - - Call(PKAlloc((void **) pbSet, cbMetadata)); - memcpy(*pbSet, pbMetadata, cbMetadata); - *pcbSet = cbMetadata; - -Cleanup: - return err; -} - - - -ERR PKImageEncode_SetColorContext_WMP(PKImageEncode *pIE, - const U8 *pbColorContext, - U32 cbColorContext) -{ - return SetMetadata(pIE, pbColorContext, cbColorContext, &pIE->pbColorContext, &pIE->cbColorContext); -} - - - -ERR PKImageEncode_SetXMPMetadata_WMP(PKImageEncode *pIE, const U8 *pbXMPMetadata, U32 cbXMPMetadata) -{ // same as the other Set's, but make sure dc:format is image/vnd.ms-photo - ERR err = WMP_errSuccess; - char* pbTemp = 0; - U32 cbTemp; - char* pszFormatBegin; - // const char* pszXMPMetadata = (const char*)pbXMPMetadata; - size_t cbBuffer; - - // Fail if the caller called us after we've already written the header out - FailIf(pIE->fHeaderDone, WMP_errOutOfSequence); - - // Free any previously set XMP metadata - PKFree((void **) &pIE->pbXMPMetadata); - pIE->cbXMPMetadataByteCount = 0; - - // allocate a block big enough for data passed in plus added trailing null plus added HD Photo dc:format - // there may already be a trailing null (but ps doesn't seem to) - // there may already be a dc:format we will replace with HD Photo's - // but anyway this block will be large enough guaranteed - cbBuffer = cbXMPMetadata + 1 + sizeof("") - 1 + sizeof("") - 1 + sizeof(szHDPhotoFormat) - 1; - Call(PKAlloc((void **) &pbTemp, cbBuffer)); - memcpy(pbTemp, pbXMPMetadata, cbXMPMetadata); // Make a copy of the metadata - pbTemp[cbXMPMetadata] = '\0'; - cbXMPMetadata = (U32)strlen(pbTemp); - pszFormatBegin = strstr(pbTemp, ""); - if ( pszFormatBegin != 0 ) - { - char* pszFormatEnd; - const char* pszLessThan; - - pszFormatEnd = strstr(pszFormatBegin, ""); - FailIf(pszFormatEnd == 0, WMP_errFail); - pszLessThan = strchr(pszFormatBegin + sizeof("") - 1, '<'); - FailIf(pszLessThan != pszFormatEnd, WMP_errFail); - pszFormatEnd += sizeof("") - 1; - - // photoshop doesn't put a trailing null, so we don't either - // hd and tiff don't put a trailing null, so we don't either - cbTemp = cbXMPMetadata - (U32) ( pszFormatEnd - pszFormatBegin ) + sizeof(szHDPhotoFormat) - 1; - assert(cbTemp <= cbBuffer); - FailIf(0 != STRCPY_SAFE(pszFormatBegin, - cbBuffer - (pszFormatBegin - pbTemp), - szHDPhotoFormat), - WMP_errBufferOverflow); - memcpy(pszFormatBegin + sizeof(szHDPhotoFormat) - 1, pbXMPMetadata + ( pszFormatEnd - pbTemp ), - cbXMPMetadata - ( pszFormatEnd - pbTemp )); - } - else - { - cbTemp = cbXMPMetadata; - } - - pIE->pbXMPMetadata = (U8 *) pbTemp; - pIE->cbXMPMetadataByteCount = cbTemp; - return ( err ); - -Cleanup: - PKFree((void **) &pbTemp); - pIE->cbXMPMetadataByteCount = 0; - return err; -} - - - -ERR PKImageEncode_SetEXIFMetadata_WMP(PKImageEncode *pIE, const U8 *pbEXIFMetadata, U32 cbEXIFMetadata) -{ - return SetMetadata(pIE, pbEXIFMetadata, cbEXIFMetadata, - &pIE->pbEXIFMetadata, &pIE->cbEXIFMetadataByteCount); -} - - - -ERR PKImageEncode_SetGPSInfoMetadata_WMP(PKImageEncode *pIE, const U8 *pbGPSInfoMetadata, U32 cbGPSInfoMetadata) -{ - return SetMetadata(pIE, pbGPSInfoMetadata, cbGPSInfoMetadata, - &pIE->pbGPSInfoMetadata, &pIE->cbGPSInfoMetadataByteCount); -} - - - -ERR PKImageEncode_SetIPTCNAAMetadata_WMP(PKImageEncode *pIE, const U8 *pbIPTCNAAMetadata, U32 cbIPTCNAAMetadata) -{ - return SetMetadata(pIE, pbIPTCNAAMetadata, cbIPTCNAAMetadata, - &pIE->pbIPTCNAAMetadata, &pIE->cbIPTCNAAMetadataByteCount); -} - - - -ERR PKImageEncode_SetPhotoshopMetadata_WMP(PKImageEncode *pIE, const U8 *pbPhotoshopMetadata, U32 cbPhotoshopMetadata) -{ - return SetMetadata(pIE, pbPhotoshopMetadata, cbPhotoshopMetadata, - &pIE->pbPhotoshopMetadata, &pIE->cbPhotoshopMetadataByteCount); -} - - - -ERR PKImageEncode_SetDescriptiveMetadata_WMP(PKImageEncode *pIE, const DESCRIPTIVEMETADATA *pSrcMeta) -{ - ERR err = WMP_errSuccess; - DESCRIPTIVEMETADATA *pDstMeta = &pIE->sDescMetadata; - - // Fail if the caller called us after we've already written the header out - if (pIE->fHeaderDone) - { - assert(FALSE); // Message to programmer - FailIf(TRUE, WMP_errOutOfSequence); - } - - // Make a copy of the descriptive metadata - Call(CopyDescMetadata(&pDstMeta->pvarImageDescription, pSrcMeta->pvarImageDescription)); - Call(CopyDescMetadata(&pDstMeta->pvarCameraMake, pSrcMeta->pvarCameraMake)); - Call(CopyDescMetadata(&pDstMeta->pvarCameraModel, pSrcMeta->pvarCameraModel)); - Call(CopyDescMetadata(&pDstMeta->pvarSoftware, pSrcMeta->pvarSoftware)); - Call(CopyDescMetadata(&pDstMeta->pvarDateTime, pSrcMeta->pvarDateTime)); - Call(CopyDescMetadata(&pDstMeta->pvarArtist, pSrcMeta->pvarArtist)); - Call(CopyDescMetadata(&pDstMeta->pvarCopyright, pSrcMeta->pvarCopyright)); - Call(CopyDescMetadata(&pDstMeta->pvarRatingStars, pSrcMeta->pvarRatingStars)); - Call(CopyDescMetadata(&pDstMeta->pvarRatingValue, pSrcMeta->pvarRatingValue)); - Call(CopyDescMetadata(&pDstMeta->pvarCaption, pSrcMeta->pvarCaption)); - Call(CopyDescMetadata(&pDstMeta->pvarDocumentName, pSrcMeta->pvarDocumentName)); - Call(CopyDescMetadata(&pDstMeta->pvarPageName, pSrcMeta->pvarPageName)); - Call(CopyDescMetadata(&pDstMeta->pvarPageNumber, pSrcMeta->pvarPageNumber)); - Call(CopyDescMetadata(&pDstMeta->pvarHostComputer, pSrcMeta->pvarHostComputer)); - -Cleanup: - return err; -} - - - -ERR PKImageEncode_WritePixels_WMP( - PKImageEncode* pIE, - U32 cLine, - U8* pbPixels, - U32 cbStride) -{ - ERR err = WMP_errSuccess; - // U32 i = 0; - PKPixelInfo PI; - - // Performing non-banded encode - assert(BANDEDENCSTATE_UNINITIALIZED == pIE->WMP.eBandedEncState); - pIE->WMP.eBandedEncState = BANDEDENCSTATE_NONBANDEDENCODE; - - PI.pGUIDPixFmt = &pIE->guidPixFormat; - PixelFormatLookup(&PI, LOOKUP_FORWARD); - pIE->WMP.bHasAlpha = !!(PI.grBit & PK_pixfmtHasAlpha); - - if (!pIE->fHeaderDone) - { - // write metadata - Call(WriteContainerPre(pIE)); - - pIE->fHeaderDone = !FALSE; - } - -/* if (pIE->WMP.bHasAlpha && pIE->WMP.wmiSCP.uAlphaMode == 2){ - pIE->WMP.wmiSCP_Alpha = pIE->WMP.wmiSCP; - } -*/ - Call(PKImageEncode_EncodeContent(pIE, PI, cLine, pbPixels, cbStride)); - if (pIE->WMP.bHasAlpha && pIE->WMP.wmiSCP.uAlphaMode == 2){//planar alpha - Call(PKImageEncode_EncodeAlpha(pIE, PI, cLine, pbPixels, cbStride)); - } - - Call(WriteContainerPost(pIE)); - -Cleanup: - return err; -} - - -ERR PKImageEncode_WritePixelsBandedBegin_WMP(PKImageEncode* pIE, struct WMPStream *pPATempFile) -{ - ERR err = WMP_errSuccess; - - // Just make sure that we are in the correct state to begin a banded decode - assert(BANDEDENCSTATE_UNINITIALIZED == pIE->WMP.eBandedEncState); - pIE->WMP.eBandedEncState = BANDEDENCSTATE_INIT; - - // Save the planar alpha tempfile for future use - pIE->WMP.pPATempFile = pPATempFile; - -//Cleanup: - return err; -} - -ERR PKImageEncode_WritePixelsBanded_WMP(PKImageEncode* pIE, U32 cLine, U8* pbPixels, U32 cbStride, Bool fLastCall) -{ - ERR err = WMP_errSuccess; - PKPixelInfo PI = {0}; - Bool fPI = FALSE; - BANDEDENCSTATE eEncStateOrig = pIE->WMP.eBandedEncState; - struct WMPStream *pPATempFile = pIE->WMP.pPATempFile; - - // Unless this is the last call, reject inputs which are not multiples of 16 - FailIf(!fLastCall && 0 != cLine % 16, WMP_errMustBeMultipleOf16LinesUntilLastCall); - - if (!pIE->fHeaderDone || BANDEDENCSTATE_INIT == pIE->WMP.eBandedEncState) - { - PI.pGUIDPixFmt = &pIE->guidPixFormat; - PixelFormatLookup(&PI, LOOKUP_FORWARD); - pIE->WMP.bHasAlpha = !!(PI.grBit & PK_pixfmtHasAlpha); - fPI = TRUE; - - // Check if this is planar alpha: banded encode requires temp file - if (pIE->WMP.bHasAlpha && pIE->WMP.wmiSCP.uAlphaMode == 2) - { - FailIf(NULL == pPATempFile, WMP_errPlanarAlphaBandedEncRequiresTempFile); - } - } - - if (!pIE->fHeaderDone) - { - // write metadata - assert(fPI); - Call(WriteContainerPre(pIE)); - pIE->fHeaderDone = !FALSE; - } - - if (BANDEDENCSTATE_INIT == pIE->WMP.eBandedEncState) - { - // Record start of main content for future call to WriteContainerPost - size_t offPos; - Call(pIE->pStream->GetPos(pIE->pStream, &offPos)); - pIE->WMP.nOffImage = (Long)offPos; - - assert(fPI); - Call(PKImageEncode_EncodeContent_Init(pIE, PI, cLine, pbPixels, cbStride)); - pIE->WMP.eBandedEncState = BANDEDENCSTATE_ENCODING; - } - - Call(PKImageEncode_EncodeContent_Encode(pIE, cLine, pbPixels, cbStride)); - if (pIE->WMP.bHasAlpha && pIE->WMP.wmiSCP.uAlphaMode == 2) - { - //planar alpha - if (BANDEDENCSTATE_INIT == eEncStateOrig) - { - size_t offStart; - - // We assume the following which allows us to avoid saving state - Call(pPATempFile->GetPos(pPATempFile, &offStart)); - assert(0 == offStart); - assert(pIE->WMP.wmiSCP_Alpha.pWStream == pIE->WMP.wmiSCP.pWStream); - - // For planar alpha, we write the file to a temp file - pIE->WMP.wmiSCP_Alpha.pWStream = pPATempFile; - Call(PKImageEncode_EncodeAlpha_Init(pIE, PI, cLine, pbPixels, cbStride)); - } - - Call(PKImageEncode_EncodeAlpha_Encode(pIE, cLine, pbPixels, cbStride)); - } - -Cleanup: - return err; -} - -ERR PKImageEncode_WritePixelsBandedEnd_WMP(PKImageEncode* pIE) -{ - ERR err = WMP_errSuccess; - struct WMPStream *pMainStream = pIE->WMP.wmiSCP.pWStream; - size_t offAlpha; - - assert(BANDEDENCSTATE_ENCODING == pIE->WMP.eBandedEncState); - - // Finish off main content, update its length ptr for WriteContainerPost - Call(PKImageEncode_EncodeContent_Term(pIE)); - Call(pMainStream->GetPos(pIE->pStream, &offAlpha)); - pIE->WMP.nCbImage = (Long)offAlpha - pIE->WMP.nOffImage; - - if (pIE->WMP.bHasAlpha && pIE->WMP.wmiSCP.uAlphaMode == 2) - { - size_t cbAlpha; - size_t cbBytesCopied; - struct WMPStream *pAlphaStream = pIE->WMP.wmiSCP_Alpha.pWStream; - - assert(pAlphaStream != pMainStream); // Otherwise we didn't use a temp file - - // Close it up - this causes write to temp file - Call(PKImageEncode_EncodeAlpha_Term(pIE)); - - // Calculate size of alpha bitstream and its new offset - Call(pAlphaStream->GetPos(pAlphaStream, &cbAlpha)); - - // Copy alpha bitstream to end of main stream - cbBytesCopied = 0; - Call(pAlphaStream->SetPos(pAlphaStream, 0)); - while (cbBytesCopied < cbAlpha) - { - char rgbBuf[TEMPFILE_COPYBUF_SIZE]; - size_t cbCopy; - - cbCopy = MIN(sizeof(rgbBuf), cbAlpha - cbBytesCopied); - Call(pAlphaStream->Read(pAlphaStream, rgbBuf, cbCopy)); - Call(pMainStream->Write(pMainStream, rgbBuf, cbCopy)); - - cbBytesCopied += cbCopy; - } - assert(cbBytesCopied == cbAlpha); - - // Update alpha offset/length for WriteContainerPost - pIE->WMP.nOffAlpha = (Long)offAlpha; - pIE->WMP.nCbAlpha = (Long)cbAlpha; - } - - Call(WriteContainerPost(pIE)); - -Cleanup: - return err; -} - - -ERR PKImageEncode_Transcode_WMP( - PKImageEncode* pIE, - PKImageDecode* pID, - CWMTranscodingParam* pParam) -{ - ERR err = WMP_errSuccess; - Float fResX = 0, fResY = 0; - PKPixelFormatGUID pixGUID = {0}; - CWMTranscodingParam tcParamAlpha; - size_t offPos = 0; - Bool fPlanarAlpha; - PKPixelInfo PI; - - struct WMPStream* pWSDec = NULL; - struct WMPStream* pWSEnc= pIE->pStream; - - // pass through metadata - Call(pID->GetPixelFormat(pID, &pixGUID)); - Call(pIE->SetPixelFormat(pIE, pixGUID)); - - Call(pIE->SetSize(pIE, (I32)pParam->cWidth, (I32)pParam->cHeight)); - - Call(pID->GetResolution(pID, &fResX, &fResY)); - Call(pIE->SetResolution(pIE, fResX, fResY)); - - PI.pGUIDPixFmt = &pIE->guidPixFormat; - PixelFormatLookup(&PI, LOOKUP_FORWARD); - pIE->WMP.bHasAlpha = !!(PI.grBit & PK_pixfmtHasAlpha) && (2 == pParam->uAlphaMode); - assert(0 == pIE->WMP.bHasAlpha || (pParam->uAlphaMode == 2)); // Decode alpha mode does not match encode alpha mode! - - // Check for any situations where transcoder is being asked to convert alpha - we can't do this - // NOTE: Decoder's bHasAlpha parameter really means, "has PLANAR alpha" - PI.pGUIDPixFmt = &pixGUID; - PixelFormatLookup(&PI, LOOKUP_FORWARD); - FailIf(0 == (PI.grBit & PK_pixfmtHasAlpha) && pParam->uAlphaMode != 0, - WMP_errAlphaModeCannotBeTranscoded); // Destination is planar/interleaved, src has no alpha - FailIf(!!(PI.grBit & PK_pixfmtHasAlpha) && 2 == pParam->uAlphaMode && - FALSE == pID->WMP.bHasAlpha, WMP_errAlphaModeCannotBeTranscoded); // Destination is planar, src is interleaved - FailIf(!!(PI.grBit & PK_pixfmtHasAlpha) && 3 == pParam->uAlphaMode && - pID->WMP.bHasAlpha, WMP_errAlphaModeCannotBeTranscoded); // Destination is interleaved, src is planar - assert(/*pParam->uAlphaMode >= 0 &&*/ pParam->uAlphaMode <= 3); // All the above statements make this assumption - - fPlanarAlpha = pIE->WMP.bHasAlpha && (2 == pParam->uAlphaMode); - - // write matadata - Call(WriteContainerPre(pIE)); - - // Copy transcoding params for alpha (codec changes the struct) - if (fPlanarAlpha) - tcParamAlpha = *pParam; - - // write compressed bitstream - Call(pID->GetRawStream(pID, &pWSDec)); - - FailIf(ICERR_OK != WMPhotoTranscode(pWSDec, pWSEnc, pParam), WMP_errFail); - Call(pIE->pStream->GetPos(pIE->pStream, &offPos)); - pIE->WMP.nCbImage = (Long)offPos - pIE->WMP.nOffImage; - - if (fPlanarAlpha) - { - pIE->WMP.nOffAlpha = (Long)offPos; - - // Cue the stream to alpha block - assert(pID->WMP.wmiDEMisc.uAlphaOffset > 0); - Call(pWSDec->SetPos(pWSDec, pID->WMP.wmiDEMisc.uAlphaOffset)); - - FailIf(ICERR_OK != WMPhotoTranscode(pWSDec, pWSEnc, &tcParamAlpha), WMP_errFail); - Call(pIE->pStream->GetPos(pIE->pStream, &offPos)); - pIE->WMP.nCbAlpha = (Long)offPos - pIE->WMP.nOffAlpha; - } - - // fixup matadata - Call(WriteContainerPost(pIE)); - -Cleanup: - return err; -} - -ERR PKImageEncode_CreateNewFrame_WMP( - PKImageEncode* pIE, - void* pvParam, - size_t cbParam) -{ - ERR err = WMP_errSuccess; - - //UNREFERENCED_PARAMETER( pIE ); - //UNREFERENCED_PARAMETER( pvParam ); - //UNREFERENCED_PARAMETER( cbParam ); - - Call(WMP_errNotYetImplemented); - -Cleanup: - return err; -} - -ERR PKImageEncode_Release_WMP( - PKImageEncode** ppIE) -{ - ERR err = WMP_errSuccess; - - PKImageEncode *pIE = *ppIE; - pIE->pStream->Close(&pIE->pStream); - - PKFree((void **) &pIE->pbColorContext); - pIE->cbColorContext = 0; - PKFree((void **) &pIE->pbXMPMetadata); - pIE->cbXMPMetadataByteCount = 0; - PKFree((void **) &pIE->pbEXIFMetadata); - pIE->cbEXIFMetadataByteCount = 0; - PKFree((void **) &pIE->pbGPSInfoMetadata); - pIE->cbGPSInfoMetadataByteCount = 0; - PKFree((void **) &pIE->pbIPTCNAAMetadata); - pIE->cbIPTCNAAMetadataByteCount = 0; - PKFree((void **) &pIE->pbPhotoshopMetadata); - pIE->cbPhotoshopMetadataByteCount = 0; - - // Free descriptive metadata - FreeDescMetadata(&pIE->sDescMetadata.pvarImageDescription); - FreeDescMetadata(&pIE->sDescMetadata.pvarCameraMake); - FreeDescMetadata(&pIE->sDescMetadata.pvarCameraModel); - FreeDescMetadata(&pIE->sDescMetadata.pvarSoftware); - FreeDescMetadata(&pIE->sDescMetadata.pvarDateTime); - FreeDescMetadata(&pIE->sDescMetadata.pvarArtist); - FreeDescMetadata(&pIE->sDescMetadata.pvarCopyright); - FreeDescMetadata(&pIE->sDescMetadata.pvarRatingStars); - FreeDescMetadata(&pIE->sDescMetadata.pvarRatingValue); - FreeDescMetadata(&pIE->sDescMetadata.pvarCaption); - FreeDescMetadata(&pIE->sDescMetadata.pvarDocumentName); - FreeDescMetadata(&pIE->sDescMetadata.pvarPageName); - FreeDescMetadata(&pIE->sDescMetadata.pvarPageNumber); - FreeDescMetadata(&pIE->sDescMetadata.pvarHostComputer); - - Call(PKFree((void **) ppIE)); - -Cleanup: - return err; -} - -//---------------------------------------------------------------- -ERR PKImageEncode_Create_WMP(PKImageEncode** ppIE) -{ - ERR err = WMP_errSuccess; - - PKImageEncode* pIE = NULL; - - Call(PKImageEncode_Create(ppIE)); - - pIE = *ppIE; - pIE->Initialize = PKImageEncode_Initialize_WMP; - pIE->Terminate = PKImageEncode_Terminate_WMP; - pIE->SetColorContext = PKImageEncode_SetColorContext_WMP; - pIE->SetDescriptiveMetadata = PKImageEncode_SetDescriptiveMetadata_WMP; - pIE->WritePixels = PKImageEncode_WritePixels_WMP; - - pIE->WritePixelsBandedBegin = PKImageEncode_WritePixelsBandedBegin_WMP; - pIE->WritePixelsBanded = PKImageEncode_WritePixelsBanded_WMP; - pIE->WritePixelsBandedEnd = PKImageEncode_WritePixelsBandedEnd_WMP; - - pIE->Transcode = PKImageEncode_Transcode_WMP; - pIE->CreateNewFrame = PKImageEncode_CreateNewFrame_WMP; - pIE->Release = PKImageEncode_Release_WMP; - pIE->bWMP = TRUE; - -Cleanup: - return err; -} - - -//================================================================ -// PKImageDecode_WMP -//================================================================ -ERR ParsePFDEntry( - PKImageDecode* pID, - U16 uTag, - U16 uType, - U32 uCount, - U32 uValue) -{ - ERR err = WMP_errSuccess; - ERR errTmp = WMP_errSuccess; - PKPixelInfo PI; - struct WMPStream* pWS = pID->pStream; - // size_t offPos = 0; - - union uf{ - U32 uVal; - Float fVal; - }ufValue = {0}; - - //================================ - switch (uTag) - { - case WMP_tagPixelFormat: - { - unsigned char *pGuid = (unsigned char *) &pID->guidPixFormat; - /** following code is endian-agnostic **/ - Call(GetULong(pWS, uValue, (U32 *)pGuid)); - Call(GetUShort(pWS, uValue + 4, (unsigned short *)(pGuid + 4))); - Call(GetUShort(pWS, uValue + 6, (unsigned short *)(pGuid + 6))); - Call(pWS->Read(pWS, pGuid + 8, 8)); - - PI.pGUIDPixFmt = &pID->guidPixFormat; - PixelFormatLookup(&PI, LOOKUP_FORWARD); - - pID->WMP.bHasAlpha = !!(PI.grBit & PK_pixfmtHasAlpha); - pID->WMP.wmiI.cBitsPerUnit = PI.cbitUnit; - pID->WMP.wmiI.bRGB = !(PI.grBit & PK_pixfmtBGR); - - break; - } - - case WMP_tagTransformation: - FailIf(1 != uCount, WMP_errUnsupportedFormat); - assert(uValue < O_MAX); - pID->WMP.fOrientationFromContainer = TRUE; - pID->WMP.oOrientationFromContainer = uValue; - break; - - case WMP_tagImageWidth: - FailIf(0 == uValue, WMP_errUnsupportedFormat); - break; - - case WMP_tagImageHeight: - FailIf(0 == uValue, WMP_errUnsupportedFormat); - break; - - case WMP_tagImageOffset: - FailIf(1 != uCount, WMP_errUnsupportedFormat); - pID->WMP.wmiDEMisc.uImageOffset = uValue; - break; - - case WMP_tagImageByteCount: - FailIf(1 != uCount, WMP_errUnsupportedFormat); - pID->WMP.wmiDEMisc.uImageByteCount = uValue; - break; - - case WMP_tagAlphaOffset: - FailIf(1 != uCount, WMP_errUnsupportedFormat); - pID->WMP.wmiDEMisc.uAlphaOffset = uValue; - break; - - case WMP_tagAlphaByteCount: - FailIf(1 != uCount, WMP_errUnsupportedFormat); - pID->WMP.wmiDEMisc.uAlphaByteCount = uValue; - break; - - case WMP_tagWidthResolution: - FailIf(1 != uCount, WMP_errUnsupportedFormat); - ufValue.uVal = uValue; - pID->fResX = ufValue.fVal; - break; - - case WMP_tagHeightResolution: - FailIf(1 != uCount, WMP_errUnsupportedFormat); - ufValue.uVal = uValue; - pID->fResY = ufValue.fVal; - break; - - case WMP_tagIccProfile: - pID->WMP.wmiDEMisc.uColorProfileByteCount = uCount; - pID->WMP.wmiDEMisc.uColorProfileOffset = uValue; - break; - - case WMP_tagXMPMetadata: - pID->WMP.wmiDEMisc.uXMPMetadataByteCount = uCount; - pID->WMP.wmiDEMisc.uXMPMetadataOffset = uValue; - break; - - case WMP_tagEXIFMetadata: - pID->WMP.wmiDEMisc.uEXIFMetadataOffset = uValue; - CallIgnoreError(errTmp, StreamCalcIFDSize(pWS, uValue, &pID->WMP.wmiDEMisc.uEXIFMetadataByteCount)); - break; - - case WMP_tagGPSInfoMetadata: - pID->WMP.wmiDEMisc.uGPSInfoMetadataOffset = uValue; - CallIgnoreError(errTmp, StreamCalcIFDSize(pWS, uValue, &pID->WMP.wmiDEMisc.uGPSInfoMetadataByteCount)); - break; - - case WMP_tagIPTCNAAMetadata: - pID->WMP.wmiDEMisc.uIPTCNAAMetadataByteCount = uCount; - pID->WMP.wmiDEMisc.uIPTCNAAMetadataOffset = uValue; - break; - - case WMP_tagPhotoshopMetadata: - pID->WMP.wmiDEMisc.uPhotoshopMetadataByteCount = uCount; - pID->WMP.wmiDEMisc.uPhotoshopMetadataOffset = uValue; - break; - - case WMP_tagCompression: - case WMP_tagImageType: - case WMP_tagImageDataDiscard: - case WMP_tagAlphaDataDiscard: - break; - - // Descriptive Metadata - case WMP_tagImageDescription: - CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, - &pID->WMP.sDescMetadata.pvarImageDescription)); - assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarImageDescription.vt); - break; - - case WMP_tagCameraMake: - CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, - &pID->WMP.sDescMetadata.pvarCameraMake)); - assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarCameraMake.vt); - break; - - case WMP_tagCameraModel: - CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, - &pID->WMP.sDescMetadata.pvarCameraModel)); - assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarCameraModel.vt); - break; - - case WMP_tagSoftware: - CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, - &pID->WMP.sDescMetadata.pvarSoftware)); - assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarSoftware.vt); - break; - - case WMP_tagDateTime: - CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, - &pID->WMP.sDescMetadata.pvarDateTime)); - assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarDateTime.vt); - break; - - case WMP_tagArtist: - CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, - &pID->WMP.sDescMetadata.pvarArtist)); - assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarArtist.vt); - break; - - case WMP_tagCopyright: - CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, - &pID->WMP.sDescMetadata.pvarCopyright)); - assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarCopyright.vt); - break; - - case WMP_tagRatingStars: - CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, - &pID->WMP.sDescMetadata.pvarRatingStars)); - assert(DPKVT_UI2 == pID->WMP.sDescMetadata.pvarRatingStars.vt); - break; - - case WMP_tagRatingValue: - CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, - &pID->WMP.sDescMetadata.pvarRatingValue)); - assert(DPKVT_UI2 == pID->WMP.sDescMetadata.pvarRatingValue.vt); - break; - - case WMP_tagCaption: - CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, - &pID->WMP.sDescMetadata.pvarCaption)); - assert((DPKVT_BYREF | DPKVT_UI1) == pID->WMP.sDescMetadata.pvarCaption.vt); - - // Change type from C-style byte array to LPWSTR - assert((U8*)pID->WMP.sDescMetadata.pvarCaption.VT.pwszVal == - pID->WMP.sDescMetadata.pvarCaption.VT.pbVal); - assert(0 == pID->WMP.sDescMetadata.pvarCaption.VT.pwszVal[uCount/sizeof(U16) - 1]); // Confirm null-term - // make sure null term (ReadPropvar allocated enough space for this) - pID->WMP.sDescMetadata.pvarCaption.VT.pwszVal[uCount/sizeof(U16)] = 0; - pID->WMP.sDescMetadata.pvarCaption.vt = DPKVT_LPWSTR; - break; - - case WMP_tagDocumentName: - CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, - &pID->WMP.sDescMetadata.pvarDocumentName)); - assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarDocumentName.vt); - break; - - case WMP_tagPageName: - CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, - &pID->WMP.sDescMetadata.pvarPageName)); - assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarPageName.vt); - break; - - case WMP_tagPageNumber: - CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, - &pID->WMP.sDescMetadata.pvarPageNumber)); - assert(DPKVT_UI4 == pID->WMP.sDescMetadata.pvarPageNumber.vt); - break; - - case WMP_tagHostComputer: - CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue, - &pID->WMP.sDescMetadata.pvarHostComputer)); - assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarHostComputer.vt); - break; - - default: - /*fprintf(stderr, "Unrecognized WMPTag: %d(%#x), %d, %d, %#x" CRLF, - (int)uTag, (int)uTag, (int)uType, (int)uCount, (int)uValue);*/ - break; - } - -Cleanup: - return err; -} - -ERR ParsePFD( - PKImageDecode* pID, - size_t offPos, - U16 cEntry) -{ - ERR err = WMP_errSuccess; - struct WMPStream* pWS = pID->pStream; - U16 i = 0; - - for (i = 0; i < cEntry; ++i) - { - U16 uTag = 0; - U16 uType = 0; - U32 uCount = 0; - U32 uValue = 0; - - Call(GetUShort(pWS, offPos, &uTag)); offPos += 2; - Call(GetUShort(pWS, offPos, &uType)); offPos += 2; - Call(GetULong(pWS, offPos, &uCount)); offPos += 4; - Call(GetULong(pWS, offPos, &uValue)); offPos += 4; - - Call(ParsePFDEntry(pID, uTag, uType, uCount, uValue)); - } - - pID->WMP.bHasAlpha = ((pID->WMP.bHasAlpha) && (pID->WMP.wmiDEMisc.uAlphaOffset != 0) && (pID->WMP.wmiDEMisc.uAlphaByteCount != 0));//has planar alpha - -Cleanup: - return err; -} - -ERR ReadContainer( - PKImageDecode* pID) -{ - ERR err = WMP_errSuccess; - - struct WMPStream* pWS = pID->pStream; - size_t offPos = 0; - - char szSig[2] = {0}; - U16 uWmpID = 0; - U32 offPFD = 0; - U16 cPFDEntry = 0; - U8 bVersion; - - //================================ - Call(pWS->GetPos(pWS, &offPos)); - FailIf(0 != offPos, WMP_errUnsupportedFormat); - - //================================ - // Header - Call(pWS->Read(pWS, szSig, sizeof(szSig))); offPos += 2; - FailIf(szSig != strstr(szSig, "II"), WMP_errUnsupportedFormat); - - Call(GetUShort(pWS, offPos, &uWmpID)); offPos += 2; - FailIf(WMP_valWMPhotoID != (0x00FF & uWmpID), WMP_errUnsupportedFormat); - - // We accept version 00 and version 01 bitstreams - all others rejected - bVersion = (0xFF00 & uWmpID) >> 8; - FailIf(bVersion != 0 && bVersion != 1, WMP_errUnsupportedFormat); - - Call(GetULong(pWS, offPos, &offPFD)); offPos += 4; - - //================================ - // PFD - offPos = (size_t)offPFD; - Call(GetUShort(pWS, offPos, &cPFDEntry)); offPos += 2; - FailIf(0 == cPFDEntry || USHRT_MAX == cPFDEntry, WMP_errUnsupportedFormat); - Call(ParsePFD(pID, offPos, cPFDEntry)); - - //================================ - Call(pWS->SetPos(pWS, pID->WMP.wmiDEMisc.uImageOffset)); - -Cleanup: - return err; -} - - -//================================================ -ERR PKImageDecode_Initialize_WMP( - PKImageDecode* pID, - struct WMPStream* pWS) -{ - ERR err = WMP_errSuccess; - - CWMImageInfo* pII = NULL; - - //================================ - Call(PKImageDecode_Initialize(pID, pWS)); - - //================================ - Call(ReadContainer(pID)); - - //================================ - pID->WMP.wmiSCP.pWStream = pWS; - pID->WMP.DecoderCurrMBRow = 0; - pID->WMP.cLinesDecoded = 0; - pID->WMP.cLinesCropped = 0; - pID->WMP.fFirstNonZeroDecode = FALSE; - - FailIf(ICERR_OK != ImageStrDecGetInfo(&pID->WMP.wmiI, &pID->WMP.wmiSCP), WMP_errFail); - assert(Y_ONLY <= pID->WMP.wmiSCP.cfColorFormat && pID->WMP.wmiSCP.cfColorFormat < CFT_MAX); - assert(BD_SHORT == pID->WMP.wmiSCP.bdBitDepth || BD_LONG == pID->WMP.wmiSCP.bdBitDepth); - - // If HD Photo container provided an orientation, this should override bitstream orientation - // If container did NOT provide an orientation, force O_NONE. This is to be consistent with - // Vista behaviour, which is to ignore bitstream orientation (only looks at container). - if (pID->WMP.fOrientationFromContainer) - { - pID->WMP.wmiI.oOrientation = pID->WMP.oOrientationFromContainer; - } - else - { - // Force to O_NONE to match Vista decode behaviour - pID->WMP.wmiI.oOrientation = O_NONE; - } - - pII = &pID->WMP.wmiI; - pID->uWidth = (U32)pII->cWidth; - pID->uHeight = (U32)pII->cHeight; - -Cleanup: - return err; -} - - -ERR PKImageDecode_GetSize_WMP( - PKImageDecode* pID, - I32* piWidth, - I32* piHeight) -{ - if (pID->WMP.wmiI.oOrientation >= O_RCW) - { - *piWidth = (I32)pID->uHeight; - *piHeight = (I32)pID->uWidth; - } - else - { - *piWidth = (I32)pID->uWidth; - *piHeight = (I32)pID->uHeight; - } - return WMP_errSuccess; -} - - -ERR PKImageDecode_GetRawStream_WMP( - PKImageDecode* pID, - struct WMPStream** ppWS) -{ - ERR err = WMP_errSuccess; - struct WMPStream* pWS = pID->pStream; - - *ppWS = NULL; - Call(pWS->SetPos(pWS, pID->WMP.wmiDEMisc.uImageOffset)); - *ppWS = pWS; - -Cleanup: - return err; -} - -ERR PKImageDecode_Copy_WMP( - PKImageDecode* pID, - const PKRect* pRect, - U8* pb, - U32 cbStride) -{ - ERR err = WMP_errSuccess; - U32 cThumbnailScale; - U32 linesperMBRow; - CWMImageBufferInfo wmiBI = { 0 }; -#ifdef REENTRANT_MODE - U8 *pbLowMemAdj = NULL; - U32 i, cMBRow; - U32 cMBRowStart; -#endif // REENTRANT_MODE - struct WMPStream* pWS = pID->pStream; - U8 tempAlphaMode = 0; - wmiBI.pv = pb; - wmiBI.cLine = pRect->Height; - wmiBI.cbStride = cbStride; -#ifdef REENTRANT_MODE - // In REENTRANT_MODE, we allow rectangles with any top left corner (not just (0,0)) -#else - FailIf(0 != pRect->X, WMP_errInvalidParameter); - FailIf(0 != pRect->Y, WMP_errInvalidParameter); -#endif // REENTRANT_MODE - - cThumbnailScale = 1; - if (pID->WMP.wmiI.cThumbnailWidth > 0) - { - while(cThumbnailScale * pID->WMP.wmiI.cThumbnailWidth < pID->uWidth) - cThumbnailScale <<= 1; - } - // note the following implementation can't handle fractional linesperMBRow limiting - // us to >= 1/256 thumbnail which is unfortunate, but all the PS plugin needs is 1/256 - // and I didn't care to get into floating point or a bunch of conditional tests or - // other rewrite for a case not needed nor tested by PS plugin. sorry. - linesperMBRow = 16 / cThumbnailScale; - -#ifdef REENTRANT_MODE - if (0 == pID->WMP.DecoderCurrMBRow) - { -#endif // REENTRANT_MODE - // Set the fPaddedUserBuffer if the following conditions are met - if (0 == ((size_t)pb % 128) && // Frame buffer is aligned to 128-byte boundary - 0 == (pRect->Height % 16) && // Horizontal resolution is multiple of 16 - 0 == (pRect->Width % 16) && // Vertical resolution is multiple of 16 - 0 == (cbStride % 128)) // Stride is a multiple of 128 bytes - { - pID->WMP.wmiI.fPaddedUserBuffer = TRUE; - // Note that there are additional conditions in strdec_x86.c's strDecOpt - // which could prevent optimization from being engaged - } -#ifdef REENTRANT_MODE - } -#endif // REENTRANT_MODE - //if(pID->WMP.wmiSCP.uAlphaMode != 1) - if((!pID->WMP.bHasAlpha) || (pID->WMP.wmiSCP.uAlphaMode != 1)) - { - if(pID->WMP.bHasAlpha)//planar alpha - { - tempAlphaMode = pID->WMP.wmiSCP.uAlphaMode; - pID->WMP.wmiSCP.uAlphaMode = 0; - } - pID->WMP.wmiSCP.fMeasurePerf = TRUE; -#ifdef REENTRANT_MODE - if (0 == pID->WMP.DecoderCurrMBRow) - { - Call(pID->WMP.wmiSCP.pWStream->GetPos(pID->WMP.wmiSCP.pWStream, &(pID->WMP.cMarker))); - FailIf(ICERR_OK != ImageStrDecInit(&pID->WMP.wmiI, &pID->WMP.wmiSCP, &pID->WMP.ctxSC), WMP_errFail); - } - // Re-entrant mode incurs 1 MBR delay, so to get 0th MBR, we have to ask for 1st MBR - cMBRow = ((U32) pID->WMP.cLinesCropped + pRect->Y + pRect->Height + - (pRect->Y + pRect->Height >= (I32) pID->WMP.wmiI.cROIHeight ? linesperMBRow - 1 : 0)) / // round up if last MBR - linesperMBRow + 1; - cMBRowStart = ((U32) pID->WMP.cLinesCropped + pRect->Y) / linesperMBRow + 1; - // if current request starts before current state, then rewind. - if (cMBRowStart < pID->WMP.DecoderCurrMBRow) - { - pID->WMP.DecoderCurrMBRow = 0; - pID->WMP.cLinesDecoded = 0; - pID->WMP.cLinesCropped = 0; - pID->WMP.fFirstNonZeroDecode = FALSE; - FailIf(ICERR_OK != ImageStrDecTerm(pID->WMP.ctxSC), WMP_errFail); - Call(pID->WMP.wmiSCP.pWStream->SetPos(pID->WMP.wmiSCP.pWStream, pID->WMP.cMarker)); - FailIf(ICERR_OK != ImageStrDecInit(&pID->WMP.wmiI, &pID->WMP.wmiSCP, &pID->WMP.ctxSC), WMP_errFail); - } - - // In "Low Memory mode", we don't have full frame buffer. We therefore cannot rotate the image. - // We can flip H, V and HV, but no rotations. - FailIf(pID->WMP.wmiI.oOrientation >= O_RCW, WMP_errFail); - - // In low-memory mode, the full frame buffer is unavailable. This doesn't seem to - // matter in O_NONE and O_FLIPH, but for O_FLIPV and O_FLIPVH, outputMBRow tries to write to - // the bottom of full-frame buffer. Adjust the buffer pointer to compensate. - if (O_FLIPV == pID->WMP.wmiI.oOrientation || O_FLIPVH == pID->WMP.wmiI.oOrientation) - { - I32 iActualY2 = pRect->Y + pRect->Height; - pbLowMemAdj = pb - (pID->WMP.wmiI.cROIHeight - (iActualY2 - pID->WMP.cLinesCropped)) * cbStride; - } - else - { - pbLowMemAdj = pb - pRect->Y * cbStride; - } - wmiBI.pv = pbLowMemAdj; - - for (i = (U32)pID->WMP.DecoderCurrMBRow; i < cMBRow; i++) - { - size_t cLinesDecoded; - wmiBI.uiFirstMBRow = i; - wmiBI.uiLastMBRow = i; - FailIf(ICERR_OK != ImageStrDecDecode(pID->WMP.ctxSC, &wmiBI, &cLinesDecoded), WMP_errFail); - pID->WMP.cLinesDecoded = cLinesDecoded; - if (FALSE == pID->WMP.fFirstNonZeroDecode && cLinesDecoded > 0) - { - pID->WMP.cLinesCropped += (linesperMBRow - cLinesDecoded); - pID->WMP.fFirstNonZeroDecode = TRUE; - // update cMBRow if partial MB row cropped - cMBRow = ((U32) pID->WMP.cLinesCropped + pRect->Y + pRect->Height + - (pRect->Y + pRect->Height >= (I32) pID->WMP.wmiI.cROIHeight ? linesperMBRow - 1 : 0)) / // round up if last MBR - linesperMBRow + 1; - } - - if (0 == cLinesDecoded && i > 0) - { - pID->WMP.cLinesCropped += linesperMBRow; - // update cMBRow if whole MB row cropped - cMBRow++; - } - } - wmiBI.pv = pbLowMemAdj; - - // If we're past the top of the image, then we're done, so terminate. - if ((size_t)linesperMBRow * (cMBRow - 1) >= (U32) pID->WMP.cLinesCropped + pID->WMP.wmiI.cROIHeight) { - FailIf(ICERR_OK != ImageStrDecTerm(pID->WMP.ctxSC), WMP_errFail); - } - pID->WMP.DecoderCurrMBRow = cMBRow; // Set to next possible MBRow that is decodable - -#else - FailIf(ICERR_OK != ImageStrDecInit(&pID->WMP.wmiI, &pID->WMP.wmiSCP, &pID->WMP.ctxSC), WMP_errFail); - FailIf(ICERR_OK != ImageStrDecDecode(pID->WMP.ctxSC, &wmiBI), WMP_errFail); - FailIf(ICERR_OK != ImageStrDecTerm(pID->WMP.ctxSC), WMP_errFail); -#endif //REENTRANT_MODE - - if(pID->WMP.bHasAlpha)//planar alpha - { - pID->WMP.wmiSCP.uAlphaMode = tempAlphaMode; - } - } - -// if(pID->WMP.bHasAlpha && pID->WMP.wmiSCP.uAlphaMode == 2) -// if(pID->WMP.bHasAlpha && pID->WMP.wmiSCP.uAlphaMode != 1) - if(pID->WMP.bHasAlpha && pID->WMP.wmiSCP.uAlphaMode != 0) - { - pID->WMP.wmiI_Alpha = pID->WMP.wmiI; - pID->WMP.wmiSCP_Alpha = pID->WMP.wmiSCP; - -// assert(pID->WMP.wmiI_Alpha.cfColorFormat == CF_RGB); // only RGBA is supported for now! - pID->WMP.wmiI_Alpha.cfColorFormat = Y_ONLY; - - switch (pID->WMP.wmiI.bdBitDepth) - { - case BD_8: - pID->WMP.wmiI_Alpha.cLeadingPadding += (pID->WMP.wmiI.cBitsPerUnit >> 3) - 1; - break; - - case BD_16: - case BD_16S: - case BD_16F: - pID->WMP.wmiI_Alpha.cLeadingPadding += (pID->WMP.wmiI.cBitsPerUnit >> 3) / sizeof(U16) - 1; - break; - - case BD_32: - case BD_32S: - case BD_32F: - pID->WMP.wmiI_Alpha.cLeadingPadding += (pID->WMP.wmiI.cBitsPerUnit >> 3) / sizeof(float) - 1; - break; - - case BD_5: - case BD_10: - case BD_565: - default: - break; - } - - pID->WMP.wmiSCP_Alpha.fMeasurePerf = TRUE; - Call(pWS->SetPos(pWS, pID->WMP.wmiDEMisc.uAlphaOffset)); -#ifdef REENTRANT_MODE - if (0 == pID->WMP.DecoderCurrAlphaMBRow) // add this to WMP struct! - { - FailIf(ICERR_OK != ImageStrDecInit(&pID->WMP.wmiI_Alpha, &pID->WMP.wmiSCP_Alpha, &pID->WMP.ctxSC_Alpha), WMP_errFail); - } - - // Re-entrant mode incurs 1 MBR delay, so to get 0th MBR, we have to ask for 1st MBR - cMBRow = ((U32) pID->WMP.cLinesCropped + pRect->Y + pRect->Height + - (pRect->Y + pRect->Height >= (I32) pID->WMP.wmiI.cROIHeight ? linesperMBRow - 1 : 0)) / // round up if last MBR - linesperMBRow + 1; - cMBRowStart = ((U32) pID->WMP.cLinesCropped + pRect->Y) / linesperMBRow + 1; - // if current request starts before current state, then rewind. - if (cMBRowStart < pID->WMP.DecoderCurrAlphaMBRow) - { - pID->WMP.DecoderCurrAlphaMBRow = 0; - FailIf(ICERR_OK != ImageStrDecTerm(pID->WMP.ctxSC_Alpha), WMP_errFail); - FailIf(ICERR_OK != ImageStrDecInit(&pID->WMP.wmiI_Alpha, &pID->WMP.wmiSCP_Alpha, &pID->WMP.ctxSC_Alpha), WMP_errFail); - } - - for (i = (U32)pID->WMP.DecoderCurrAlphaMBRow; i < cMBRow; i++) - { - size_t cLinesDecoded; - wmiBI.uiFirstMBRow = i; - wmiBI.uiLastMBRow = i; - FailIf(ICERR_OK != ImageStrDecDecode(pID->WMP.ctxSC_Alpha, &wmiBI, &cLinesDecoded), WMP_errFail); - } - - // If we're past the top of the image, then we're done, so terminate - if ((size_t)linesperMBRow * (cMBRow - 1) >= (U32) pID->WMP.cLinesCropped + pID->WMP.wmiI.cROIHeight) { - FailIf(ICERR_OK != ImageStrDecTerm(pID->WMP.ctxSC_Alpha), WMP_errFail); - } - pID->WMP.DecoderCurrAlphaMBRow = cMBRow; // Set to next possible MBRow that is decodable - wmiBI.pv = pb; -#else - FailIf(ICERR_OK != ImageStrDecInit(&pID->WMP.wmiI_Alpha, &pID->WMP.wmiSCP_Alpha, &pID->WMP.ctxSC_Alpha), WMP_errFail); - FailIf(ICERR_OK != ImageStrDecDecode(pID->WMP.ctxSC_Alpha, &wmiBI), WMP_errFail); - FailIf(ICERR_OK != ImageStrDecTerm(pID->WMP.ctxSC_Alpha), WMP_errFail); -#endif //REENTRANT_MODE - } - - pID->idxCurrentLine += pRect->Height; - -Cleanup: - return err; -} - - -ERR PKImageDecode_GetMetadata_WMP(PKImageDecode *pID, U32 uOffset, U32 uByteCount, U8 *pbGot, U32 *pcbGot) -{ - ERR err = WMP_errSuccess; - - if (pbGot && uOffset) - { - struct WMPStream* pWS = pID->pStream; - size_t iCurrPos; - - FailIf(*pcbGot < uByteCount, WMP_errBufferOverflow); - Call(pWS->GetPos(pWS, &iCurrPos)); - Call(pWS->SetPos(pWS, uOffset)); - Call(pWS->Read(pWS, pbGot, uByteCount)); - Call(pWS->SetPos(pWS, iCurrPos)); - } - -Cleanup: - if (Failed(err)) - *pcbGot = 0; - else - *pcbGot = uByteCount; - - return err; -} - - - -ERR PKImageDecode_GetColorContext_WMP(PKImageDecode *pID, U8 *pbColorContext, U32 *pcbColorContext) -{ - return PKImageDecode_GetMetadata_WMP(pID, pID->WMP.wmiDEMisc.uColorProfileOffset, - pID->WMP.wmiDEMisc.uColorProfileByteCount, pbColorContext, pcbColorContext); -} - - -ERR PKImageDecode_GetXMPMetadata_WMP(PKImageDecode *pID, U8 *pbXMPMetadata, U32 *pcbXMPMetadata) -{ - return PKImageDecode_GetMetadata_WMP(pID, pID->WMP.wmiDEMisc.uXMPMetadataOffset, - pID->WMP.wmiDEMisc.uXMPMetadataByteCount, pbXMPMetadata, pcbXMPMetadata); -} - - -ERR PKImageDecode_GetEXIFMetadata_WMP(PKImageDecode *pID, U8 *pbEXIFMetadata, U32 *pcbEXIFMetadata) -{ - return PKImageDecode_GetMetadata_WMP(pID, pID->WMP.wmiDEMisc.uEXIFMetadataOffset, - pID->WMP.wmiDEMisc.uEXIFMetadataByteCount, pbEXIFMetadata, pcbEXIFMetadata); -} - - -ERR PKImageDecode_GetGPSInfoMetadata_WMP(PKImageDecode *pID, U8 *pbGPSInfoMetadata, U32 *pcbGPSInfoMetadata) -{ - return PKImageDecode_GetMetadata_WMP(pID, pID->WMP.wmiDEMisc.uGPSInfoMetadataOffset, - pID->WMP.wmiDEMisc.uGPSInfoMetadataByteCount, pbGPSInfoMetadata, pcbGPSInfoMetadata); -} - - -ERR PKImageDecode_GetIPTCNAAMetadata_WMP(PKImageDecode *pID, U8 *pbIPTCNAAMetadata, U32 *pcbIPTCNAAMetadata) -{ - return PKImageDecode_GetMetadata_WMP(pID, pID->WMP.wmiDEMisc.uIPTCNAAMetadataOffset, - pID->WMP.wmiDEMisc.uIPTCNAAMetadataByteCount, pbIPTCNAAMetadata, pcbIPTCNAAMetadata); -} - - -ERR PKImageDecode_GetPhotoshopMetadata_WMP(PKImageDecode *pID, U8 *pbPhotoshopMetadata, U32 *pcbPhotoshopMetadata) -{ - return PKImageDecode_GetMetadata_WMP(pID, pID->WMP.wmiDEMisc.uPhotoshopMetadataOffset, - pID->WMP.wmiDEMisc.uPhotoshopMetadataByteCount, pbPhotoshopMetadata, pcbPhotoshopMetadata); -} - - -ERR PKImageDecode_GetDescriptiveMetadata_WMP(PKImageDecode *pID, DESCRIPTIVEMETADATA *pDescMetadata) -{ - ERR err = WMP_errSuccess; - *pDescMetadata = pID->WMP.sDescMetadata; - return err; -} - - -ERR PKImageDecode_Release_WMP(PKImageDecode** ppID) -{ - ERR err = WMP_errSuccess; - PKImageDecode *pID; - - if (NULL == ppID) - goto Cleanup; - - pID = *ppID; - - // Free descriptive metadata - FreeDescMetadata(&pID->WMP.sDescMetadata.pvarImageDescription); - FreeDescMetadata(&pID->WMP.sDescMetadata.pvarCameraMake); - FreeDescMetadata(&pID->WMP.sDescMetadata.pvarCameraModel); - FreeDescMetadata(&pID->WMP.sDescMetadata.pvarSoftware); - FreeDescMetadata(&pID->WMP.sDescMetadata.pvarDateTime); - FreeDescMetadata(&pID->WMP.sDescMetadata.pvarArtist); - FreeDescMetadata(&pID->WMP.sDescMetadata.pvarCopyright); - FreeDescMetadata(&pID->WMP.sDescMetadata.pvarRatingStars); - FreeDescMetadata(&pID->WMP.sDescMetadata.pvarRatingValue); - FreeDescMetadata(&pID->WMP.sDescMetadata.pvarCaption); - FreeDescMetadata(&pID->WMP.sDescMetadata.pvarDocumentName); - FreeDescMetadata(&pID->WMP.sDescMetadata.pvarPageName); - FreeDescMetadata(&pID->WMP.sDescMetadata.pvarPageNumber); - FreeDescMetadata(&pID->WMP.sDescMetadata.pvarHostComputer); - - // Release base class - Call(PKImageDecode_Release(ppID)); - -Cleanup: - return err; -} - - - -ERR PKImageDecode_Create_WMP(PKImageDecode** ppID) -{ - ERR err = WMP_errSuccess; - PKImageDecode* pID = NULL; - - Call(PKImageDecode_Create(ppID)); - - pID = *ppID; - pID->Initialize = PKImageDecode_Initialize_WMP; - pID->GetSize = PKImageDecode_GetSize_WMP; - pID->GetRawStream = PKImageDecode_GetRawStream_WMP; - pID->Copy = PKImageDecode_Copy_WMP; - pID->GetColorContext = PKImageDecode_GetColorContext_WMP; - pID->GetDescriptiveMetadata = PKImageDecode_GetDescriptiveMetadata_WMP; - pID->Release = PKImageDecode_Release_WMP; - -Cleanup: - return err; -} - diff --git a/Src/JxrDecode/Jxr/JXRGluePFC.c b/Src/JxrDecode/Jxr/JXRGluePFC.c deleted file mode 100644 index e2a29a5e..00000000 --- a/Src/JxrDecode/Jxr/JXRGluePFC.c +++ /dev/null @@ -1,2338 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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 - -#include "JXRGlue.h" -#include - -//================================================================ -// PKFormatConverter -//================================================================ -#define HLF_MIN 0.00006103515625f -#define HLF_MAX 65504.0f - -#define HLF_MIN_BITS 0x0400 -#define HLF_MAX_BITS 0x7bff - -#define HLF_MIN_BITS_NEG (HLF_MIN_BITS | 0x8000) -#define HLF_MAX_BITS_NEG (HLF_MAX_BITS | 0x8000) - -#define HLF_QNaN_BITZS 0x7fff - -// simple and slow implementation of half <-> float conversion -static U32 Convert_Half_To_Float(U16 u16) -{ - // 1s5e10m -> 1s8e23m - const U32 s = (u16 >> 15) & 0x0001; - const U32 e = (u16 >> 10) & 0x001f; - const U32 m = (u16 >> 0) & 0x03ff; - - if (0 == e) // 0, denorm - { - return s << 31; - } - else if (~(0xffffffe0/*~0 << 5*/) == e) // inf, snan, qnan - { - return (s << 31) | ~(0xffffff00/*~0 << 8*/) << 23| (m << 13); - } - - return (s << 31) | ((e - 15 + 127) << 23) | (m << 13); // norm -} - - -static U16 Convert_Float_To_Half(float f) -{ - // 1s5e10m -> 1s8e23m - const U32 iFloat = *(U32*)&f; // Convert float to U32 - - if (f != f) - { - return (U16)(iFloat | HLF_QNaN_BITZS); // +QNaN, -QNaN - } - else if (f < -HLF_MAX) - { - return HLF_MAX_BITS_NEG; - } - else if (HLF_MAX < f) - { - return HLF_MAX_BITS; - } - else if (-HLF_MIN < f && f < HLF_MIN) - { - return (U16)((iFloat >> 16) & 0x8000); // +0, -0 - } - - // Cut-and-paste from C++, introduce scope so we can decl more vars - { - const U32 s = (iFloat >> 31) & 0x00000001; - const U32 e = (iFloat >> 23) & 0x000000ff; - const U32 m = (iFloat >> 0) & 0x007fffff; - - return (U16) ((s << 15) | ((e - 127 + 15) << 10) | (m >> 13)); - } -} - - -static U8 Convert_Float_To_U8(float f) -{ - // convert from linear scRGB to non-linear sRGB - if (f <= 0) - { - return 0; - } - else if (f <= 0.0031308f) - { - return (U8)((255.0f * f * 12.92f) + 0.5f); - } - else if (f < 1.0f) - { - return (U8)((255.0f * ((1.055f * (float)pow(f, 1.0 / 2.4)) - 0.055f)) + 0.5f); - } - else - { - return 255; - } -} - -static U8 Convert_AlphaFloat_To_U8(float f) -{ - // alpha is converted differently than RGB in scRGB - if (f <= 0) - { - return 0; - } - else if (f < 1.0f) - { - return (U8)((255.0f * f) + 0.5f); - } - else - { - return 255; - } -} - - -ERR RGB24_BGR24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - I32 i = 0, j = 0; - -// //UNREFERENCED_PARAMETER( pFC ); - - for (i = 0; i < pRect->Height; ++i) - { - for (j = 0; j < pRect->Width * 3; j += 3) - { - // swap red with blue - U8 t = pb[j]; - pb[j] = pb[j + 2]; - pb[j + 2] = t; - } - - pb += cbStride; - } - - return WMP_errSuccess; -} - -ERR BGR24_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - return RGB24_BGR24(pFC, pRect, pb, cbStride); -} - -ERR RGB24_BGR32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - I32 i = 0, j = 0; - -// //UNREFERENCED_PARAMETER( pFC ); - - for (i = 0; i < pRect->Height; ++i) - { - for (j = 0; j < pRect->Width; j++) - { - // swap red with blue - U8 t = pb[3*j]; - pb[4*j] = pb[3*j + 2]; - pb[4*j + 1] = pb[3*j + 1]; - pb[4*j + 2] = t; - } - - pb += cbStride; - } - - return WMP_errSuccess; -} - -ERR BGR32_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - I32 i = 0, j = 0; - -// //UNREFERENCED_PARAMETER( pFC ); - - for (i = 0; i < pRect->Height; ++i) - { - for (j = 0; j < pRect->Width; j++) - { - // swap red with blue - U8 t = pb[4*j]; - pb[3*j] = pb[4*j + 2]; - pb[3*j + 1] = pb[4*j + 1]; - pb[3*j + 2] = t; - } - - pb += cbStride; - } - - return WMP_errSuccess; -} - -ERR RGB24_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - I32 i = 0, j = 0, k = 0; - -// //UNREFERENCED_PARAMETER( pFC ); - - for (i = 0; i < pRect->Height; ++i) - { - for (j = 0, k = 0; j < pRect->Width * 3; j += 3, ++k) - { - U8 r = pb[j]; - U8 g = pb[j + 1]; - U8 b = pb[j + 2]; - - pb[k] = r / 4 + g / 2 + b / 8 + 16; - } - - pb += cbStride; - } - - return WMP_errSuccess; -} - -ERR BGR24_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - ERR err = WMP_errSuccess; - - Call(BGR24_RGB24(pFC, pRect, pb, cbStride)); - Call(RGB24_Gray8(pFC, pRect, pb, cbStride)); - -Cleanup: - return err; -} - -ERR Gray8_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - I32 i = 0, j = 0, k = 0; - -// //UNREFERENCED_PARAMETER( pFC ); - - for (i = 0; i < pRect->Height; ++i) - { - for (j = pRect->Width - 1, k = 3 * j; 0 <= j; j--, k -= 3) - { - U8 v = pb[j]; - - pb[k] = v; - pb[k + 1] = v; - pb[k + 2] = v; - } - - pb += cbStride; - } - - return WMP_errSuccess; -} - -ERR Gray8_BGR24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - return Gray8_RGB24(pFC, pRect, pb, cbStride); -} - -#if 0 -ERR RGB48_BGR48(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - ERR err = WMP_errSuccess; - - I32 i = 0, j = 0; - - //UNREFERENCED_PARAMETER( pFC ); - - Call(PKFormatConverter_Copy(pFC, pRect, pb, cbStride)); - - for (i = 0; i < pRect->Height; ++i) - { - for (j = 0; j < pRect->Width; j += 3) - { - U16* ps = (U16*)pb; - - // swap red with blue - U16 t = ps[j]; - ps[j] = ps[j + 2]; - ps[j + 2] = t; - } - - pb += cbStride; - } - -Cleanup: - return err; -} - -ERR BGR48_RGB48(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - return RGB48_BGR48(pFC, pRect, pb, cbStride); -} - -ERR RGB48_Gray16(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - ERR err = WMP_errSuccess; - - I32 i = 0, j = 0, k = 0; - - //UNREFERENCED_PARAMETER( pFC ); - - Call(PKFormatConverter_Copy(pFC, pRect, pb, cbStride)); - - for (i = 0; i < pRect->Height; ++i) - { - for (j = 0, k = 0; j < pRect->Width; j += 3, ++k) - { - U16* ps = (U16*)pb; - - // Y = r / 4 + g / 2 + b / 8 + 16 - U16 r = ps[j]; - U16 g = ps[j + 1]; - U16 b = ps[j + 2]; - - ps[k] = r / 4 + g / 2 + b / 8 + 16; - } - - pb += cbStride; - } - -Cleanup: - return err; -} -#endif - -ERR RGBA128Fixed_RGBA128Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidthX4 = 4 * pRect->Width; // 4 == R, G, B, A - const float fltCvtFactor = 1.0F / (1 << 24); - I32 y; - -// //UNREFERENCED_PARAMETER( pFC ); - - for (y = 0; y < iHeight; y++) - { - I32 x; - float *pfltDstPixel = (float*)(pb + cbStride*y); - const I32 *piSrcPixel = (I32*)pfltDstPixel; - - for (x = 0; x < iWidthX4; x++) - pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor; - } - - return WMP_errSuccess; -} - - -ERR RGBA128Float_RGBA128Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidthX4 = 4 * pRect->Width; // 4 == R, G, B, A - const float fltCvtFactor = (float)(1 << 24); - I32 y; - - // //UNREFERENCED_PARAMETER( pFC ); - - for (y = 0; y < iHeight; y++) - { - I32 x; - I32 *piDstPixel = (I32*)(pb + cbStride*y); - const float *pfltSrcPixel = (float*)piDstPixel; - - for (x = 0; x < iWidthX4; x++) - piDstPixel[x] = (I32) (pfltSrcPixel[x] * fltCvtFactor + 0.5F); - } - - return WMP_errSuccess; -} - - - -ERR RGB96Fixed_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidthX3 = 3 * pRect->Width; // 3 == R, G, B - const float fltCvtFactor = 1.0F / (1 << 24); - I32 y; - -// //UNREFERENCED_PARAMETER( pFC ); - - for (y = 0; y < iHeight; y++) - { - I32 x; - float *pfltDstPixel = (float*)(pb + cbStride*y); - const I32 *piSrcPixel = (I32*)pfltDstPixel; - - for (x = 0; x < iWidthX3; x++) - pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor; - } - - return WMP_errSuccess; -} - - -ERR RGB128Fixed_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - const float fltCvtFactor = 1.0F / (1 << 24); - I32 y; - - // //UNREFERENCED_PARAMETER( pFC ); - - for (y = 0; y < iHeight; y++) - { - I32 x; - float *pfltDstPixel = (float*)(pb + cbStride*y); - const I32 *piSrcPixel = (I32*)pfltDstPixel; - - for (x = 0; x < iWidth; x++) - { - pfltDstPixel[3*x] = piSrcPixel[4*x] * fltCvtFactor; - pfltDstPixel[3*x+1] = piSrcPixel[4*x+1] * fltCvtFactor; - pfltDstPixel[3*x+2] = piSrcPixel[4*x+2] * fltCvtFactor; - } - } - - return WMP_errSuccess; -} - - - -ERR RGB96Float_RGB96Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidthX3 = 3 * pRect->Width; // 3 == R, G, B - const float fltCvtFactor = (float) (1 << 24); - I32 y; - -// //UNREFERENCED_PARAMETER( pFC ); - - for (y = 0; y < iHeight; y++) - { - I32 x; - I32 *piDstPixel = (I32*)(pb + cbStride*y); - const float *pfltSrcPixel = (float*)piDstPixel; - - for (x = 0; x < iWidthX3; x++) - piDstPixel[x] = (I32)(pfltSrcPixel[x] * fltCvtFactor + 0.5F); - } - - return WMP_errSuccess; -} - - -ERR RGB96Float_RGB128Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - const float fltCvtFactor = (float) (1 << 24); - I32 y; - - // //UNREFERENCED_PARAMETER( pFC ); - - assert(iWidth > 2); // Otherwise, we corrupt source data in inner loop - for (y = iHeight - 1; y >= 0; y--) - { - I32 x; - I32 *piDstPixel = (I32*)(pb + cbStride*y); - const float *pfltSrcPixel = (float*)piDstPixel; - - for (x = iWidth - 1; x >= 0; x--) - { - piDstPixel[4*x] = (I32)(pfltSrcPixel[3*x] * fltCvtFactor + 0.5F); - piDstPixel[4*x+1] = (I32)(pfltSrcPixel[3*x+1] * fltCvtFactor + 0.5F); - piDstPixel[4*x+2] = (I32)(pfltSrcPixel[3*x+2] * fltCvtFactor + 0.5F); - piDstPixel[4*x+3] = 0; // Zero out the alpha channel - } - } - - return WMP_errSuccess; -} - - -ERR RGB96Float_RGB128Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - // //UNREFERENCED_PARAMETER( pFC ); - - assert(iWidth > 2); // Otherwise, we corrupt source data in inner loop - for (y = iHeight - 1; y >= 0; y--) - { - I32 x; - float *pfltDstPixel = (float*)(pb + cbStride*y); - const float *pfltSrcPixel = (float*)pfltDstPixel; - - for (x = iWidth - 1; x >= 0; x--) - { - pfltDstPixel[4*x] = pfltSrcPixel[3*x]; - pfltDstPixel[4*x+1] = pfltSrcPixel[3*x+1]; - pfltDstPixel[4*x+2] = pfltSrcPixel[3*x+2]; - pfltDstPixel[4*x+3] = 0.0F; // Zero out the alpha channel - } - } - - return WMP_errSuccess; -} - - -ERR RGB128Float_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - -// //UNREFERENCED_PARAMETER( pFC ); - - for (y = 0; y < iHeight; y++) - { - I32 x; - float *pfltDstPixel = (float*)(pb + cbStride*y); - const float *pfltSrcPixel = (float*)pfltDstPixel; - - for (x = 0; x < iWidth; x++) - { - pfltDstPixel[3*x] = pfltSrcPixel[4*x]; - pfltDstPixel[3*x+1] = pfltSrcPixel[4*x+1]; - pfltDstPixel[3*x+2] = pfltSrcPixel[4*x+2]; - } - } - - return WMP_errSuccess; -} - - -ERR RGB48Half_RGB64Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - assert(iWidth > 2); // Otherwise, we corrupt source data in inner loop - for (y = iHeight - 1; y >= 0; y--) - { - I32 x; - I16 *piDstPixel = (I16*)(pb + cbStride*y); - const I16 *piSrcPixel = (I16*)piDstPixel; - - for (x = iWidth - 1; x >= 0; x--) - { - piDstPixel[4*x] = piSrcPixel[3*x]; - piDstPixel[4*x+1] = piSrcPixel[3*x+1]; - piDstPixel[4*x+2] = piSrcPixel[3*x+2]; - piDstPixel[4*x+3] = 0; // Zero out the alpha channel - } - } - - return WMP_errSuccess; -} - - -ERR RGB64Half_RGB48Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - for (y = 0; y < iHeight; y++) - { - I32 x; - I16 *piDstPixel = (I16*)(pb + cbStride*y); - const short *piSrcPixel = (I16*)piDstPixel; - - for (x = 0; x < iWidth; x++) - { - piDstPixel[3*x] = piSrcPixel[4*x]; - piDstPixel[3*x+1] = piSrcPixel[4*x+1]; - piDstPixel[3*x+2] = piSrcPixel[4*x+2]; - } - } - - return WMP_errSuccess; -} - - -ERR BGR24_BGR32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - assert(iWidth > 2); // Otherwise, we corrupt source data in inner loop - for (y = iHeight - 1; y >= 0; y--) - { - I32 x; - U8 *piDstPixel = pb + cbStride*y; - const U8 *piSrcPixel = piDstPixel; - - for (x = iWidth - 1; x >= 0; x--) - { - piDstPixel[4*x] = piSrcPixel[3*x]; - piDstPixel[4*x+1] = piSrcPixel[3*x+1]; - piDstPixel[4*x+2] = piSrcPixel[3*x+2]; - piDstPixel[4*x+3] = 0; // Zero out the alpha channel - } - } - - return WMP_errSuccess; -} - - -ERR BGR32_BGR24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - for (y = 0; y < iHeight; y++) - { - I32 x; - U8 *piDstPixel = pb + cbStride*y; - const U8 *piSrcPixel = piDstPixel; - - for (x = 0; x < iWidth; x++) - { - piDstPixel[3*x] = piSrcPixel[4*x]; - piDstPixel[3*x+1] = piSrcPixel[4*x+1]; - piDstPixel[3*x+2] = piSrcPixel[4*x+2]; - } - } - - return WMP_errSuccess; -} - - -ERR Gray32Fixed_Gray32Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - const float fltCvtFactor = 1.0F / (1 << 24); - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - for (y = 0; y < iHeight; y++) - { - I32 x; - float *pfltDstPixel = (float*)(pb + cbStride*y); - const I32 *piSrcPixel = (I32*)pfltDstPixel; - - for (x = 0; x < iWidth; x++) - pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor; - } - - return WMP_errSuccess; -} - - -ERR Gray32Float_Gray32Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - const float fltCvtFactor = (float) (1 << 24); - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - for (y = 0; y < iHeight; y++) - { - I32 x; - I32 *piDstPixel = (I32*)(pb + cbStride*y); - const float *pfltSrcPixel = (float*)piDstPixel; - - for (x = 0; x < iWidth; x++) - piDstPixel[x] = (I32)(pfltSrcPixel[x] * fltCvtFactor + 0.5F); - } - - return WMP_errSuccess; -} - - - -ERR Gray16Fixed_Gray32Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - const float fltCvtFactor = 1.0F / (1 << 13); - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = iHeight - 1; y >= 0; y--) - { - I32 x; - float *pfltDstPixel = (float*)(pb + cbStride*y); - const I16 *piSrcPixel = (I16*)pfltDstPixel; - - for (x = iWidth - 1; x >= 0; x--) - pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor; - } - - return WMP_errSuccess; -} - - -ERR Gray32Float_Gray16Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - const float fltCvtFactor = (float) (1 << 13); - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = 0; y < iHeight; y++) - { - I32 x; - I16 *piDstPixel = (I16*)(pb + cbStride*y); - const float *pfltSrcPixel = (float*)piDstPixel; - - for (x = 0; x < iWidth; x++) - piDstPixel[x] = (I16)(pfltSrcPixel[x] * fltCvtFactor + 0.5F); - } - - return WMP_errSuccess; -} - - -ERR RGB48Fixed_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidthX3 = 3 * pRect->Width; - const float fltCvtFactor = 1.0F / (1 << 13); - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = iHeight - 1; y >= 0; y--) - { - I32 x; - float *pfltDstPixel = (float*)(pb + cbStride*y); - const I16 *piSrcPixel = (I16*)pfltDstPixel; - - for (x = iWidthX3 - 1; x >= 0; x--) - pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor; - } - - return WMP_errSuccess; -} - - -ERR RGB96Float_RGB48Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidthX3 = 3 * pRect->Width; - const float fltCvtFactor = (float)(1 << 13); - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = 0; y < iHeight; y++) - { - I32 x; - I16 *piDstPixel = (I16*)(pb + cbStride*y); - const float *pfltSrcPixel = (float*)piDstPixel; - - for (x = 0; x < iWidthX3; x++) - piDstPixel[x] = (I16)(pfltSrcPixel[x] * fltCvtFactor + 0.5F); - } - - return WMP_errSuccess; -} - - -ERR RGB64Fixed_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - const float fltCvtFactor = 1.0F / (1 << 13); - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = iHeight - 1; y >= 0; y--) - { - I32 x; - float *pfltDstPixel = (float*)(pb + cbStride*y); - const I16 *piSrcPixel = (I16*)pfltDstPixel; - - for (x = iWidth - 1; x >= 0; x--) - { - pfltDstPixel[3*x] = piSrcPixel[4*x] * fltCvtFactor; - pfltDstPixel[3*x+1] = piSrcPixel[4*x+1] * fltCvtFactor; - pfltDstPixel[3*x+2] = piSrcPixel[4*x+2] * fltCvtFactor; - } - } - - return WMP_errSuccess; -} - - -ERR RGB96Float_RGB64Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - const float fltCvtFactor = (float)(1 << 13); - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = 0; y < iHeight; y++) - { - I32 x; - I16 *piDstPixel = (I16*)(pb + cbStride*y); - const float *pfltSrcPixel = (float*)piDstPixel; - - for (x = 0; x < iWidth; x++) - { - piDstPixel[4*x] = (I16)(pfltSrcPixel[3*x] * fltCvtFactor + 0.5F); - piDstPixel[4*x+1] = (I16)(pfltSrcPixel[3*x+1] * fltCvtFactor + 0.5F); - piDstPixel[4*x+2] = (I16)(pfltSrcPixel[3*x+2] * fltCvtFactor + 0.5F); - piDstPixel[4*x+3] = 0; // Zero out the alpha channel - } - } - - return WMP_errSuccess; -} - - -ERR RGBA64Fixed_RGBA128Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidthX4 = 4 * pRect->Width; - const float fltCvtFactor = 1.0F / (1 << 13); - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = iHeight - 1; y >= 0; y--) - { - I32 x; - float *pfltDstPixel = (float*)(pb + cbStride*y); - const I16 *piSrcPixel = (I16*)pfltDstPixel; - - for (x = iWidthX4 - 1; x >= 0; x--) - pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor; - } - - return WMP_errSuccess; -} - - - -ERR RGBA128Float_RGBA64Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidthX4 = 4 * pRect->Width; - const float fltCvtFactor = (float)(1 << 13); - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = 0; y < iHeight; y++) - { - I32 x; - I16 *piDstPixel = (I16*)(pb + cbStride*y); - const float *pfltSrcPixel = (float*)piDstPixel; - - for (x = 0; x < iWidthX4; x++) - piDstPixel[x] = (I16)(pfltSrcPixel[x] * fltCvtFactor + 0.5F); - } - - return WMP_errSuccess; -} - - - -ERR RGBE_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = iHeight - 1; y >= 0; y--) - { - I32 x; - float *pfltDstPixel = (float*)(pb + cbStride*y); - const U8 *piSrcPixel = (U8*)pfltDstPixel; - - for (x = iWidth - 1; x >= 0; x--) - { - // First read the exponent - const U8 rawExp = piSrcPixel[4*x+3]; - - if (0 == rawExp) - { - pfltDstPixel[3*x] = 0.0F; - pfltDstPixel[3*x+1] = 0.0F; - pfltDstPixel[3*x+2] = 0.0F; - } - else - { - const I32 adjExp = (I32)rawExp - 128 - 8; // Can be negative - float fltExp; - - if (adjExp > -32 && adjExp < 32) - { - fltExp = (float) (((U32)1) << abs(adjExp)); - if (adjExp < 0) - fltExp = 1.0F / fltExp; - } - else - { - fltExp = (float)ldexp(1.0F, adjExp); - } - - pfltDstPixel[3*x] = piSrcPixel[4*x] * fltExp; - pfltDstPixel[3*x + 1] = piSrcPixel[4*x + 1] * fltExp; - pfltDstPixel[3*x + 2] = piSrcPixel[4*x + 2] * fltExp; - } - } - } - - return WMP_errSuccess; -} - - -ERR RGB96Float_RGBE(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - assert(iWidth > 2); // Otherwise, we corrupt source data in inner loop - - // Stride is assumed to be same for src/dst - for (y = 0; y < iHeight; y++) - { - I32 x; - U8 *piDstPixel = (U8*)(pb + cbStride*y); - const float *pfltSrcPixel = (float*)piDstPixel; - - for (x = 0; x < iWidth; x++) - { - // We clamp source RGB values at zero (don't allow negative numbers) - const float fltRed = MAX(pfltSrcPixel[3*x], 0.0F); - const float fltGreen = MAX(pfltSrcPixel[3*x+1], 0.0F); - const float fltBlue = MAX(pfltSrcPixel[3*x+2], 0.0F); - float fltMaxPos = fltRed; - - if (fltGreen > fltMaxPos) - fltMaxPos = fltGreen; - - if (fltBlue > fltMaxPos) - fltMaxPos = fltBlue; - - if (fltMaxPos < 1e-32) - { - piDstPixel[4*x] = 0; // R - piDstPixel[4*x+1] = 0; // G - piDstPixel[4*x+2] = 0; // B - piDstPixel[4*x+3] = 0; // E - } - else - { - int e; - const float fltScale = (float)frexp(fltMaxPos, &e) * 256 / fltMaxPos; - - // rounding SHOULD NOT be added - it has the potential to roll over to zero (and yes, 256 is the correct multiplier above) - piDstPixel[4*x] = (U8)(fltRed * fltScale); // R - piDstPixel[4*x+1] = (U8)(fltGreen * fltScale); // G - piDstPixel[4*x+2] = (U8)(fltBlue * fltScale); // B - piDstPixel[4*x+3] = (U8)(e + 128); // E - } - } - } - - return WMP_errSuccess; -} - - -ERR RGBA64Half_RGBA128Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidthX4 = 4 * pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = iHeight - 1; y >= 0; y--) - { - I32 x; - U32 *pfltDstPixel = (U32*)(pb + cbStride*y); // It's really float, but use U32 ptr - const I16 *piSrcPixel = (I16*)pfltDstPixel; - - for (x = iWidthX4 - 1; x >= 0; x--) - pfltDstPixel[x] = Convert_Half_To_Float(piSrcPixel[x]); - } - - return WMP_errSuccess; -} - - -ERR RGBA128Float_RGBA64Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidthX4 = 4 * pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = 0; y < iHeight; y++) - { - I32 x; - I16 *piDstPixel = (I16*)(pb + cbStride*y); - const float *pfltSrcPixel = (float*)piDstPixel; - - for (x = 0; x < iWidthX4; x++) - piDstPixel[x] = Convert_Float_To_Half(pfltSrcPixel[x]); - } - - return WMP_errSuccess; -} - - -ERR RGB64Half_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = iHeight - 1; y >= 0; y--) - { - I32 x; - U32 *pfltDstPixel = (U32*)(pb + cbStride*y); // It's really float, but use U32 ptr - const I16 *piSrcPixel = (I16*)pfltDstPixel; - - for (x = iWidth - 1; x >= 0; x--) - { - pfltDstPixel[3*x] = Convert_Half_To_Float(piSrcPixel[4*x]); - pfltDstPixel[3*x+1] = Convert_Half_To_Float(piSrcPixel[4*x+1]); - pfltDstPixel[3*x+2] = Convert_Half_To_Float(piSrcPixel[4*x+2]); - } - } - - return WMP_errSuccess; -} - - -ERR RGB96Float_RGB64Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = 0; y < iHeight; y++) - { - I32 x; - I16 *piDstPixel = (I16*)(pb + cbStride*y); - const float *pfltSrcPixel = (float*)piDstPixel; - - for (x = 0; x < iWidth; x++) - { - piDstPixel[4*x] = Convert_Float_To_Half(pfltSrcPixel[3*x]); - piDstPixel[4*x+1] = Convert_Float_To_Half(pfltSrcPixel[3*x+1]); - piDstPixel[4*x+2] = Convert_Float_To_Half(pfltSrcPixel[3*x+2]); - piDstPixel[4*x+3] = 0; // Zero out the alpha channel - } - } - - return WMP_errSuccess; -} - - -ERR RGB48Half_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidthX3 = 3*pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = iHeight - 1; y >= 0; y--) - { - I32 x; - U32 *pfltDstPixel = (U32*)(pb + cbStride*y); // It's really float, but use U32 ptr - const I16 *piSrcPixel = (I16*)pfltDstPixel; - - for (x = iWidthX3 - 1; x >= 0; x--) - pfltDstPixel[x] = Convert_Half_To_Float(piSrcPixel[x]); - } - - return WMP_errSuccess; -} - - -ERR RGB96Float_RGB48Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidthX3 = 3*pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = 0; y < iHeight; y++) - { - I32 x; - I16 *piDstPixel = (I16*)(pb + cbStride*y); - const float *pfltSrcPixel = (float*)piDstPixel; - - for (x = 0; x < iWidthX3; x++) - piDstPixel[x] = Convert_Float_To_Half(pfltSrcPixel[x]); - } - - return WMP_errSuccess; -} - - -ERR Gray16Half_Gray32Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = iHeight - 1; y >= 0; y--) - { - I32 x; - U32 *pfltDstPixel = (U32*)(pb + cbStride*y); // It's really float, but use U32 ptr - const I16 *piSrcPixel = (I16*)pfltDstPixel; - - for (x = iWidth - 1; x >= 0; x--) - pfltDstPixel[x] = Convert_Half_To_Float(piSrcPixel[x]); - } - - return WMP_errSuccess; -} - - -ERR Gray32Float_Gray16Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = 0; y < iHeight; y++) - { - I32 x; - I16 *piDstPixel = (I16*)(pb + cbStride*y); - const float *pfltSrcPixel = (float*)piDstPixel; - - for (x = 0; x < iWidth; x++) - piDstPixel[x] = Convert_Float_To_Half(pfltSrcPixel[x]); - } - - return WMP_errSuccess; -} - -ERR RGB555_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = iHeight - 1; y >= 0; y--) - { - I32 x; - U8 *piDstPixel = (pb + cbStride*y); - const U16 *piSrcPixel = (U16*)piDstPixel; - - for (x = iWidth - 1; x >= 0; x--) - { - const U16 v = piSrcPixel[x]; - const unsigned int r = ((v >> 10) & 0x1f); - const unsigned int g = ((v >> 5) & 0x1f); - const unsigned int b = (v & 0x1f); - - piDstPixel[3*x] = (U8)(r << 3); // R - piDstPixel[3*x+1] = (U8)(g << 3); // G - piDstPixel[3*x+2] = (U8)(b << 3); // B - } - } - - return WMP_errSuccess; -} - - -ERR RGB101010_RGB48(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = iHeight - 1; y >= 0; y--) - { - I32 x; - U16 *piDstPixel = (U16*)(pb + cbStride*y); - const U32 *piSrcPixel = (U32*)piDstPixel; - - for (x = iWidth - 1; x >= 0; x--) - { - const U32 v = piSrcPixel[x]; - const unsigned int r = ((v >> 20) & 0x3FF); - const unsigned int g = ((v >> 10) & 0x3FF); - const unsigned int b = (v & 0x3FF); - - piDstPixel[3*x] = (U16)(r << 6); // R - piDstPixel[3*x+1] = (U16)(g << 6); // G - piDstPixel[3*x+2] = (U16)(b << 6); // B - } - } - - return WMP_errSuccess; -} - - -ERR RGB24_RGB555(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = 0; y < iHeight; y++) - { - I32 x; - U16 *piDstPixel = (U16*)(pb + cbStride*y); - const U8 *piSrcPixel = (U8*)piDstPixel; - - for (x = 0; x < iWidth; x++) - { - const unsigned int r = piSrcPixel[3*x]; - const unsigned int g = piSrcPixel[3*x+1]; - const unsigned int b = piSrcPixel[3*x+2]; - - piDstPixel[x] = (U16) ( - ((r & 0xF8) << 7) | - ((g & 0xF8) << 2) | - (b >> 3)); - } - } - - return WMP_errSuccess; -} - - - -ERR RGB48_RGB101010(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = 0; y < iHeight; y++) - { - I32 x; - U32 *piDstPixel = (U32*)(pb + cbStride*y); - const U16 *piSrcPixel = (U16*)piDstPixel; - - for (x = 0; x < iWidth; x++) - { - const unsigned int r = piSrcPixel[3*x]; - const unsigned int g = piSrcPixel[3*x+1]; - const unsigned int b = piSrcPixel[3*x+2]; - - piDstPixel[x] = (3 << 30) | // For compatibility with D3D's 2-10-10-10 format. - ((r & 0x0000FFC0) << 14) | - ((g & 0x0000FFC0) << 4) | - (b >> 6); - } - } - - return WMP_errSuccess; -} - - - -ERR RGB565_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = iHeight - 1; y >= 0; y--) - { - I32 x; - U8 *piDstPixel = (pb + cbStride*y); - const U16 *piSrcPixel = (U16*)piDstPixel; - - for (x = iWidth - 1; x >= 0; x--) - { - const U16 v = piSrcPixel[x]; - const unsigned int r = ((v >> 11) & 0x1f); - const unsigned int g = ((v >> 5) & 0x3f); - const unsigned int b = (v & 0x1f); - - piDstPixel[3*x] = (U8)(r << 3); // R - piDstPixel[3*x+1] = (U8)(g << 2); // G - piDstPixel[3*x+2] = (U8)(b << 3); // B - } - } - - return WMP_errSuccess; -} - - - -ERR RGB24_RGB565(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = 0; y < iHeight; y++) - { - I32 x; - U16 *piDstPixel = (U16*)(pb + cbStride*y); - const U8 *piSrcPixel = (U8*)piDstPixel; - - for (x = 0; x < iWidth; x++) - { - const unsigned int r = piSrcPixel[3*x]; - const unsigned int g = piSrcPixel[3*x+1]; - const unsigned int b = piSrcPixel[3*x+2]; - - piDstPixel[x] = (U16) ( - ((r & 0xF8) << 8) | - ((g & 0xFC) << 3) | - (b >> 3)); - } - } - - return WMP_errSuccess; -} - - -ERR RGBA32_BGRA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidthX4 = 4 * pRect->Width; // 4 == R, G, B, A - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - for (y = 0; y < iHeight; y++) - { - I32 x; - U8 *piPixel = (U8*)(pb + cbStride*y); - - for (x = 0; x < iWidthX4; x += 4) - { - // Swap R and B - U8 bTemp = piPixel[x]; - piPixel[x] = piPixel[x+2]; - piPixel[x+2] = bTemp; - } - } - - return WMP_errSuccess; -} - - -ERR BGRA32_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - return RGBA32_BGRA32(pFC, pRect, pb, cbStride); -} - - -ERR BlackWhite_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - Bool bBlackWhite = pFC->pDecoder->WMP.wmiSCP.bBlackWhite; - I32 y; - - // Stride is assumed to be same for src/dst - for (y = iHeight - 1; y >= 0; y--) - { - I32 x; - I32 n; - U8 *piDstPixel = (pb + cbStride*y); - const U8 *piSrcPixel = (U8*)piDstPixel; - - if (iWidth % 8 != 0) - { - const U8 v = piSrcPixel[iWidth / 8]; - - for (n = 0; n < iWidth % 8; n++) - { - piDstPixel[iWidth/8*8+n] = (((v >> (7 - n)) & 0x1) != 0) ^ bBlackWhite ? 0xFF : 0x00; - } - } - - for (x = iWidth / 8 - 1; x >= 0; x--) - { - const U8 v = piSrcPixel[x]; - - for (n = 0; n < 8; n++) - { - piDstPixel[8*x+n] = (((v >> (7 - n)) & 0x1) != 0) ^ bBlackWhite ? 0xFF : 0x00; - } - } - } - - return WMP_errSuccess; -} - - -ERR Gray16_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - I32 i = 0, j = 0; - - //UNREFERENCED_PARAMETER( pFC ); - - for (i = 0; i < pRect->Height; ++i) - { - for (j = 0; j < pRect->Width; ++j) - { - U16 v = ((U16*)pb)[j]; - - pb[j] = v >> 8; - } - - pb += cbStride; - } - - return WMP_errSuccess; -} - -ERR RGB48_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = 0; y < iHeight; y++) - { - I32 x; - U8 *piDstPixel = (U8*)(pb + cbStride*y); - const U16 *piSrcPixel = (U16*)piDstPixel; - - for (x = 0; x < iWidth; x++) - { - const U16 r = piSrcPixel[3*x]; - const U16 g = piSrcPixel[3*x+1]; - const U16 b = piSrcPixel[3*x+2]; - - piDstPixel[3*x] = r >> 8; - piDstPixel[3*x+1] = g >> 8; - piDstPixel[3*x+2] = b >> 8; - } - } - - return WMP_errSuccess; -} - -ERR RGBA64_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = 0; y < iHeight; y++) - { - I32 x; - U8 *piDstPixel = (U8*)(pb + cbStride*y); - const U16 *piSrcPixel = (U16*)piDstPixel; - - for (x = 0; x < iWidth; x++) - { - const U16 r = piSrcPixel[4*x]; - const U16 g = piSrcPixel[4*x+1]; - const U16 b = piSrcPixel[4*x+2]; - const U16 a = piSrcPixel[4*x+3]; - - piDstPixel[4*x] = r >> 8; - piDstPixel[4*x+1] = g >> 8; - piDstPixel[4*x+2] = b >> 8; - piDstPixel[4*x+3] = a >> 8; - } - } - - return WMP_errSuccess; -} - -ERR Gray32Float_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = 0; y < iHeight; y++) - { - I32 x; - U8 *piDstPixel = (U8*)(pb + cbStride*y); - const float *piSrcPixel = (float*)piDstPixel; - - for (x = 0; x < iWidth; x++) - { - const float v = piSrcPixel[x]; - - piDstPixel[x] = Convert_Float_To_U8(v); - } - } - - return WMP_errSuccess; -} - -ERR RGB96Float_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = 0; y < iHeight; y++) - { - I32 x; - U8 *piDstPixel = (U8*)(pb + cbStride*y); - const float *piSrcPixel = (float*)piDstPixel; - - for (x = 0; x < iWidth; x++) - { - const float r = piSrcPixel[3*x]; - const float g = piSrcPixel[3*x+1]; - const float b = piSrcPixel[3*x+2]; - - piDstPixel[3*x] = Convert_Float_To_U8(r); - piDstPixel[3*x+1] = Convert_Float_To_U8(g); - piDstPixel[3*x+2] = Convert_Float_To_U8(b); - } - } - - return WMP_errSuccess; -} - -ERR RGB128Float_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = 0; y < iHeight; y++) - { - I32 x; - U8 *piDstPixel = (U8*)(pb + cbStride*y); - const float *piSrcPixel = (float*)piDstPixel; - - for (x = 0; x < iWidth; x++) - { - const float r = piSrcPixel[4*x]; - const float g = piSrcPixel[4*x+1]; - const float b = piSrcPixel[4*x+2]; - - piDstPixel[3*x] = Convert_Float_To_U8(r); - piDstPixel[3*x+1] = Convert_Float_To_U8(g); - piDstPixel[3*x+2] = Convert_Float_To_U8(b); - } - } - - return WMP_errSuccess; -} - -ERR RGBA128Float_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = 0; y < iHeight; y++) - { - I32 x; - U8 *piDstPixel = (U8*)(pb + cbStride*y); - const float *piSrcPixel = (float*)piDstPixel; - - for (x = 0; x < iWidth; x++) - { - const float r = piSrcPixel[4*x]; - const float g = piSrcPixel[4*x+1]; - const float b = piSrcPixel[4*x+2]; - const float a = piSrcPixel[4*x+3]; - - piDstPixel[4*x] = Convert_Float_To_U8(r); - piDstPixel[4*x+1] = Convert_Float_To_U8(g); - piDstPixel[4*x+2] = Convert_Float_To_U8(b); - piDstPixel[4*x+3] = Convert_AlphaFloat_To_U8(a); - } - } - - return WMP_errSuccess; -} - -ERR Gray16Fixed_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - const float fltCvtFactor = 1.0F / (1 << 13); - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = 0; y < iHeight; y++) - { - I32 x; - U8 *piDstPixel = (U8*)(pb + cbStride*y); - const I16 *piSrcPixel = (I16*)piDstPixel; - - for (x = 0; x < iWidth; x++) - { - piDstPixel[x] = Convert_Float_To_U8(piSrcPixel[x] * fltCvtFactor); - } - } - - return WMP_errSuccess; -} - -ERR Gray32Fixed_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - const float fltCvtFactor = 1.0F / (1 << 24); - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = 0; y < iHeight; y++) - { - I32 x; - U8 *piDstPixel = (U8*)(pb + cbStride*y); - const I32 *piSrcPixel = (I32*)piDstPixel; - - for (x = 0; x < iWidth; x++) - { - piDstPixel[x] = Convert_Float_To_U8(piSrcPixel[x] * fltCvtFactor); - } - } - - return WMP_errSuccess; -} - -ERR RGB48Fixed_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - const float fltCvtFactor = 1.0F / (1 << 13); - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - for (y = 0; y < iHeight; y++) - { - I32 x; - U8 *pfltDstPixel = (U8*)(pb + cbStride*y); - const I16 *piSrcPixel = (I16*)pfltDstPixel; - - for (x = 0; x < iWidth; x++) - { - pfltDstPixel[3*x] = Convert_Float_To_U8(piSrcPixel[3*x] * fltCvtFactor); - pfltDstPixel[3*x+1] = Convert_Float_To_U8(piSrcPixel[3*x+1] * fltCvtFactor); - pfltDstPixel[3*x+2] = Convert_Float_To_U8(piSrcPixel[3*x+2] * fltCvtFactor); - } - } - - return WMP_errSuccess; -} - -ERR RGB64Fixed_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - const float fltCvtFactor = 1.0F / (1 << 13); - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - for (y = 0; y < iHeight; y++) - { - I32 x; - U8 *pfltDstPixel = (U8*)(pb + cbStride*y); - const I16 *piSrcPixel = (I16*)pfltDstPixel; - - for (x = 0; x < iWidth; x++) - { - pfltDstPixel[3*x] = Convert_Float_To_U8(piSrcPixel[4*x] * fltCvtFactor); - pfltDstPixel[3*x+1] = Convert_Float_To_U8(piSrcPixel[4*x+1] * fltCvtFactor); - pfltDstPixel[3*x+2] = Convert_Float_To_U8(piSrcPixel[4*x+2] * fltCvtFactor); - } - } - - return WMP_errSuccess; -} - -ERR RGB96Fixed_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - const float fltCvtFactor = 1.0F / (1 << 24); - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - for (y = 0; y < iHeight; y++) - { - I32 x; - U8 *pfltDstPixel = (U8*)(pb + cbStride*y); - const I32 *piSrcPixel = (I32*)pfltDstPixel; - - for (x = 0; x < iWidth; x++) - { - pfltDstPixel[3*x] = Convert_Float_To_U8(piSrcPixel[3*x] * fltCvtFactor); - pfltDstPixel[3*x+1] = Convert_Float_To_U8(piSrcPixel[3*x+1] * fltCvtFactor); - pfltDstPixel[3*x+2] = Convert_Float_To_U8(piSrcPixel[3*x+2] * fltCvtFactor); - } - } - - return WMP_errSuccess; -} - -ERR RGB128Fixed_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - const float fltCvtFactor = 1.0F / (1 << 24); - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - for (y = 0; y < iHeight; y++) - { - I32 x; - U8 *pfltDstPixel = (U8*)(pb + cbStride*y); - const I32 *piSrcPixel = (I32*)pfltDstPixel; - - for (x = 0; x < iWidth; x++) - { - pfltDstPixel[3*x] = Convert_Float_To_U8(piSrcPixel[4*x] * fltCvtFactor); - pfltDstPixel[3*x+1] = Convert_Float_To_U8(piSrcPixel[4*x+1] * fltCvtFactor); - pfltDstPixel[3*x+2] = Convert_Float_To_U8(piSrcPixel[4*x+2] * fltCvtFactor); - } - } - - return WMP_errSuccess; -} - -ERR RGBA64Fixed_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - const float fltCvtFactor = 1.0F / (1 << 13); - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - for (y = 0; y < iHeight; y++) - { - I32 x; - U8 *pfltDstPixel = (U8*)(pb + cbStride*y); - const I16 *piSrcPixel = (I16*)pfltDstPixel; - - for (x = 0; x < iWidth; x++) - { - pfltDstPixel[4*x] = Convert_Float_To_U8(piSrcPixel[4*x] * fltCvtFactor); - pfltDstPixel[4*x+1] = Convert_Float_To_U8(piSrcPixel[4*x+1] * fltCvtFactor); - pfltDstPixel[4*x+2] = Convert_Float_To_U8(piSrcPixel[4*x+2] * fltCvtFactor); - pfltDstPixel[4*x+3] = Convert_AlphaFloat_To_U8(piSrcPixel[4*x+3] * fltCvtFactor); - } - } - - return WMP_errSuccess; -} - -ERR RGBA128Fixed_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - const float fltCvtFactor = 1.0F / (1 << 24); - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - for (y = 0; y < iHeight; y++) - { - I32 x; - U8 *pfltDstPixel = (U8*)(pb + cbStride*y); - const I32 *piSrcPixel = (I32*)pfltDstPixel; - - for (x = 0; x < iWidth; x++) - { - pfltDstPixel[4*x] = Convert_Float_To_U8(piSrcPixel[4*x] * fltCvtFactor); - pfltDstPixel[4*x+1] = Convert_Float_To_U8(piSrcPixel[4*x+1] * fltCvtFactor); - pfltDstPixel[4*x+2] = Convert_Float_To_U8(piSrcPixel[4*x+2] * fltCvtFactor); - pfltDstPixel[4*x+3] = Convert_AlphaFloat_To_U8(piSrcPixel[4*x+3] * fltCvtFactor); - } - } - - return WMP_errSuccess; -} - -ERR Gray16Half_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = 0; y < iHeight; y++) - { - I32 x; - U8 *piDstPixel = (U8*)(pb + cbStride*y); - const U16 *piSrcPixel = (U16*)piDstPixel; - - for (x = 0; x < iWidth; x++) - { - const U32 v = Convert_Half_To_Float(piSrcPixel[x]); - - piDstPixel[x] = Convert_Float_To_U8(*(float*)&v); - } - } - - return WMP_errSuccess; -} - -ERR RGB48Half_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - for (y = 0; y < iHeight; y++) - { - I32 x; - U8 *pfltDstPixel = (U8*)(pb + cbStride*y); - const U16 *piSrcPixel = (U16*)pfltDstPixel; - - for (x = 0; x < iWidth; x++) - { - const U32 r = Convert_Half_To_Float(piSrcPixel[3*x]); - const U32 g = Convert_Half_To_Float(piSrcPixel[3*x+1]); - const U32 b = Convert_Half_To_Float(piSrcPixel[3*x+2]); - - pfltDstPixel[3*x] = Convert_Float_To_U8(*(float*)&r); - pfltDstPixel[3*x+1] = Convert_Float_To_U8(*(float*)&g); - pfltDstPixel[3*x+2] = Convert_Float_To_U8(*(float*)&b); - } - } - - return WMP_errSuccess; -} - -ERR RGB64Half_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - for (y = 0; y < iHeight; y++) - { - I32 x; - U8 *pfltDstPixel = (U8*)(pb + cbStride*y); - const U16 *piSrcPixel = (U16*)pfltDstPixel; - - for (x = 0; x < iWidth; x++) - { - const U32 r = Convert_Half_To_Float(piSrcPixel[4*x]); - const U32 g = Convert_Half_To_Float(piSrcPixel[4*x+1]); - const U32 b = Convert_Half_To_Float(piSrcPixel[4*x+2]); - - pfltDstPixel[3*x] = Convert_Float_To_U8(*(float*)&r); - pfltDstPixel[3*x+1] = Convert_Float_To_U8(*(float*)&g); - pfltDstPixel[3*x+2] = Convert_Float_To_U8(*(float*)&b); - } - } - - return WMP_errSuccess; -} - -ERR RGBA64Half_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - for (y = 0; y < iHeight; y++) - { - I32 x; - U8 *pfltDstPixel = (U8*)(pb + cbStride*y); - const U16 *piSrcPixel = (U16*)pfltDstPixel; - - for (x = 0; x < iWidth; x++) - { - const U32 r = Convert_Half_To_Float(piSrcPixel[4*x]); - const U32 g = Convert_Half_To_Float(piSrcPixel[4*x+1]); - const U32 b = Convert_Half_To_Float(piSrcPixel[4*x+2]); - const U32 a = Convert_Half_To_Float(piSrcPixel[4*x+3]); - - pfltDstPixel[4*x] = Convert_Float_To_U8(*(float*)&r); - pfltDstPixel[4*x+1] = Convert_Float_To_U8(*(float*)&g); - pfltDstPixel[4*x+2] = Convert_Float_To_U8(*(float*)&b); - pfltDstPixel[4*x+3] = Convert_AlphaFloat_To_U8(*(float*)&a); - } - } - - return WMP_errSuccess; -} - -ERR RGB101010_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - const I32 iHeight = pRect->Height; - const I32 iWidth = pRect->Width; - I32 y; - - //UNREFERENCED_PARAMETER( pFC ); - - // Stride is assumed to be same for src/dst - for (y = 0; y < iHeight; y++) - { - I32 x; - U8 *piDstPixel = (U8*)(pb + cbStride*y); - const U32 *piSrcPixel = (U32*)piDstPixel; - - for (x = 0; x < iWidth; x++) - { - const U32 v = piSrcPixel[x]; - const unsigned int r = ((v >> 20) & 0x3FF); - const unsigned int g = ((v >> 10) & 0x3FF); - const unsigned int b = (v & 0x3FF); - - piDstPixel[3*x] = (U8) (r >> 2); - piDstPixel[3*x+1] = (U8) (g >> 2); - piDstPixel[3*x+2] = (U8) (b >> 2); - } - } - - return WMP_errSuccess; -} - -ERR RGBE_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - I32 i = 0, j = 0; - - //UNREFERENCED_PARAMETER( pFC ); - - for (i = 0; i < pRect->Height; ++i) - { - for (j = 0; j < pRect->Width; j++) - { - // First read the exponent - const U8 rawExp = pb[4*j+3]; - - if (0 == rawExp) - { - pb[3*j] = 0; - pb[3*j+1] = 0; - pb[3*j+2] = 0; - } - else - { - const I32 adjExp = (I32)rawExp - 128 - 8; // Can be negative - float fltExp; - - if (adjExp > -32 && adjExp < 32) - { - fltExp = (float) (((U32)1) << abs(adjExp)); - if (adjExp < 0) - fltExp = 1.0F / fltExp; - } - else - { - fltExp = (float)ldexp(1.0F, adjExp); - } - - pb[3*j] = Convert_Float_To_U8(pb[4*j] * fltExp); - pb[3*j + 1] = Convert_Float_To_U8(pb[4*j + 1] * fltExp); - pb[3*j + 2] = Convert_Float_To_U8(pb[4*j + 2] * fltExp); - } - } - - pb += cbStride; - } - - return WMP_errSuccess; -} - -//================================================================ -typedef struct tagPKPixelConverterInfo -{ - const PKPixelFormatGUID* pGUIDPixFmtFrom; - const PKPixelFormatGUID* pGUIDPixFmtTo; - - ERR (*Convert)(PKFormatConverter*, const PKRect*, U8*, U32); -} PKPixelConverterInfo; - -static PKPixelConverterInfo s_pcInfo[] = { - {&GUID_PKPixelFormat24bppRGB, &GUID_PKPixelFormat24bppBGR, RGB24_BGR24}, // Fwd - {&GUID_PKPixelFormat24bppBGR, &GUID_PKPixelFormat24bppRGB, BGR24_RGB24}, // Rev - {&GUID_PKPixelFormat24bppRGB, &GUID_PKPixelFormat32bppBGR, RGB24_BGR32}, // Fwd - {&GUID_PKPixelFormat32bppBGR, &GUID_PKPixelFormat24bppRGB, BGR32_RGB24}, // Rev - - // The following are not to be exposed when building the Adobe Photoshop plugin -#ifndef ADOBE_PS_PLUGIN - {&GUID_PKPixelFormat24bppRGB, &GUID_PKPixelFormat8bppGray, RGB24_Gray8}, // Fwd - {&GUID_PKPixelFormat8bppGray, &GUID_PKPixelFormat24bppRGB, Gray8_RGB24}, // Rev - {&GUID_PKPixelFormat24bppBGR, &GUID_PKPixelFormat8bppGray, BGR24_Gray8}, // Fwd - {&GUID_PKPixelFormat8bppGray, &GUID_PKPixelFormat24bppBGR, Gray8_BGR24}, // Rev -#endif // ADOBE_PS_PLUGIN - - {&GUID_PKPixelFormat128bppRGBAFixedPoint, &GUID_PKPixelFormat128bppRGBAFloat, RGBA128Fixed_RGBA128Float}, // Fwd - {&GUID_PKPixelFormat128bppRGBAFloat, &GUID_PKPixelFormat128bppRGBAFixedPoint, RGBA128Float_RGBA128Fixed}, // Rev - {&GUID_PKPixelFormat96bppRGBFixedPoint, &GUID_PKPixelFormat96bppRGBFloat, RGB96Fixed_RGB96Float}, // Fwd - {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat96bppRGBFixedPoint, RGB96Float_RGB96Fixed}, // Rev - {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat128bppRGBFloat, RGB96Float_RGB128Float}, // Fwd - {&GUID_PKPixelFormat128bppRGBFloat, &GUID_PKPixelFormat96bppRGBFloat, RGB128Float_RGB96Float}, // Rev - {&GUID_PKPixelFormat96bppRGBFixedPoint, &GUID_PKPixelFormat128bppRGBFixedPoint, RGB96Float_RGB128Float}, // Fwd - {&GUID_PKPixelFormat128bppRGBFixedPoint, &GUID_PKPixelFormat96bppRGBFixedPoint, RGB128Float_RGB96Float}, // Rev - {&GUID_PKPixelFormat64bppRGBHalf, &GUID_PKPixelFormat48bppRGBHalf, RGB64Half_RGB48Half}, // Fwd - {&GUID_PKPixelFormat48bppRGBHalf, &GUID_PKPixelFormat64bppRGBHalf, RGB48Half_RGB64Half}, // Rev - {&GUID_PKPixelFormat64bppRGBFixedPoint, &GUID_PKPixelFormat48bppRGBFixedPoint, RGB64Half_RGB48Half}, // Fwd - {&GUID_PKPixelFormat48bppRGBFixedPoint, &GUID_PKPixelFormat64bppRGBFixedPoint, RGB48Half_RGB64Half}, // Rev - {&GUID_PKPixelFormat32bppBGR, &GUID_PKPixelFormat24bppBGR, BGR32_BGR24}, // Fwd - {&GUID_PKPixelFormat24bppBGR, &GUID_PKPixelFormat32bppBGR, BGR24_BGR32}, // Rev - {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat128bppRGBFixedPoint, RGB96Float_RGB128Fixed}, // Fwd - {&GUID_PKPixelFormat128bppRGBFixedPoint, &GUID_PKPixelFormat96bppRGBFloat, RGB128Fixed_RGB96Float}, // Rev - {&GUID_PKPixelFormat32bppGrayFixedPoint, &GUID_PKPixelFormat32bppGrayFloat, Gray32Fixed_Gray32Float}, // Fwd - {&GUID_PKPixelFormat32bppGrayFloat, &GUID_PKPixelFormat32bppGrayFixedPoint, Gray32Float_Gray32Fixed}, // Rev - {&GUID_PKPixelFormat16bppGrayFixedPoint, &GUID_PKPixelFormat32bppGrayFloat, Gray16Fixed_Gray32Float}, // Fwd - {&GUID_PKPixelFormat32bppGrayFloat, &GUID_PKPixelFormat16bppGrayFixedPoint, Gray32Float_Gray16Fixed}, // Rev - {&GUID_PKPixelFormat48bppRGBFixedPoint, &GUID_PKPixelFormat96bppRGBFloat, RGB48Fixed_RGB96Float}, // Fwd - {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat48bppRGBFixedPoint, RGB96Float_RGB48Fixed}, // Rev - {&GUID_PKPixelFormat64bppRGBFixedPoint, &GUID_PKPixelFormat96bppRGBFloat, RGB64Fixed_RGB96Float}, // Fwd - {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat64bppRGBFixedPoint, RGB96Float_RGB64Fixed}, // Rev - {&GUID_PKPixelFormat64bppRGBAFixedPoint, &GUID_PKPixelFormat128bppRGBAFloat, RGBA64Fixed_RGBA128Float}, // Fwd - {&GUID_PKPixelFormat128bppRGBAFloat, &GUID_PKPixelFormat64bppRGBAFixedPoint, RGBA128Float_RGBA64Fixed}, // Rev - {&GUID_PKPixelFormat32bppRGBE, &GUID_PKPixelFormat96bppRGBFloat, RGBE_RGB96Float}, // Fwd - {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat32bppRGBE, RGB96Float_RGBE}, // Rev - {&GUID_PKPixelFormat64bppRGBAHalf, &GUID_PKPixelFormat128bppRGBAFloat, RGBA64Half_RGBA128Float}, // Fwd - {&GUID_PKPixelFormat128bppRGBAFloat, &GUID_PKPixelFormat64bppRGBAHalf, RGBA128Float_RGBA64Half}, // Rev - {&GUID_PKPixelFormat64bppRGBHalf, &GUID_PKPixelFormat96bppRGBFloat, RGB64Half_RGB96Float}, // Fwd - {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat64bppRGBHalf, RGB96Float_RGB64Half}, // Rev - {&GUID_PKPixelFormat48bppRGBHalf, &GUID_PKPixelFormat96bppRGBFloat, RGB48Half_RGB96Float}, // Fwd - {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat48bppRGBHalf, RGB96Float_RGB48Half}, // Rev - {&GUID_PKPixelFormat16bppGrayHalf, &GUID_PKPixelFormat32bppGrayFloat, Gray16Half_Gray32Float}, // Fwd - {&GUID_PKPixelFormat32bppGrayFloat, &GUID_PKPixelFormat16bppGrayHalf, Gray32Float_Gray16Half}, // Rev - {&GUID_PKPixelFormat16bppRGB555, &GUID_PKPixelFormat24bppRGB, RGB555_RGB24}, // Fwd - {&GUID_PKPixelFormat24bppRGB, &GUID_PKPixelFormat16bppRGB555, RGB24_RGB555}, // Rev - {&GUID_PKPixelFormat16bppRGB565, &GUID_PKPixelFormat24bppRGB, RGB565_RGB24}, // Fwd - {&GUID_PKPixelFormat24bppRGB, &GUID_PKPixelFormat16bppRGB565, RGB24_RGB565}, // Rev - {&GUID_PKPixelFormat32bppRGB101010, &GUID_PKPixelFormat48bppRGB, RGB101010_RGB48}, // Fwd - {&GUID_PKPixelFormat48bppRGB, &GUID_PKPixelFormat32bppRGB101010, RGB48_RGB101010}, // Rev - {&GUID_PKPixelFormat32bppRGBA, &GUID_PKPixelFormat32bppBGRA, RGBA32_BGRA32}, // Fwd - {&GUID_PKPixelFormat32bppBGRA, &GUID_PKPixelFormat32bppRGBA, BGRA32_RGBA32}, // Rev - {&GUID_PKPixelFormat32bppPRGBA, &GUID_PKPixelFormat32bppPBGRA, RGBA32_BGRA32}, // Fwd - {&GUID_PKPixelFormat32bppPBGRA, &GUID_PKPixelFormat32bppPRGBA, BGRA32_RGBA32}, // Rev - - // conversions to 8bppGray / 24bppRGB / 32bppRGBA - {&GUID_PKPixelFormatBlackWhite, &GUID_PKPixelFormat8bppGray, BlackWhite_Gray8}, - {&GUID_PKPixelFormat16bppGray, &GUID_PKPixelFormat8bppGray, Gray16_Gray8}, - {&GUID_PKPixelFormat48bppRGB, &GUID_PKPixelFormat24bppRGB, RGB48_RGB24}, - {&GUID_PKPixelFormat64bppRGBA, &GUID_PKPixelFormat32bppRGBA, RGBA64_RGBA32}, - {&GUID_PKPixelFormat32bppGrayFloat, &GUID_PKPixelFormat8bppGray, Gray32Float_Gray8}, - {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat24bppRGB, RGB96Float_RGB24}, - {&GUID_PKPixelFormat128bppRGBFloat, &GUID_PKPixelFormat24bppRGB, RGB128Float_RGB24}, - {&GUID_PKPixelFormat128bppRGBAFloat, &GUID_PKPixelFormat32bppRGBA, RGBA128Float_RGBA32}, - {&GUID_PKPixelFormat16bppGrayFixedPoint, &GUID_PKPixelFormat8bppGray, Gray16Fixed_Gray8}, - {&GUID_PKPixelFormat32bppGrayFixedPoint, &GUID_PKPixelFormat8bppGray, Gray32Fixed_Gray8}, - {&GUID_PKPixelFormat48bppRGBFixedPoint, &GUID_PKPixelFormat24bppRGB, RGB48Fixed_RGB24}, - {&GUID_PKPixelFormat64bppRGBFixedPoint, &GUID_PKPixelFormat24bppRGB, RGB64Fixed_RGB24}, - {&GUID_PKPixelFormat96bppRGBFixedPoint, &GUID_PKPixelFormat24bppRGB, RGB96Fixed_RGB24}, - {&GUID_PKPixelFormat128bppRGBFixedPoint, &GUID_PKPixelFormat24bppRGB, RGB128Fixed_RGB24}, - {&GUID_PKPixelFormat64bppRGBAFixedPoint, &GUID_PKPixelFormat32bppRGBA, RGBA64Fixed_RGBA32}, - {&GUID_PKPixelFormat128bppRGBAFixedPoint, &GUID_PKPixelFormat32bppRGBA, RGBA128Fixed_RGBA32}, - {&GUID_PKPixelFormat16bppGrayHalf, &GUID_PKPixelFormat8bppGray, Gray16Half_Gray8}, - {&GUID_PKPixelFormat48bppRGBHalf, &GUID_PKPixelFormat24bppRGB, RGB48Half_RGB24}, - {&GUID_PKPixelFormat64bppRGBHalf, &GUID_PKPixelFormat24bppRGB, RGB64Half_RGB24}, - {&GUID_PKPixelFormat64bppRGBAHalf, &GUID_PKPixelFormat32bppRGBA, RGBA64Half_RGBA32}, - {&GUID_PKPixelFormat32bppRGB101010, &GUID_PKPixelFormat24bppRGB, RGB101010_RGB24}, - {&GUID_PKPixelFormat32bppRGBE, &GUID_PKPixelFormat24bppRGB, RGBE_RGB24} -}; - -/* auxiliary data structure and hack to support valid encoding from/to configurations that -// don't actually require any color conversion. This is a conservative approach, where we -// include as few formats as necessary to encode situations that we're currently aware of. -*/ -typedef struct tagPKPixelConverter2Info -{ - const PKPixelFormatGUID* pGUIDPixFmtFrom; - const PKPixelFormatGUID* pGUIDPixFmtTo; - -} PKPixelConverter2Info; - -static PKPixelConverter2Info s_pcInfo2[] = { - // This allows us to view an RGBA input file as RGB, for when we create a planar alpha file - {&GUID_PKPixelFormat128bppRGBFloat, &GUID_PKPixelFormat128bppRGBAFloat}, - // 16- and 32-bpp RGB input files are given the "DontCare" GUID, so the next three - // from/to combinations are ok, and allowed on encoding: - {&GUID_PKPixelFormatDontCare, &GUID_PKPixelFormat16bppRGB555}, - {&GUID_PKPixelFormatDontCare, &GUID_PKPixelFormat16bppRGB565}, - {&GUID_PKPixelFormatDontCare, &GUID_PKPixelFormat32bppBGRA} -}; - -ERR PKFormatConverter_Initialize(PKFormatConverter* pFC, PKImageDecode* pID, char *pExt, PKPixelFormatGUID enPF) -{ - ERR err; - PKPixelFormatGUID enPFFrom; - - Call(pID->GetPixelFormat(pID, &enPFFrom)); - Call(PKFormatConverter_InitializeConvert(pFC, enPFFrom, pExt, enPF)); - - pFC->pDecoder = pID; - -Cleanup: - return err; -} - - -extern int PKStrnicmp(const char* s1, const char* s2, size_t c); - -ERR PKFormatConverter_InitializeConvert(PKFormatConverter* pFC, const PKPixelFormatGUID enPFFrom, - char *pExt, PKPixelFormatGUID enPFTo) -{ - ERR err = WMP_errSuccess; - - //================================ - pFC->enPixelFormat = enPFTo; - - if (pExt != NULL && IsEqualGUID(&enPFTo, &GUID_PKPixelFormat24bppRGB) && - 0 == PKStrnicmp(pExt, ".bmp", strlen(pExt))) - enPFTo = GUID_PKPixelFormat24bppBGR; - if (pExt != NULL && (0 == PKStrnicmp(pExt, ".tif", strlen(pExt)) || 0 == PKStrnicmp(pExt, ".tiff", strlen(pExt)))) - { - if (IsEqualGUID(&enPFTo, &GUID_PKPixelFormat32bppBGRA)) - enPFTo = GUID_PKPixelFormat32bppRGBA; - if (IsEqualGUID(&enPFTo, &GUID_PKPixelFormat32bppPBGRA)) - enPFTo = GUID_PKPixelFormat32bppPRGBA; - } - - //================================ - if (!IsEqualGUID(&enPFFrom, &enPFTo)) - { - size_t i = 0; - for (i = 0; i < sizeof2(s_pcInfo); ++i) - { - PKPixelConverterInfo* pPCI = s_pcInfo + i; - - if (IsEqualGUID(&enPFFrom, pPCI->pGUIDPixFmtFrom) && IsEqualGUID(&enPFTo, pPCI->pGUIDPixFmtTo)) - { - pFC->Convert= pPCI->Convert; - goto Cleanup; - } - } - // Bugfix to allow legitimate encoding from/to combinations that don't actually - // involve color conversions. - for (i = 0; i < sizeof2(s_pcInfo2); ++i) - { - PKPixelConverter2Info* pPCI = s_pcInfo2 + i; - - if (IsEqualGUID(&enPFFrom, pPCI->pGUIDPixFmtFrom) && IsEqualGUID(&enPFTo, pPCI->pGUIDPixFmtTo)) - { - goto Cleanup; - } - } - // If we failed the original check, and this bugfix check, then exit with error - Call(WMP_errUnsupportedFormat); - } - -Cleanup: - return err; -} - -ERR PKFormatConverter_EnumConversions(const PKPixelFormatGUID *pguidSourcePF, - const U32 iIndex, - const PKPixelFormatGUID **ppguidTargetPF) -{ - U32 iCurrIdx = 0; - U32 i; - ERR errResult = WMP_errIndexNotFound; - - *ppguidTargetPF = &GUID_PKPixelFormatDontCare; // Init return value - for (i = 0; i < sizeof2(s_pcInfo); i++) - { - if (IsEqualGUID(s_pcInfo[i].pGUIDPixFmtFrom, pguidSourcePF)) - { - if (iCurrIdx == iIndex) - { - // Found our target - errResult = WMP_errSuccess; - *ppguidTargetPF = s_pcInfo[i].pGUIDPixFmtTo; - break; - } - iCurrIdx += 1; - } - } - - return errResult; -} - -ERR PKFormatConverter_GetPixelFormat(PKFormatConverter* pFC, PKPixelFormatGUID* pPF) -{ - *pPF = pFC->enPixelFormat; - - return WMP_errSuccess; -} - -ERR PKFormatConverter_GetSourcePixelFormat(PKFormatConverter* pFC, PKPixelFormatGUID* pPF) -{ - return pFC->pDecoder->GetPixelFormat(pFC->pDecoder, pPF); -} - -ERR PKFormatConverter_GetSize(PKFormatConverter* pFC, I32* piWidth, I32* piHeight) -{ - return pFC->pDecoder->GetSize(pFC->pDecoder, piWidth, piHeight); -} - -ERR PKFormatConverter_GetResolution(PKFormatConverter* pFC, Float* pfrX, Float* pfrY) -{ - return pFC->pDecoder->GetResolution(pFC->pDecoder, pfrX, pfrY); -} - -ERR PKFormatConverter_Copy(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - ERR err = WMP_errSuccess; - - Call(pFC->pDecoder->Copy(pFC->pDecoder, pRect, pb, cbStride)); - Call(pFC->Convert(pFC, pRect, pb, cbStride)); - -Cleanup: - return err; -} - -ERR PKFormatConverter_Convert(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride) -{ - //UNREFERENCED_PARAMETER( pFC ); - //UNREFERENCED_PARAMETER( pRect ); - //UNREFERENCED_PARAMETER( pb ); - //UNREFERENCED_PARAMETER( cbStride ); - - return WMP_errSuccess; -} - -ERR PKFormatConverter_Release(PKFormatConverter** ppFC) -{ - ERR err = WMP_errSuccess; - - Call(PKFree((void **) ppFC)); - -Cleanup: - return err; -} - diff --git a/Src/JxrDecode/Jxr/JXRMeta.c b/Src/JxrDecode/Jxr/JXRMeta.c deleted file mode 100644 index 0563b74a..00000000 --- a/Src/JxrDecode/Jxr/JXRMeta.c +++ /dev/null @@ -1,912 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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)); - if (pcbDataWrittenToOffset) - { - *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; -} - diff --git a/Src/JxrDecode/Jxr/JXRMeta.h b/Src/JxrDecode/Jxr/JXRMeta.h deleted file mode 100644 index 6fb7a036..00000000 --- a/Src/JxrDecode/Jxr/JXRMeta.h +++ /dev/null @@ -1,258 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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); diff --git a/Src/JxrDecode/Jxr/JXRTest.c b/Src/JxrDecode/Jxr/JXRTest.c deleted file mode 100644 index 4a60f470..00000000 --- a/Src/JxrDecode/Jxr/JXRTest.c +++ /dev/null @@ -1,503 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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 "JXRTest.h" -#include "JXRTestWrapper.h" -//EXTERN_C const PKIID IID_PKImageBmpDecode; -const PKIID IID_PKImageBmpDecode = 202; -const PKIID IID_PKImageEncodeWrapper = 109; -static ERR GetTestInfo(const char* szExt, const PKIIDInfo** ppInfo) -{ - ERR err = WMP_errSuccess; - - static PKIIDInfo iidInfo[] = { - {"wrapper", &IID_PKImageEncodeWrapper, /*don't care/not used*/&IID_PKImageBmpDecode }, - /* {".bmp", &IID_PKImageBmpEncode, &IID_PKImageBmpDecode}, - {".ppm", &IID_PKImagePnmEncode, &IID_PKImagePnmDecode}, - {".pgm", &IID_PKImagePnmEncode, &IID_PKImagePnmDecode}, - {".pnm", &IID_PKImagePnmEncode, &IID_PKImagePnmDecode}, - {".pfm", &IID_PKImagePnmEncode, &IID_PKImagePnmDecode}, - {".tif", &IID_PKImageTifEncode, &IID_PKImageTifDecode}, - {".hdr", &IID_PKImageHdrEncode, &IID_PKImageHdrDecode}, - {".iyuv", &IID_PKImageIyuvEncode, &IID_PKImageIyuvDecode}, - {".yuv422", &IID_PKImageYuv422Encode, &IID_PKImageYuv422Decode}, - {".yuv444", &IID_PKImageYuv444Encode, &IID_PKImageYuv444Decode},*/ - }; - 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 GetTestEncodeIID(const char* szExt, const PKIID** ppIID) -{ - ERR err = WMP_errSuccess; - - const PKIIDInfo* pInfo = NULL; - - Call(GetTestInfo(szExt, &pInfo)); - *ppIID = pInfo->pIIDEnc; - -Cleanup: - return err; -} - -//ERR PKImageEncode_Initialize_Wrapper(struct tagPKImageEncode* pIE, struct WMPStream* stream, void* vp, size_t size); -//ERR PKImageEncode_Create_Wrapper(struct tagPKImageEncode** ppIE); -//ERR PKImageEncode_WritePixels_Wrapper( -//struct PKImageEncode* pIE, -//U32 cLine, -//U8* pbPixel, -//U32 cbStride); -ERR PKImageEncode_Initialize_Wrapper(PKImageEncode* pIE, struct WMPStream* stream, void* vp, size_t size) -{ - if (size != sizeof(JxrTestWrapperInitializeInfo)) - { - return WMP_errInvalidArgument; - } - - JxrTestWrapperInitializeInfo* ptrInfo = (JxrTestWrapperInitializeInfo*)vp; - pIE->WRAPPER.info = *ptrInfo; - return WMP_errSuccess; -} - -ERR PKImageEncode_WritePixels_Wrapper( - PKImageEncode* pIE, - U32 cLine, - U8* pbPixel, - U32 cbStride) -{ - pIE->WRAPPER.info.pfnPutData( - pIE->guidPixFormat, - pIE->uWidth, - pIE->uHeight, - cLine, - pbPixel, - cbStride, - pIE->WRAPPER.info.userParamPutData); - return WMP_errSuccess; -} - -ERR PKImageEncode_Create_Wrapper(PKImageEncode** ppIE) -{ - ERR err = WMP_errSuccess; - - PKImageEncode* pIE = NULL; - - Call(PKImageEncode_Create(ppIE)); - - pIE = *ppIE; - pIE->Initialize = PKImageEncode_Initialize_Wrapper; - pIE->WritePixels = PKImageEncode_WritePixels_Wrapper; - -Cleanup: - return err; -} - - -ERR PKTestFactory_CreateCodec(const PKIID* iid, void** ppv) -{ - ERR err = WMP_errSuccess; - - /*if (IID_PKImageBmpEncode == *iid) - { - Call(PKImageEncode_Create_BMP((PKImageEncode**)ppv)); - } - else if (IID_PKImagePnmEncode == *iid) - { - Call(PKImageEncode_Create_PNM((PKImageEncode**)ppv)); - } - else if (IID_PKImageTifEncode == *iid) - { - Call(PKImageEncode_Create_TIF((PKImageEncode**)ppv)); - } - else if (IID_PKImageHdrEncode == *iid) - { - Call(PKImageEncode_Create_HDR((PKImageEncode**)ppv)); - } - else if (IID_PKImageIyuvEncode == *iid) - { - Call(PKImageEncode_Create_IYUV((PKImageEncode**)ppv)); - } - else if (IID_PKImageYuv422Encode == *iid) - { - Call(PKImageEncode_Create_YUV422((PKImageEncode**)ppv)); - } - else if (IID_PKImageYuv444Encode == *iid) - { - Call(PKImageEncode_Create_YUV444((PKImageEncode**)ppv)); - } - else */if (IID_PKImageEncodeWrapper == *iid) - { - Call(PKImageEncode_Create_Wrapper((PKImageEncode**)ppv)); - } - /* - else if (IID_PKImageBmpDecode == *iid) - { - Call(PKImageDecode_Create_BMP((PKTestDecode**)ppv)); - } - else if (IID_PKImagePnmDecode == *iid) - { - Call(PKImageDecode_Create_PNM((PKTestDecode**)ppv)); - } - else if (IID_PKImageTifDecode == *iid) - { - Call(PKImageDecode_Create_TIF((PKTestDecode**)ppv)); - } - else if (IID_PKImageHdrDecode == *iid) - { - Call(PKImageDecode_Create_HDR((PKTestDecode**)ppv)); - } - else if (IID_PKImageIyuvDecode == *iid) - { - Call(PKImageDecode_Create_IYUV((PKTestDecode**)ppv)); - } - else if (IID_PKImageYuv422Decode == *iid) - { - Call(PKImageDecode_Create_YUV422((PKTestDecode**)ppv)); - } - else if (IID_PKImageYuv444Decode == *iid) - { - Call(PKImageDecode_Create_YUV444((PKTestDecode**)ppv)); - }*/ - - else - { - Call(WMP_errUnsupportedFormat); - } - -Cleanup: - return err; -} - -#if false - -//================================================================ -const PKIID IID_PKImagePnmEncode = 102; -const PKIID IID_PKImageBmpEncode = 103; -const PKIID IID_PKImageTifEncode = 104; -const PKIID IID_PKImageHdrEncode = 105; -const PKIID IID_PKImageIyuvEncode = 106; -const PKIID IID_PKImageYuv422Encode = 107; -const PKIID IID_PKImageYuv444Encode = 108; -const PKIID IID_PKImageEncodeWrapper = 109; - -const PKIID IID_PKImageBmpDecode = 202; -const PKIID IID_PKImagePnmDecode = 203; -const PKIID IID_PKImageTifDecode = 204; -const PKIID IID_PKImageHdrDecode = 205; -const PKIID IID_PKImageIyuvDecode = 206; -const PKIID IID_PKImageYuv422Decode = 207; -const PKIID IID_PKImageYuv444Decode = 208; - -//================================================================ -// Misc supporting functions -//================================================================ -extern int PKStrnicmp(const char* s1, const char* s2, size_t c); - -//---------------------------------------------------------------- -typedef struct tagPKIIDInfo -{ - const char* szExt; - const PKIID* pIIDEnc; - const PKIID* pIIDDec; -} PKIIDInfo; - -static ERR GetTestInfo(const char* szExt, const PKIIDInfo** ppInfo) -{ - ERR err = WMP_errSuccess; - - static PKIIDInfo iidInfo[] = { - {"wrapper", &IID_PKImageEncodeWrapper, /*don't care/not used*/&IID_PKImageBmpDecode }, - {".bmp", &IID_PKImageBmpEncode, &IID_PKImageBmpDecode}, - {".ppm", &IID_PKImagePnmEncode, &IID_PKImagePnmDecode}, - {".pgm", &IID_PKImagePnmEncode, &IID_PKImagePnmDecode}, - {".pnm", &IID_PKImagePnmEncode, &IID_PKImagePnmDecode}, - {".pfm", &IID_PKImagePnmEncode, &IID_PKImagePnmDecode}, - {".tif", &IID_PKImageTifEncode, &IID_PKImageTifDecode}, - {".hdr", &IID_PKImageHdrEncode, &IID_PKImageHdrDecode}, - {".iyuv", &IID_PKImageIyuvEncode, &IID_PKImageIyuvDecode}, - {".yuv422", &IID_PKImageYuv422Encode, &IID_PKImageYuv422Decode}, - {".yuv444", &IID_PKImageYuv444Encode, &IID_PKImageYuv444Decode}, - }; - 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 GetTestEncodeIID(const char* szExt, const PKIID** ppIID) -{ - ERR err = WMP_errSuccess; - - const PKIIDInfo* pInfo = NULL; - - Call(GetTestInfo(szExt, &pInfo)); - *ppIID = pInfo->pIIDEnc; - -Cleanup: - return err; -} - -ERR GetTestDecodeIID(const char* szExt, const PKIID** ppIID) -{ - ERR err = WMP_errSuccess; - - const PKIIDInfo* pInfo = NULL; - - Call(GetTestInfo(szExt, &pInfo)); - *ppIID = pInfo->pIIDDec; - -Cleanup: - return err; -} - - -//================================================================ -// PKTestFactory -//================================================================ -ERR PKTestFactory_CreateCodec(const PKIID* iid, void** ppv) -{ - ERR err = WMP_errSuccess; - - if (IID_PKImageBmpEncode == *iid) - { - Call(PKImageEncode_Create_BMP((PKImageEncode**)ppv)); - } - else if (IID_PKImagePnmEncode == *iid) - { - Call(PKImageEncode_Create_PNM((PKImageEncode**)ppv)); - } - else if (IID_PKImageTifEncode == *iid) - { - Call(PKImageEncode_Create_TIF((PKImageEncode**)ppv)); - } - else if (IID_PKImageHdrEncode == *iid) - { - Call(PKImageEncode_Create_HDR((PKImageEncode**)ppv)); - } - else if (IID_PKImageIyuvEncode == *iid) - { - Call(PKImageEncode_Create_IYUV((PKImageEncode**)ppv)); - } - else if (IID_PKImageYuv422Encode == *iid) - { - Call(PKImageEncode_Create_YUV422((PKImageEncode**)ppv)); - } - else if (IID_PKImageYuv444Encode == *iid) - { - Call(PKImageEncode_Create_YUV444((PKImageEncode**)ppv)); - } - else if (IID_PKImageEncodeWrapper == *iid) - { - Call(PKImageEncode_Create_Wrapper((PKImageEncode**)ppv)); - } - - else if (IID_PKImageBmpDecode == *iid) - { - Call(PKImageDecode_Create_BMP((PKTestDecode**)ppv)); - } - else if (IID_PKImagePnmDecode == *iid) - { - Call(PKImageDecode_Create_PNM((PKTestDecode**)ppv)); - } - else if (IID_PKImageTifDecode == *iid) - { - Call(PKImageDecode_Create_TIF((PKTestDecode**)ppv)); - } - else if (IID_PKImageHdrDecode == *iid) - { - Call(PKImageDecode_Create_HDR((PKTestDecode**)ppv)); - } - else if (IID_PKImageIyuvDecode == *iid) - { - Call(PKImageDecode_Create_IYUV((PKTestDecode**)ppv)); - } - else if (IID_PKImageYuv422Decode == *iid) - { - Call(PKImageDecode_Create_YUV422((PKTestDecode**)ppv)); - } - else if (IID_PKImageYuv444Decode == *iid) - { - Call(PKImageDecode_Create_YUV444((PKTestDecode**)ppv)); - } - - else - { - Call(WMP_errUnsupportedFormat); - } - -Cleanup: - return err; -} - -ERR PKTestFactory_CreateDecoderFromFile(const char* szFilename, PKImageDecode** ppDecoder) -{ - ERR err = WMP_errSuccess; - - char *pExt = NULL; - 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(GetTestDecodeIID(pExt, (const PKIID**)&pIID)); - - // create stream - Call(CreateWS_File(&pStream, szFilename, "rb")); - - // Create decoder - Call(PKTestFactory_CreateCodec(pIID, (void**)ppDecoder)); - pDecoder = *ppDecoder; - - // attach stream to decoder - Call(pDecoder->Initialize(pDecoder, pStream)); - pDecoder->fStreamOwner = !0; - -Cleanup: - return err; -} - -ERR PKCreateTestFactory(PKCodecFactory** ppCFactory, U32 uVersion) -{ - ERR err = WMP_errSuccess; - PKCodecFactory* pCFactory = NULL; - -// UNREFERENCED_PARAMETER( uVersion ); - - Call(PKAlloc((void**)ppCFactory, sizeof(**ppCFactory))); - pCFactory = *ppCFactory; - - pCFactory->CreateCodec = PKTestFactory_CreateCodec; - pCFactory->CreateDecoderFromFile = PKTestFactory_CreateDecoderFromFile; - pCFactory->CreateFormatConverter = PKCodecFactory_CreateFormatConverter; - pCFactory->Release = PKCreateCodecFactory_Release; - -Cleanup: - return err; -} - - -//================================================================ -// PKTestDecode -//================================================================ -ERR PKTestDecode_Initialize( - PKTestDecode* 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)); - -Cleanup: - return WMP_errSuccess; -} - -ERR PKTestDecode_Copy( - PKTestDecode* pID, - const PKRect* pRect, - U8* pb, - U32 cbStride) -{ - //UNREFERENCED_PARAMETER( pID ); - //UNREFERENCED_PARAMETER( pRect ); - //UNREFERENCED_PARAMETER( pb ); - //UNREFERENCED_PARAMETER( cbStride ); - - return WMP_errAbstractMethod; -} - -ERR PKTestDecode_Release( - PKTestDecode** ppID) -{ - PKTestDecode* pID = *ppID; - - pID->fStreamOwner && pID->pStream->Close(&pID->pStream); - - return PKFree((void**)ppID); -} - -ERR PKTestDecode_Create( - PKTestDecode** ppID) -{ - ERR err = WMP_errSuccess; - PKTestDecode* pID = NULL; - - Call(PKAlloc((void**)ppID, sizeof(**ppID))); - - pID = *ppID; - pID->Initialize = PKTestDecode_Initialize; - pID->GetPixelFormat = PKImageDecode_GetPixelFormat; - pID->GetSize = PKImageDecode_GetSize; - pID->GetResolution = PKImageDecode_GetResolution; - pID->GetColorContext = PKImageDecode_GetColorContext; - pID->GetDescriptiveMetadata = PKImageDecode_GetDescriptiveMetadata; - pID->Copy = PKTestDecode_Copy; - pID->GetFrameCount = PKImageDecode_GetFrameCount; - pID->SelectFrame = PKImageDecode_SelectFrame; - pID->Release = PKTestDecode_Release; - -Cleanup: - return err; -} -#endif \ No newline at end of file diff --git a/Src/JxrDecode/Jxr/JXRTest.h b/Src/JxrDecode/Jxr/JXRTest.h deleted file mode 100644 index 8b9aa244..00000000 --- a/Src/JxrDecode/Jxr/JXRTest.h +++ /dev/null @@ -1,189 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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 "JXRGlue.h" -#ifdef __cplusplus -extern "C" { -#endif - typedef struct tagPKIIDInfo - { - const char* szExt; - const PKIID* pIIDEnc; - const PKIID* pIIDDec; - } PKIIDInfo; -ERR GetTestEncodeIID(const char* szExt, const PKIID** ppIID); -ERR PKTestFactory_CreateCodec(const PKIID* iid, void** ppv); -#ifdef __cplusplus -} -#endif -//================================================================ - - - -#if false -#include "JXRGlue.h" -#include "JXRTestWrapper.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -EXTERN_C const PKIID IID_PKImageBmpEncode; -EXTERN_C const PKIID IID_PKImagePnmEncode; -EXTERN_C const PKIID IID_PKImageTifEncode; - -EXTERN_C const PKIID IID_PKImageBmpDecode; -EXTERN_C const PKIID IID_PKImagePnmDecode; -EXTERN_C const PKIID IID_PKImageTifDecode; - -//---------------------------------------------------------------- -ERR GetTestEncodeIID(const char* szExt, const PKIID** ppIID); -ERR GetTestDecodeIID(const char* szExt, const PKIID** ppIID); - -//================================================================ -#ifdef __ANSI__ -#define PKTestDecode struct tagPKTestDecode -#else // __ANSI__ -typedef struct tagPKTestDecode PKTestDecode; -#endif // __ANSI__ -//================================================================ - -//---------------------------------------------------------------- -ERR PKTestFactory_CreateCodec(const PKIID* iid, void** ppv); - -EXTERN_C ERR PKCreateTestFactory(PKCodecFactory**, U32); - -//---------------------------------------------------------------- -ERR PKImageEncode_Create_BMP(PKImageEncode** ppIE); -ERR PKImageEncode_Create_PNM(PKImageEncode** ppIE); -ERR PKImageEncode_Create_TIF(PKImageEncode** ppIE); -ERR PKImageEncode_Create_HDR(PKImageEncode** ppIE); -ERR PKImageEncode_Create_IYUV(PKImageEncode** ppIE); -ERR PKImageEncode_Create_YUV422(PKImageEncode** ppIE); -ERR PKImageEncode_Create_YUV444(PKImageEncode** ppIE); -ERR PKImageEncode_Create_Wrapper(PKImageEncode** ppIE); - -//================================================================ -typedef struct tagPKTestDecode -{ - ERR (*Initialize)(PKTestDecode*, 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)(PKTestDecode*, const PKRect*, U8*, U32); - - ERR (*GetFrameCount)(PKImageDecode*, U32*); - ERR (*SelectFrame)(PKImageDecode*, U32); - - ERR (*Release)(PKTestDecode**); - - struct WMPStream* pStream; - Bool fStreamOwner; - size_t offStart; - - PKPixelFormatGUID guidPixFormat; - - U32 uWidth; - U32 uHeight; - U32 idxCurrentLine; - - Float fResX; - Float fResY; - - U32 cFrame; - - union - { - struct - { - size_t offPixel; - size_t cbPixel; - } BMP; - struct - { - size_t offPixel; - size_t cbPixel; - } HDR; - struct - { - size_t offPixel; - } PNM; - struct - { - U32 uRowsPerStrip; - U32* uStripOffsets; - U32* uStripByteCounts; - - U32 uInterpretation; - U32 uSamplePerPixel; - U32 uBitsPerSample; - U32 uSampleFormat; - U32 uExtraSamples; - - U16 uResolutionUnit; - Float fResX; - Float fResY; - Bool fLittleEndian; - } TIF; - } EXT; -#ifdef __ANSI__ -#undef PKTestDecode -#endif // __ANSI__ -} PKTestDecode; - -//---------------------------------------------------------------- -ERR PKImageDecode_Create_BMP(PKTestDecode** ppID); -ERR PKImageDecode_Create_PNM(PKTestDecode** ppID); -ERR PKImageDecode_Create_TIF(PKTestDecode** ppID); -ERR PKImageDecode_Create_HDR(PKTestDecode** ppID); -ERR PKImageDecode_Create_IYUV(PKTestDecode** ppID); -ERR PKImageDecode_Create_YUV422(PKTestDecode** ppID); -ERR PKImageDecode_Create_YUV444(PKTestDecode** ppID); - -ERR PKTestDecode_Initialize(PKTestDecode* pID, struct WMPStream* pStream); -ERR PKTestDecode_Copy(PKTestDecode* pID, const PKRect* pRect, U8* pb, U32 cbStride); -ERR PKTestDecode_Release(PKTestDecode** ppID); - -ERR PKTestDecode_Create(PKTestDecode** ppID); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/Src/JxrDecode/Jxr/JXRTestBmp.c b/Src/JxrDecode/Jxr/JXRTestBmp.c deleted file mode 100644 index 4e615af4..00000000 --- a/Src/JxrDecode/Jxr/JXRTestBmp.c +++ /dev/null @@ -1,404 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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. -// -//*@@@---@@@@****************************************************************** - -#if false - -#include -#include - -#include "JXRTest.h" - -#pragma pack(push, 1) - -#define BI_RGB 0 -#define BI_BITFIELDS 3 - -#define BI_RGB555_MASK_B 0x001F -#define BI_RGB555_MASK_G 0x03E0 -#define BI_RGB555_MASK_R 0x7C00 - -#define BI_RGB565_MASK_B 0x001F -#define BI_RGB565_MASK_G 0x07E0 -#define BI_RGB565_MASK_R 0xF800 - -#define BI_RGB101010_MASK_B 0x000003FF -#define BI_RGB101010_MASK_G 0x000FFC00 -#define BI_RGB101010_MASK_R 0x3FF00000 - -typedef struct tagBITMAPFILEHEADER { - U8 szBM[2]; - U32 uSize; - U16 reserved1; - U16 reserved2; - U32 uOffBits; -} BITMAPFILEHEADER, *PBITMAPFILEHEADER; - -typedef struct tagBITMAPINFOHEADER{ - U32 uSize; - I32 iWidth; - I32 iHeight; - I16 iPlanes; - I16 iBitCount; - U32 uCompression; - U32 uImageSize; - I32 iPelsPerMeterX; - I32 iPelsPerMeterY; - U32 uColorUsed; - U32 uColorImportant; -} BITMAPINFOHEADER, *PBITMAPINFOHEADER; - -typedef struct tagBITMAPINFOHEADEREXT{ - U32 uA; - U32 uB; - U32 uC; - U32 uD; -} BITMAPINFOHEADEREXT, *PBITMAPINFOHEADEREXT; - - -#pragma pack(pop) - -//================================================================ -// PKImageEncode_BMP -//================================================================ -ERR WriteBMPHeader( - PKImageEncode* pIE) -{ - ERR err = WMP_errSuccess; - - static U32 rguColorTable[256] = {0}; - size_t cbColorTable = 0; - size_t cbLineS = 0; - U32 i = 0; - - struct WMPStream* pS = pIE->pStream; - BITMAPFILEHEADER bmpFH = { 0, }; - BITMAPINFOHEADER bmpIH = {sizeof(bmpIH), 0, }; - - bmpFH.szBM[0] = 'B'; - bmpFH.szBM[1] = 'M'; - - if (IsEqualGUID(&GUID_PKPixelFormat24bppRGB, &pIE->guidPixFormat) || IsEqualGUID(&GUID_PKPixelFormat24bppBGR, &pIE->guidPixFormat)) - { - pIE->cbPixel = 3; - cbColorTable = 0; - } - else if (IsEqualGUID(&GUID_PKPixelFormat32bppBGRA, &pIE->guidPixFormat) - || IsEqualGUID(&GUID_PKPixelFormat32bppBGR, &pIE->guidPixFormat) - || IsEqualGUID(&GUID_PKPixelFormat32bppPBGRA, &pIE->guidPixFormat)) - { - pIE->cbPixel = 4; - cbColorTable = 0; - } - else if (IsEqualGUID(&GUID_PKPixelFormat8bppGray, &pIE->guidPixFormat)) - { - pIE->cbPixel = 1; - - cbColorTable = sizeof(rguColorTable); - for (i = 0; i < sizeof2(rguColorTable); ++i) - { - rguColorTable[i] = i | (i << 8) | (i << 16); - } - } - else if (IsEqualGUID(&GUID_PKPixelFormat16bppRGB555, &pIE->guidPixFormat)) - { - pIE->cbPixel = 2; - bmpIH.uCompression = BI_BITFIELDS; - - cbColorTable = sizeof(rguColorTable[0]) * 3; - rguColorTable[0] = BI_RGB555_MASK_R; - rguColorTable[1] = BI_RGB555_MASK_G; - rguColorTable[2] = BI_RGB555_MASK_B; - } - else if (IsEqualGUID(&GUID_PKPixelFormat16bppRGB565, &pIE->guidPixFormat)) - { - pIE->cbPixel = 2; - bmpIH.uCompression = BI_BITFIELDS; - - cbColorTable = sizeof(rguColorTable[0]) * 3; - rguColorTable[0] = BI_RGB565_MASK_R; - rguColorTable[1] = BI_RGB565_MASK_G; - rguColorTable[2] = BI_RGB565_MASK_B; - } - else if (IsEqualGUID(&GUID_PKPixelFormat32bppRGB101010, &pIE->guidPixFormat)) - { - pIE->cbPixel = 4; - bmpIH.uCompression = BI_BITFIELDS; - - cbColorTable = sizeof(rguColorTable[0]) * 3; - rguColorTable[0] = BI_RGB101010_MASK_R; - rguColorTable[1] = BI_RGB101010_MASK_G; - rguColorTable[2] = BI_RGB101010_MASK_B; - } - else - Call(WMP_errUnsupportedFormat); - - cbLineS = (pIE->cbPixel * pIE->uWidth + 3) / 4 * 4; - - bmpFH.uOffBits = (U32)(sizeof(bmpFH) + sizeof(bmpIH) + cbColorTable); - bmpFH.uSize = (U32)(bmpFH.uOffBits + cbLineS * pIE->uHeight); - - bmpIH.iWidth = pIE->uWidth; - bmpIH.iHeight = pIE->uHeight; - bmpIH.iPlanes = 1; - bmpIH.iBitCount = (I16)(8 * pIE->cbPixel); - bmpIH.uImageSize = (U32)(cbLineS * pIE->uHeight); - bmpIH.iPelsPerMeterX = (I32)(pIE->fResX * 39.37); - bmpIH.iPelsPerMeterY = (I32)(pIE->fResY * 39.37); - - Call(pS->Write(pS, &bmpFH, sizeof(bmpFH))); - Call(pS->Write(pS, &bmpIH, sizeof(bmpIH))); - Call(pS->Write(pS, rguColorTable, cbColorTable)); - - pIE->offPixel = pIE->offStart + bmpFH.uOffBits; - pIE->fHeaderDone = !FALSE; - -Cleanup: - return err; -} - -ERR PKImageEncode_WritePixels_BMP( - PKImageEncode* pIE, - U32 cLine, - U8* pbPixel, - U32 cbStride) -{ - ERR err = WMP_errSuccess; - - struct WMPStream* pS = pIE->pStream; - size_t cbLineM = 0, cbLineS = 0; - I32 i = 0; - static U8 pPadding[4] = {0}; - - // header - if (!pIE->fHeaderDone) - { - // WriteBMPHeader() also inits this object - Call(WriteBMPHeader(pIE)); - } - - // body - // calculate line size in memory and in stream - cbLineM = pIE->cbPixel * pIE->uWidth; - cbLineS = (cbLineM + 3) / 4 * 4; - - //FailIf(pRect->X < 0 || pID->uWidth <= pRect->X, WMP_errInvalidParameter); - //FailIf(pRect->Y < 0 || pID->uHeight <= pRect->Y, WMP_errInvalidParameter); - //FailIf(pRect->Width < 0 || pID->uWidth < pRect->X + pRect->Width, WMP_errInvalidParameter); - //FailIf(pRect->Height < 0 || pID->uHeight < pRect->Y + pRect->Height, WMP_errInvalidParameter); - FailIf(cbStride < cbLineM, WMP_errInvalidParameter); - - for (i = cLine - 1; 0 <= i; --i) - { - size_t offM = (size_t)cbStride * i; - size_t offS = cbLineS * (pIE->uHeight - (pIE->idxCurrentLine + i + 1)); - - Call(pS->SetPos(pS, pIE->offPixel + offS)); - Call(pS->Write(pS, pbPixel + offM, cbLineM)); - } - Call(pS->Write(pS, pPadding, (cbLineS - cbLineM))); - pIE->idxCurrentLine += cLine; - -Cleanup: - return err; -} - -ERR PKImageEncode_Create_BMP( - PKImageEncode** ppIE) -{ - ERR err = WMP_errSuccess; - PKImageEncode* pIE = NULL; - - Call(PKImageEncode_Create(ppIE)); - - pIE = *ppIE; - pIE->WritePixels = PKImageEncode_WritePixels_BMP; - -Cleanup: - return err; -} - - -//================================================================ -// PKImageDecode_BMP -//================================================================ -ERR ParseBMPHeader( - PKTestDecode* pID, - struct WMPStream* pWS) -{ - ERR err = WMP_errSuccess; - - BITMAPFILEHEADER bmpFH = {0}; - BITMAPINFOHEADER bmpIH = {0}; - static U32 bmpIHE[32] = {0}; // should be >= sizeof(BITMAPV5HEADER) - sizeof(BITMAPINFOHEADER) - static U32 rguColorTable[256] = {0}; - U32 i = 0; - - Call(pWS->Read(pWS, &bmpFH, sizeof(bmpFH))); - FailIf(bmpFH.szBM != (U8 *) strstr((char *) bmpFH.szBM, "BM"), WMP_errUnsupportedFormat); - - Call(pWS->Read(pWS, &bmpIH, sizeof(bmpIH))); - - FailIf(((sizeof(bmpIH) > bmpIH.uSize) || ((sizeof(bmpIH) + sizeof(bmpIHE)) < bmpIH.uSize)), WMP_errUnsupportedFormat); - - if (sizeof(bmpIH) < bmpIH.uSize) - { - Call(pWS->Read(pWS, &bmpIHE, bmpIH.uSize - sizeof(bmpIH))); - } - - switch (bmpIH.iBitCount) - { - case 8: - // check the color table to verify the image is actually gray scale - Call(pWS->Read(pWS, rguColorTable, sizeof(rguColorTable))); - for (i = 0; i < sizeof2(rguColorTable); ++i) - { - U32 c = i | (i << 8) | (i << 16); - FailIf(c != rguColorTable[i], WMP_errUnsupportedFormat); - } - - pID->guidPixFormat = GUID_PKPixelFormat8bppGray; - pID->EXT.BMP.cbPixel = 1; - break; - - case 16: - Call(pWS->Read(pWS, rguColorTable, sizeof(rguColorTable[0]) * 3)); - if (BI_RGB555_MASK_B == rguColorTable[0] && BI_RGB555_MASK_G == rguColorTable[1] && BI_RGB555_MASK_R == rguColorTable[2]) - { - pID->guidPixFormat = GUID_PKPixelFormat16bppRGB555; - } - if (BI_RGB565_MASK_B == rguColorTable[0] && BI_RGB565_MASK_G == rguColorTable[1] && BI_RGB565_MASK_R == rguColorTable[2]) - { - pID->guidPixFormat = GUID_PKPixelFormat16bppRGB565; - } - else - { - Call(WMP_errUnsupportedFormat); - } - pID->EXT.BMP.cbPixel = 2; - break; - - case 24: - pID->guidPixFormat = GUID_PKPixelFormat24bppBGR; - pID->EXT.BMP.cbPixel = 3; - break; - - case 32: - Call(pWS->Read(pWS, rguColorTable, sizeof(rguColorTable[0]) * 3)); - if (BI_RGB101010_MASK_B == rguColorTable[0] && BI_RGB101010_MASK_G == rguColorTable[1] && BI_RGB101010_MASK_R == rguColorTable[2]) - { - pID->guidPixFormat = GUID_PKPixelFormat32bppRGB101010; - } - else - { - pID->guidPixFormat = GUID_PKPixelFormat32bppBGRA; - } - pID->EXT.BMP.cbPixel = 4; - break; - - default: - Call(WMP_errUnsupportedFormat); - break; - } - - pID->uWidth = (U32)bmpIH.iWidth; - pID->uHeight = (U32)bmpIH.iHeight; - - pID->fResX = (0 == bmpIH.iPelsPerMeterX ? 96 : (Float)(bmpIH.iPelsPerMeterX * .0254)); - pID->fResY = (0 == bmpIH.iPelsPerMeterY ? 96 : (Float)(bmpIH.iPelsPerMeterY * .0254)); - - pID->EXT.BMP.offPixel = pID->offStart + bmpFH.uOffBits; - -Cleanup: - return err; -} - -ERR PKImageDecode_Initialize_BMP( - PKTestDecode* pID, - struct WMPStream* pWS) -{ - ERR err = WMP_errSuccess; - - Call(PKTestDecode_Initialize(pID, pWS)); - Call(ParseBMPHeader(pID, pWS)); - -Cleanup: - return err; -} - -ERR PKImageDecode_Copy_BMP( - PKTestDecode* pID, - const PKRect* pRect, - U8* pb, - U32 cbStride) -{ - ERR err = WMP_errSuccess; - - struct WMPStream* pS = pID->pStream; - - size_t cbLineS = (pID->EXT.BMP.cbPixel * pID->uWidth + 3) / 4 * 4; - size_t cbLineM = pID->EXT.BMP.cbPixel * pRect->Width; - - I32 i = 0; - - //FailIf(pRect->X < 0 || pID->uWidth <= pRect->X, WMP_errInvalidParameter); - //FailIf(pRect->Y < 0 || pID->uHeight <= pRect->Y, WMP_errInvalidParameter); - //FailIf(pRect->Width < 0 || pID->uWidth < pRect->X + pRect->Width, WMP_errInvalidParameter); - //FailIf(pRect->Height < 0 || pID->uHeight < pRect->Y + pRect->Height, WMP_errInvalidParameter); - FailIf(cbStride < cbLineM, WMP_errInvalidParameter); - - for (i = pRect->Y + pRect->Height - 1; pRect->Y <= i; --i) - { - size_t offLine = pID->EXT.BMP.cbPixel * pRect->X; - size_t offS = cbLineS * (pID->uHeight - i - 1) + offLine; - size_t offM = (size_t)cbStride * (i - pRect->Y) + offLine; - - Call(pS->SetPos(pS, pID->EXT.BMP.offPixel + offS)); - Call(pS->Read(pS, pb + offM, cbLineM)); - } - -Cleanup: - return err; -} - -ERR PKImageDecode_Create_BMP( - PKTestDecode** ppID) -{ - ERR err = WMP_errSuccess; - PKTestDecode* pID = NULL; - - Call(PKTestDecode_Create(ppID)); - - pID = *ppID; - pID->Initialize = PKImageDecode_Initialize_BMP; - pID->Copy = PKImageDecode_Copy_BMP; - -Cleanup: - return err; -} - -#endif \ No newline at end of file diff --git a/Src/JxrDecode/Jxr/JXRTestHdr.c b/Src/JxrDecode/Jxr/JXRTestHdr.c deleted file mode 100644 index 58dcc012..00000000 --- a/Src/JxrDecode/Jxr/JXRTestHdr.c +++ /dev/null @@ -1,245 +0,0 @@ -#if false -//*@@@+++@@@@****************************************************************** -// -// 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 ANSI -#define _CRT_SECURE_NO_WARNINGS -#endif// ANSI - -#include -#include - -#include "JXRTest.h" - -#pragma pack(push, 1) -#pragma pack(pop) - -//================================================================ -// PKImageEncode_HDR -//================================================================ -ERR WriteHDRHeader( - PKImageEncode* pIE) -{ - ERR err = WMP_errSuccess; - struct WMPStream* pS = pIE->pStream; - - char txtbuff[100]; - - strcpy(txtbuff, "#?RADIANCE\nFORMAT=32-bit_rle_rgbe\n\n"); - Call(pS->Write(pS, txtbuff, strlen(txtbuff))); - - pIE->offPixel = strlen(txtbuff); - - sprintf(txtbuff, "-Y %d +X %d\n", pIE->uHeight, pIE->uWidth); - Call(pS->Write(pS, txtbuff, strlen(txtbuff))); - pIE->offPixel += strlen(txtbuff); - - pIE->cbPixel = 4; - - pIE->fHeaderDone = !FALSE; - -Cleanup: - return err; -} - -ERR PKImageEncode_WritePixels_HDR( - PKImageEncode* pIE, - U32 cLine, - U8* pbPixel, - U32 cbStride) -{ - ERR err = WMP_errSuccess; - - struct WMPStream* pS = pIE->pStream; - size_t cbLineM = 0, cbLineS = 0; - size_t i = 0; - - // header - if (!pIE->fHeaderDone) - { - // WriteHDRHeader() also inits this object - Call(WriteHDRHeader(pIE)); - } - - // body - // calculate line size in memory and in stream - cbLineM = pIE->cbPixel * pIE->uWidth; - cbLineS = (cbLineM + 3) / 4 * 4; - - //FailIf(pRect->X < 0 || pID->uWidth <= pRect->X, WMP_errInvalidParameter); - //FailIf(pRect->Y < 0 || pID->uHeight <= pRect->Y, WMP_errInvalidParameter); - //FailIf(pRect->Width < 0 || pID->uWidth < pRect->X + pRect->Width, WMP_errInvalidParameter); - //FailIf(pRect->Height < 0 || pID->uHeight < pRect->Y + pRect->Height, WMP_errInvalidParameter); - FailIf(cbStride < cbLineM, WMP_errInvalidParameter); - - for (i = 0; i <= cLine - 1; i++) - { - size_t offM = cbStride * i; - size_t offS = cbLineS * (pIE->idxCurrentLine + i); - - Call(pS->SetPos(pS, pIE->offPixel + offS)); - Call(pS->Write(pS, pbPixel + offM, cbLineM)); - } - pIE->idxCurrentLine += cLine; - -Cleanup: - return err; -} - -ERR PKImageEncode_Create_HDR( - PKImageEncode** ppIE) -{ - ERR err = WMP_errSuccess; - PKImageEncode* pIE = NULL; - - Call(PKImageEncode_Create(ppIE)); - - pIE = *ppIE; - pIE->WritePixels = PKImageEncode_WritePixels_HDR; - -Cleanup: - return err; -} - - -//================================================================ -// PKImageDecode_HDR -//================================================================ -ERR ParseHDRHeader( - PKTestDecode* pID, - struct WMPStream* pWS) -{ - ERR err = WMP_errSuccess; - - char txtbuff[512]; - Bool done = FALSE; - - FailIf(NULL == fgets(txtbuff, 12, pWS->state.file.pFile), WMP_errUnsupportedFormat); - FailIf(0 != strcmp(txtbuff, "#?RADIANCE\n"), WMP_errUnsupportedFormat); - - // Read lines to image size - while (!done) { - FailIf(NULL == fgets(txtbuff, 512, pWS->state.file.pFile), WMP_errUnsupportedFormat); - - if (0 == strncmp(txtbuff, "FORMAT", 6)) { - FailIf(0 != strcmp(txtbuff, "FORMAT=32-bit_rle_rgbe\n"), WMP_errUnsupportedFormat); - } - if (0 == strncmp(txtbuff, "-Y", 2)) { - sscanf(txtbuff, "-Y %d +X %d\n", &pID->uHeight, &pID->uWidth); - done = TRUE; - } - } - - Call(pWS->Read(pWS, txtbuff, 3)); - - if(((2 == txtbuff[0]) && (2 == txtbuff[1]) && (0 == (txtbuff[2] & 0x80))) || - ((1 == txtbuff[0]) && (1 == txtbuff[1]) && (1 == txtbuff[2]))) - { - /*printf("Doesn't support compressed HDR files.\n");*/ - err = WMP_errUnsupportedFormat; - goto Cleanup; - } - - // Set header other header parameters - pID->guidPixFormat = GUID_PKPixelFormat32bppRGBE; - pID->EXT.HDR.cbPixel = 4; - // Set pointer to first pixel - Call(pWS->GetPos(pWS, &pID->EXT.HDR.offPixel)); - pID->EXT.HDR.offPixel -= 3; - Call(pWS->SetPos(pWS, pID->EXT.HDR.offPixel)); - - // We don't need: pID->fResX and pID->fResY -Cleanup: - return err; -} - -ERR PKImageDecode_Initialize_HDR( - PKTestDecode* pID, - struct WMPStream* pWS) -{ - ERR err = WMP_errSuccess; - - Call(PKTestDecode_Initialize(pID, pWS)); - Call(ParseHDRHeader(pID, pWS)); - -Cleanup: - return err; -} - -ERR PKImageDecode_Copy_HDR( - PKTestDecode* pID, - const PKRect* pRect, - U8* pb, - U32 cbStride) -{ - ERR err = WMP_errSuccess; - - struct WMPStream* pS = pID->pStream; - - size_t cbLineS = (pID->EXT.HDR.cbPixel * pID->uWidth + 3) / 4 * 4; - size_t cbLineM = pID->EXT.HDR.cbPixel * pRect->Width; - - I32 i = 0; - - //FailIf(pRect->X < 0 || pID->uWidth <= pRect->X, WMP_errInvalidParameter); - //FailIf(pRect->Y < 0 || pID->uHeight <= pRect->Y, WMP_errInvalidParameter); - //FailIf(pRect->Width < 0 || pID->uWidth < pRect->X + pRect->Width, WMP_errInvalidParameter); - //FailIf(pRect->Height < 0 || pID->uHeight < pRect->Y + pRect->Height, WMP_errInvalidParameter); - FailIf(cbStride < cbLineM, WMP_errInvalidParameter); - - for (i = pRect->Y ; i < pRect->Y + pRect->Height ; i++) - { - size_t offLine = pID->EXT.HDR.cbPixel * pRect->X; - size_t offS = cbLineS * i + offLine; - size_t offM = (size_t)cbStride * (i - pRect->Y) + offLine; - - Call(pS->SetPos(pS, pID->EXT.HDR.offPixel + offS)); - Call(pS->Read(pS, pb + offM, cbLineM)); - } - -Cleanup: - return err; -} - -ERR PKImageDecode_Create_HDR( - PKTestDecode** ppID) -{ - ERR err = WMP_errSuccess; - PKTestDecode* pID = NULL; - - Call(PKTestDecode_Create(ppID)); - - pID = *ppID; - pID->Initialize = PKImageDecode_Initialize_HDR; - pID->Copy = PKImageDecode_Copy_HDR; - -Cleanup: - return err; -} - - -#endif \ No newline at end of file diff --git a/Src/JxrDecode/Jxr/JXRTestPnm.c b/Src/JxrDecode/Jxr/JXRTestPnm.c deleted file mode 100644 index 1f537b73..00000000 --- a/Src/JxrDecode/Jxr/JXRTestPnm.c +++ /dev/null @@ -1,336 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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. -// -//*@@@---@@@@****************************************************************** - -#if false - -#ifndef ANSI -#define _CRT_SECURE_NO_WARNINGS -#endif// ANSI - -#include - -#include "JXRTest.h" - - -//================================================================ -// PKImageEncode_PNM helpers -//================================================================ -ERR WritePNMHeader(PKImageEncode* pIE) -{ - ERR err = WMP_errSuccess; - - PKPixelInfo PI; - struct WMPStream* pS = pIE->pStream; - U8 buf[64] = {0}; - int cb = 0; - - char szSig[2]; - U32 uMaxVal = 0; - - PI.pGUIDPixFmt = &pIE->guidPixFormat; - PixelFormatLookup(&PI, LOOKUP_FORWARD); - - if (IsEqualGUID(&GUID_PKPixelFormatBlackWhite, PI.pGUIDPixFmt)) - { - szSig[0] = 'P', szSig[1] = '5'; - uMaxVal = 1; - } - else if (IsEqualGUID(&GUID_PKPixelFormat8bppGray, PI.pGUIDPixFmt)) - { - szSig[0] = 'P', szSig[1] = '5'; - uMaxVal = 255; - } - else if (IsEqualGUID(&GUID_PKPixelFormat24bppRGB, PI.pGUIDPixFmt)) - { - szSig[0] = 'P', szSig[1] = '6'; - uMaxVal = 255; - } - else if (IsEqualGUID(&GUID_PKPixelFormat48bppRGB, PI.pGUIDPixFmt)) - { - szSig[0] = 'P', szSig[1] = '6'; - uMaxVal = 65535; - } - else if (IsEqualGUID(&GUID_PKPixelFormat16bppGray, PI.pGUIDPixFmt)) - { - szSig[0] = 'P', szSig[1] = '6'; - uMaxVal = 65535; - } - else if (IsEqualGUID(&GUID_PKPixelFormat96bppRGBFloat, PI.pGUIDPixFmt)) - { - szSig[0] = 'P', szSig[1] = 'F'; - } - else - Call(WMP_errUnsupportedFormat); - - if('P' == szSig[0] && 'F' == szSig[1]) - cb = sprintf((char *) buf, "%c%c\n%u\n%u\n%s\n", - szSig[0], szSig[1], (int)pIE->uWidth, (int)pIE->uHeight, "-1.0000"); - else - cb = sprintf((char *) buf, "%c%c\n%u %u\n%u\n", - szSig[0], szSig[1], (int)pIE->uWidth, (int)pIE->uHeight, (int)uMaxVal); - - assert(cb < sizeof2(buf)); - Call(pS->Write(pS, buf, cb)); - - Call(pS->GetPos(pS, &pIE->offPixel)); - pIE->cbPixel = ((PI.cbitUnit + 7) >> 3);// ->cbPixel / pPI->cbPixelDenom; - pIE->fHeaderDone = !FALSE; - -Cleanup: - return err; -} - -//================================================================ -// PKImageEncode_PNM -//================================================================ -ERR PKImageEncode_WritePixels_PNM( - PKImageEncode* pIE, - U32 cLine, - U8* pbPixel, - U32 cbStride) -{ - ERR err = WMP_errSuccess; - - struct WMPStream* pS = pIE->pStream; - size_t cbLine = 0; - size_t offPos = 0; - size_t i = 0; - - // header - if (!pIE->fHeaderDone) - { - Call(WritePNMHeader(pIE)); - } - - // body - cbLine = pIE->cbPixel * pIE->uWidth; - FailIf(cbStride < cbLine, WMP_errInvalidParameter); - - offPos = pIE->offPixel + cbLine * pIE->idxCurrentLine; - Call(pS->SetPos(pS, offPos)); - - for (i = 0; i < cLine; ++i) - { - Call(pS->Write(pS, pbPixel + cbStride * i, cbLine)); - } - pIE->idxCurrentLine += cLine; - -Cleanup: - return err; -} - -ERR PKImageEncode_Create_PNM( - PKImageEncode** ppIE) -{ - ERR err = WMP_errSuccess; - PKImageEncode* pIE = NULL; - - Call(PKImageEncode_Create(ppIE)); - - pIE = *ppIE; - pIE->WritePixels = PKImageEncode_WritePixels_PNM; - -Cleanup: - return err; -} - - -//================================================================ -// PKImageDecode_PNM helpers -//================================================================ -ERR GetLineSkipPound(struct WMPStream* pWS, U8* pb, size_t cb) -{ - ERR err = WMP_errSuccess; - U8 *pb1; - size_t cb1; - - do - { - pb1 = pb; - cb1 = cb; - - do { - Call(pWS->Read(pWS, pb1, 1)); - cb1--; - pb1++; - } - while (cb1 > 0 && pb1[-1] != '\n'); - - //Call(pWS->GetLine(pWS, pb, cb)); - } while('#' == pb[0]); - -Cleanup: - return err; -} - -ERR ParsePNMHeader( - PKTestDecode* pID, - struct WMPStream* pWS) -{ - ERR err = WMP_errSuccess; - - U8 line[128] = {0}; - size_t idxChannel = 0, idxBitDepth = 0; - unsigned int width = 0, height = 0, maxval = 0; - - static const PKPixelFormatGUID* pixFormat[2][2] = - { - {&GUID_PKPixelFormat8bppGray, &GUID_PKPixelFormat16bppGray,}, - {&GUID_PKPixelFormat24bppRGB, &GUID_PKPixelFormat48bppRGB,}, - }; - - //================================ - Call(GetLineSkipPound(pWS, line, sizeof2(line))); - if (line == (U8 *) strstr((char *) line, "P5")) - { - idxChannel = 0; - Call(GetLineSkipPound(pWS, line, sizeof2(line))); - FailIf(2 != sscanf((char *) line, "%u %u", &width, &height), WMP_errUnsupportedFormat); - } - else if(line == (U8 *) strstr((char *) line, "P6")) - { - idxChannel = 1; - Call(GetLineSkipPound(pWS, line, sizeof2(line))); - FailIf(2 != sscanf((char *) line, "%u %u", &width, &height), WMP_errUnsupportedFormat); - } - else if(line == (U8 *) strstr((char *) line, "PF")) - { - idxChannel = 2; - Call(GetLineSkipPound(pWS, line, sizeof2(line))); - FailIf(1 != sscanf((char *) line, "%u", &width), WMP_errUnsupportedFormat); - Call(GetLineSkipPound(pWS, line, sizeof2(line))); - FailIf(1 != sscanf((char *) line, "%u", &height), WMP_errUnsupportedFormat); - } - else - { - Call(WMP_errUnsupportedFormat); - } - - //================================ -// Call(GetLineSkipPound(pWS, line, sizeof2(line))); -// FailIf(2 != sscanf(line, "%u %u", &width, &height), WMP_errUnsupportedFormat); - - FailIf(0 == width || 0 == height, WMP_errUnsupportedFormat); - - pID->uWidth = (U32)width; - pID->uHeight = (U32)height; - - //================================ - Call(GetLineSkipPound(pWS, line, sizeof2(line))); - - FailIf(1 != sscanf((char *) line, "%u", &maxval), WMP_errUnsupportedFormat); - - if (2==idxChannel) - { - FailIf(maxval != -1, WMP_errUnsupportedFormat); - pID->guidPixFormat = GUID_PKPixelFormat96bppRGBFloat; - } - else - { - FailIf(maxval < 1 || 65535 < maxval, WMP_errUnsupportedFormat); - idxBitDepth = 255 < maxval; - pID->guidPixFormat = *pixFormat[idxChannel][idxBitDepth]; - } - - Call(pWS->GetPos(pWS, &pID->EXT.PNM.offPixel)); - -Cleanup: - return err; -} - - -//================================================================ -// PKImageDecode_PNM -//================================================================ -ERR PKImageDecode_Initialize_PNM( - PKTestDecode* pID, - struct WMPStream* pWS) -{ - ERR err = WMP_errSuccess; - - Call(PKTestDecode_Initialize(pID, pWS)); - Call(ParsePNMHeader(pID, pWS)); - -Cleanup: - return err; -} - - -ERR PKImageDecode_Copy_PNM( - PKTestDecode* pID, - const PKRect* pRect, - U8* pb, - U32 cbStride) -{ - ERR err = WMP_errSuccess; - - struct WMPStream* pS = pID->pStream; - PKPixelInfo PI; - size_t cbLineS = 0; - size_t cbLineM = 0; - I32 i = 0; - - PI.pGUIDPixFmt = &pID->guidPixFormat; - PixelFormatLookup(&PI, LOOKUP_FORWARD); - - cbLineS = (BD_1 == PI.bdBitDepth ? ((PI.cbitUnit * pID->uWidth + 7) >> 3) : (((PI.cbitUnit + 7) >> 3) * pID->uWidth)); - cbLineM = (BD_1 == PI.bdBitDepth ? ((PI.cbitUnit * pRect->Width + 7) >> 3) : (((PI.cbitUnit + 7) >> 3) * pRect->Width)); - FailIf(cbStride < cbLineM, WMP_errInvalidParameter); - - for (i = 0; i < pRect->Height; ++i) - { - size_t offLine = (BD_1 == PI.bdBitDepth ? ((PI.cbitUnit * pRect->X + 7) >> 3) : (((PI.cbitUnit + 7) >> 3) * pRect->X)); - size_t offS = cbLineS * (pRect->Y + i) + offLine; - size_t offM = (size_t)cbStride * i + offLine; - - Call(pS->SetPos(pS, pID->EXT.PNM.offPixel + offS)); - Call(pS->Read(pS, pb + offM, cbLineM)); - } - -Cleanup: - return err; -} - -ERR PKImageDecode_Create_PNM( - PKTestDecode** ppID) -{ - ERR err = WMP_errSuccess; - PKTestDecode* pID = NULL; - - Call(PKTestDecode_Create(ppID)); - - pID = *ppID; - pID->Initialize = PKImageDecode_Initialize_PNM; - pID->Copy = PKImageDecode_Copy_PNM; - -Cleanup: - return err; -} - - -#endif \ No newline at end of file diff --git a/Src/JxrDecode/Jxr/JXRTestTif.c b/Src/JxrDecode/Jxr/JXRTestTif.c deleted file mode 100644 index 8cd21585..00000000 --- a/Src/JxrDecode/Jxr/JXRTestTif.c +++ /dev/null @@ -1,940 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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. -// -//*@@@---@@@@****************************************************************** - -#if false - -#include -#include - -#include "strcodec.h" -#include "JXRTest.h" - -//================================================================ -#define TIF_tagNull 0 -#define TIF_tagSubfileType 0xff -#define TIF_tagNewSubfileType 0xfe -#define TIF_tagImageWidth 0x100 -#define TIF_tagImageLength 0x101 -#define TIF_tagBitsPerSample 0x102 -#define TIF_tagCompression 0x103 -#define TIF_tagPhotometricInterpretation 0x106 -#define TIF_tagStripOffsets 0x111 -#define TIF_tagOrientation 0x112 -#define TIF_tagSamplesPerPixel 0x115 -#define TIF_tagRowsPerStrip 0x116 -#define TIF_tagStripByteCounts 0x117 -#define TIF_tagXResolution 0x11a -#define TIF_tagYResolution 0x11b -#define TIF_tagPlanarConfiguration 0x11c -#define TIF_tagResolutionUnit 0x128 -#define TIF_tagSoftware 0x131 -#define TIF_tagColorMap 0x140 -#define TIF_tagPredictor 0x13d -#define TIF_tagInkSet 0x14c -#define TIF_tagExtraSamples 0x152 -#define TIF_tagSampleFormat 0x153 - -#define TIF_typBYTE 1 -#define TIF_typASCII 2 -#define TIF_typSHORT 3 -#define TIF_typLONG 4 -#define TIF_typRATIOAL 5 -#define TIF_typSBYTE 6 -#define TIF_typUNDEFINED 7 -#define TIF_typSSHORT 8 -#define TIF_typSLONG 9 -#define TIF_typSRATIONAL 10 -#define TIF_typFLOAT 11 -#define TIF_typDOUBLE 12 - - -//================================================================ -typedef float FLOAT; -typedef double DOUBLE; - - -//================================================================ -// PKImageEncode_TIF helpers -//================================================================ -typedef struct tagTifDE -{ - U16 uTag; - U16 uType; - U32 uCount; - U32 uValueOrOffset; -} TifDE; - -typedef struct tagTifDEMisc -{ - U32 offBitsPerSample; - U32 offSampleFormat; - U32 bps, spp, sf; - U32 iPhotometricInterpretation; - - U32 offXResolution; - U32 resXF, resXD; - - U32 offYResolution; - U32 resYF, resYD; -} TifDEMisc; - -ERR PutTifUShort( - struct WMPStream* pS, - size_t offPos, - U16 uValue) -{ - ERR err = WMP_errSuccess; - - Call(pS->SetPos(pS, offPos)); - Call(pS->Write(pS, &uValue, sizeof(uValue))); - -Cleanup: - return err; -} - -ERR PutTifULong( - struct WMPStream* pS, - size_t offPos, - U32 uValue) -{ - ERR err = WMP_errSuccess; - - Call(pS->SetPos(pS, offPos)); - Call(pS->Write(pS, &uValue, sizeof(uValue))); - -Cleanup: - return err; -} - -ERR WriteTifDE( - struct WMPStream* pS, - size_t offPos, - TifDE* pDE) -{ - ERR err = WMP_errSuccess; - - assert(-1 != pDE->uCount); - assert(-1 != pDE->uValueOrOffset); - - Call(PutTifUShort(pS, offPos, pDE->uTag)); offPos += 2; - Call(PutTifUShort(pS, offPos, pDE->uType)); offPos += 2; - Call(PutTifULong(pS, offPos, pDE->uCount)); offPos += 4; - - switch (pDE->uType) - { - case TIF_typSHORT: - if (1 == pDE->uCount) - { - Call(PutTifUShort(pS, offPos, (U16)pDE->uValueOrOffset)); offPos += 2; - Call(PutTifUShort(pS, offPos, 0)); offPos += 2; - break; - } - - case TIF_typLONG: - case TIF_typRATIOAL: - Call(PutTifULong(pS, offPos, pDE->uValueOrOffset)); offPos += 4; - break; - - default: - Call(WMP_errInvalidParameter); - break; - } - -Cleanup: - return err; -} - -ERR WriteTifHeader( - PKImageEncode* pIE) -{ - ERR err = WMP_errSuccess; - struct WMPStream* pS = pIE->pStream; - size_t offPos = 0; - -#ifdef _BIG__ENDIAN_ - U8 IIMM[3] = "MM"; -#else // _BIG__ENDIAN_ - U8 IIMM[3] = "II"; -#endif // _BIG__ENDIAN_ - - TifDEMisc tifDEMisc = { - (U32) -1, (U32) -1, (U32) -1, (U32) -1, (U32) -1, - 2, // photometric interpretation - (U32) -1, 10000, 10000, - (U32) -1, 10000, 10000, - }; - // const U32 cbTifDEMisc = sizeof(U16) * 10 + sizeof(U32) * 2 * 2; - - const static TifDE tifDEs[] = - { - {0x100, 4, 1, (U32) -1}, // TIF_tagImageWidth - {0x101, 4, 1, (U32) -1}, // TIF_tagImageLength - {0x102, 3, (U32) -1, (U32) -1}, // TIF_tagBitsPerSample - {0x103, 3, 1, 1}, // TIF_tagCompression - {0x106, 3, 1, (U32) -1}, // TIF_tagPhotometricInterpretation - {0x111, 4, 1, (U32) -1}, // TIF_tagStripOffsets - {0x112, 3, 1, 1}, // TIF_tagOrientation - {0x115, 3, 1, (U32) -1}, // TIF_tagSamplesPerPixel - {0x116, 4, 1, (U32) -1}, // TIF_tagRowsPerStrip - {0x117, 4, 1, (U32) -1}, // TIF_tagStripByteCounts - {0x11a, 5, 1, (U32) -1}, // TIF_tagXResolution - {0x11b, 5, 1, (U32) -1}, // TIF_tagYResolution - {0x11c, 3, 1, 1}, // TIF_tagPlanarConfiguration - {0x128, 3, 1, 2}, // TIF_tagResolutionUnit - {0x153, 3, (U32) -1, (U32) -1}, // TIF_tagSampleFormat -// {0x131, 2, -1, -1}, // TIF_tagSoftware -// {0x140, 3, -1, -1}, // TIF_tagColorMap - }; - U16 cTifDEs = sizeof2(tifDEs); - TifDE tifDE = {0}; - PKPixelInfo PI; - size_t cbLine = 0; - - size_t i = 0; - size_t j; - - tifDEMisc.resXF = (U32)(pIE->fResX * 10000); - tifDEMisc.resYF = (U32)(pIE->fResY * 10000); - - Call(pS->GetPos(pS, &offPos)); - FailIf(0 != offPos, WMP_errUnsupportedFormat); - - //================ - // TifHeader - Call(pS->Write(pS, IIMM, 2)); offPos += 2; - Call(PutTifUShort(pS, offPos, 42)); offPos += 2; - Call(PutTifULong(pS, offPos, (U32)(offPos + 4))); offPos += 4; - - //================ - // TifDEMisc - PI.pGUIDPixFmt = &pIE->guidPixFormat; - PixelFormatLookup(&PI, LOOKUP_FORWARD); - - tifDEMisc.iPhotometricInterpretation = - //the N channel TIF by PS has PhotometricInterpretation of PK_PI_RGB - PI.uInterpretation == PK_PI_NCH || PI.uInterpretation == PK_PI_RGBE ? PK_PI_RGB : - (PI.uInterpretation == PK_PI_B0 && pIE->WMP.wmiSCP.bBlackWhite ? PK_PI_W0 : PI.uInterpretation); - tifDEMisc.spp = PI.uSamplePerPixel; - tifDEMisc.bps = PI.uBitsPerSample; - tifDEMisc.sf = PI.uSampleFormat; - - if (tifDEMisc.iPhotometricInterpretation == PK_PI_CMYK) - cTifDEs++; - if (PI.grBit & PK_pixfmtHasAlpha) - cTifDEs++; - tifDEMisc.offBitsPerSample = (U32)offPos + sizeof(U16) + 12 * cTifDEs + sizeof(U32); - tifDEMisc.offSampleFormat = tifDEMisc.offBitsPerSample + (tifDEMisc.spp == 1 ? 0 : tifDEMisc.spp * 2); - tifDEMisc.offXResolution = tifDEMisc.offSampleFormat + (tifDEMisc.spp == 1 ? 0 : tifDEMisc.spp * 2); - tifDEMisc.offYResolution = tifDEMisc.offXResolution + 8; - - //================ - // TifIFD - pIE->offPixel = tifDEMisc.offYResolution + 8; - Call(PutTifUShort(pS, offPos, cTifDEs)); offPos += 2; - - //================ - tifDE = tifDEs[i++]; - assert(TIF_tagImageWidth == tifDE.uTag); - tifDE.uValueOrOffset = pIE->uWidth; - Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12; - - tifDE = tifDEs[i++]; - assert(TIF_tagImageLength == tifDE.uTag); - tifDE.uValueOrOffset = pIE->uHeight; - Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12; - - tifDE = tifDEs[i++]; - assert(TIF_tagBitsPerSample == tifDE.uTag); - tifDE.uCount = tifDEMisc.spp; - tifDE.uValueOrOffset = 1 == tifDE.uCount ? tifDEMisc.bps : tifDEMisc.offBitsPerSample; - Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12; - - tifDE = tifDEs[i++]; - assert(TIF_tagCompression == tifDE.uTag); - Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12; - - tifDE = tifDEs[i++]; - assert(TIF_tagPhotometricInterpretation == tifDE.uTag); - tifDE.uValueOrOffset = tifDEMisc.iPhotometricInterpretation; - Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12; - - tifDE = tifDEs[i++]; - assert(TIF_tagStripOffsets == tifDE.uTag); - tifDE.uValueOrOffset = (U32)pIE->offPixel; - Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12; - - tifDE = tifDEs[i++]; - assert(TIF_tagOrientation == tifDE.uTag); - Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12; - - tifDE = tifDEs[i++]; - assert(TIF_tagSamplesPerPixel == tifDE.uTag); - tifDE.uValueOrOffset = tifDEMisc.spp; - Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12; - - tifDE = tifDEs[i++]; - assert(TIF_tagRowsPerStrip == tifDE.uTag); - tifDE.uValueOrOffset = pIE->uHeight; - Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12; - - tifDE = tifDEs[i++]; - assert(TIF_tagStripByteCounts == tifDE.uTag); - cbLine = (BD_1 == PI.bdBitDepth ? ((PI.cbitUnit * pIE->uWidth + 7) >> 3) : (((PI.cbitUnit + 7) >> 3) * pIE->uWidth)); - tifDE.uValueOrOffset = (U32)(cbLine * pIE->uHeight); - Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12; - - tifDE = tifDEs[i++]; - assert(TIF_tagXResolution == tifDE.uTag); - tifDE.uValueOrOffset = tifDEMisc.offXResolution; - Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12; - - tifDE = tifDEs[i++]; - assert(TIF_tagYResolution == tifDE.uTag); - tifDE.uValueOrOffset = tifDEMisc.offYResolution; - Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12; - - tifDE = tifDEs[i++]; - assert(TIF_tagPlanarConfiguration == tifDE.uTag); - Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12; - - tifDE = tifDEs[i++]; - assert(TIF_tagResolutionUnit == tifDE.uTag); - Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12; - - if (tifDEMisc.iPhotometricInterpretation == PK_PI_CMYK) - { - TifDE tmpDE = {TIF_tagInkSet, 3, 1, 1}; - Call(WriteTifDE(pS, offPos, &tmpDE)); offPos += 12; - } - - if (PI.grBit & PK_pixfmtHasAlpha) - { - TifDE tmpDE = {TIF_tagExtraSamples, 3, 1, 1}; - if (!(PI.grBit & PK_pixfmtPreMul)) - tmpDE.uValueOrOffset++; - Call(WriteTifDE(pS, offPos, &tmpDE)); offPos += 12; - } - - tifDE = tifDEs[i++]; - assert(TIF_tagSampleFormat == tifDE.uTag); - tifDE.uCount = tifDEMisc.spp; - tifDE.uValueOrOffset = 1 == tifDE.uCount ? tifDEMisc.sf : tifDEMisc.offSampleFormat; - Call(WriteTifDE(pS, offPos, &tifDE)); offPos += 12; - - //================ - Call(PutTifULong(pS, offPos, 0)); offPos += 4; - - //================ - // TifDEMisc - if (tifDE.uCount > 1) - { - assert(tifDEMisc.offBitsPerSample == offPos); - if (PI.bdBitDepth == BD_565) - { - Call(PutTifUShort(pS, offPos, 5)); offPos += 2; - Call(PutTifUShort(pS, offPos, 6)); offPos += 2; - Call(PutTifUShort(pS, offPos, 5)); offPos += 2; - } - else - { - for (j = 0; j < tifDE.uCount; j++) - { - Call(PutTifUShort(pS, offPos, (U16)tifDEMisc.bps)); offPos += 2; - } - } - - assert(tifDEMisc.offSampleFormat == offPos); - for (j = 0; j < tifDE.uCount; j++) - { - Call(PutTifUShort(pS, offPos, (U16)tifDEMisc.sf)); offPos += 2; - } - } - - assert(tifDEMisc.offXResolution == offPos); - Call(PutTifULong(pS, offPos, tifDEMisc.resXF)); offPos += 4; - Call(PutTifULong(pS, offPos, tifDEMisc.resXD)); offPos += 4; - - assert(tifDEMisc.offYResolution == offPos); - Call(PutTifULong(pS, offPos, tifDEMisc.resYF)); offPos += 4; - Call(PutTifULong(pS, offPos, tifDEMisc.resYD)); offPos += 4; - - assert(pIE->offPixel == offPos); - - pIE->fHeaderDone = !FALSE; - -Cleanup: - return err; -} - -//================================================================ -// PKImageEncode_TIF -//================================================================ -ERR PKImageEncode_WritePixels_TIF( - PKImageEncode* pIE, - U32 cLine, - U8* pbPixel, - U32 cbStride) -{ - ERR err = WMP_errSuccess; - - struct WMPStream* pS = pIE->pStream; - PKPixelInfo PI; - size_t cbLine = 0; - size_t offPos = 0; - size_t i = 0; - - // header - if (!pIE->fHeaderDone) - { - Call(WriteTifHeader(pIE)); - } - - // body - PI.pGUIDPixFmt = &pIE->guidPixFormat; - PixelFormatLookup(&PI, LOOKUP_FORWARD); - - cbLine = (BD_1 == PI.bdBitDepth ? ((PI.cbitUnit * pIE->uWidth + 7) >> 3) : (((PI.cbitUnit + 7) >> 3) * pIE->uWidth)); - - FailIf(cbStride < cbLine, WMP_errInvalidParameter); - - offPos = pIE->offPixel + cbLine * pIE->idxCurrentLine; - Call(pS->SetPos(pS, offPos)); - - for (i = 0; i < cLine; ++i) - { - Call(pS->Write(pS, pbPixel + cbStride * i, cbLine)); - } - pIE->idxCurrentLine += cLine; - -Cleanup: - return err; -} - -ERR PKImageEncode_Create_TIF(PKImageEncode** ppIE) -{ - ERR err = WMP_errSuccess; - - PKImageEncode* pIE = NULL; - - Call(PKImageEncode_Create(ppIE)); - - pIE = *ppIE; - pIE->WritePixels = PKImageEncode_WritePixels_TIF; - -Cleanup: - return err; -} - - -//================================================================ -// PKImageDecode_TIF helpers -//================================================================ -ERR GetTifUShort( - struct WMPStream* pWS, - size_t offPos, - Bool fLittleEndian, - U16* puValue) -{ - ERR err = WMP_errSuccess; - U8 buf[2]; - - Call(pWS->SetPos(pWS, offPos)); - Call(pWS->Read(pWS, buf, sizeof2(buf))); - - if (fLittleEndian) - { - *puValue = buf[0] + ((U16)buf[1] << 8); - } - else - { - *puValue = ((U16)buf[0] << 8) + buf[1]; - } - -Cleanup: - return err; -} - -ERR GetTifULong( - struct WMPStream* pWS, - size_t offPos, - Bool fLittleEndian, - U32* puValue) -{ - ERR err = WMP_errSuccess; - U8 buf[4]; - - Call(pWS->SetPos(pWS, offPos)); - Call(pWS->Read(pWS, buf, sizeof2(buf))); - - if (fLittleEndian) - { - *puValue = buf[0] + ((U32)buf[1] << 8) + ((U32)buf[2] << 16) + ((U32)buf[3] << 24); - } - else - { - *puValue = ((U32)buf[0] << 24) + ((U32)buf[1] << 16) + ((U32)buf[2] << 8) + buf[3]; - } - -Cleanup: - return err; -} - -ERR GetTifULongArray( - struct WMPStream* pWS, - size_t offPos, - size_t cElements, - Bool fLittleEndian, - U32* puValue) -{ - ERR err = WMP_errSuccess; - - if (1 == cElements) - { - puValue[0] = (U32)offPos; - } - else - { - size_t i = 0; - for (i = 0; i < cElements; ++i) - { - Call(GetTifULong(pWS, offPos, fLittleEndian, &puValue[i])); - offPos += sizeof(*puValue); - } - } - -Cleanup: - return err; -} - -ERR ParseTifDEValue( - PKTestDecode* pID, - U16 uTag, - U16 uType, - U32 uCount) -{ - ERR err = WMP_errSuccess; - - struct WMPStream* pWS = pID->pStream; - U16 bpc[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; - U16 sf[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; - U32 uPos = 0; - U16 usValue = 0; - U32 uValue0 = 0; - U32 uValue1 = 0; - size_t i, offPos = 0; - - //================================ - Call(pWS->GetPos(pWS, &offPos)); - - //================================ - switch (uType) - { - case TIF_typSHORT: - Call(GetTifUShort(pWS, offPos, pID->EXT.TIF.fLittleEndian, &usValue)); - uValue0 = usValue; - break; - - case TIF_typLONG: - Call(GetTifULong(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uValue0)); - break; - } - - //================================ - switch (uTag) - { - case TIF_tagNewSubfileType: - FailIf(0 != uValue0, WMP_errUnsupportedFormat); - break; - - case TIF_tagSubfileType: - case TIF_tagPredictor: - FailIf(1 != uValue0, WMP_errUnsupportedFormat); - break; - - case TIF_tagImageWidth: - pID->uWidth = uValue0; - break; - - case TIF_tagImageLength: - pID->uHeight = uValue0; - break; - - case TIF_tagBitsPerSample: - if (1 == uCount) - { - pID->EXT.TIF.uBitsPerSample = uValue0; - } - else - { - Bool bpcAnd = 1; - - Call(GetTifULong(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uPos)); - offPos = uPos; - - Call(GetTifUShort(pWS, offPos, pID->EXT.TIF.fLittleEndian, &bpc[0])); - - for (i = 1; i < uCount; i++) - { - Call(GetTifUShort(pWS, offPos + (i << 1) , pID->EXT.TIF.fLittleEndian, &bpc[i])); - bpcAnd = (bpcAnd && (bpc[0] == bpc[i])); - } - - if (bpcAnd) - pID->EXT.TIF.uBitsPerSample = bpc[0]; - else - Call(WMP_errUnsupportedFormat); - } - break; - - case TIF_tagExtraSamples: - FailIf(0 != uValue0 && 1 != uValue0 && 2 != uValue0, WMP_errUnsupportedFormat); - pID->EXT.TIF.uExtraSamples = uValue0; - break; - - case TIF_tagSampleFormat: - if (1 == uCount) - { - pID->EXT.TIF.uSampleFormat = uValue0; - } - else - { - Bool sfAnd = 1; - - Call(GetTifULong(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uPos)); - offPos = uPos; - - Call(GetTifUShort(pWS, offPos, pID->EXT.TIF.fLittleEndian, &sf[0])); - - for (i = 1; i < uCount; i++) - { - Call(GetTifUShort(pWS, offPos + (i << 1) , pID->EXT.TIF.fLittleEndian, &sf[i])); - sfAnd = (sfAnd && (sf[0] == sf[i])); - } - - if (sfAnd) - pID->EXT.TIF.uSampleFormat = sf[0]; - else - Call(WMP_errUnsupportedFormat); - } - break; - - case TIF_tagCompression: - FailIf(1 != uValue0, WMP_errUnsupportedFormat); - break; - - case TIF_tagPhotometricInterpretation: - Test(PK_PI_W0 == uValue0 || PK_PI_B0 == uValue0 || PK_PI_RGB == uValue0 - || PK_PI_RGBPalette == uValue0 || PK_PI_TransparencyMask == uValue0 - || PK_PI_CMYK == uValue0 || PK_PI_YCbCr == uValue0 - || PK_PI_CIELab == uValue0, WMP_errUnsupportedFormat); - - pID->EXT.TIF.uInterpretation = uValue0; - break; - - case TIF_tagStripOffsets: - Call(WMPAlloc((void **) &pID->EXT.TIF.uStripOffsets, sizeof(*pID->EXT.TIF.uStripOffsets) * uCount)); - Call(GetTifULong(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uValue0)); - Call(GetTifULongArray(pWS, uValue0, uCount, pID->EXT.TIF.fLittleEndian, pID->EXT.TIF.uStripOffsets)); - break; - - case TIF_tagOrientation: - case TIF_tagSamplesPerPixel: - pID->EXT.TIF.uSamplePerPixel = uValue0; - break; - - case TIF_tagRowsPerStrip: - pID->EXT.TIF.uRowsPerStrip = uValue0; - break; - - case TIF_tagStripByteCounts: - Call(WMPAlloc((void **) &pID->EXT.TIF.uStripByteCounts, sizeof(*pID->EXT.TIF.uStripByteCounts) * uCount)); - Call(GetTifULong(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uValue0)); - Call(GetTifULongArray(pWS, uValue0, uCount, pID->EXT.TIF.fLittleEndian, pID->EXT.TIF.uStripByteCounts)); - break; - - case TIF_tagXResolution: - Call(GetTifULong(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uPos)); - offPos = uPos; - - Call(GetTifULong(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uValue0));//numerator - Call(GetTifULong(pWS, offPos + 4, pID->EXT.TIF.fLittleEndian, &uValue1));//denominator - - pID->EXT.TIF.fResX = (Float)uValue0/(Float)uValue1; - break; - - case TIF_tagYResolution: - Call(GetTifULong(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uPos)); - offPos = uPos; - - Call(GetTifULong(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uValue0));//numerator - Call(GetTifULong(pWS, offPos + 4, pID->EXT.TIF.fLittleEndian, &uValue1));//denominator - pID->EXT.TIF.fResY = (Float)uValue0/(Float)uValue1; - break; - - case TIF_tagResolutionUnit: - pID->EXT.TIF.uResolutionUnit = usValue; - break; - - case TIF_tagPlanarConfiguration: - case TIF_tagSoftware: - case TIF_tagColorMap: - break; - - default: - /*printf("Unrecognized TIFTag: %d(%#x), %d, %d" CRLF, (int)uTag, (int)uTag, (int)uType, (int)uCount);*/ - break; - } - -Cleanup: - return err; -} - -ERR ParseTifDEArray( - PKTestDecode* pID, - size_t offPos) -{ - ERR err = WMP_errSuccess; - - struct WMPStream* pWS = pID->pStream; - U16 uTag = 0; - U16 uType = 0; - U32 uCount = 0; - - Call(GetTifUShort(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uTag)); - offPos += 2; - - Call(GetTifUShort(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uType)); - offPos += 2; - - Call(GetTifULong(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uCount)); - offPos += 4; - - Call(ParseTifDEValue(pID, uTag, uType, uCount)); - -Cleanup: - return err; -} - -ERR ParseTifHeader( - PKTestDecode* pID, - struct WMPStream* pWS) -{ - ERR err = WMP_errSuccess; - PKPixelInfo PI; - - size_t offPosBase = 0; - size_t offPos = 0; - - U8 szSig[3] = {0, 0, '\0'}; - U16 uTiffId = 0; - U32 uOffNextIFD = 0; - U16 uCountDE = 0, i = 0; - - //default - pID->EXT.TIF.uRowsPerStrip = (U32) -1; - pID->EXT.TIF.uInterpretation = (U32) -1; - pID->EXT.TIF.uSamplePerPixel = (U32) -1; - pID->EXT.TIF.uBitsPerSample = (U32) -1; - pID->EXT.TIF.uSampleFormat = 1; - pID->EXT.TIF.uResolutionUnit = 2; - pID->EXT.TIF.fResX = 96; - pID->EXT.TIF.fResY = 96; - - //================================ - Call(pWS->GetPos(pWS, &offPosBase)); - FailIf(0 != offPosBase, WMP_errUnsupportedFormat); - - //================================ - // Header - Call(pWS->Read(pWS, szSig, 2)); - offPos += 2; - if (szSig == (U8 *) strstr((char *) szSig, "II")) - { - pID->EXT.TIF.fLittleEndian = !FALSE; - } - else if (szSig == (U8 *) strstr((char *) szSig, "MM")) - { - pID->EXT.TIF.fLittleEndian = FALSE; - } - else - { - Call(WMP_errUnsupportedFormat); - } - - Call(GetTifUShort(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uTiffId)); - offPos += 2; - FailIf(42 != uTiffId, WMP_errUnsupportedFormat); - - Call(GetTifULong(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uOffNextIFD)); - offPos += 4; - - //================================ - // IFD - offPos = (size_t)uOffNextIFD; - Call(GetTifUShort(pWS, offPos, pID->EXT.TIF.fLittleEndian, &uCountDE)); - offPos += 2; - - for (i = 0; i < uCountDE; ++i) - { - Call(ParseTifDEArray(pID, offPos)); - offPos += 12; - } - - if(pID->EXT.TIF.uRowsPerStrip == -1) - pID->EXT.TIF.uRowsPerStrip = pID->uHeight;//default - - FailIf((-1 == pID->EXT.TIF.uInterpretation - || -1 == pID->EXT.TIF.uSamplePerPixel - || -1 == pID->EXT.TIF.uBitsPerSample), WMP_errUnsupportedFormat); - - PI.uInterpretation = pID->EXT.TIF.uInterpretation; - PI.uSamplePerPixel = pID->EXT.TIF.uSamplePerPixel; - PI.uBitsPerSample = pID->EXT.TIF.uBitsPerSample; - PI.uSampleFormat = pID->EXT.TIF.uSampleFormat; - - PI.grBit = pID->EXT.TIF.uExtraSamples == 1 || pID->EXT.TIF.uExtraSamples == 2 || - /* Workaround for some images without correct info about alpha channel */ - (pID->EXT.TIF.uExtraSamples == 0 && pID->EXT.TIF.uSamplePerPixel > 3) ? PK_pixfmtHasAlpha : 0x0; - PI.grBit |= pID->EXT.TIF.uExtraSamples == 1 ? PK_pixfmtPreMul : 0x0; - - pID->fResX = (3 == pID->EXT.TIF.uResolutionUnit ? (Float)(pID->EXT.TIF.fResX * 2.54) : pID->EXT.TIF.fResX);//cm -> inch - pID->fResY = (3 == pID->EXT.TIF.uResolutionUnit ? (Float)(pID->EXT.TIF.fResY * 2.54) : pID->EXT.TIF.fResY);//cm -> inch - - Call(PixelFormatLookup(&PI, LOOKUP_BACKWARD_TIF)); - - pID->guidPixFormat = *(PI.pGUIDPixFmt); - -Cleanup: - return err; -} - -//================================================================ -// PKImageDecode_TIF -//================================================================ -ERR PKImageDecode_Initialize_TIF( - PKTestDecode* pID, - struct WMPStream* pWS) -{ - ERR err = WMP_errSuccess; - - Call(PKTestDecode_Initialize(pID, pWS)); - Call(ParseTifHeader(pID, pWS)); - -Cleanup: - return err; -} - -ERR GetScanLineOffset( - PKTestDecode* pID, - I32 iLine, - U32 cbLine, - U32 *offLine) -{ - *offLine = pID->EXT.TIF.uRowsPerStrip ? - (pID->EXT.TIF.uStripOffsets[iLine / pID->EXT.TIF.uRowsPerStrip] + - cbLine * (iLine % pID->EXT.TIF.uRowsPerStrip)) : - 0; - - return WMP_errSuccess; -} - -ERR PKImageDecode_Copy_TIF( - PKTestDecode* pID, - const PKRect* pRect, - U8* pb, - U32 cbStride) -{ - ERR err = WMP_errSuccess; - - struct WMPStream* pS = pID->pStream; - PKPixelInfo PI; - U32 cbLine = 0; - I32 i = 0; - - PI.pGUIDPixFmt = &pID->guidPixFormat; - PixelFormatLookup(&PI, LOOKUP_FORWARD); - - cbLine = (BD_1 == PI.bdBitDepth ? ((PI.cbitUnit * pRect->Width + 7) >> 3) : (((PI.cbitUnit + 7) >> 3) * pRect->Width)); - - assert(0 == pRect->X && pID->uWidth == (U32)pRect->Width); - assert(cbLine <= cbStride); - - for (i = 0; i < pRect->Height; ++i) - { - U32 offPixels = 0; - Call(GetScanLineOffset(pID, pRect->Y + i, cbLine, &offPixels)); - - Call(pS->SetPos(pS, offPixels)); - Call(pS->Read(pS, pb + cbStride * i, cbLine)); - - if (PK_PI_W0 == pID->EXT.TIF.uInterpretation) - { - U32 j, begin = cbStride * (U32)i, end = begin + cbLine; - for (j = begin; j < end; ++j) - { - pb[j] = ~pb[j]; - } - } - } - -Cleanup: - return err; -} - -ERR PKImageDecode_Release_TIF(PKTestDecode** ppID) -{ - ERR err = WMP_errSuccess; - - PKTestDecode *pID = *ppID; - - Call(WMPFree((void**)&pID->EXT.TIF.uStripOffsets)); - Call(WMPFree((void**)&pID->EXT.TIF.uStripByteCounts)); - - Call(PKTestDecode_Release(ppID)); - -Cleanup: - return err; -} - -ERR PKImageDecode_Create_TIF(PKTestDecode** ppID) -{ - ERR err = WMP_errSuccess; - PKTestDecode* pID = NULL; - - Call(PKTestDecode_Create(ppID)); - - pID = *ppID; - pID->Initialize = PKImageDecode_Initialize_TIF; - pID->Copy = PKImageDecode_Copy_TIF; - pID->Release = PKImageDecode_Release_TIF; - -Cleanup: - return err; -} - -#endif \ No newline at end of file diff --git a/Src/JxrDecode/Jxr/JXRTestWrapper.c b/Src/JxrDecode/Jxr/JXRTestWrapper.c deleted file mode 100644 index 4b18cdea..00000000 --- a/Src/JxrDecode/Jxr/JXRTestWrapper.c +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include - -#include "JXRGlue.h" -//#include "JXRTestWrapper.h" -#include "strcodec.h" -#include "JXRTest.h" - -//ERR PKImageEncode_Initialize_Wrapper(PKImageEncode* pIE, struct WMPStream* stream, void* vp, size_t size) -//{ -// if (size!=sizeof(JxrTestWrapperInitializeInfo)) -// { -// return WMP_errInvalidArgument; -// } -// -// JxrTestWrapperInitializeInfo* ptrInfo = (JxrTestWrapperInitializeInfo*)vp; -// pIE->WRAPPER.info = *ptrInfo; -// return WMP_errSuccess; -//} -// -//ERR PKImageEncode_WritePixels_Wrapper( -// PKImageEncode* pIE, -// U32 cLine, -// U8* pbPixel, -// U32 cbStride) -//{ -// pIE->WRAPPER.info.pfnPutData( -// pIE->guidPixFormat, -// pIE->uWidth, -// pIE->uHeight, -// cLine, -// pbPixel, -// cbStride, -// pIE->WRAPPER.info.userParamPutData); -// return WMP_errSuccess; -//} -// -//ERR PKImageEncode_Create_Wrapper(PKImageEncode** ppIE) -//{ -// ERR err = WMP_errSuccess; -// -// PKImageEncode* pIE = NULL; -// -// Call(PKImageEncode_Create(ppIE)); -// -// pIE = *ppIE; -// pIE->Initialize = PKImageEncode_Initialize_Wrapper; -// pIE->WritePixels = PKImageEncode_WritePixels_Wrapper; -// -//Cleanup: -// return err; -//} \ No newline at end of file diff --git a/Src/JxrDecode/Jxr/JXRTestWrapper.h b/Src/JxrDecode/Jxr/JXRTestWrapper.h deleted file mode 100644 index f299e2fb..00000000 --- a/Src/JxrDecode/Jxr/JXRTestWrapper.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - - -#ifdef __cplusplus -extern "C" { -#endif - typedef struct tagJxrTestWrapperInitializeInfo - { - void(*pfnPutData)( - PKPixelFormatGUID pixeltype, - unsigned int width, - unsigned int height, - unsigned int cLines, - void* ptrData, - unsigned int stride, - void* userParam); - void* userParamPutData; - } JxrTestWrapperInitializeInfo; - - //ERR PKImageEncode_Initialize_Wrapper(struct tagPKImageEncode* pIE, struct WMPStream* stream, void* vp, size_t size); - //ERR PKImageEncode_Create_Wrapper(struct tagPKImageEncode** ppIE); - //ERR PKImageEncode_WritePixels_Wrapper( - //struct PKImageEncode* pIE, - //U32 cLine, - //U8* pbPixel, - //U32 cbStride); - -#ifdef __cplusplus -} -#endif diff --git a/Src/JxrDecode/Jxr/JXRTestYUV.c b/Src/JxrDecode/Jxr/JXRTestYUV.c deleted file mode 100644 index 39205139..00000000 --- a/Src/JxrDecode/Jxr/JXRTestYUV.c +++ /dev/null @@ -1,722 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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 -#include - -#include "JXRGlue.h" - -#pragma pack(push, 1) -#pragma pack(pop) - -//================================================================ -// PKImageEncode_Iyuv -//================================================================ -ERR WriteIYUVHeader( - PKImageEncode* pIE) -{ - ERR err = WMP_errSuccess; - // struct WMPStream* pS = pIE->pStream; - - pIE->offPixel = 0; - - pIE->cbPixel = 3; - - pIE->fHeaderDone = !FALSE; - - return err; -} - -//================================================================ -// PKImageEncode_Yuv422 -//================================================================ -ERR WriteYUV422Header( - PKImageEncode* pIE) -{ - ERR err = WMP_errSuccess; - // struct WMPStream* pS = pIE->pStream; - - pIE->offPixel = 0; - - pIE->cbPixel = 3; - - pIE->fHeaderDone = !FALSE; - - return err; -} - -//================================================================ -// PKImageEncode_Yuv444 -//================================================================ -ERR WriteYUV444Header( - PKImageEncode* pIE) -{ - ERR err = WMP_errSuccess; - // struct WMPStream* pS = pIE->pStream; - - pIE->offPixel = 0; - - pIE->cbPixel = 3; - - pIE->fHeaderDone = !FALSE; - - return err; -} - -ERR PKImageEncode_WritePixels_IYUV( - PKImageEncode* pIE, - U32 cLine, - U8* pbPixel, - U32 cbStride) -{ - ERR err = WMP_errSuccess; - struct WMPStream* pS = pIE->pStream; - size_t iRow, iCol; - U32 uYSize, uUVSize; - U8 *pY; - U8 *pU; - U8 *pV; - - //UNREFERENCED_PARAMETER( cbStride ); - - // header - if (!pIE->fHeaderDone) - { - Call(WriteIYUVHeader(pIE)); - } - - //from packed to planar: - uYSize = cLine * pIE->uWidth; - uUVSize = (uYSize >> 2); - - pY = (U8 *)malloc(uYSize); - pU = (U8 *)malloc(uUVSize); - pV = (U8 *)malloc(uUVSize); - - if(pY == NULL || pU == NULL || pV == NULL) - { - return ICERR_ERROR; - } - - for (iRow = 0; iRow < pIE->uHeight; iRow += 2, pY += pIE->uWidth) - { - for (iCol = 0; iCol < pIE->uWidth; iCol += 2, pY += 2) - { - - *pY = *pbPixel; - pbPixel++; - *(pY + 1)= *pbPixel; - pbPixel++; - *(pY + pIE->uWidth) = *pbPixel; - pbPixel++; - *(pY + pIE->uWidth + 1) = *pbPixel; - pbPixel++; - - *pU = *pbPixel; - pbPixel++; pU++; - *pV = *pbPixel; - pbPixel++; pV++; - } - } - - pY-=uYSize; - pU-=uUVSize; - pV-=uUVSize; - - Call(pS->Write(pS, pY, uYSize)); - Call(pS->Write(pS, pU, uUVSize)); - Call(pS->Write(pS, pV, uUVSize)); - - if(pY!=NULL) - free(pY); - if(pU!=NULL) - free(pU); - if(pV!=NULL) - free(pV); - - pIE->idxCurrentLine += cLine; - -Cleanup: - return err; -} - - -ERR PKImageEncode_WritePixels_YUV422( - PKImageEncode* pIE, - U32 cLine, - U8* pbPixel, - U32 cbStride) -{ - ERR err = WMP_errSuccess; - struct WMPStream* pS = pIE->pStream; - size_t iRow, iCol; - U32 uYSize, uUVSize; - U8 *pY; - U8 *pU; - U8 *pV; - -// UNREFERENCED_PARAMETER( cbStride ); - - // header - if (!pIE->fHeaderDone) - { - Call(WriteIYUVHeader(pIE)); - } - - //from packed to planar: - uYSize = cLine * pIE->uWidth; - uUVSize = (uYSize >> 1); - - pY = (U8 *)malloc(uYSize); - pU = (U8 *)malloc(uUVSize); - pV = (U8 *)malloc(uUVSize); - - if(pY == NULL || pU == NULL || pV == NULL) - { - return ICERR_ERROR; - } -//YYUV - for (iRow = 0; iRow < pIE->uHeight; iRow += 1) - { - for (iCol = 0; iCol < pIE->uWidth; iCol += 2) - { - *pU = *pbPixel; - pbPixel++; pU++; - - *pY = *pbPixel; - pbPixel++; pY++; - - *pV = *pbPixel; - pbPixel++; pV++; - - *pY = *pbPixel; - pbPixel++; pY++; - } - } - - pY-=uYSize; - pU-=uUVSize; - pV-=uUVSize; - - Call(pS->Write(pS, pY, uYSize)); - Call(pS->Write(pS, pU, uUVSize)); - Call(pS->Write(pS, pV, uUVSize)); - - if(pY!=NULL) - free(pY); - if(pU!=NULL) - free(pU); - if(pV!=NULL) - free(pV); - - pIE->idxCurrentLine += cLine; - -Cleanup: - return err; -} - - -ERR PKImageEncode_WritePixels_YUV444( - PKImageEncode* pIE, - U32 cLine, - U8* pbPixel, - U32 cbStride) -{ - ERR err = WMP_errSuccess; - struct WMPStream* pS = pIE->pStream; - size_t iRow, iCol; - U32 uYSize, uUVSize; - U8 *pY; - U8 *pU; - U8 *pV; - -// UNREFERENCED_PARAMETER( cbStride ); - - // header - if (!pIE->fHeaderDone) - { - Call(WriteIYUVHeader(pIE)); - } - - //from packed to planar: - uYSize = cLine * pIE->uWidth; - uUVSize = uYSize; - - pY = (U8 *)malloc(uYSize); - pU = (U8 *)malloc(uUVSize); - pV = (U8 *)malloc(uUVSize); - - if(pY == NULL || pU == NULL || pV == NULL) - { - return ICERR_ERROR; - } - - for (iRow = 0; iRow < pIE->uHeight; iRow += 1) - { - for (iCol = 0; iCol < pIE->uWidth; iCol += 1) - { - - *pY = *pbPixel; - pbPixel++; pY++; - - *pU = *pbPixel; - pbPixel++; pU++; - *pV = *pbPixel; - pbPixel++; pV++; - } - } - - pY-=uYSize; - pU-=uUVSize; - pV-=uUVSize; - - Call(pS->Write(pS, pY, uYSize)); - Call(pS->Write(pS, pU, uUVSize)); - Call(pS->Write(pS, pV, uUVSize)); - - if(pY!=NULL) - free(pY); - if(pU!=NULL) - free(pU); - if(pV!=NULL) - free(pV); - - pIE->idxCurrentLine += cLine; - -Cleanup: - return err; -} - - - -ERR PKImageEncode_Create_IYUV( - PKImageEncode** ppIE) -{ - ERR err = WMP_errSuccess; - PKImageEncode* pIE = NULL; - - Call(PKImageEncode_Create(ppIE)); - - pIE = *ppIE; - pIE->WritePixels = PKImageEncode_WritePixels_IYUV; - -Cleanup: - return err; -} - -ERR PKImageEncode_Create_YUV422( - PKImageEncode** ppIE) -{ - ERR err = WMP_errSuccess; - PKImageEncode* pIE = NULL; - - Call(PKImageEncode_Create(ppIE)); - - pIE = *ppIE; - pIE->WritePixels = PKImageEncode_WritePixels_YUV422; - -Cleanup: - return err; -} - -ERR PKImageEncode_Create_YUV444( - PKImageEncode** ppIE) -{ - ERR err = WMP_errSuccess; - PKImageEncode* pIE = NULL; - - Call(PKImageEncode_Create(ppIE)); - - pIE = *ppIE; - pIE->WritePixels = PKImageEncode_WritePixels_YUV444; - -Cleanup: - return err; -} - -//================================================================ -// PKImageDecode_IYUV -//================================================================ -ERR ParseIYUVHeader( - PKImageDecode* pID, - struct WMPStream* pWS) -{ - ERR err = WMP_errSuccess; - -// UNREFERENCED_PARAMETER( pWS ); - - // Set header other header parameters - pID->guidPixFormat = GUID_PKPixelFormat12bppYUV420; - - pID->uHeight = 144; - pID->uWidth = 176; - - //I don't need offpixel for raw data! Call(pWS->GetPos(pWS, &pID->YUV420.offPixel)); - - return err; -} - -//================================================================ -// PKImageDecode_YUV422 -//================================================================ -ERR ParseYUV422Header( - PKImageDecode* pID, - struct WMPStream* pWS) -{ - ERR err = WMP_errSuccess; - -// UNREFERENCED_PARAMETER( pWS ); - - // Set header other header parameters - pID->guidPixFormat = GUID_PKPixelFormat16bppYUV422; - - pID->uHeight = 144; - pID->uWidth = 176; - - return err; -} - -//================================================================ -// PKImageDecode_YUV422 -//================================================================ -ERR ParseYUV444Header( - PKImageDecode* pID, - struct WMPStream* pWS) -{ - ERR err = WMP_errSuccess; - -// UNREFERENCED_PARAMETER( pWS ); - - // Set header other header parameters - pID->guidPixFormat = GUID_PKPixelFormat24bppYUV444; - - pID->uHeight = 144; - pID->uWidth = 176; - - return err; -} - -ERR PKImageDecode_Initialize_IYUV( - PKImageDecode* pID, - struct WMPStream* pWS) -{ - ERR err = WMP_errSuccess; - - Call(PKImageDecode_Initialize(pID, pWS)); - Call(ParseIYUVHeader(pID, pWS)); - -Cleanup: - return err; -} - -ERR PKImageDecode_Initialize_YUV422( - PKImageDecode* pID, - struct WMPStream* pWS) -{ - ERR err = WMP_errSuccess; - - Call(PKImageDecode_Initialize(pID, pWS)); - Call(ParseYUV422Header(pID, pWS)); - -Cleanup: - return err; -} - -ERR PKImageDecode_Initialize_YUV444( - PKImageDecode* pID, - struct WMPStream* pWS) -{ - ERR err = WMP_errSuccess; - - Call(PKImageDecode_Initialize(pID, pWS)); - Call(ParseYUV444Header(pID, pWS)); - -Cleanup: - return err; -} - - -ERR PKImageDecode_Copy_IYUV( - PKImageDecode* pID, - const PKRect* pRect, - U8* pb, - U32 cbStride) -{ - ERR err = WMP_errSuccess; - U32 uYSize, uUVSize; - U8 *pY; - U8 *pU; - U8 *pV; - - struct WMPStream* pS = pID->pStream; - - size_t iRow, iCol; - - //UNREFERENCED_PARAMETER( pRect ); - //UNREFERENCED_PARAMETER( cbStride ); - - //from planar to packed! YYYYUV YYYYUV - uYSize = pID->uWidth * pID->uHeight; - uUVSize = (uYSize >> 2); - - pY = (U8 *)malloc(uYSize); - pU = (U8 *)malloc(uUVSize); - pV = (U8 *)malloc(uUVSize); - - if(pY == NULL || pU == NULL || pV == NULL) - { - return ICERR_ERROR; - } - - Call(pS->Read(pS, pY, uYSize)); - Call(pS->Read(pS, pU, uUVSize)); - Call(pS->Read(pS, pV, uUVSize)); - - //re-organize it to Y0 Y1 - // Y2 Y3 U V - - for (iRow = 0; iRow < pID->uHeight; iRow += 2, pY += pID->uWidth) - { - for (iCol = 0; iCol < pID->uWidth; iCol += 2, pY += 2) - { - *pb = *pY; - pb++; - *pb = *(pY + 1); - pb++; - *pb = *(pY + pID->uWidth); - pb++; - *pb = *(pY + pID->uWidth + 1); - pb++; - - *pb = *pU; - pb++; pU++; - *pb = *pV; - pb++; pV++; - } - } - - pY-=uYSize; - pU-=uUVSize; - pV-=uUVSize; - if(pY!=NULL) - free(pY); - if(pU!=NULL) - free(pU); - if(pV!=NULL) - free(pV); - -Cleanup: - return err; -} - - -ERR PKImageDecode_Copy_YUV422( - PKImageDecode* pID, - const PKRect* pRect, - U8* pb, - U32 cbStride) -{ - ERR err = WMP_errSuccess; - U32 uYSize, uUVSize; - U8 *pY; - U8 *pU; - U8 *pV; - - struct WMPStream* pS = pID->pStream; - - size_t iRow, iCol; - - //UNREFERENCED_PARAMETER( pRect ); - //UNREFERENCED_PARAMETER( cbStride ); - - uYSize = pID->uWidth * pID->uHeight; - uUVSize = (uYSize >> 1); - - pY = (U8 *)malloc(uYSize); - pU = (U8 *)malloc(uUVSize); - pV = (U8 *)malloc(uUVSize); - - if(pY == NULL || pU == NULL || pV == NULL) - { - return ICERR_ERROR; - } - - Call(pS->Read(pS, pY, uYSize)); - Call(pS->Read(pS, pU, uUVSize)); - Call(pS->Read(pS, pV, uUVSize)); - - //re-organize to iMode 0 : YYUV - - for (iRow = 0; iRow < pID->uHeight; iRow += 1) - { - for (iCol = 0; iCol < pID->uWidth; iCol += 2) - { - *pb = *pU; - pb++; pU++; - - *pb = *pY; - pb++; pY++; - - *pb = *pV; - pb++; pV++; - - *pb = *pY; - pb++; pY++; - } - } - - pY-=uYSize; - pU-=uUVSize; - pV-=uUVSize; - if(pY!=NULL) - free(pY); - if(pU!=NULL) - free(pU); - if(pV!=NULL) - free(pV); - -Cleanup: - return err; -} - - -ERR PKImageDecode_Copy_YUV444( - PKImageDecode* pID, - const PKRect* pRect, - U8* pb, - U32 cbStride) -{ - ERR err = WMP_errSuccess; - U32 uYSize, uUVSize; - U8 *pY; - U8 *pU; - U8 *pV; - - struct WMPStream* pS = pID->pStream; - - size_t iRow, iCol; - - //UNREFERENCED_PARAMETER( pRect ); - //UNREFERENCED_PARAMETER( cbStride ); - - //from planar to packed! YYYYUV YYYYUV - uYSize = pID->uWidth * pID->uHeight; - uUVSize = uYSize; - - pY = (U8 *)malloc(uYSize); - pU = (U8 *)malloc(uUVSize); - pV = (U8 *)malloc(uUVSize); - - if(pY == NULL || pU == NULL || pV == NULL) - { - return ICERR_ERROR; - } - - Call(pS->Read(pS, pY, uYSize)); - Call(pS->Read(pS, pU, uUVSize)); - Call(pS->Read(pS, pV, uUVSize)); - - //Organize it as YUVYUVYUV... - - for (iRow = 0; iRow < pID->uHeight; iRow += 1) - { - for (iCol = 0; iCol < pID->uWidth; iCol += 1) - { - *pb = *pY; - pb++; pY++; - - *pb = *pU; - pb++; pU++; - *pb = *pV; - pb++; pV++; - } - } - - pY-=uYSize; - pU-=uUVSize; - pV-=uUVSize; - if(pY!=NULL) - free(pY); - if(pU!=NULL) - free(pU); - if(pV!=NULL) - free(pV); - -Cleanup: - return err; -} - - -ERR PKImageDecode_Create_IYUV( - PKImageDecode** ppID) -{ - ERR err = WMP_errSuccess; - PKImageDecode* pID = NULL; - - Call(PKImageDecode_Create(ppID)); - - pID = *ppID; - pID->Initialize = PKImageDecode_Initialize_IYUV; - pID->Copy = PKImageDecode_Copy_IYUV; - -Cleanup: - return err; -} - -ERR PKImageDecode_Create_YUV422( - PKImageDecode** ppID) -{ - ERR err = WMP_errSuccess; - PKImageDecode* pID = NULL; - - Call(PKImageDecode_Create(ppID)); - - pID = *ppID; - pID->Initialize = PKImageDecode_Initialize_YUV422; - pID->Copy = PKImageDecode_Copy_YUV422; - -Cleanup: - return err; -} - -ERR PKImageDecode_Create_YUV444( - PKImageDecode** ppID) -{ - ERR err = WMP_errSuccess; - PKImageDecode* pID = NULL; - - Call(PKImageDecode_Create(ppID)); - - pID = *ppID; - pID->Initialize = PKImageDecode_Initialize_YUV444; - pID->Copy = PKImageDecode_Copy_YUV444; - -Cleanup: - return err; -} - diff --git a/Src/JxrDecode/Jxr/JXRTranscode.c b/Src/JxrDecode/Jxr/JXRTranscode.c deleted file mode 100644 index ef14fced..00000000 --- a/Src/JxrDecode/Jxr/JXRTranscode.c +++ /dev/null @@ -1,991 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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; -} diff --git a/Src/JxrDecode/Jxr/_x86/_x86.h b/Src/JxrDecode/Jxr/_x86/_x86.h deleted file mode 100644 index c182fc9d..00000000 --- a/Src/JxrDecode/Jxr/_x86/_x86.h +++ /dev/null @@ -1,58 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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 -#include - -//================================ -// 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 - - diff --git a/Src/JxrDecode/Jxr/adapthuff.c b/Src/JxrDecode/Jxr/adapthuff.c deleted file mode 100644 index da1c584e..00000000 --- a/Src/JxrDecode/Jxr/adapthuff.c +++ /dev/null @@ -1,502 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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" - -// 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) -{ - 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 -**********************************************************************/ -const Int THRESHOLD = 8; -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*/0x80000000) : -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; -} - diff --git a/Src/JxrDecode/Jxr/ansi.h b/Src/JxrDecode/Jxr/ansi.h deleted file mode 100644 index 74900c97..00000000 --- a/Src/JxrDecode/Jxr/ansi.h +++ /dev/null @@ -1,61 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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 - - diff --git a/Src/JxrDecode/Jxr/common.h b/Src/JxrDecode/Jxr/common.h deleted file mode 100644 index 600dc3bc..00000000 --- a/Src/JxrDecode/Jxr/common.h +++ /dev/null @@ -1,131 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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 diff --git a/Src/JxrDecode/Jxr/decode.c b/Src/JxrDecode/Jxr/decode.c deleted file mode 100644 index 82195cc4..00000000 --- a/Src/JxrDecode/Jxr/decode.c +++ /dev/null @@ -1,200 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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); - } -} - diff --git a/Src/JxrDecode/Jxr/decode.h b/Src/JxrDecode/Jxr/decode.h deleted file mode 100644 index 404fe47b..00000000 --- a/Src/JxrDecode/Jxr/decode.h +++ /dev/null @@ -1,143 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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 - diff --git a/Src/JxrDecode/Jxr/encode.c b/Src/JxrDecode/Jxr/encode.c deleted file mode 100644 index 82db3415..00000000 --- a/Src/JxrDecode/Jxr/encode.c +++ /dev/null @@ -1,144 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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 -#include -#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); - } -} - diff --git a/Src/JxrDecode/Jxr/encode.h b/Src/JxrDecode/Jxr/encode.h deleted file mode 100644 index db9e7bb3..00000000 --- a/Src/JxrDecode/Jxr/encode.h +++ /dev/null @@ -1,113 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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 - diff --git a/Src/JxrDecode/Jxr/image.c b/Src/JxrDecode/Jxr/image.c deleted file mode 100644 index 9bcfe4be..00000000 --- a/Src/JxrDecode/Jxr/image.c +++ /dev/null @@ -1,182 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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 -#include - -#if !(defined(__ANSI__)) && !(defined(__GNUC__)) -// Desktop -#include -#else -// ANSI -#include -#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) { - for (Int 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]]; - } - } -} diff --git a/Src/JxrDecode/Jxr/jxr_defines.h b/Src/JxrDecode/Jxr/jxr_defines.h deleted file mode 100644 index df2dcbbc..00000000 --- a/Src/JxrDecode/Jxr/jxr_defines.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -#define DISABLE_PERF_MEASUREMENT (1) diff --git a/Src/JxrDecode/Jxr/perfTimer.h b/Src/JxrDecode/Jxr/perfTimer.h deleted file mode 100644 index 87fd40b7..00000000 --- a/Src/JxrDecode/Jxr/perfTimer.h +++ /dev/null @@ -1,117 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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_ diff --git a/Src/JxrDecode/Jxr/perfTimerANSI.c b/Src/JxrDecode/Jxr/perfTimerANSI.c deleted file mode 100644 index 91207556..00000000 --- a/Src/JxrDecode/Jxr/perfTimerANSI.c +++ /dev/null @@ -1,276 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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. -// -//*@@@---@@@@****************************************************************** -#if 0 -//*************************************************************************** -// Includes -//*************************************************************************** -#include "jxr_defines.h" -#include -#include "strcodec.h" -#include "perfTimer.h" - - -#ifndef DISABLE_PERF_MEASUREMENT - - -//*************************************************************************** -// Private Functions -//*************************************************************************** - -Bool AccumulateTime(PERFTIMERSTATE *pState, PERFTIMERTIME *ptAccumulator) -{ - Bool fResult = FALSE; - clock_t iStopTime; - clock_t iIntervalTime; - iStopTime = clock(); - - // Check clock result - if ((clock_t)-1 == iStopTime) - { - TraceResult(WM_E_CLOCKFAILURE); - goto exit; - } - - iIntervalTime = (iStopTime - (clock_t) pState->iPrevStartTime); - - // Check for zero-time interval - if (0 == iIntervalTime) - pState->iZeroTimeIntervals += 1; - - // Accumulate current interval's time - *ptAccumulator += iIntervalTime; - fResult = TRUE; - -exit: - return fResult; -} - - -//*************************************************************************** -// Public Functions -//*************************************************************************** - - -Bool PerfTimerNew(PERFTIMERSTATE **ppNewPerfTimer) -{ - Bool fResult = FALSE; - PERFTIMERSTATE *pState = NULL; - clock_t ctResult; - - // Check if this clock works - ctResult = clock(); - if ((clock_t)-1 == ctResult) - { - TraceResult(WM_E_CLOCKFAILURE); - goto exit; - } - - pState = malloc(sizeof(*pState)); - if (NULL == pState) - { - TraceResult(E_OUTOFMEMORY); - goto exit; - } - memset(pState, 0, sizeof(*pState)); - pState->eState = CS_STOPPED; - pState->iElapsedTime = 0; - pState->iPrevStartTime = 0; - pState->iZeroTimeIntervals = 0; - - *ppNewPerfTimer = pState; - fResult = TRUE; - -exit: - assert(fResult || NULL == pState); // If error, we need to free pState - return fResult; -} // PerfTimerNew - - - -void PerfTimerDelete(PERFTIMERSTATE *pState) -{ - free(pState); -} // PerfTimerDelete - - - -Bool PerfTimerStart(PERFTIMERSTATE *pState) -{ - Bool fResult = FALSE; - - if (NULL == pState) - { - // Can happen because we typically ignore errors and use a single bool to - // control all perf timing (some of which can fail to init) - goto exit; - } - - // Make sure we are in the right state - if (CS_STOPPED != pState->eState) - { - assert(FALSE); - goto exit; - } - - pState->iPrevStartTime = clock(); - - // Check clock result - if ((clock_t)-1 == pState->iPrevStartTime) - { - TraceResult(WM_E_CLOCKFAILURE); - goto exit; - } - - pState->eState = CS_RUNNING; - fResult = TRUE; - -exit: - return fResult; -} // PerfTimerStart - - - -Bool PerfTimerStop(PERFTIMERSTATE *pState) -{ - Bool fResult = FALSE; - - if (NULL == pState) - { - // Can happen because we typically ignore errors and use a single bool to - // control all perf timing (some of which can fail to init) - goto exit; - } - - // Make sure we are in the right state - if (CS_RUNNING != pState->eState) - { - assert(FALSE); - goto exit; - } - - fResult = AccumulateTime(pState, &pState->iElapsedTime); - pState->eState = CS_STOPPED; - fResult = TRUE; - -exit: - return fResult; -} // PerfTimerStop - - - -Bool PerfTimerGetResults(PERFTIMERSTATE *pState, PERFTIMERRESULTS *pResults) -{ - Bool fResult = FALSE; - PERFTIMERTIME iElapsedTime; - - if (NULL == pState) - { - // Can happen because we typically ignore errors and use a single bool to - // control all perf timing (some of which can fail to init) - goto exit; - } - - // Make sure we are in the right state - if (CS_STOPPED != pState->eState && CS_RUNNING != pState->eState) - { - assert(FALSE); - goto exit; - } - - iElapsedTime = pState->iElapsedTime; - if (CS_RUNNING == pState->eState) - { - // Must take a "checkpoint" time reading - fResult = AccumulateTime(pState, &iElapsedTime); - if (FALSE == fResult) - goto exit; - } - - // Convert clock ticks to nanoseconds. - // Use floating point for ease of math. If your platform really blows - // with floating point, replace this with appropriate integer calculation - // based on your clock interval. - pResults->iElapsedTime = (PERFTIMERTIME)((float)iElapsedTime * - ((float)NANOSECONDS_PER_SECOND / (float)CLOCKS_PER_SEC)); - pResults->iTicksPerSecond = CLOCKS_PER_SEC; - pResults->iZeroTimeIntervals = pState->iZeroTimeIntervals; - fResult = TRUE; - -exit: - return fResult; -} // PerfTimerGetResults - - - -Bool PerfTimerCopyStartTime(PERFTIMERSTATE *pDestPerfTimer, - PERFTIMERSTATE *pSrcPerfTimer) -{ - Bool fResult = FALSE; - - if (NULL == pDestPerfTimer) - { - TraceResult(E_INVALIDARG); - goto exit; - } - - if (NULL == pSrcPerfTimer) - { - TraceResult(E_INVALIDARG); - goto exit; - } - - // Check that both timers are in proper state - both must be running - if (CS_RUNNING != pDestPerfTimer->eState) - { - TraceResult(WM_E_INVALIDSTATE); - goto exit; - } - - if (CS_RUNNING != pSrcPerfTimer->eState) - { - TraceResult(WM_E_INVALIDSTATE); - goto exit; - } - - if (0 != pDestPerfTimer->iElapsedTime) - { - // If iElapsedTime is non-zero, caller won't get what he is expecting - // when he calls PerfTimerGetResults - TraceResult(WM_E_INVALIDSTATE); - goto exit; - } - - pDestPerfTimer->iPrevStartTime = pSrcPerfTimer->iPrevStartTime; - fResult = TRUE; - -exit: - return fResult; -} // PerfTimerCopyStartTime - -#endif // DISABLE_PERF_MEASUREMENT -#endif \ No newline at end of file diff --git a/Src/JxrDecode/Jxr/postprocess.c b/Src/JxrDecode/Jxr/postprocess.c deleted file mode 100644 index 252d11f5..00000000 --- a/Src/JxrDecode/Jxr/postprocess.c +++ /dev/null @@ -1,288 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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]); - } - } - } - } -} - diff --git a/Src/JxrDecode/Jxr/priv_guiddef.h b/Src/JxrDecode/Jxr/priv_guiddef.h deleted file mode 100644 index f8360ea8..00000000 --- a/Src/JxrDecode/Jxr/priv_guiddef.h +++ /dev/null @@ -1,232 +0,0 @@ -//+--------------------------------------------------------------------------- -// -// 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. -// -// File: guiddef.h -// -// Contents: GUID definition -// -//---------------------------------------------------------------------------- - -#ifndef GUID_DEFINED -#define GUID_DEFINED -#if defined(__midl) -typedef struct { - unsigned long Data1; - unsigned short Data2; - unsigned short Data3; - byte Data4[8]; -} GUID; -#else -typedef struct _GUID { -#if defined(_WINDOWS_) || !__LP64__ - unsigned long Data1; -#else - unsigned int Data1; -#endif - unsigned short Data2; - unsigned short Data3; - unsigned char Data4[8]; -} GUID; -#endif -#endif - -#ifndef FAR -#if defined(_WIN32) || defined(__ANSI__) -#define FAR -#else -//#define FAR _far -#define FAR -#endif -#endif - -#ifndef DECLSPEC_SELECTANY -#if (_MSC_VER >= 1100) -#define DECLSPEC_SELECTANY __declspec(selectany) -#else -#define DECLSPEC_SELECTANY -#endif -#endif - -#ifndef EXTERN_C -#ifdef __cplusplus -#define EXTERN_C extern "C" -#else -#define EXTERN_C extern -#endif -#endif - -#ifdef DEFINE_GUID -#undef DEFINE_GUID -#endif - -#ifdef INITGUID -#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - const GUID DECLSPEC_SELECTANY name \ - = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } -#else -#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - EXTERN_C const GUID FAR name -#endif // INITGUID - -#define DEFINE_OLEGUID(name, l, w1, w2) DEFINE_GUID(name, l, w1, w2, 0xC0,0,0,0,0,0,0,0x46) - -#ifndef _GUIDDEF_H_ -#define _GUIDDEF_H_ - -#ifndef __LPGUID_DEFINED__ -#define __LPGUID_DEFINED__ -typedef GUID *LPGUID; -#endif - -#ifndef __LPCGUID_DEFINED__ -#define __LPCGUID_DEFINED__ -typedef const GUID *LPCGUID; -#endif - -#ifndef __IID_DEFINED__ -#define __IID_DEFINED__ - -typedef GUID IID; -typedef IID *LPIID; -#define IID_NULL GUID_NULL -#define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2) -typedef GUID CLSID; -typedef CLSID *LPCLSID; -#define CLSID_NULL GUID_NULL -#define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2) -typedef GUID FMTID; -typedef FMTID *LPFMTID; -#define FMTID_NULL GUID_NULL -#define IsEqualFMTID(rfmtid1, rfmtid2) IsEqualGUID(rfmtid1, rfmtid2) - -#ifdef __midl_proxy -#define __MIDL_CONST -#else -#define __MIDL_CONST const -#endif - -#ifndef _REFGUID_DEFINED -#define _REFGUID_DEFINED -#ifdef __cplusplus -#define REFGUID const GUID & -#else -#define REFGUID const GUID * __MIDL_CONST -#endif -#endif - -#ifndef _REFIID_DEFINED -#define _REFIID_DEFINED -#ifdef __cplusplus -#define REFIID const IID & -#else -#define REFIID const IID * __MIDL_CONST -#endif -#endif - -#ifndef _REFCLSID_DEFINED -#define _REFCLSID_DEFINED -#ifdef __cplusplus -#define REFCLSID const IID & -#else -#define REFCLSID const IID * __MIDL_CONST -#endif -#endif - -#ifndef _REFFMTID_DEFINED -#define _REFFMTID_DEFINED -#ifdef __cplusplus -#define REFFMTID const IID & -#else -#define REFFMTID const IID * __MIDL_CONST -#endif -#endif - -#endif // !__IID_DEFINED__ - -#if !defined (__midl) -#if !defined (_SYS_GUID_OPERATORS_) -#define _SYS_GUID_OPERATORS_ -#include - -// Faster (but makes code fatter) inline version...use sparingly -#ifdef __cplusplus -__inline int InlineIsEqualGUID(REFGUID rguid1, REFGUID rguid2) -{ - return ( - ((unsigned long *)&rguid1)[0] == ((unsigned long *)&rguid2)[0] && - ((unsigned long *)&rguid1)[1] == ((unsigned long *)&rguid2)[1] && - ((unsigned long *)&rguid1)[2] == ((unsigned long *)&rguid2)[2] && - ((unsigned long *)&rguid1)[3] == ((unsigned long *)&rguid2)[3]); -} - -__inline int IsEqualGUID(REFGUID rguid1, REFGUID rguid2) -{ - return !memcmp(&rguid1, &rguid2, sizeof(GUID)); -} - -#else // ! __cplusplus - -#define InlineIsEqualGUID(rguid1, rguid2) \ - (((unsigned long *) rguid1)[0] == ((unsigned long *) rguid2)[0] && \ - ((unsigned long *) rguid1)[1] == ((unsigned long *) rguid2)[1] && \ - ((unsigned long *) rguid1)[2] == ((unsigned long *) rguid2)[2] && \ - ((unsigned long *) rguid1)[3] == ((unsigned long *) rguid2)[3]) - -#define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID))) - -#endif // __cplusplus - -#ifdef __INLINE_ISEQUAL_GUID -#undef IsEqualGUID -#define IsEqualGUID(rguid1, rguid2) InlineIsEqualGUID(rguid1, rguid2) -#endif - -// Same type, different name - -#define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2) -#define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2) - - -#if !defined _SYS_GUID_OPERATOR_EQ_ && !defined _NO_SYS_GUID_OPERATOR_EQ_ -#define _SYS_GUID_OPERATOR_EQ_ -// A couple of C++ helpers - -#ifdef __cplusplus -__inline int operator==(REFGUID guidOne, REFGUID guidOther) -{ - return IsEqualGUID(guidOne, guidOther); -} - -__inline int operator!=(REFGUID guidOne, REFGUID guidOther) -{ - return !(guidOne == guidOther); -} -#endif -#endif // _SYS_GUID_OPERATOR_EQ_ -#endif // _SYS_GUID_OPERATORS_ -#endif // __midl -#endif // _GUIDDEF_H_ - diff --git a/Src/JxrDecode/Jxr/segdec.c b/Src/JxrDecode/Jxr/segdec.c deleted file mode 100644 index 59f47bc9..00000000 --- a/Src/JxrDecode/Jxr/segdec.c +++ /dev/null @@ -1,1227 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// Copyright © Microsoft Corp. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// • Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// • Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -//*@@@---@@@@****************************************************************** - -#include "strcodec.h" -#include "decode.h" - -#ifdef MEM_TRACE -#define TRACE_MALLOC 1 -#define TRACE_NEW 0 -#define TRACE_HEAP 0 -#include "memtrace.h" -#endif - -extern const int dctIndex[3][16]; -extern const int blkOffset[16]; -extern const int blkOffsetUV[4]; -static Int DecodeSignificantAbsLevel(struct CAdaptiveHuffman *pAHexpt, BitIOInfo* pIO); - -//#undef X86OPT_INLINE - -#ifdef X86OPT_INLINE -#define _FORCEINLINE __forceinline -#else // X86OPT_INLINE -#define _FORCEINLINE -#endif // X86OPT_INLINE - -//================================================================ -// Memory access functions -//================================================================ -static U32 _FORCEINLINE _load4(void* pv) -{ -#ifdef _BIG__ENDIAN_ - #ifdef _NO_UNALIGNED_LOAD_ - U32 v; - memcpy(&v, pv, 4); - return v; - #else - return (*(U32*)pv); - #endif -#else // _BIG__ENDIAN_ -#if defined(__GNUC__) && !defined(__EMSCRIPTEN__) - return __builtin_bswap32(*(U32*)pv); -#else -#if defined(__EMSCRIPTEN__) - const U8* pb = (const U8*)pv; - U32 v = ((U32)(*(pb + 0)) << 24) | ((U32)(*(pb + 1)) << 16) | ((U32)(*(pb + 2)) << 8) | (*(pb + 3)); - return v; -#else -#if defined(_M_IA64) || defined(_ARM_) - U32 v; - v = ((U16*)pv)[0]; - v |= ((U32)((U16*)pv)[1]) << 16; - return _byteswap_ulong(v); -#else // _M_IA64 - #ifdef _NO_UNALIGNED_LOAD_ - U32 v; - memcpy(&v, pv, 4); - return _byteswap_ulong(v); - #else - return _byteswap_ulong(*(U32*)pv); - #endif -#endif // _M_IA64 -#endif -#endif -#endif // _BIG__ENDIAN_ -} - -static _FORCEINLINE U32 _peekBit16(BitIOInfo* pIO, U32 cBits) -{ - PEEKBIT16(pIO, cBits); - // masking is not needed here because shift of unsigned int is implemented as a logical shift (SHR)! -} - -#define LOAD16 _load4 -static _FORCEINLINE U32 _flushBit16(BitIOInfo* pIO, U32 cBits) -{ - FLUSHBIT16(pIO, cBits); -} - -static _FORCEINLINE U32 _getBit16(BitIOInfo* pIO, U32 cBits) -{ - U32 uiRet = _peekBit16(pIO, cBits); - _flushBit16(pIO, cBits); - - return uiRet; -} - -#define SIGN_BIT(TypeOrValue) (((UInt) 1) << (8 * sizeof (TypeOrValue) - 1)) -/*********************************************************************************************************** - Huffman decode (input is a fully built Huffman table) -***********************************************************************************************************/ -Int getHuff(const short *pDecodeTable, BitIOInfo* pIO) -{ - Int iSymbol, iSymbolHuff; - iSymbol = pDecodeTable[peekBit16(pIO, HUFFMAN_DECODE_ROOT_BITS)]; - - flushBit16(pIO, iSymbol < 0 ? HUFFMAN_DECODE_ROOT_BITS : iSymbol & ((1 << HUFFMAN_DECODE_ROOT_BITS_LOG) - 1)); - iSymbolHuff = iSymbol >> HUFFMAN_DECODE_ROOT_BITS_LOG; - - if (iSymbolHuff < 0) { - iSymbolHuff = iSymbol; - while ((iSymbolHuff = pDecodeTable[iSymbolHuff + SIGN_BIT(pDecodeTable[0]) + getBit16(pIO, 1)]) < 0); - } - return (iSymbolHuff); -} - -#if 1 -static _FORCEINLINE U32 _getBool16(BitIOInfo* pIO) -{ - U32 uiRet = pIO->uiAccumulator >> 31;//_peekBit16(pIO, 1); - //_flushBit16(pIO, 1); - pIO->cBitsUsed++; - if (pIO->cBitsUsed < 16) { - pIO->uiAccumulator <<= 1; - } - else { - pIO->pbCurrent = MASKPTR(pIO->pbCurrent + ((pIO->cBitsUsed >> 3)/* & 2*/), pIO->iMask); - pIO->cBitsUsed &= 16 - 1; - pIO->uiAccumulator = LOAD16(pIO->pbCurrent) << pIO->cBitsUsed; - } - - return uiRet; -} - -static _FORCEINLINE I32 _getSign(BitIOInfo* pIO) -{ - I32 uiRet = (int)pIO->uiAccumulator >> 31;//_peekBit16(pIO, 1); - //_flushBit16(pIO, 1); - pIO->cBitsUsed++; - if (pIO->cBitsUsed < 16) { - pIO->uiAccumulator <<= 1; - } - else { - pIO->pbCurrent = MASKPTR(pIO->pbCurrent + ((pIO->cBitsUsed >> 3)/* & 2*/), pIO->iMask); - pIO->cBitsUsed &= 16 - 1; - pIO->uiAccumulator = LOAD16(pIO->pbCurrent) << pIO->cBitsUsed; - } - - return uiRet; -} -#else -#define _getBool16(x) _getBit16((x),1) -#define _getSign(x) (-_getBit16((x),1)) -#endif - -/** this function returns cBits if zero is read, or a signed value if first cBits are not all zero **/ -static _FORCEINLINE I32 _getBit16s(BitIOInfo* pIO, U32 cBits) -{ - I32 iRet = (I32)_peekBit16(pIO, cBits + 1); - iRet = ((iRet >> 1) ^ (-(iRet & 1))) + (iRet & 1); - _flushBit16(pIO, cBits + (iRet != 0)); - return iRet; -} - -/************************************************************************* - Huffman decoding with short tables -*************************************************************************/ -static _FORCEINLINE Int _getHuffShort(const short *pDecodeTable, BitIOInfo* pIO) -{ - Int iSymbol = pDecodeTable[_peekBit16(pIO, HUFFMAN_DECODE_ROOT_BITS)]; - assert(iSymbol >= 0); - // for some strange reason, inlining flushBit doesn't work well - flushBit16(pIO, iSymbol & ((1 << HUFFMAN_DECODE_ROOT_BITS_LOG) - 1)); - return (iSymbol >> HUFFMAN_DECODE_ROOT_BITS_LOG); -} -/************************************************************************* - Adapt + Huffman init -*************************************************************************/ -static Int AdaptDecFixed(CAdaptiveHuffman *pAH) -{ - AdaptDiscriminant(pAH); - return ICERR_OK; -} - -/************************************************************************* - DecodeCBP -*************************************************************************/ -static Void DecodeCBP(CWMImageStrCodec * pSC, CCodingContext *pContext) -{ - BitIOInfo* pIO = pContext->m_pIOAC; - const COLORFORMAT cf = pSC->m_param.cfColorFormat; - const Int iChannel = (cf == NCOMPONENT || cf == CMYK) ? (Int)pSC->m_param.cNumChannels : 1; - Int iCBPCY, iCBPCU, iCBPCV; - Int k, iBlock, i; - Int iNumCBP; - Bool bIsChroma; - CAdaptiveHuffman *pAHCBP = pContext->m_pAdaptHuffCBPCY; - CAdaptiveHuffman *pAHCBP1 = pContext->m_pAdaptHuffCBPCY1; - CAdaptiveHuffman *pAHex1 = pContext->m_pAHexpt[1]; - - readIS_L1(pSC, pIO); - - for (i = 0; i < iChannel; i++) { - - iCBPCY = iCBPCU = iCBPCV = 0; - iNumCBP = _getHuffShort(pAHCBP1->m_hufDecTable, pIO); - pAHCBP1->m_iDiscriminant += pAHCBP1->m_pDelta[iNumCBP]; - - switch (iNumCBP) { - case 2: - iNumCBP = _getBit16(pIO, 2); - if (iNumCBP == 0) - iNumCBP = 3; - else if (iNumCBP == 1) - iNumCBP = 5; - else { - static const Int aTab[] = { 6, 9, 10, 12 }; - iNumCBP = aTab[iNumCBP * 2 + _getBool16(pIO) - 4]; - } - break; - case 1: - iNumCBP = 1 << _getBit16(pIO, 2); - break; - case 3: - iNumCBP = 0xf ^ (1 << _getBit16(pIO, 2)); - break; - case 4: - iNumCBP = 0xf; - } - - for (iBlock = 0; iBlock < 4; iBlock++) { - if (iNumCBP & (1 << iBlock)) { - static const UInt gFLC0[] = { 0,2,1,2,2,0 }; - static const UInt gOff0[] = { 0,4,2,8,12,1 }; - static const UInt gOut0[] = { 0,15,3,12, 1,2,4,8, 5,6,9,10, 7,11,13,14 }; - Int iNumBlockCBP = getHuff(pAHCBP->m_hufDecTable, pIO); - unsigned int val = (unsigned int)iNumBlockCBP + 1, iCode1; - - pAHCBP->m_iDiscriminant += pAHCBP->m_pDelta[iNumBlockCBP]; - iNumBlockCBP = 0; - - if (val >= 6) { // chroma present - if (_getBool16(pIO)) { - iNumBlockCBP = 0x10; - } - else if (_getBool16(pIO)) { - iNumBlockCBP = 0x20; - } - else { - iNumBlockCBP = 0x30; - } - if (val == 9) { - if (_getBool16(pIO)) { - // do nothing - } - else if (_getBool16(pIO)) { - val = 10; - } - else { - val = 11; - } - } - val -= 6; - } - iCode1 = gOff0[val]; - if (gFLC0[val]) { - iCode1 += _getBit16(pIO, gFLC0[val]); - } - iNumBlockCBP += gOut0[iCode1]; - - switch (cf) { - case YUV_444: - iCBPCY |= ((iNumBlockCBP & 0xf) << (iBlock * 4)); - for (k = 0; k < 2; k++) { - bIsChroma = ((iNumBlockCBP >> (k + 4)) & 0x01); - if (bIsChroma) { // U is present in block - Int iCode = _getHuffShort(pAHex1->m_hufDecTable, pIO); - switch (iCode) { - case 1: - iCode = _getBit16(pIO, 2); - if (iCode == 0) - iCode = 3; - else if (iCode == 1) - iCode = 5; - else { - static const Int aTab[] = { 6, 9, 10, 12 }; - iCode = aTab[iCode * 2 + _getBool16(pIO) - 4]; - } - break; - case 0: - iCode = 1 << _getBit16(pIO, 2); - break; - case 2: - iCode = 0xf ^ (1 << _getBit16(pIO, 2)); - break; - case 3: - iCode = 0xf; - } - if (k == 0) - iCBPCU |= (iCode << (iBlock * 4)); - else - iCBPCV |= (iCode << (iBlock * 4)); - } - } - break; - - case YUV_420: - iCBPCY |= ((iNumBlockCBP & 0xf) << (iBlock * 4)); - iCBPCU |= ((iNumBlockCBP >> 4) & 0x1) << (iBlock); - iCBPCV |= ((iNumBlockCBP >> 5) & 0x1) << (iBlock); - break; - - case YUV_422: - iCBPCY |= ((iNumBlockCBP & 0xf) << (iBlock * 4)); - for (k = 0; k < 2; k++) { - Int iCode = 5; - const Int iShift[4] = { 0, 1, 4, 5 }; - if ((iNumBlockCBP >> (k + 4)) & 0x01) { - if (_getBool16(pIO)) { - iCode = 1; - } - else if (_getBool16(pIO)) { - iCode = 4; - } - iCode <<= iShift[iBlock]; - if (k == 0) iCBPCU |= iCode; - else iCBPCV |= iCode; - } - } - break; - - default: - iCBPCY |= (iNumBlockCBP << (iBlock * 4)); - } - } - } - - pSC->MBInfo.iDiffCBP[i] = iCBPCY; - if (cf == YUV_420 || cf == YUV_444 || cf == YUV_422) { - pSC->MBInfo.iDiffCBP[1] = iCBPCU; - pSC->MBInfo.iDiffCBP[2] = iCBPCV; - } - } -} - -/************************************************************************* - Experimental code -- decodeBlock - SR = <0 1 2> == - alphabet 12: - pAHexpt[0] == - alphabet 6: - pAHexpt[1] == - pAHexpt[2] == - alphabet 4: - pAHexpt[3] == (SR may be last or insignificant only) - alphabet f(run) (this can be extended to 6 contexts - SL and SR') - pAHexpt[4] == - alphabet f(lev) (this can be extended to 9 contexts) - pAHexpt[5-6] == first symbol - pAHexpt[7-8] == condition on SRn no use -*************************************************************************/ - -Int _FORCEINLINE DecodeSignificantRun(Int iMaxRun, struct CAdaptiveHuffman *pAHexpt, BitIOInfo* pIO) -{ - Int iIndex; - static const Int aRemap[] = { 1,2,3,5,7, 1,2,3,5,7, /*1,2,3,4,6, */1,2,3,4,5 }; - Int iBin = gSignificantRunBin[iMaxRun]; - Int iRun = 0, iFLC = 0; - - if (iMaxRun < 5) { - if (iMaxRun == 1) { - return 1; - } - else if (_getBool16(pIO)) { - return 1; - } - else if (iMaxRun == 2 || _getBool16(pIO)) { - return 2; - } - else if (iMaxRun == 3 || _getBool16(pIO)) { - return 3; - } - return 4; - } - iIndex = _getHuffShort(pAHexpt->m_hufDecTable, pIO); - iIndex += iBin * 5; - iRun = aRemap[iIndex]; - iFLC = gSignificantRunFixedLength[iIndex]; - if (iFLC) { - iRun += _getBit16(pIO, iFLC); - } - return iRun; -} - -#ifndef X86OPT_INLINE -static Void DecodeFirstIndex(Int *pIndex, struct CAdaptiveHuffman *pAHexpt, - BitIOInfo* pIO) -#else -static __forceinline Void DecodeFirstIndex(Int *pIndex, struct CAdaptiveHuffman *pAHexpt, - BitIOInfo* pIO) -#endif -{ - Int iIndex; - iIndex = getHuff(pAHexpt->m_hufDecTable, pIO); - pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex]; - pAHexpt->m_iDiscriminant1 += pAHexpt->m_pDelta1[iIndex]; - *pIndex = iIndex; -} - -#ifndef X86OPT_INLINE -static Void DecodeIndex(Int *pIndex, Int iLoc, struct CAdaptiveHuffman *pAHexpt, - BitIOInfo* pIO) -#else -static __forceinline Void DecodeIndex(Int *pIndex, Int iLoc, -struct CAdaptiveHuffman *pAHexpt, BitIOInfo* pIO) -#endif -{ - Int iIndex; - if (iLoc < 15) { - iIndex = _getHuffShort(pAHexpt->m_hufDecTable, pIO); - pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex]; - pAHexpt->m_iDiscriminant1 += pAHexpt->m_pDelta1[iIndex]; - *pIndex = iIndex; - } - else if (iLoc == 15) { - if (_getBool16(pIO) == 0) { - iIndex = 0; - } - else if (_getBool16(pIO) == 0) { - iIndex = 2; - } - else { - iIndex = 1 + 2 * _getBool16(pIO); - } - *pIndex = iIndex; - } - else { //if (iLoc == 16) { /* deterministic */ - Int iSL = _getBit16(pIO, 1/* + 1*/); - *pIndex = iSL;// >> 1; - } -} - -static _FORCEINLINE Int DecodeBlock(Bool bChroma, Int *aLocalCoef, struct CAdaptiveHuffman **pAHexpt, - const Int iContextOffset, BitIOInfo* pIO, Int iLocation) -{ - Int iSR, iSRn, iIndex, iNumNonzero = 1, iCont, iSign; - struct CAdaptiveHuffman **pAH1 = pAHexpt + iContextOffset + bChroma * 3; - - /** first symbol **/ - DecodeFirstIndex(&iIndex, /*&iSign, */pAH1[0], pIO); - iSR = (iIndex & 1); - iSRn = iIndex >> 2; - - iCont = iSR & iSRn; - iSign = _getSign(pIO); - - if (iIndex & 2 /* iSL */) { - aLocalCoef[1] = (DecodeSignificantAbsLevel(pAHexpt[6 + iContextOffset + iCont], pIO) ^ iSign) - iSign; - } - else { - aLocalCoef[1] = (1 | iSign); // 0 -> 1; -1 -> -1 - } - aLocalCoef[0] = 0; - if (iSR == 0) { - aLocalCoef[0] = DecodeSignificantRun(15 - iLocation, pAHexpt[0], pIO); - } - iLocation += aLocalCoef[0] + 1; - - while (iSRn != 0) { - iSR = iSRn & 1; - aLocalCoef[iNumNonzero * 2] = 0; - if (iSR == 0) { - aLocalCoef[iNumNonzero * 2] = DecodeSignificantRun(15 - iLocation, pAHexpt[0], pIO); - } - iLocation += aLocalCoef[iNumNonzero * 2] + 1; - DecodeIndex(&iIndex, /*&iSign, */iLocation, pAH1[iCont + 1], pIO); - iSRn = iIndex >> 1; - - assert(iSRn >= 0 && iSRn < 3); - iCont &= iSRn; /** huge difference! **/ - iSign = _getSign(pIO); - - if (iIndex & 1 /* iSL */) { - aLocalCoef[iNumNonzero * 2 + 1] = - (DecodeSignificantAbsLevel(pAHexpt[6 + iContextOffset + iCont], pIO) ^ iSign) - iSign; - } - else { - aLocalCoef[iNumNonzero * 2 + 1] = (1 | iSign); // 0 -> 1; -1 -> -1 (was 1 + (iSign * 2)) - } - iNumNonzero++; - } - return iNumNonzero; -} - -/************************************************************************* - DecodeBlockHighpass : -*************************************************************************/ -static _FORCEINLINE Int DecodeBlockHighpass(const Bool bChroma, struct CAdaptiveHuffman **pAHexpt, - BitIOInfo* pIO, const Int iQP, Int *pCoef, CAdaptiveScan *pScan) -{ - const Int iContextOffset = CTDC + CONTEXTX; - UInt iLoc = 1; - Int iSR, iSRn, iIndex, iNumNonzero = 1, iCont, iSign, iLevel; - struct CAdaptiveHuffman **pAH1 = pAHexpt + iContextOffset + bChroma * 3; - const CAdaptiveScan *pConstScan = (const CAdaptiveScan *)pScan; - - /** first symbol **/ - DecodeFirstIndex(&iIndex, /*&iSign, */pAH1[0], pIO); - iSR = (iIndex & 1); - iSRn = iIndex >> 2; - - iCont = iSR & iSRn; - iSign = _getSign(pIO); - - iLevel = (iQP ^ iSign) - iSign; - if (iIndex & 2 /* iSL */) { - iLevel *= DecodeSignificantAbsLevel(pAHexpt[6 + iContextOffset + iCont], pIO);// ^ iSign) - iSign; - } - //else { - // iLevel = (1 | iSign); // 0 -> 1; -1 -> -1 - //} - if (iSR == 0) { - iLoc += DecodeSignificantRun(15 - iLoc, pAHexpt[0], pIO); - } - iLoc &= 0xf; - pCoef[pConstScan[iLoc].uScan] = (PixelI)iLevel;//(PixelI)(iQP * iLevel); - pScan[iLoc].uTotal++; - if (iLoc && pScan[iLoc].uTotal > pScan[iLoc - 1].uTotal) { - CAdaptiveScan cTemp = pScan[iLoc]; - pScan[iLoc] = pScan[iLoc - 1]; - pScan[iLoc - 1] = cTemp; - } - iLoc = (iLoc + 1) & 0xf; - //iLoc++; - - while (iSRn != 0) { - iSR = iSRn & 1; - if (iSR == 0) { - iLoc += DecodeSignificantRun(15 - iLoc, pAHexpt[0], pIO); - if (iLoc >= 16) - return 16; - } - DecodeIndex(&iIndex, /*&iSign, */iLoc + 1, pAH1[iCont + 1], pIO); - iSRn = iIndex >> 1; - - assert(iSRn >= 0 && iSRn < 3); - iCont &= iSRn; /** huge difference! **/ - iSign = _getSign(pIO); - - iLevel = (iQP ^ iSign) - iSign; - if (iIndex & 1 /* iSL */) { - iLevel *= DecodeSignificantAbsLevel(pAHexpt[6 + iContextOffset + iCont], pIO);// ^ iSign) - iSign; - //iLevel = (DecodeSignificantAbsLevel (pAHexpt[6 + iContextOffset + iCont], pIO) ^ iSign) - iSign; - } - //else { - // iLevel = (1 | iSign); // 0 -> 1; -1 -> -1 (was 1 + (iSign * 2)) - //} - - pCoef[pConstScan[iLoc].uScan] = (PixelI)iLevel;//(PixelI)(iQP * iLevel); - pScan[iLoc].uTotal++; - if (iLoc && pScan[iLoc].uTotal > pScan[iLoc - 1].uTotal) { - CAdaptiveScan cTemp = pScan[iLoc]; - pScan[iLoc] = pScan[iLoc - 1]; - pScan[iLoc - 1] = cTemp; - } - - iLoc = (iLoc + 1) & 0xf; - iNumNonzero++; - } - return iNumNonzero; -} - -/************************************************************************* - DecodeBlockAdaptive -*************************************************************************/ -static _FORCEINLINE Int DecodeBlockAdaptive(Bool bNoSkip, Bool bChroma, CAdaptiveHuffman **pAdHuff, - BitIOInfo *pIO, BitIOInfo *pIOFL, - PixelI *pCoeffs, CAdaptiveScan *pScan, - const Int iModelBits, const Int iTrim, const Int iQP, - const Int *pOrder, const Bool bSkipFlexbits) -{ - // const Int iLocation = 1; - // const Int iContextOffset = CTDC + CONTEXTX; - Int kk, iNumNonzero = 0, iFlex = iModelBits - iTrim; - - if (iFlex < 0 || bSkipFlexbits) - iFlex = 0; - - if (bNoSkip) { - const Int iQP1 = (iQP << iModelBits); - iNumNonzero = DecodeBlockHighpass(bChroma, pAdHuff, pIO, iQP1, pCoeffs, pScan); - } - if (iFlex) { - UInt k; - if (iQP + iTrim == 1) { // only iTrim = 0, iQP = 1 is legal - assert(iTrim == 0); - assert(iQP == 1); - - for (k = 1; k < 16; k++) { - PixelI *pk = pCoeffs + pOrder[k]; - if (*pk < 0) { - Int fine = _getBit16(pIOFL, iFlex); - *pk -= (PixelI)(fine); - } - else if (*pk > 0) { - Int fine = _getBit16(pIOFL, iFlex); - *pk += (PixelI)(fine); - } - else { - *pk = (PixelI)(_getBit16s(pIOFL, iFlex)); - } - } - } - else { - const Int iQP1 = iQP << iTrim; - for (k = 1; k < 16; k++) { - kk = pCoeffs[pOrder[k]]; - if (kk < 0) { - Int fine = _getBit16(pIOFL, iFlex); - pCoeffs[pOrder[k]] -= (PixelI)(iQP1 * fine); - } - else if (kk > 0) { - Int fine = _getBit16(pIOFL, iFlex); - pCoeffs[pOrder[k]] += (PixelI)(iQP1 * fine); - } - else { - pCoeffs[pOrder[k]] = (PixelI)(iQP1 * _getBit16s(pIOFL, iFlex)); - } - } - } - } - - return iNumNonzero; -} - - -/************************************************************************* - GetCoeffs -*************************************************************************/ -static _FORCEINLINE Int DecodeCoeffs(CWMImageStrCodec * pSC, CCodingContext *pContext, - Int iMBX, Int iMBY, - BitIOInfo* pIO, BitIOInfo *pIOFL) -{ - CWMITile * pTile = pSC->pTile + pSC->cTileColumn; - const COLORFORMAT cf = pSC->m_param.cfColorFormat; - const Int iChannels = (Int)pSC->m_param.cNumChannels; - const Int iPlanes = (cf == YUV_420 || cf == YUV_422) ? 1 : iChannels; - Int iQP; - CAdaptiveScan *pScan; - PixelI *pCoeffs; - Int i, iBlock, iSubblock, iNBlocks = 4; - Int iModelBits = pContext->m_aModelAC.m_iFlcBits[0]; - Int aLaplacianMean[2] = { 0, 0 }, *pLM = aLaplacianMean + 0; - const Int *pOrder = dctIndex[0]; - const Int iOrient = pSC->MBInfo.iOrientation; - Bool bChroma = FALSE; - - Int iCBPCU = pSC->MBInfo.iCBP[1]; - Int iCBPCV = pSC->MBInfo.iCBP[2]; - Int iCBPCY = pSC->MBInfo.iCBP[0]; - - UNREFERENCED_PARAMETER(iMBX); - UNREFERENCED_PARAMETER(iMBY); - - /** set scan arrays and other MB level constants **/ - if (iOrient == 1) { - pScan = pContext->m_aScanVert; - } - else { - pScan = pContext->m_aScanHoriz; - } - - if (cf == YUV_420) { - iNBlocks = 6; - iCBPCY += (iCBPCU << 16) + (iCBPCV << 20); - } - else if (cf == YUV_422) { - iNBlocks = 8; - iCBPCY += (iCBPCU << 16) + (iCBPCV << 24); - } - - for (i = 0; i < iPlanes; i++) { - Int iIndex = 0, iNumNonZero; - - if (pSC->WMISCP.sbSubband != SB_NO_FLEXBITS) - readIS_L1(pSC, pIOFL); - - for (iBlock = 0; iBlock < iNBlocks; iBlock++) { - - /*readIS_L2(pSC, pIO); - if (pIO != pIOFL) - readIS_L2(pSC, pIOFL);*/ - - iQP = (pSC->m_param.bTranscode ? 1 : pTile->pQuantizerHP[iPlanes > 1 ? i : (iBlock > 3 ? (cf == YUV_420 ? iBlock - 3 : iBlock / 2 - 1) : 0)][pSC->MBInfo.iQIndexHP].iQP); - - for (iSubblock = 0; iSubblock < 4; iSubblock++, iIndex++, iCBPCY >>= 1) { - pCoeffs = pSC->p1MBbuffer[i] + blkOffset[iIndex & 0xf]; - - //if (iBlock < 4) {//(cf == YUV_444) { - //bBlockNoSkip = ((iTempCBPC & (1 << iIndex1)) != 0); - //pCoeffs = pSC->p1MBbuffer[iBlock >> 2] + blkOffset[iIndex & 0xf]; - //} - //else { - if (iBlock >= 4) { - if (cf == YUV_420) { - pCoeffs = pSC->p1MBbuffer[iBlock - 3] + blkOffsetUV[iSubblock]; - } - else { // YUV_422 - pCoeffs = pSC->p1MBbuffer[1 + (1 & (iBlock >> 1))] + ((iBlock & 1) * 32) + blkOffsetUV_422[iSubblock]; - } - } - - /** read AC values **/ - assert(pSC->m_Dparam->bSkipFlexbits == 0 || pSC->WMISCP.bfBitstreamFormat == FREQUENCY || pSC->WMISCP.sbSubband == SB_NO_FLEXBITS); - iNumNonZero = DecodeBlockAdaptive((iCBPCY & 1), bChroma, pContext->m_pAHexpt, - pIO, pIOFL, pCoeffs, pScan, iModelBits, pContext->m_iTrimFlexBits, - iQP, pOrder, pSC->m_Dparam->bSkipFlexbits); - if (iNumNonZero > 16) // something is wrong! - return ICERR_ERROR; - // shouldn't this be > 15? - (*pLM) += iNumNonZero; - } - if (iBlock == 3) { - iModelBits = pContext->m_aModelAC.m_iFlcBits[1]; - pLM = aLaplacianMean + 1; - bChroma = TRUE; - } - } - - iCBPCY = pSC->MBInfo.iCBP[(i + 1) & 0xf]; - assert(MAX_CHANNELS == 16); - } - - /** update model at end of MB **/ - UpdateModelMB(cf, iChannels, aLaplacianMean, &(pContext->m_aModelAC)); - return ICERR_OK; -} - -/************************************************************************* - DecodeSignificantAbsLevel -*************************************************************************/ -#ifndef X86OPT_INLINE -static Int DecodeSignificantAbsLevel(struct CAdaptiveHuffman *pAHexpt, BitIOInfo* pIO) -#else -static __forceinline Int DecodeSignificantAbsLevel(struct CAdaptiveHuffman *pAHexpt, BitIOInfo* pIO) -#endif -{ - UInt iIndex; - Int iFixed, iLevel; - static const Int aRemap[] = { 2, 3, 4, 6, 10, 14 }; - static const Int aFixedLength[] = { 0, 0, 1, 2, 2, 2 }; - - iIndex = (UInt)getHuff(pAHexpt->m_hufDecTable, pIO); - assert(iIndex <= 6); - pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex]; - if (iIndex < 2) { - iLevel = iIndex + 2; // = aRemap[iIndex] - } - else if (iIndex < 6) { - iFixed = aFixedLength[iIndex]; - iLevel = aRemap[iIndex] + _getBit16(pIO, iFixed); - } - else { - iFixed = _getBit16(pIO, 4) + 4; - if (iFixed == 19) { - iFixed += _getBit16(pIO, 2); - if (iFixed == 22) { - iFixed += _getBit16(pIO, 3); - } - } - iLevel = 2 + (1 << iFixed); - iIndex = getBit32(pIO, iFixed); - iLevel += iIndex; - } - return iLevel; -} - -U8 decodeQPIndex(BitIOInfo* pIO, U8 cBits) -{ - if (_getBit16(pIO, 1) == 0) - return 0; - return (U8)(_getBit16(pIO, cBits) + 1); -} - -/************************************************************************* - DecodeSecondStageCoeff -*************************************************************************/ -Int DecodeMacroblockLowpass(CWMImageStrCodec * pSC, CCodingContext *pContext, - Int iMBX, Int iMBYdummy) -{ - const COLORFORMAT cf = pSC->m_param.cfColorFormat; - const Int iChannels = (Int)pSC->m_param.cNumChannels; - const Int iFullPlanes = (cf == YUV_420 || cf == YUV_422) ? 2 : iChannels; - Int k; - CAdaptiveScan *pScan = pContext->m_aScanLowpass; - BitIOInfo* pIO = pContext->m_pIOLP; - Int iModelBits = pContext->m_aModelLP.m_iFlcBits[0]; - Int aRLCoeffs[32], iNumNonzero = 0, iIndex = 0; - Int aLaplacianMean[2] = { 0, 0 }, *pLM = aLaplacianMean; - Int iChannel, iCBP = 0; -#ifndef ARMOPT_BITIO // ARM opt always uses 32-bit version of getBits - U32(*getBits)(BitIOInfo* pIO, U32 cBits) = _getBit16; -#endif - CWMIMBInfo * pMBInfo = &pSC->MBInfo; - I32 *aDC[MAX_CHANNELS]; - - UNREFERENCED_PARAMETER(iMBX); - UNREFERENCED_PARAMETER(iMBYdummy); - - readIS_L1(pSC, pIO); - if ((pSC->WMISCP.bfBitstreamFormat != SPATIAL) && (pSC->pTile[pSC->cTileColumn].cBitsLP > 0)) // MB-based LP QP index - pMBInfo->iQIndexLP = decodeQPIndex(pIO, pSC->pTile[pSC->cTileColumn].cBitsLP); - - // set arrays - for (k = 0; k < (Int)pSC->m_param.cNumChannels; k++) { - aDC[k & 15] = pMBInfo->iBlockDC[k]; - } - - /** reset adaptive scan totals **/ - if (pSC->m_bResetRGITotals) { - int iScale = 2; - int iWeight = iScale * 16; - pScan[0].uTotal = MAXTOTAL; - for (k = 1; k < 16; k++) { - pScan[k].uTotal = iWeight; - iWeight -= iScale; - } - } - - /** in raw mode, this can take 6% of the bits in the extreme low rate case!!! **/ - if (cf == YUV_420 || cf == YUV_422 || cf == YUV_444) { - int iCountM = pContext->m_iCBPCountMax, iCountZ = pContext->m_iCBPCountZero; - int iMax = iFullPlanes * 4 - 5; /* actually (1 << iNChannels) - 1 **/ - if (iCountZ <= 0 || iCountM < 0) { - iCBP = 0; - if (_getBool16(pIO)) { - iCBP = 1; - k = _getBit16(pIO, iFullPlanes - 1); - if (k) { - iCBP = k * 2 + _getBit16(pIO, 1); - } - } - if (iCountM < iCountZ) - iCBP = iMax - iCBP; - } - else { - iCBP = _getBit16(pIO, iFullPlanes); - } - - iCountM += 1 - 4 * (iCBP == iMax);//(b + c - 2*a); - iCountZ += 1 - 4 * (iCBP == 0);//(a + b - 2*c); - if (iCountM < -8) - iCountM = -8; - else if (iCountM > 7) - iCountM = 7; - pContext->m_iCBPCountMax = iCountM; - - if (iCountZ < -8) - iCountZ = -8; - else if (iCountZ > 7) - iCountZ = 7; - pContext->m_iCBPCountZero = iCountZ; - } - else { /** 1 or N channel **/ - for (iChannel = 0; iChannel < iChannels; iChannel++) - iCBP |= (getBits(pIO, 1) << iChannel); - } - -#ifndef ARMOPT_BITIO // ARM opt always uses 32-bit version of getBits - if (pContext->m_aModelLP.m_iFlcBits[0] > 14 || pContext->m_aModelLP.m_iFlcBits[1] > 14) { - getBits = getBit32; - } -#endif - - for (iChannel = 0; iChannel < iFullPlanes; iChannel++) { - PixelI *pCoeffs = aDC[iChannel]; - - if (iCBP & 1) { - iNumNonzero = DecodeBlock(iChannel > 0, aRLCoeffs, pContext->m_pAHexpt, - CTDC, pIO, 1 + 9 * ((cf == YUV_420) && (iChannel == 1)) - + ((cf == YUV_422) && (iChannel == 1))); - - if ((cf == YUV_420 || cf == YUV_422) && iChannel) { - Int aTemp[16]; //14 required, 16 for security - static const Int aRemap[] = { 4, 1,2,3, 5,6,7 }; - const Int *pRemap = aRemap + (cf == YUV_420); - const Int iCount = (cf == YUV_420) ? 6 : 14; - - (*pLM) += iNumNonzero; - iIndex = 0; - memset(aTemp, 0, sizeof(aTemp)); - - for (k = 0; k < iNumNonzero; k++) { - iIndex += aRLCoeffs[k * 2]; - aTemp[iIndex & 0xf] = aRLCoeffs[k * 2 + 1]; - iIndex++; - } - - for (k = 0; k < iCount; k++) { - aDC[(k & 1) + 1][pRemap[k >> 1]] = aTemp[k]; - } - } - else { - (*pLM) += iNumNonzero; - iIndex = 1; - - for (k = 0; k < iNumNonzero; k++) { - iIndex += aRLCoeffs[k * 2]; - pCoeffs[pScan[iIndex].uScan] = aRLCoeffs[k * 2 + 1]; - pScan[iIndex].uTotal++; - if (pScan[iIndex].uTotal > pScan[iIndex - 1].uTotal) { - CAdaptiveScan cTemp = pScan[iIndex]; - pScan[iIndex] = pScan[iIndex - 1]; - pScan[iIndex - 1] = cTemp; - } - iIndex++; - } - } - } - - if (iModelBits) { - if ((cf == YUV_420 || cf == YUV_422) && iChannel) { - for (k = 1; k < (cf == YUV_420 ? 4 : 8); k++) { - if (aDC[1][k] > 0) { - aDC[1][k] <<= iModelBits; - aDC[1][k] += getBits(pIO, iModelBits); - } - else if (aDC[1][k] < 0) { - aDC[1][k] <<= iModelBits; - aDC[1][k] -= getBits(pIO, iModelBits); - } - else { - aDC[1][k] = getBits(pIO, iModelBits); - if (aDC[1][k] && _getBool16(pIO)) - aDC[1][k] = -aDC[1][k]; - } - - if (aDC[2][k] > 0) { - aDC[2][k] <<= iModelBits; - aDC[2][k] += getBits(pIO, iModelBits); - } - else if (aDC[2][k] < 0) { - aDC[2][k] <<= iModelBits; - aDC[2][k] -= getBits(pIO, iModelBits); - } - else { - aDC[2][k] = getBits(pIO, iModelBits); - if (aDC[2][k] && _getBool16(pIO)) - aDC[2][k] = -aDC[2][k]; - } - } - } - else { -#ifdef _WIN32 - const Int iMask = (1 << iModelBits) - 1; -#endif // WIN32 - for (k = 1; k < 16; k++) { -#ifdef _WIN32 - if (pCoeffs[k]) { - Int r1 = _rotl(pCoeffs[k], iModelBits); - pCoeffs[k] = (r1 ^ getBits(pIO, iModelBits)) - (r1 & iMask); - } -#else // WIN32 - if (pCoeffs[k] > 0) { - pCoeffs[k] <<= iModelBits; - pCoeffs[k] += getBits(pIO, iModelBits); - } - else if (pCoeffs[k] < 0) { - pCoeffs[k] <<= iModelBits; - pCoeffs[k] -= getBits(pIO, iModelBits); - } -#endif // WIN32 - else { - //pCoeffs[k] = getBits (pIO, iModelBits); - //if (pCoeffs[k] && _getBool16 (pIO)) - // pCoeffs[k] = -pCoeffs[k]; - Int r1 = _peekBit16(pIO, iModelBits + 1); - pCoeffs[k] = ((r1 >> 1) ^ (-(r1 & 1))) + (r1 & 1); - _flushBit16(pIO, iModelBits + (pCoeffs[k] != 0)); - } - } - } - } - pLM = aLaplacianMean + 1; - iModelBits = pContext->m_aModelLP.m_iFlcBits[1]; - - iCBP >>= 1; - } - - UpdateModelMB(cf, iChannels, aLaplacianMean, &(pContext->m_aModelLP)); - - if (pSC->m_bResetContext) { - AdaptLowpassDec(pContext); - } - - return ICERR_OK; -} - -/************************************************************************* - 8 bit YUV 420 macroblock decode function with 4x4 transform - Index order is as follows: - Y: U: V: - 0 1 4 5 16 17 20 21 - 2 3 6 7 18 19 22 23 - 8 9 12 13 - 10 11 14 15 - - DCAC coefficients stored for 4x4 - offsets (x == no storage) - Y: - x x x [0..3] - x x x [4..7] - x x x [8..11] - [16..19] [20..23] [24..27] [28..31,12..15] - - U, V: - x [0..3] - [8..11] [4..7,12..15] -*************************************************************************/ -Int DecodeMacroblockDC(CWMImageStrCodec * pSC, CCodingContext *pContext, Int iMBX, Int iMBY) -{ - CWMITile * pTile = pSC->pTile + pSC->cTileColumn; - CWMIMBInfo * pMBInfo = &pSC->MBInfo; - const COLORFORMAT cf = pSC->m_param.cfColorFormat; - const Int iChannels = (Int)pSC->m_param.cNumChannels; - BitIOInfo* pIO = pContext->m_pIODC; - Int iIndex, i; - Int aLaplacianMean[2] = { 0, 0 }, *pLM = aLaplacianMean; - Int iModelBits = pContext->m_aModelDC.m_iFlcBits[0]; - struct CAdaptiveHuffman *pAH; - Int iQDCY, iQDCU, iQDCV; - // const Int iChromaElements = (cf == YUV_420) ? 8 * 8 : ((cf == YUV_422) ? 8 * 16 : 16 * 16); - - UNREFERENCED_PARAMETER(iMBX); - UNREFERENCED_PARAMETER(iMBY); - - for (i = 0; i < iChannels; i++) - memset(pMBInfo->iBlockDC[i], 0, 16 * sizeof(I32)); - - readIS_L1(pSC, pIO); - - pMBInfo->iQIndexLP = pMBInfo->iQIndexHP = 0; - - if (pSC->WMISCP.bfBitstreamFormat == SPATIAL && pSC->WMISCP.sbSubband != SB_DC_ONLY) { - if (pTile->cBitsLP > 0) // MB-based LP QP index - pMBInfo->iQIndexLP = decodeQPIndex(pIO, pTile->cBitsLP); - if (pSC->WMISCP.sbSubband != SB_NO_HIGHPASS && pTile->cBitsHP > 0) // MB-based HP QP index - pMBInfo->iQIndexHP = decodeQPIndex(pIO, pTile->cBitsHP); - } - if (pTile->cBitsHP == 0 && pTile->cNumQPHP > 1) // use LP QP - pMBInfo->iQIndexHP = pMBInfo->iQIndexLP; - if (pMBInfo->iQIndexLP >= pTile->cNumQPLP || pMBInfo->iQIndexHP >= pTile->cNumQPHP) - return ICERR_ERROR; - - if (cf == Y_ONLY || cf == CMYK || cf == NCOMPONENT) { - for (i = 0; i < iChannels; i++) { - iQDCY = 0; - /** get luminance DC **/ - if (_getBool16(pIO)) { - iQDCY = DecodeSignificantAbsLevel(pContext->m_pAHexpt[3], pIO) - 1; - *pLM += 1; - } - if (iModelBits) { - iQDCY = (iQDCY << iModelBits) | _getBit16(pIO, iModelBits); - } - if (iQDCY && _getBool16(pIO)) - iQDCY = -iQDCY; - pMBInfo->iBlockDC[i][0] = iQDCY; - - pLM = aLaplacianMean + 1; - iModelBits = pContext->m_aModelDC.m_iFlcBits[1]; - } - } - else { - /** find significant level in 3D **/ - pAH = pContext->m_pAHexpt[2]; - iIndex = getHuff(pAH->m_hufDecTable, pIO); - iQDCY = iIndex >> 2; - iQDCU = (iIndex >> 1) & 1; - iQDCV = iIndex & 1; - - /** get luminance DC **/ - if (iQDCY) { - iQDCY = DecodeSignificantAbsLevel(pContext->m_pAHexpt[3], pIO) - 1; - *pLM += 1; - } - if (iModelBits) { - iQDCY = (iQDCY << iModelBits) | _getBit16(pIO, iModelBits); - } - if (iQDCY && _getBool16(pIO)) - iQDCY = -iQDCY; - pMBInfo->iBlockDC[0][0] = iQDCY; - - /** get chrominance DC **/ - pLM = aLaplacianMean + 1; - iModelBits = pContext->m_aModelDC.m_iFlcBits[1]; - - if (iQDCU) { - iQDCU = DecodeSignificantAbsLevel(pContext->m_pAHexpt[4], pIO) - 1; - *pLM += 1; - } - if (iModelBits) { - iQDCU = (iQDCU << iModelBits) | _getBit16(pIO, iModelBits); - } - if (iQDCU && _getBool16(pIO)) - iQDCU = -iQDCU; - pMBInfo->iBlockDC[1][0] = iQDCU; - - if (iQDCV) { - iQDCV = DecodeSignificantAbsLevel(pContext->m_pAHexpt[4], pIO) - 1; - *pLM += 1; - } - if (iModelBits) { - iQDCV = (iQDCV << iModelBits) | _getBit16(pIO, iModelBits); - } - if (iQDCV && _getBool16(pIO)) - iQDCV = -iQDCV; - pMBInfo->iBlockDC[2][0] = iQDCV; - } - - UpdateModelMB(cf, iChannels, aLaplacianMean, &(pContext->m_aModelDC)); - - if (((!(pSC->WMISCP.bfBitstreamFormat != FREQUENCY || pSC->m_Dparam->cThumbnailScale < 16)) || pSC->WMISCP.sbSubband == SB_DC_ONLY) && pSC->m_bResetContext) { - Int kk; - for (kk = 2; kk < 5; kk++) { - if (ICERR_OK != AdaptDecFixed(pContext->m_pAHexpt[kk])) { - return ICERR_ERROR; - } - } - } - - return ICERR_OK; -} - -/************************************************************************* - DecodeMacroblockHighpass -*************************************************************************/ -Int DecodeMacroblockHighpass(CWMImageStrCodec *pSC, CCodingContext *pContext, - Int iMBX, Int iMBY) -{ - /** reset adaptive scan totals **/ - if (pSC->m_bResetRGITotals) { - int iScale = 2, k; - int iWeight = iScale * 16; - pContext->m_aScanHoriz[0].uTotal = pContext->m_aScanVert[0].uTotal = MAXTOTAL; - for (k = 1; k < 16; k++) { - pContext->m_aScanHoriz[k].uTotal = pContext->m_aScanVert[k].uTotal = iWeight; - iWeight -= iScale; - } - } - if ((pSC->WMISCP.bfBitstreamFormat != SPATIAL) && (pSC->pTile[pSC->cTileColumn].cBitsHP > 0)) { // MB-based HP QP index - pSC->MBInfo.iQIndexHP = decodeQPIndex(pContext->m_pIOAC, pSC->pTile[pSC->cTileColumn].cBitsHP); - if (pSC->MBInfo.iQIndexHP >= pSC->pTile[pSC->cTileColumn].cNumQPHP) - goto ErrorExit; - } - else if (pSC->pTile[pSC->cTileColumn].cBitsHP == 0 && pSC->pTile[pSC->cTileColumn].cNumQPHP > 1) // use LP QP - pSC->MBInfo.iQIndexHP = pSC->MBInfo.iQIndexLP; - - - DecodeCBP(pSC, pContext); - predCBPDec(pSC, pContext); - - if (DecodeCoeffs(pSC, pContext, iMBX, iMBY, - pContext->m_pIOAC, pContext->m_pIOFL) != ICERR_OK) - goto ErrorExit; - - if (pSC->m_bResetContext) { - AdaptHighpassDec(pContext); - } - - return ICERR_OK; -ErrorExit: - return ICERR_ERROR; -} - -/************************************************************************* - Adapt -*************************************************************************/ -Int AdaptLowpassDec(CCodingContext * pSC) -{ - Int kk; - for (kk = 0; kk < CONTEXTX + CTDC; kk++) { - if (ICERR_OK != AdaptDecFixed(pSC->m_pAHexpt[kk])) { - goto ErrorExit; - } - } - return ICERR_OK; - -ErrorExit: - return ICERR_ERROR; - -} - -Int AdaptHighpassDec(CCodingContext * pSC) -{ - Int kk; - if (ICERR_OK != AdaptDecFixed(pSC->m_pAdaptHuffCBPCY)) { - goto ErrorExit; - } - if (ICERR_OK != AdaptDecFixed(pSC->m_pAdaptHuffCBPCY1)) { - goto ErrorExit; - } - for (kk = 0; kk < CONTEXTX; kk++) { - if (ICERR_OK != AdaptDecFixed(pSC->m_pAHexpt[kk + CONTEXTX + CTDC])) { - goto ErrorExit; - } - } - - return ICERR_OK; - -ErrorExit: - return ICERR_ERROR; -} diff --git a/Src/JxrDecode/Jxr/segenc.c b/Src/JxrDecode/Jxr/segenc.c deleted file mode 100644 index 9055e833..00000000 --- a/Src/JxrDecode/Jxr/segenc.c +++ /dev/null @@ -1,1186 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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 -#include -#include "strcodec.h" -#include "encode.h" - -#ifdef MEM_TRACE -#define TRACE_MALLOC 1 -#define TRACE_NEW 0 -#define TRACE_HEAP 0 -#include "memtrace.h" -#endif - -/** local function definitions **/ -#ifdef X86OPT_INLINE -__forceinline -#endif -static Int EncodeBlock (Bool bChroma, const Int *aLocalCoef, Int iNumNonzero, - struct CAdaptiveHuffman **pAHexpt, - Int iContextOffset, BitIOInfo* pOut, UInt iLocation); - -/************************************************************************* - EncodeSignificantAbsLevel -*************************************************************************/ -#ifdef X86OPT_INLINE -//__forceinline -#endif -static Void EncodeSignificantAbsLevel (UInt iAbsLevel, struct CAdaptiveHuffman *pAHexpt, BitIOInfo* pOut) -{ - Int iIndex, iFixed, aIndex[] = { 0,1,2,2, 3,3,3,3, 4,4,4,4, 5,5,5,5 }; - Int aFixedLength[] = { 0, 0, 1, 2, 2, 2 }; - - assert(iAbsLevel > 0); - iAbsLevel--; - if (iAbsLevel >= 16) { - Int i = iAbsLevel; - iIndex = 6; - /** find leftmost bit **/ - i >>= 5; - iFixed = 4; - while (i) { /** caution - infinite loop if not careful **/ - iFixed++; - assert (iFixed < 30); - i >>= 1; - } - - pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex]; - putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1], pAHexpt->m_pTable[iIndex * 2 + 2]); - if (iFixed > 18) { - putBit16z (pOut, 15, 4); - if (iFixed > 21) { - putBit16z (pOut, 3, 2); - putBit16 (pOut, iFixed - 22, 3); // 22 - 29 - } - else - putBit16z (pOut, iFixed - 19, 2); // 19 20 21 - } - else { - putBit16z(pOut, (iFixed - 4), 4); - } - putBit32(pOut, iAbsLevel, iFixed); - } - else { - iIndex = aIndex[iAbsLevel]; - iFixed = aFixedLength[iIndex]; - - pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex]; - putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1], pAHexpt->m_pTable[iIndex * 2 + 2]); - putBit32(pOut, iAbsLevel, iFixed); - } -} - -/************************************************************************* - EncodeMacroblockDC -*************************************************************************/ - -Void encodeQPIndex(BitIOInfo* pIO, U8 iIndex,U8 cBits) -{ - if(iIndex == 0) - putBit16z(pIO, 0, 1); - else{ - putBit16z(pIO, 1, 1); - putBit16z(pIO, iIndex - 1, cBits); - } -} - -Int EncodeMacroblockDC (CWMImageStrCodec *pSC, CCodingContext *pContext, Int iMBX, Int iMBY) -{ - CWMITile * pTile = pSC->pTile + pSC->cTileColumn; - BitIOInfo* pIO = pContext->m_pIODC; - CWMIMBInfo *pMBInfo = &pSC->MBInfo; - Int iIndex, j = 0; - struct CAdaptiveHuffman *pAH; - Int aLaplacianMean[2] = { 0, 0}, *pLM = aLaplacianMean; - Int iModelBits = pContext->m_aModelDC.m_iFlcBits[0]; - COLORFORMAT cf = pSC->m_param.cfColorFormat; - const Int iChannels = (Int) pSC->m_param.cNumChannels; - - UNREFERENCED_PARAMETER( iMBX ); - UNREFERENCED_PARAMETER( iMBY ); - - writeIS_L1(pSC, pIO); - - if(pSC->m_param.bTranscode == FALSE){ - pMBInfo->iQIndexLP = (U8)(pTile->cNumQPLP > 1 ? (rand() % pTile->cNumQPLP) : 0); - pMBInfo->iQIndexHP = (U8)(pTile->cNumQPHP > 1 ? (rand() % pTile->cNumQPHP) : 0); - } - if(pTile->cBitsHP == 0 && pTile->cNumQPHP > 1) // use LP QP - pMBInfo->iQIndexHP = pMBInfo->iQIndexLP; - - if(pSC->WMISCP.bfBitstreamFormat == SPATIAL && pSC->WMISCP.sbSubband != SB_DC_ONLY){ - if(pTile->cBitsLP > 0) // MB-based LP QP index - encodeQPIndex(pIO, pMBInfo->iQIndexLP, pTile->cBitsLP); - if( pSC->WMISCP.sbSubband != SB_NO_HIGHPASS && pTile->cBitsHP > 0) // MB-based HP QP index - encodeQPIndex(pIO, pMBInfo->iQIndexHP, pTile->cBitsHP); - } - - if(pSC->m_param.bTranscode == FALSE) - pSC->Quantize(pSC); - - predMacroblockEnc(pSC); - - /** code path for Y_ONLY, CMYK and N_CHANNEL DC **/ - if(cf == Y_ONLY || cf == CMYK || cf == NCOMPONENT) { - Int iQDC, iDC, iSign; - for (j = 0; j < iChannels; j++) { - iDC = pMBInfo->iBlockDC[j][0]; - iSign = (iDC < 0); - iDC = abs(iDC); - iQDC = iDC >> iModelBits; - - /** send luminance DC **/ - if (iQDC) { - putBit16z(pIO, 1, 1); - EncodeSignificantAbsLevel((UInt) iQDC, pContext->m_pAHexpt[3], pIO); - *pLM += 1; - } - else { - putBit16z(pIO, 0, 1); - } - - putBit16(pIO, iDC, iModelBits); - if (iDC) { - putBit16z(pIO, iSign, 1); - } - - pLM = aLaplacianMean + 1; - iModelBits = pContext->m_aModelDC.m_iFlcBits[1]; - } - } - else { /** code path for YUV DC **/ - Int iDCY, iDCU, iDCV, iQDCY, iQDCU, iQDCV; - - pAH = pContext->m_pAHexpt[2]; - iQDCY = abs(iDCY = pMBInfo->iBlockDC[0][0]); - iQDCU = abs(iDCU = pMBInfo->iBlockDC[1][0]); - iQDCV = abs(iDCV = pMBInfo->iBlockDC[2][0]); - if (iModelBits) { - iQDCY >>= iModelBits; - } - - iModelBits = pContext->m_aModelDC.m_iFlcBits[1]; - if (iModelBits) { - iQDCU >>= iModelBits; - iQDCV >>= iModelBits; - } - iModelBits = pContext->m_aModelDC.m_iFlcBits[0]; - - iIndex = (iQDCY != 0) * 4 + (iQDCU != 0) * 2 + (iQDCV != 0); - putBit16z(pIO, pAH->m_pTable[iIndex * 2 + 1], pAH->m_pTable[iIndex * 2 + 2]); - - /** send luminance DC **/ - if (iQDCY) { - EncodeSignificantAbsLevel((UInt) iQDCY, pContext->m_pAHexpt[3], pIO); - *pLM += 1; - } - putBit16(pIO, abs(iDCY), iModelBits); - if (iDCY) { - putBit16z(pIO, (iDCY < 0), 1); - } - - /** send chroma DC **/ - pLM = aLaplacianMean + 1; - iModelBits = pContext->m_aModelDC.m_iFlcBits[1]; - - if (iQDCU) { - EncodeSignificantAbsLevel((UInt) iQDCU, pContext->m_pAHexpt[4], pIO); - *pLM += 1; - } - putBit16(pIO, abs(iDCU), iModelBits); - if (iDCU) { - putBit16z(pIO, (iDCU < 0), 1); - } - - if (iQDCV) { - EncodeSignificantAbsLevel((UInt) iQDCV, pContext->m_pAHexpt[4], pIO); - *pLM += 1; - } - putBit16(pIO, abs(iDCV), iModelBits); - if (iDCV) { - putBit16z(pIO, (iDCV < 0), 1); - } - } - - UpdateModelMB (cf, iChannels, aLaplacianMean, &(pContext->m_aModelDC)); - - if (pSC->m_bResetContext && pSC->WMISCP.sbSubband == SB_DC_ONLY) { - AdaptDiscriminant(pContext->m_pAHexpt[2]); - AdaptDiscriminant(pContext->m_pAHexpt[3]); - AdaptDiscriminant(pContext->m_pAHexpt[4]); - } - - return ICERR_OK; -} - -/************************************************************************* - Scan block with zero model bits -*************************************************************************/ -#ifdef X86OPT_INLINE -__forceinline -#endif -static Int AdaptiveScanZero (const PixelI *pCoeffs, CAdaptiveScan *pScan, - Int *pRLCoeffs, const Int iCount) -{ - Int k, iRun = 1, iLevel, iNumNonzero = 0; - - iLevel = pCoeffs[pScan[1].uScan]; - if (iLevel) { - pScan[1].uTotal++; - pRLCoeffs[iNumNonzero * 2] = 0; - pRLCoeffs[iNumNonzero * 2 + 1] = iLevel; - iNumNonzero++; - iRun = 0; - } - for (k = 2; k < iCount; k++) { - iLevel = pCoeffs[pScan[k].uScan]; - iRun++; - if (iLevel) { - pScan[k].uTotal++; - if (pScan[k].uTotal > pScan[k - 1].uTotal) { - CAdaptiveScan cTemp = pScan[k]; - pScan[k] = pScan[k - 1]; - pScan[k - 1] = cTemp; - } - pRLCoeffs[iNumNonzero * 2] = iRun - 1; - pRLCoeffs[iNumNonzero * 2 + 1] = iLevel; - iNumNonzero++; - iRun = 0; - } - } - return iNumNonzero; -} - -/************************************************************************* - Scan block with nonzero model bits, all trimmed -*************************************************************************/ -#ifdef X86OPT_INLINE -__forceinline -#endif -static Int AdaptiveScanTrim (const PixelI *pCoeffs, CAdaptiveScan *pScan, - const Int iModelBits, Int *pRLCoeffs, const Int iCount) -{ - Int k, iRun = 1, iLevel, iNumNonzero = 0; - Int iTemp; - unsigned int iThOff = (1 << iModelBits) - 1, iTh = iThOff * 2 + 1; - - iLevel = pCoeffs[pScan[1].uScan]; - - if ((unsigned int)(iLevel + iThOff) >= iTh) { - iTemp = abs (iLevel) >> iModelBits; - pScan[1].uTotal++; - pRLCoeffs[iNumNonzero * 2] = 0; - pRLCoeffs[iNumNonzero * 2 + 1] = (iLevel < 0) ? -iTemp : iTemp; - iNumNonzero++; - iRun = 0; - } - for (k = 2; k < iCount; k++) { - iRun++; - iLevel = pCoeffs[pScan[k].uScan]; - if ((unsigned int)(iLevel + iThOff) >= iTh) { - iTemp = abs (iLevel) >> iModelBits; - pScan[k].uTotal++; - if (pScan[k].uTotal > pScan[k - 1].uTotal) { - CAdaptiveScan cTemp = pScan[k]; - pScan[k] = pScan[k - 1]; - pScan[k - 1] = cTemp; - } - pRLCoeffs[iNumNonzero * 2] = iRun - 1; - pRLCoeffs[iNumNonzero * 2 + 1] = (iLevel < 0) ? -iTemp : iTemp; - iNumNonzero++; - iRun = 0; - } - } - return iNumNonzero; -} - -/************************************************************************* - Scan block with nonzero model bits -*************************************************************************/ -/** saves around 1.5% at QP=1 (no SIMD opt) **/ -#define USE_GRES_LUT -#ifdef USE_GRES_LUT -static const Int gRes[] = { -65*2+1, 63*2+1, 61*2+1, 59*2+1, 57*2+1, 55*2+1, 53*2+1, 51*2+1, 49*2+1, 47*2+1, 45*2+1, 43*2+1, 41*2+1, -39*2+1, 37*2+1, 35*2+1, 33*2+1, 31*2+1, 29*2+1, 27*2+1, 25*2+1, 23*2+1, 21*2+1, 19*2+1, 17*2+1, 15*2+1, -13*2+1, 11*2+1, 9*2+1, 7*2+1, 5*2+1, 3*2+1, -0, -2*2+1, 4*2+1, 6*2+1, 8*2+1, 10*2+1, 12*2+1, 14*2+1, 16*2+1, 18*2+1, 20*2+1, 22*2+1, 24*2+1, -26*2+1, 28*2+1, 30*2+1, 32*2+1, 34*2+1, 36*2+1, 38*2+1, 40*2+1, 42*2+1, 44*2+1, 46*2+1, 48*2+1, 50*2+1, -52*2+1, 54*2+1, 56*2+1, 58*2+1, 60*2+1, 62*2+1, 64*2+1 }; -#endif // USE_GRES_LUT - -#ifdef X86OPT_INLINE -//__forceinline -#endif -static Int AdaptiveScan (const PixelI *pCoeffs, Int *pResidual, - CAdaptiveScan *pScan, - const Int iModelBits, const Int iTrimBits, - Int *pRLCoeffs, const Int iCount) -{ - if (iModelBits == 0) { - return AdaptiveScanZero (pCoeffs, pScan, pRLCoeffs, iCount); - } - else if (iModelBits <= iTrimBits) { - return AdaptiveScanTrim (pCoeffs, pScan, iModelBits, pRLCoeffs, iCount); - } - else if (iTrimBits == 0 -#ifdef USE_GRES_LUT - && iModelBits < 6 -#endif // USE_GRES_LUT - ) { - Int k, iRun = 0, iLevel, iNumNonzero = 0; - Int iTemp, iTemp1; - const unsigned int iThOff = (1 << iModelBits) - 1, iTh = iThOff * 2 + 1; - - iLevel = pCoeffs[pScan[1].uScan]; - - if ((unsigned int)(iLevel + iThOff) >= iTh) { - iTemp1 = abs (iLevel); - iTemp = iTemp1 >> iModelBits; - pResidual[pScan[1].uScan] = (iTemp1 & iThOff) * 2; - pScan[1].uTotal++; - pRLCoeffs[iNumNonzero * 2] = iRun; - pRLCoeffs[iNumNonzero * 2 + 1] = (iLevel < 0) ? -iTemp : iTemp; - iNumNonzero++; - iRun = 0; - } - else { - iRun++; -#ifdef USE_GRES_LUT - pResidual[pScan[1].uScan] = gRes[(iLevel + 32)]; -#else // USE_GRES_LUT - iTemp = -(iLevel < 0); - pResidual[pScan[1].uScan] = (iLevel ^ iTemp) * 4 + (6 & iTemp) + (iLevel != 0); -#endif // USE_GRES_LUT - } - for (k = 2; k < iCount; k++) { - const Int sk = pScan[k].uScan; - //pResidual++; - iLevel = pCoeffs[sk]; - if ((unsigned int)(iLevel + iThOff) >= iTh) { - const Int iSign = -(iLevel < 0); - iTemp1 = (iSign ^ iLevel) - iSign; - iTemp = iTemp1 >> iModelBits; - pResidual[sk] = (iTemp1 & iThOff) * 2; - pScan[k].uTotal++; - if (pScan[k].uTotal > pScan[k - 1].uTotal) { - CAdaptiveScan cTemp = pScan[k]; - pScan[k] = pScan[k - 1]; - pScan[k - 1] = cTemp; - } - pRLCoeffs[iNumNonzero * 2] = iRun; - pRLCoeffs[iNumNonzero * 2 + 1] = (iTemp ^ iSign) - iSign; - iNumNonzero++; - iRun = 0; - } - else { - iRun++; -#ifdef USE_GRES_LUT - pResidual[sk] = gRes[(iLevel + 32)]; -#else // USE_GRES_LUT - iTemp = -(iLevel < 0); - pResidual[sk] = (iLevel ^ iTemp) * 4 + (6 & iTemp) + (iLevel != 0); -#endif // USE_GRES_LUT - ////(abs(iLevel) * 4) + ((iLevel < 0) * 2) + (iLevel != 0); - } - } - return iNumNonzero; - } - else { - Int k, iRun = 0, iLevel, iNumNonzero = 0; - Int iTemp, iTemp1; - const unsigned int iThOff = (1 << iModelBits) - 1, iTh = iThOff * 2 + 1; - - iLevel = pCoeffs[pScan[1].uScan]; - //pResidual++; - if ((unsigned int)(iLevel + iThOff) >= iTh) { - iTemp1 = abs (iLevel); - iTemp = iTemp1 >> iModelBits; - pResidual[pScan[1].uScan] = ((iTemp1 & iThOff) >> iTrimBits) * 2; - pScan[1].uTotal++; - pRLCoeffs[iNumNonzero * 2] = iRun; - pRLCoeffs[iNumNonzero * 2 + 1] = (iLevel < 0) ? -iTemp : iTemp; - iNumNonzero++; - iRun = 0; - } - else { - iRun++; - iTemp = -(iLevel < 0); - iLevel = ((iLevel + iTemp) >> iTrimBits) - iTemp; // round towards zero - iTemp = -(iLevel < 0); - pResidual[pScan[1].uScan] = (iLevel ^ iTemp) * 4 + (6 & iTemp) + (iLevel != 0); - } - for (k = 2; k < iCount; k++) { - const Int sk = pScan[k].uScan; - //pResidual++; - iLevel = pCoeffs[sk]; - if ((unsigned int)(iLevel + iThOff) >= iTh) { - iTemp1 = abs (iLevel); - iTemp = iTemp1 >> iModelBits; - pResidual[sk] = ((iTemp1 & iThOff) >> iTrimBits) * 2; - pScan[k].uTotal++; - if (pScan[k].uTotal > pScan[k - 1].uTotal) { - CAdaptiveScan cTemp = pScan[k]; - pScan[k] = pScan[k - 1]; - pScan[k - 1] = cTemp; - } - pRLCoeffs[iNumNonzero * 2] = iRun; - pRLCoeffs[iNumNonzero * 2 + 1] = (iLevel < 0) ? -iTemp : iTemp; - iNumNonzero++; - iRun = 0; - } - else { - iRun++; - iTemp = -(iLevel < 0); - iLevel = ((iLevel + iTemp) >> iTrimBits) - iTemp; // round towards zero - iTemp = -(iLevel < 0); - pResidual[sk] = (iLevel ^ iTemp) * 4 + (6 & iTemp) + (iLevel != 0); - } - } - return iNumNonzero; - } -} - -/************************************************************************* - EncodeMacroblockLowpass -*************************************************************************/ -Int EncodeMacroblockLowpass (CWMImageStrCodec *pSC, CCodingContext *pContext, Int iMBX, Int iMBY) -{ - const COLORFORMAT cf = pSC->m_param.cfColorFormat; - const Int iChannels = (Int) pSC->m_param.cNumChannels; - Int iFullChannels = (cf == YUV_420 || cf == YUV_422) ? 1 : iChannels; - CWMIMBInfo *pMBInfo = &pSC->MBInfo; - BitIOInfo* pIO = pContext->m_pIOLP; - - CAdaptiveScan *pScan = pContext->m_aScanLowpass; - Int k, /*iPrevRun = -1,*/ iRun = 0;// iLastIndex = 0; - Int iModelBits = pContext->m_aModelLP.m_iFlcBits[0]; - PixelI aBuf[2][8]; - Int aLaplacianMean[2] = {0, 0}, *pLM = aLaplacianMean; - Int iChannel, iVal; - Int aRLCoeffs[MAX_CHANNELS][32], iNumCoeffs[MAX_CHANNELS]; - const I32 *aDC[MAX_CHANNELS]; - Int aResidual[MAX_CHANNELS][16]; - Void (*putBits)(BitIOInfo* pIO, U32 uiBits, U32 cBits) = putBit16; - - UNREFERENCED_PARAMETER( iMBX ); - UNREFERENCED_PARAMETER( iMBY ); - - if (iChannels > MAX_CHANNELS) - return ICERR_ERROR; - - if((pSC->WMISCP.bfBitstreamFormat != SPATIAL) && (pSC->pTile[pSC->cTileColumn].cBitsLP > 0)) // MB-based LP QP index - encodeQPIndex(pIO, pMBInfo->iQIndexLP, pSC->pTile[pSC->cTileColumn].cBitsLP); - - // set arrays - for (k = 0; k < iChannels; k++) { - aDC[k] = pMBInfo->iBlockDC[k]; - } - - /** reset adaptive scan totals **/ - if (pSC->m_bResetRGITotals) { - int iScale = 2; - int iWeight = iScale * 16; - pScan[0].uTotal = MAXTOTAL; - for (k = 1; k < 16; k++) { - pScan[k].uTotal = iWeight; - iWeight -= iScale; - } - } - - /** scan 4x4 transform **/ - for (iChannel = 0; iChannel < iFullChannels; iChannel++) { - iNumCoeffs[iChannel] = AdaptiveScan (aDC[iChannel], aResidual[iChannel], - pScan, iModelBits, 0, aRLCoeffs[iChannel], 16); - - iModelBits = pContext->m_aModelLP.m_iFlcBits[1]; - } - - if (cf == YUV_420 || cf == YUV_422) { /** interleave U and V **/ - static const Int aRemap[] = { 4, 1,2,3, 5,6,7 }; - const Int *pRemap = aRemap + (cf == YUV_420); - const Int iCount = (cf == YUV_420) ? 6 : 14; - Int iCoef = 0; - - iRun = 0; - iModelBits = pContext->m_aModelLP.m_iFlcBits[1]; - - for (k = 0; k < iCount; k++) { - Int iIndex = pRemap[k >> 1]; - Int iDC = aDC[(k & 1) + 1][iIndex]; - aBuf[k & 1][iIndex] = iVal = abs (iDC) >> iModelBits; - - if (iVal) { - aRLCoeffs[1][iCoef * 2] = iRun; - aRLCoeffs[1][iCoef * 2 + 1] = (iDC < 0) ? -iVal : iVal; - iCoef++; - iRun = 0; - } - else { - iRun++; - } - } - iNumCoeffs[1] = iCoef; - } - - /** in raw mode, this can take 6% of the bits in the extreme low rate case!!! **/ - if (cf == YUV_420 || cf == YUV_422) - iFullChannels = 2; - - if (cf == YUV_420 || cf == YUV_422 || cf == YUV_444) { - int iCBP, iMax = iFullChannels * 4 - 5; /* actually (1 << iNChannels) - 1 **/ - int iCountM = pContext->m_iCBPCountMax, iCountZ = pContext->m_iCBPCountZero; - iCBP = (iNumCoeffs[0] > 0) + (iNumCoeffs[1] > 0) * 2; - if (iFullChannels == 3) - iCBP += (iNumCoeffs[2] > 0) * 4; - - if (iCountZ <= 0 || iCountM < 0) { - iVal = iCBP; - if (iCountM < iCountZ) { - iVal = iMax - iCBP; - } - if (iVal == 0) - putBit16z(pIO, 0, 1); - else if (iVal == 1) - putBit16z(pIO, (iFullChannels + 1) & 0x6, iFullChannels); // 2 or 4 - else - putBit16z(pIO, iVal + iMax + 1, iFullChannels + 1); // cbp + 4 or cbp + 8 - } - else { - putBit16z(pIO, iCBP, iFullChannels); - } - - iCountM += 1 - 4 * (iCBP == iMax);//(b + c - 2*a); - iCountZ += 1 - 4 * (iCBP == 0);//(a + b - 2*c); - if (iCountM < -8) - iCountM = -8; - else if (iCountM > 7) - iCountM = 7; - pContext->m_iCBPCountMax = iCountM; - - if (iCountZ < -8) - iCountZ = -8; - else if (iCountZ > 7) - iCountZ = 7; - pContext->m_iCBPCountZero = iCountZ; - } - else { /** 1 or N channel **/ - for (iChannel = 0; iChannel < iChannels; iChannel++) { - putBit16z(pIO, (iNumCoeffs[iChannel] > 0), 1); - } - } - - // set appropriate function pointer - if (pContext->m_aModelLP.m_iFlcBits[0] > 14 || pContext->m_aModelLP.m_iFlcBits[1] > 14) { - putBits = putBit32; - } - - iModelBits = pContext->m_aModelLP.m_iFlcBits[0]; - - for (iChannel = 0; iChannel < iFullChannels; iChannel++) { - const Int *pRL = aRLCoeffs[iChannel]; - Int iCoef = iNumCoeffs[iChannel]; - - if (iCoef) { - (*pLM) += iCoef; - if(EncodeBlock (iChannel > 0, pRL, iCoef, pContext->m_pAHexpt, CTDC, - pIO, 1 + 9 * ((cf == YUV_420) && (iChannel == 1)) + ((cf == YUV_422) && (iChannel == 1))) != ICERR_OK) - return ICERR_ERROR; - } - - if (iModelBits) { - if ((cf == YUV_420 || cf == YUV_422) && iChannel) { // 420/422 chroma - for (k = 1; k < ((cf == YUV_420) ? 4 : 8); k++) { - putBits(pIO, abs(aDC[1][k]), iModelBits); - if (aBuf[0][k] == 0 && aDC[1][k]) { - putBit16z(pIO, (aDC[1][k] < 0), 1); - } - putBits(pIO, abs(aDC[2][k]), iModelBits); - if (aBuf[1][k] == 0 && aDC[2][k]) { - putBit16z(pIO, (aDC[2][k] < 0), 1); - } - } - } - else { // normal case - for (k = 1; k < 16; k++) { - putBit16z(pIO, aResidual[iChannel][k] >> 1, iModelBits + (aResidual[iChannel][k] & 1)); - } - } - } - - pLM = aLaplacianMean + 1; - iModelBits = pContext->m_aModelLP.m_iFlcBits[1]; - } - - writeIS_L1(pSC, pIO); - - UpdateModelMB (cf, iChannels, aLaplacianMean, &pContext->m_aModelLP); - - if (pSC->m_bResetContext) { - AdaptLowpassEnc(pContext); - } - - return ICERR_OK; -} - -/************************************************************************* - Adapt -*************************************************************************/ -Void AdaptLowpassEnc(CCodingContext *pSC) -{ - Int kk; - for (kk = 0; kk < CONTEXTX + CTDC; kk++) { /** adapt fixed code (index 0 and 1) as well **/ - AdaptDiscriminant (pSC->m_pAHexpt[kk]); - } -} - -Void AdaptHighpassEnc(CCodingContext *pSC) -{ - Int kk; - //Adapt (pSC->m_pAdaptHuffCBPCY, FALSE); - AdaptDiscriminant (pSC->m_pAdaptHuffCBPCY); - AdaptDiscriminant (pSC->m_pAdaptHuffCBPCY1); - for (kk = 0; kk < CONTEXTX; kk++) { /** adapt fixed code **/ - AdaptDiscriminant (pSC->m_pAHexpt[kk + CONTEXTX + CTDC]); - } -} - -/************************************************************************* - Experimental code -- encodeBlock - SR = <0 1 2> == - alphabet 12: - pAHexpt[0] == - alphabet 6: - pAHexpt[1] == - pAHexpt[2] == - alphabet 4: - pAHexpt[3] == (SR may be last or insignificant only) - alphabet f(run) (this can be extended to 6 contexts - SL and SR') - pAHexpt[4] == - alphabet f(lev) (this can be extended to 9 contexts) - pAHexpt[5-6] == first symbol - pAHexpt[7-8] == condition on SRn no use -*************************************************************************/ -#ifdef X86OPT_INLINE -__forceinline -#endif -static Void EncodeSignificantRun (Int iRun, Int iMaxRun, struct CAdaptiveHuffman *pAHexpt, BitIOInfo* pOut) -{ - Int iIndex, iFLC, iBin; - static const Int aIndex[] = { - 0,1,2,2,3,3,4,4,4,4,4,4,4,4, - 0,1,2,2,3,3,4,4,4,4,0,0,0,0, - 0,1,2,3,4,4 - }; - - if (iMaxRun < 5) { - //if (iMaxRun == 4) { - //static const Int gCode[] = { 0, 1, 1, 1 }; - static const Int gLen[] = { 3, 3, 2, 1 }; - if (iMaxRun > 1) - putBit16z(pOut, (iMaxRun != iRun), gLen[iMaxRun - iRun] - (4 - iMaxRun)); - //} - //else if (iMaxRun == 3) { - // if (iRun == 1) { - // putBit16z(pOut, 1, 1); - // } - // else { - // putBit16z(pOut, 3 ^ iRun, 2); - // } - //} - //else if (iMaxRun == 2) { - // putBit16z(pOut, 2 - iRun, 1); - //} - return; - } - - iBin = gSignificantRunBin[iMaxRun]; - iIndex = aIndex[iRun + iBin * 14 - 1]; - iFLC = gSignificantRunFixedLength[iIndex + iBin * 5]; - putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1], pAHexpt->m_pTable[iIndex * 2 + 2]); - //this always uses table 0 - //pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex]; - putBit16(pOut, iRun + 1, iFLC); -} - -#ifdef X86OPT_INLINE -__forceinline -#endif -static Void EncodeFirstIndex (Bool bChroma, Int iLoc, Int iCont, Int iIndex, Int iSign, - struct CAdaptiveHuffman **ppAHexpt, BitIOInfo* pOut) -{ - // Int iContext = iCont + 1 + bChroma * 3; - struct CAdaptiveHuffman *pAHexpt = ppAHexpt[bChroma * 3]; - UNREFERENCED_PARAMETER( iLoc ); - UNREFERENCED_PARAMETER( iCont ); - pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex]; - pAHexpt->m_iDiscriminant1 += pAHexpt->m_pDelta1[iIndex]; - putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1] * 2 + iSign, pAHexpt->m_pTable[iIndex * 2 + 2] + 1); - return; -} - -#ifdef X86OPT_INLINE -__forceinline -#endif -static Void EncodeIndex (Bool bChroma, Int iLoc, Int iCont, Int iIndex, Int iSign, - struct CAdaptiveHuffman **ppAHexpt, BitIOInfo* pOut) -{ - Int iContext = iCont + 1 + bChroma * 3; - - if (iLoc < 15) { - struct CAdaptiveHuffman *pAHexpt = ppAHexpt[iContext]; - pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex]; - pAHexpt->m_iDiscriminant1 += pAHexpt->m_pDelta1[iIndex]; - putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1] * 2 + iSign, pAHexpt->m_pTable[iIndex * 2 + 2] + 1); - } - else if (iLoc == 15) { - static const U32 gCode[] = { 0, 6, 2, 7 }; - static const U32 gLen[] = { 1, 3, 2, 3 }; - putBit16z(pOut, gCode[iIndex] * 2 + iSign, gLen[iIndex] + 1); - return; - } - else {//if (iLoc == 16) { - putBit16z(pOut, iIndex * 2 + iSign, 1 + 1); - return; - } -} - -#ifdef X86OPT_INLINE -__forceinline -#endif -static Int EncodeBlock (Bool bChroma, const Int *aLocalCoef, Int iNumNonzero, - struct CAdaptiveHuffman **pAHexpt, Int iContextOffset, - BitIOInfo* pOut, UInt iLocation) -{ - Int iSR, iSL, iSRn, iIndex, k, iCont, iLev; - - /** first symbol **/ - iLev = aLocalCoef[1]; - iSR = (aLocalCoef[0] == 0); - iSL = ((unsigned int) (iLev + 1) > 2U); - iSRn = 1; - if (iNumNonzero == 1) { - iSRn = 0; - } - else if (aLocalCoef[2] > 0) { - iSRn = 2; - } - iIndex = iSRn * 4 + iSL * 2 + iSR; - EncodeFirstIndex (bChroma, iLocation, 0, iIndex, (iLev < 0), pAHexpt + iContextOffset, pOut); - iCont = iSR & iSRn; - if (iSL) { - EncodeSignificantAbsLevel ((UInt)(abs(iLev) - 1), pAHexpt[6 + iContextOffset + iCont], pOut); - } - if (iSR == 0) { - EncodeSignificantRun (aLocalCoef[0], 15 - iLocation, pAHexpt[0], pOut); - } - iLocation += aLocalCoef[0] + 1; - - for (k = 1; k < iNumNonzero; k++) { - if (iSRn == 2) { - EncodeSignificantRun (aLocalCoef[k * 2], 15 - iLocation, pAHexpt[0], pOut); - } - iLocation += aLocalCoef[k * 2] + 1; - iSRn = 1; - if (k == iNumNonzero - 1) { - iSRn = 0; - } - else if (aLocalCoef[k * 2 + 2] > 0) { - iSRn = 2; - } - //iSL = (abs(aLocalCoef[k * 2 + 1]) > 1); - iLev = aLocalCoef[k * 2 + 1]; - iSL = ((unsigned int) (iLev + 1) > 2U); - iIndex = iSRn * 2 + iSL; - EncodeIndex (bChroma, iLocation, iCont, iIndex, (iLev < 0), pAHexpt + iContextOffset, pOut); - - iCont &= iSRn; /** big difference! **/ - if (iSL) { - EncodeSignificantAbsLevel ((UInt)(abs(iLev) - 1), pAHexpt[6 + iContextOffset + iCont], pOut); - } - //else { - // putBit16z(pOut, (iLev < 0), 1); - //} - } - - return ICERR_OK; -} - -/************************************************************************* - CodeCoeffs -*************************************************************************/ -#ifdef X86OPT_INLINE -__forceinline -#endif -static Int CodeCoeffs (CWMImageStrCodec * pSC, CCodingContext *pContext, - Int iMBX, Int iMBY, BitIOInfo* pIO, BitIOInfo* pIOFL) -{ - const COLORFORMAT cf = pSC->m_param.cfColorFormat; - const Int iChannels = (Int) pSC->m_param.cNumChannels; - const Int iPlanes = (cf == YUV_420 || cf == YUV_422) ? 1 : iChannels; - CWMIMBInfo * pMBInfo = &pSC->MBInfo; - CAdaptiveScan *pScan; - Int iBlock, iNBlocks = 4; - Int iSubblock, iIndex = 0; - Int i, k; - const Int iNumCoeffs = 16; - Int iModelBits = pContext->m_aModelAC.m_iFlcBits[0], iFlex = 0, iTrim = 0, iMask = 0; - Int aLaplacianMean[2] = { 0, 0}, *pLM = aLaplacianMean; - Bool bChroma = FALSE; - - UNREFERENCED_PARAMETER( iMBX ); - UNREFERENCED_PARAMETER( iMBY ); - - assert (iModelBits < 16); - if (pContext->m_iTrimFlexBits <= iModelBits && pSC->WMISCP.sbSubband != SB_NO_FLEXBITS) { - iTrim = pContext->m_iTrimFlexBits; - iFlex = iModelBits - pContext->m_iTrimFlexBits; - iMask = (1 << iFlex) - 1; - } - - if(pSC->WMISCP.sbSubband != SB_NO_FLEXBITS) - writeIS_L1(pSC, pIOFL); - - /** set scan arrays **/ - if (pMBInfo->iOrientation == 1) { - pScan = pContext->m_aScanVert; - } - else { - pScan = pContext->m_aScanHoriz; - } - - /** write out coefficients **/ - for (i = 0; i < iPlanes; i++) { - Int iPattern = pMBInfo->iCBP[i]; - - if (cf == YUV_420) { - iNBlocks = 6; - iPattern += (pMBInfo->iCBP[1] << 16) + (pMBInfo->iCBP[2] << 20); - } - else if (cf == YUV_422) { - iNBlocks = 8; - iPattern += (pMBInfo->iCBP[1] << 16) + (pMBInfo->iCBP[2] << 24); - } - - for (iBlock = iIndex = 0; iBlock < iNBlocks; iBlock++) { - /*writeIS_L2(pSC, pIO); - if (pIO != pIOFL) - writeIS_L2(pSC, pIOFL);*/ - - for (iSubblock = 0; iSubblock < 4; iSubblock++, iPattern >>= 1, iIndex ++) { - const PixelI *pCoeffs = NULL; - - if(iBlock < 4){ - pCoeffs = pSC->pPlane[i] + blkOffset[iIndex]; - } - else if(cf == YUV_420){ - pCoeffs = pSC->pPlane[iBlock - 3] + blkOffsetUV[iSubblock]; - } - else if(cf == YUV_422){ - pCoeffs = pSC->pPlane[1 + ((iBlock - 4) >> 1)] + blkOffsetUV_422[(iBlock & 1) * 4 + iSubblock]; - } - - /** put AC bits **/ - - if ((iPattern & 1) == 0) { - if (iFlex) { - /** FLC only, all else is skipped **/ - for (k = 1; k < iNumCoeffs; k++) { - Int data = pCoeffs[dctIndex[0][k]]; - Int atdata = (abs(data) >> iTrim); - Int word = atdata & iMask, len = iFlex; - if (atdata) { - word += word + (data < 0); - len++; - } - putBit16z(pIOFL, word, len); - } - } - } - else { -// WARNING!!! interaction between lowpass coefficients and highpass scan ordering - may lead to break in decoding when model bits is nonzero! -// Fix is to use same scan order in model bits transmission, and defer update of scan order to end of block - /** collect coefficients **/ - Int aLocalCoef[32], iNumNonzero = 0; - Int aResidual[16]; - - iNumNonzero = AdaptiveScan (pCoeffs, aResidual, - pScan, iModelBits, iTrim, aLocalCoef, 16); - (*pLM) += iNumNonzero; - EncodeBlock (bChroma, aLocalCoef, iNumNonzero, pContext->m_pAHexpt, CTDC + CONTEXTX, pIO, 1); - - if (iFlex) { - for (k = 1; k < iNumCoeffs; k++) { - putBit16z(pIOFL, aResidual[dctIndex[0][k]] >> 1, iFlex + (aResidual[dctIndex[0][k]] & 1)); - } - } - } - } - if (iBlock == 3) { - iModelBits = pContext->m_aModelAC.m_iFlcBits[1]; - assert (iModelBits < 16); - pLM = aLaplacianMean + 1; - bChroma = TRUE; - iTrim = iFlex = iMask = 0; - if (pContext->m_iTrimFlexBits <= iModelBits && pSC->WMISCP.sbSubband != SB_NO_FLEXBITS) { - iTrim = pContext->m_iTrimFlexBits; - iFlex = iModelBits - iTrim; - iMask = (1 << iFlex) - 1; - } - } - } - } - - /** update model at end of MB **/ - UpdateModelMB (cf, iChannels, aLaplacianMean, &pContext->m_aModelAC); - - return ICERR_OK; -} - - -/************************************************************************* - CodeCBP -*************************************************************************/ -static Void CodeCBP (CWMImageStrCodec * pSC, CCodingContext *pContext, - Int iMBX, Int iMBY, BitIOInfo *pIO) -{ - const COLORFORMAT cf = pSC->m_param.cfColorFormat; - const Int iChannel = (cf == NCOMPONENT || cf == CMYK) ? (Int) pSC->m_param.cNumChannels : 1; - Int iDiffCBPCY, iDiffCBPCU = 0, iDiffCBPCV = 0, iDY; - Int iBlock, i, k; - static const Int aNumOnes[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; - static const Int aTabLen[] = { 0, 2, 2, 2, 2, 2, 3, 2, 2, 3, 3, 2, 3, 2, 2, 0 }; - static const Int aTabCode[] = { 0, 0, 1, 0, 2, 1, 4, 3, 3, 5, 6, 2, 7, 1, 0, 0 }; - CAdaptiveHuffman *pAH; - Int iCount, iPattern, iCode, iCodeU = 0, iCodeV = 0; - - UNREFERENCED_PARAMETER( iMBX ); - UNREFERENCED_PARAMETER( iMBY ); - - predCBPEnc(pSC, pContext); - writeIS_L1(pSC, pIO); - - iDiffCBPCU = pSC->MBInfo.iDiffCBP[1]; - iDiffCBPCV = pSC->MBInfo.iDiffCBP[2]; - - for (i = 0; i < iChannel; i++) { - iDiffCBPCY = pSC->MBInfo.iDiffCBP[i]; - - if(cf == YUV_420){ // PackCBP420 - iDiffCBPCY = (iDiffCBPCY & 0xf) + ((iDiffCBPCU & 1) << 4) + ((iDiffCBPCV & 1) << 5) + - ((iDiffCBPCY & 0x00f0) << 2) + ((iDiffCBPCU & 2) << 9) + ((iDiffCBPCV & 2) << 10) + - ((iDiffCBPCY & 0x0f00) << 4) + ((iDiffCBPCU & 4) << 14) + ((iDiffCBPCV & 4) << 15) + - ((iDiffCBPCY & 0xf000) << 6) + ((iDiffCBPCU & 8) << 19) + ((iDiffCBPCV & 8) << 20); - } - else if(cf == YUV_422){// PackCBP422 - iDiffCBPCY = (iDiffCBPCY & 0xf) + ((iDiffCBPCU & 1) << 4) + ((iDiffCBPCU & 4) << 3) + - ((iDiffCBPCV & 1) << 6) + ((iDiffCBPCV & 4) << 5) + - ((iDiffCBPCY & 0x00f0) << 4) + ((iDiffCBPCU & 2) << 11) + ((iDiffCBPCU & 8) << 10) + - ((iDiffCBPCV & 2) << 13) + ((iDiffCBPCV & 8) << 12) + - ((iDiffCBPCY & 0x0f00) << 8) + ((iDiffCBPCU & 16) << 16) + ((iDiffCBPCU & 64) << 15) + - ((iDiffCBPCV & 16) << 18) + ((iDiffCBPCV & 64) << 17) + - ((iDiffCBPCY & 0xf000) << 12) + ((iDiffCBPCU & 32) << 23) + ((iDiffCBPCU & 128) << 22) + - ((iDiffCBPCV & 32) << 25) + ((iDiffCBPCV & 128) << 24); - } - - /** send CBPCY **/ - iPattern = 0; - iDY = iDiffCBPCY; - if (cf == YUV_444) { - iDY |= (iDiffCBPCU | iDiffCBPCV); - } - - for (iBlock = 0; iBlock < 4; iBlock++) { - if(cf == YUV_422) { - iPattern |= ((iDY & 0xff) != 0) * 0x10; - iDY >>= 8; - } - else if (cf == YUV_420) { - iPattern |= ((iDY & 0x3f) != 0) * 0x10; - iDY >>= 6; - } - else { - iPattern |= ((iDY & 0xf) != 0) * 0x10; - iDY >>= 4; - } - iPattern >>= 1; - } - - pAH = pContext->m_pAdaptHuffCBPCY1; - iCount = aNumOnes[iPattern]; - putBit16z(pIO, pAH->m_pTable[iCount * 2 + 1], pAH->m_pTable[iCount * 2 + 2]); - pAH->m_iDiscriminant += pAH->m_pDelta[iCount]; - if (aTabLen[iPattern]) { - putBit16z(pIO, aTabCode[iPattern], aTabLen[iPattern]); - } - - for (iBlock = 0; iBlock < 4; iBlock++) { - switch (cf) { - case YUV_444: - iCode = iDiffCBPCY & 0xf; - iCodeU = iDiffCBPCU & 0xf; - iCodeV = iDiffCBPCV & 0xf; - iCode |= ((iCodeU != 0) << 4); - iCode |= ((iCodeV != 0) << 5); - iDiffCBPCY >>= 4; - iDiffCBPCU >>= 4; - iDiffCBPCV >>= 4; - break; - - case YUV_422: - iCode = iDiffCBPCY & 0xff; - iDiffCBPCY >>= 8; - break; - - case YUV_420: - iCode = iDiffCBPCY & 0x3f; - iDiffCBPCY >>= 6; - break; - - default: - iCode = iDiffCBPCY & 0xf; - iDiffCBPCY >>= 4; - } - - if (iCode) { - static const Int gTab0[16] = { 0,1,1,2, 1,3,3,4, 1,3,3,4, 2,4,4,5 }; - static const Int gFL0[16] = { 0,2,2,1, 2,2,2,2, 2,2,2,2, 1,2,2,0 }; - static const Int gCode0[16] = { 0,0,1,0, 2,0,1,0, 3,2,3,1, 1,2,3,0 }; - int val, iChroma = (iCode >> 4); - iCode &= 0xf; - - if(cf == YUV_422) { - iCodeU = (iChroma & 3); - iCodeV = ((iChroma >> 2) & 3); - iChroma = (iCodeU == 0 ? 0 : 1); - if(iCodeV != 0) { - iChroma += 2; - } - } - - if (iChroma) { - if (gTab0[iCode] > 2) { - val = 8; - } - else { - val = gTab0[iCode] + 6 - 1; - } - } - else { - val = gTab0[iCode] - 1; - } - pAH = pContext->m_pAdaptHuffCBPCY; - putBit16z(pIO, pAH->m_pTable[val * 2 + 1], pAH->m_pTable[val * 2 + 2]); - pAH->m_iDiscriminant += pAH->m_pDelta[val]; - - if (iChroma) { - if (iChroma == 1) - putBit16z(pIO, 1, 1); - else - putBit16z(pIO, 3 - iChroma, 2); - } - if (val == 8) { - if (gTab0[iCode] == 3) { - putBit16z(pIO, 1, 1); - } - else { - putBit16z(pIO, 5 - gTab0[iCode], 2); - } - } - if (gFL0[iCode]) { - putBit16z(pIO, gCode0[iCode], gFL0[iCode]); - } - - if (cf == YUV_444) { - pAH = pContext->m_pAHexpt[1]; - iPattern = iCodeU; - for (k = 0; k < 2; k++) { - if (iPattern) { - iCount = aNumOnes[iPattern]; - iCount--; - putBit16z(pIO, pAH->m_pTable[iCount * 2 + 1], pAH->m_pTable[iCount * 2 + 2]); - if (aTabLen[iPattern]) { - putBit16z(pIO, aTabCode[iPattern], aTabLen[iPattern]); - } - } - iPattern = iCodeV; - } - } - else if (cf == YUV_422){ - iPattern = iCodeU; - for(k = 0; k < 2; k ++) { - if(iPattern) { - if (iPattern == 1) - putBit16z(pIO, 1, 1); - else { - putBit16z(pIO, 3 - iPattern, 2); - } - } - iPattern = iCodeV; - } - } - } - } - } -} - -/************************************************************************* - macroblock encode function using 4x4 transforms -*************************************************************************/ -Int EncodeMacroblockHighpass(CWMImageStrCodec * pSC, CCodingContext *pContext, Int iMBX, Int iMBY) -{ - BitIOInfo* pIO = pContext->m_pIOAC; - BitIOInfo* pIOFL = pContext->m_pIOFL; - - if((pSC->WMISCP.bfBitstreamFormat != SPATIAL) && (pSC->pTile[pSC->cTileColumn].cBitsHP > 0)) // MB-based HP QP index - encodeQPIndex(pIO, pSC->MBInfo.iQIndexHP, pSC->pTile[pSC->cTileColumn].cBitsHP); - - /** reset adaptive scan totals **/ - if (pSC->m_bResetRGITotals) { - Int iScale = 2; - Int iWeight = iScale * 16; - Int k; - pContext->m_aScanHoriz[0].uTotal = pContext->m_aScanVert[0].uTotal = MAXTOTAL; - for (k = 1; k < 16; k++) { - pContext->m_aScanHoriz[k].uTotal = pContext->m_aScanVert[k].uTotal = iWeight; - iWeight -= iScale; - } - } - CodeCBP(pSC, pContext, iMBX, iMBY, pIO); - if(CodeCoeffs(pSC, pContext, iMBX, iMBY, pIO, pIOFL) != ICERR_OK) - return ICERR_ERROR; - - if (pSC->m_bResetContext) { - AdaptHighpassEnc(pContext); - } - - return ICERR_OK; -} diff --git a/Src/JxrDecode/Jxr/strFwdTransform.c b/Src/JxrDecode/Jxr/strFwdTransform.c deleted file mode 100644 index 968e0106..00000000 --- a/Src/JxrDecode/Jxr/strFwdTransform.c +++ /dev/null @@ -1,1111 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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" -#include "encode.h" - -/** rotation by pi/8 **/ -#define ROTATE1(a, b) (b) -= (((a) + 1) >> 1), (a) += (((b) + 1) >> 1) // this works well too -#define ROTATE2(a, b) (b) -= (((a)*3 + 4) >> 3), (a) += (((b)*3 + 4) >> 3) // this works well too - -/** local functions **/ -static Void fwdOddOdd(PixelI *, PixelI *, PixelI *, PixelI *); -static Void fwdOddOddPre(PixelI *, PixelI *, PixelI *, PixelI *); -static Void fwdOdd(PixelI *, PixelI *, PixelI *, PixelI *); -static Void strDCT2x2alt(PixelI * a, PixelI * b, PixelI * c, PixelI * d); -static Void strHSTenc1(PixelI *, PixelI *); -static Void strHSTenc(PixelI *, PixelI *, PixelI *, PixelI *); -static Void strHSTenc1_edge (PixelI *pa, PixelI *pd); - -//static Void scaleDownUp0(PixelI *, PixelI *); -//static Void scaleDownUp1(PixelI *, PixelI *); -//static Void scaleDownUp2(PixelI *, PixelI *); -//#define FOURBUTTERFLY_ENC_ALT(p, i00, i01, i02, i03, i10, i11, i12, i13, \ -// i20, i21, i22, i23, i30, i31, i32, i33) \ -// strHSTenc(&p[i00], &p[i01], &p[i02], &p[i03]); \ -// strHSTenc(&p[i10], &p[i11], &p[i12], &p[i13]); \ -// strHSTenc(&p[i20], &p[i21], &p[i22], &p[i23]); \ -// strHSTenc(&p[i30], &p[i31], &p[i32], &p[i33]); \ -// strHSTenc1(&p[i00], &p[i03]); \ -// strHSTenc1(&p[i10], &p[i13]); \ -// strHSTenc1(&p[i20], &p[i23]); \ -// strHSTenc1(&p[i30], &p[i33]) - -/** DCT stuff **/ -/** data order before DCT **/ -/** 0 1 2 3 **/ -/** 4 5 6 7 **/ -/** 8 9 10 11 **/ -/** 12 13 14 15 **/ -/** data order after DCT **/ -/** 0 8 4 6 **/ -/** 2 10 14 12 **/ -/** 1 11 15 13 **/ -/** 9 3 7 5 **/ -/** reordering should be combined with zigzag scan **/ - -Void strDCT4x4Stage1(PixelI * p) -{ - /** butterfly **/ - //FOURBUTTERFLY(p, 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15); - FOURBUTTERFLY_HARDCODED1(p); - - /** top left corner, butterfly => butterfly **/ - strDCT2x2up(&p[0], &p[1], &p[2], &p[3]); - - /** bottom right corner, pi/8 rotation => pi/8 rotation **/ - fwdOddOdd(&p[15], &p[14], &p[13], &p[12]); - - /** top right corner, butterfly => pi/8 rotation **/ - fwdOdd(&p[5], &p[4], &p[7], &p[6]); - - /** bottom left corner, pi/8 rotation => butterfly **/ - fwdOdd(&p[10], &p[8], &p[11], &p[9]); -} - -Void strDCT4x4SecondStage(PixelI * p) -{ - /** butterfly **/ - FOURBUTTERFLY(p, 0, 192, 48, 240, 64, 128, 112, 176,16, 208, 32, 224, 80, 144, 96, 160); - - /** top left corner, butterfly => butterfly **/ - strDCT2x2up(&p[0], &p[64], &p[16], &p[80]); - - /** bottom right corner, pi/8 rotation => pi/8 rotation **/ - fwdOddOdd(&p[160], &p[224], &p[176], &p[240]); - - /** top right corner, butterfly => pi/8 rotation **/ - fwdOdd(&p[128], &p[192], &p[144], &p[208]); - - /** bottom left corner, pi/8 rotation => butterfly **/ - fwdOdd(&p[32], &p[48], &p[96], &p[112]); -} - -Void strNormalizeEnc(PixelI* p, Bool bChroma) -{ - int i; - if (!bChroma) { - //for (i = 0; i < 256; i += 16) { - // p[i] = (p[i] + 1) >> 2; - //} - } - else { - for (i = 0; i < 256; i += 16) { - p[i] >>= 1; - } - } -} - -/** 2x2 DCT with pre-scaling - for use on encoder side **/ -Void strDCT2x2dnEnc(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd) -{ - PixelI a, b, c, d, C, t; - a = (*pa + 0) >> 1; - b = (*pb + 0) >> 1; - C = (*pc + 0) >> 1; - d = (*pd + 0) >> 1; - //PixelI t1, t2; - - 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; -} - -/** pre filter stuff **/ -/** 2-point pre for boundaries **/ -Void strPre2(PixelI * pa, PixelI * pb) -{ - PixelI a, b; - a = *pa; - b = *pb; - - /** rotate **/ - b -= ((a + 2) >> 2); - a -= ((b + 1) >> 1); - - a -= (b >> 5); - a -= (b >> 9); - a -= (b >> 13); - - b -= ((a + 2) >> 2); - - *pa = a; - *pb = b; -} - -Void strPre2x2(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd) -{ - PixelI a, b, c, d; - a = *pa; - b = *pb; - c = *pc; - d = *pd; - - /** butterflies **/ - a += d; - b += c; - d -= (a + 1) >> 1; - c -= (b + 1) >> 1; - - /** rotate **/ - b -= ((a + 2) >> 2); - a -= ((b + 1) >> 1); - a -= (b >> 5); - a -= (b >> 9); - a -= (b >> 13); - b -= ((a + 2) >> 2); - - /** butterflies **/ - d += (a + 1) >> 1; - c += (b + 1) >> 1; - a -= d; - b -= c; - - *pa = a; - *pb = b; - *pc = c; - *pd = d; -} - -/** 4-point pre for boundaries **/ -Void strPre4(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd) -{ - PixelI a, b, c, d; - a = *pa; - b = *pb; - c = *pc; - d = *pd; - - a += d, b += c; - d -= ((a + 1) >> 1), c -= ((b + 1) >> 1); - - ROTATE1(c, d); - - strHSTenc1_edge(&a, &d); strHSTenc1_edge(&b, &c); - - d += ((a + 1) >> 1), c += ((b + 1) >> 1); - a -= d, b -= c; - - *pa = a; - *pb = b; - *pc = c; - *pd = d; -} - -/***************************************************************************************** - Input data offsets: - (15)(14)|(10+64)(11+64) p0 (15)(14)|(74)(75) - (13)(12)|( 8+64)( 9+64) (13)(12)|(72)(73) - --------+-------------- --------+-------- - ( 5)( 4)|( 0+64) (1+64) p1 ( 5)( 4)|(64)(65) - ( 7)( 6)|( 2+64) (3+64) ( 7)( 6)|(66)(67) -*****************************************************************************************/ -Void strPre4x4Stage1Split(PixelI *p0, PixelI *p1, Int iOffset) -{ - PixelI *p2 = p0 + 72 - iOffset; - PixelI *p3 = p1 + 64 - iOffset; - p0 += 12; - p1 += 4; - - /** butterfly & scaling **/ - strHSTenc(p0 + 0, p2 + 0, p1 + 0, p3 + 0); - strHSTenc(p0 + 1, p2 + 1, p1 + 1, p3 + 1); - strHSTenc(p0 + 2, p2 + 2, p1 + 2, p3 + 2); - strHSTenc(p0 + 3, p2 + 3, p1 + 3, p3 + 3); - strHSTenc1(p0 + 0, p3 + 0); - strHSTenc1(p0 + 1, p3 + 1); - strHSTenc1(p0 + 2, p3 + 2); - strHSTenc1(p0 + 3, p3 + 3); - - /** anti diagonal corners: rotation by pi/8 **/ - ROTATE1(p1[2], p1[3]); - ROTATE1(p1[0], p1[1]); - ROTATE1(p2[1], p2[3]); - ROTATE1(p2[0], p2[2]); - - /** bottom right corner: pi/8 rotation => pi/8 rotation **/ - fwdOddOddPre(p3 + 0, p3 + 1, p3 + 2, p3 + 3); - - /** butterfly **/ - strDCT2x2dn(p0 + 0, p2 + 0, p1 + 0, p3 + 0); - strDCT2x2dn(p0 + 1, p2 + 1, p1 + 1, p3 + 1); - strDCT2x2dn(p0 + 2, p2 + 2, p1 + 2, p3 + 2); - strDCT2x2dn(p0 + 3, p2 + 3, p1 + 3, p3 + 3); -} - -Void strPre4x4Stage1(PixelI* p, Int iOffset) -{ - strPre4x4Stage1Split(p, p + 16, iOffset); -} - -/***************************************************************************************** - Input data offsets: - (15)(14)|(10+32)(11+32) p0 (15)(14)|(42)(43) - (13)(12)|( 8+32)( 9+32) (13)(12)|(40)(41) - --------+-------------- --------+-------- - ( 5)( 4)|( 0+32)( 1+32) p1 ( 5)( 4)|(32)(33) - ( 7)( 6)|( 2+32)( 3+32) ( 7)( 6)|(34)(35) -*****************************************************************************************/ -Void strPre4x4Stage2Split(PixelI* p0, PixelI* p1) -{ - /** butterfly **/ - strHSTenc(p0 - 96, p0 + 96, p1 - 112, p1 + 80); - strHSTenc(p0 - 32, p0 + 32, p1 - 48, p1 + 16); - strHSTenc(p0 - 80, p0 + 112, p1 - 128, p1 + 64); - strHSTenc(p0 - 16, p0 + 48, p1 - 64, p1 + 0); - strHSTenc1(p0 - 96, p1 + 80); - strHSTenc1(p0 - 32, p1 + 16); - strHSTenc1(p0 - 80, p1 + 64); - strHSTenc1(p0 - 16, p1 + 0); - - /** anti diagonal corners: rotation **/ - ROTATE1(p1[-48], p1[-112]); - ROTATE1(p1[-64], p1[-128]); - ROTATE1(p0[112], p0[ 96]); - ROTATE1(p0[ 48], p0[ 32]); - - /** bottom right corner: pi/8 rotation => pi/8 rotation **/ - fwdOddOddPre(p1 + 0, p1 + 64, p1 + 16, p1 + 80); - - /** butterfly **/ - strDCT2x2dn(p0 - 96, p1 - 112, p0 + 96, p1 + 80); - strDCT2x2dn(p0 - 32, p1 - 48, p0 + 32, p1 + 16); - strDCT2x2dn(p0 - 80, p1 - 128, p0 + 112, p1 + 64); - strDCT2x2dn(p0 - 16, p1 - 64, p0 + 48, p1 + 0); -} - - -/** - Hadamard+Scale transform - for some strange reason, breaking up the function into two blocks, strHSTenc1 and strHSTenc - seems to work faster -**/ -static Void strHSTenc(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd) -{ - /** different realization : does rescaling as well! **/ - PixelI a, b, c, d; - a = *pa; - b = *pb; - d = *pc; - c = *pd; - - a += c; - b -= d; - c = ((a - b) >> 1) - c; - d += (b >> 1); - b += c; - - a -= (d * 3 + 4) >> 3; - - *pa = a; - *pb = b; - *pc = c; - *pd = d; -} - -static Void strHSTenc1(PixelI *pa, PixelI *pd) -{ - /** different realization : does rescaling as well! **/ - PixelI a, d; - a = *pa; - d = *pd; - - d -= (a >> 7); - d += (a >> 10); - - //a -= (d * 3 + 4) >> 3; - d -= (a * 3 + 0) >> 4; - a -= (d * 3 + 0) >> 3; - d = (a >> 1) - d; - a -= d; - - *pa = a; - *pd = d; -} - -static Void strHSTenc1_edge (PixelI *pa, PixelI *pd) -{ - /** different realizion as compared to scaling operator for 2D case **/ - PixelI a, d; - a = *pa; - d = -(*pd); // Negative sign needed here for 1D scaling case to ensure correct scaling. - - a -= d; - d += (a >> 1); - a -= (d * 3 + 4) >> 3; - // End new operations - - //Scaling modification of adding 7/1024 in two steps (without multiplication by 7). - d -= (a >> 7); - d += (a >> 10); - - d -= (a * 3 + 0) >> 4; - a -= (d * 3 + 0) >> 3; - d = (a >> 1) - d; - a -= d; - - *pa = a; - *pd = d; -} - -/** Kron(Rotate(pi/8), Rotate(pi/8)) **/\ -static Void fwdOddOdd(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd) -{ - PixelI a, b, c, d, t1, t2; - - a = *pa; - b = -*pb; - c = -*pc; - d = *pd; - - /** butterflies **/ - d += a; - c -= b; - a -= (t1 = d >> 1); - b += (t2 = c >> 1); - - /** rotate pi/4 **/ - a += (b * 3 + 4) >> 3; - b -= (a * 3 + 3) >> 2; - a += (b * 3 + 3) >> 3; - - /** butterflies **/ - b -= t2; - a += t1; - c += b; - d -= a; - - *pa = a; - *pb = b; - *pc = c; - *pd = d; -} -/** Kron(Rotate(pi/8), Rotate(pi/8)) **/ -static Void fwdOddOddPre(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd) -{ - PixelI a, b, c, d, t1, t2; - a = *pa; - b = *pb; - c = *pc; - d = *pd; - - /** butterflies **/ - d += a; - c -= b; - a -= (t1 = d >> 1); - b += (t2 = c >> 1); - - /** rotate pi/4 **/ - a += (b * 3 + 4) >> 3; - b -= (a * 3 + 2) >> 2; - a += (b * 3 + 6) >> 3; - - /** butterflies **/ - b -= t2; - a += t1; - c += b; - d -= a; - - *pa = a; - *pb = b; - *pc = c; - *pd = d; -} - -/** Kron(Rotate(pi/8), [1 1; 1 -1]/sqrt(2)) **/ -/** [a b c d] => [D C A B] **/ -Void fwdOdd(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd) -{ - PixelI a, b, c, d; - a = *pa; - b = *pb; - c = *pc; - d = *pd; - - /** butterflies **/ - b -= c; - a += d; - c += (b + 1) >> 1; - d = ((a + 1) >> 1) - d; - - /** rotate pi/8 **/ - ROTATE2(a, b); - ROTATE2(c, d); - - /** butterflies **/ - d += (b) >> 1; - c -= (a + 1) >> 1; - b -= d; - a += c; - - *pa = a; - *pb = b; - *pc = c; - *pd = d; -} - -/************************************************************************* - Top-level function to tranform possible part of a macroblock -*************************************************************************/ -Void transformMacroblock(CWMImageStrCodec * pSC) -{ - OVERLAP olOverlap = pSC->WMISCP.olOverlap; - COLORFORMAT cfColorFormat = pSC->m_param.cfColorFormat; - Bool left = (pSC->cColumn == 0), right = (pSC->cColumn == pSC->cmbWidth); - Bool top = (pSC->cRow == 0), bottom = (pSC->cRow == pSC->cmbHeight); - Bool leftORright = (left || right), topORbottom = (top || bottom); - Bool topORleft = (left || top);// rightORbottom = (right || bottom); - Bool leftAdjacentColumn = (pSC->cColumn == 1), rightAdjacentColumn = (pSC->cColumn == pSC->cmbWidth - 1); - // Bool topAdjacentRow = (pSC->cRow == 1), bottomAdjacentRow = (pSC->cRow == pSC->cmbHeight - 1); - PixelI * p = NULL;// * pt = NULL; - Int i, j; - Int iNumChromaFullPlanes = (Int)((YUV_420 == cfColorFormat || YUV_422 == cfColorFormat) ? - 1 : pSC->m_param.cNumChannels); - -#define mbX pSC->mbX -#define mbY pSC->mbY -#define tileX pSC->tileX -#define tileY pSC->tileY -#define bVertTileBoundary pSC->bVertTileBoundary -#define bHoriTileBoundary pSC->bHoriTileBoundary -#define bOneMBLeftVertTB pSC->bOneMBLeftVertTB -#define bOneMBRightVertTB pSC->bOneMBRightVertTB -#define iPredBefore pSC->iPredBefore -#define iPredAfter pSC->iPredAfter - - if (pSC->WMISCP.bUseHardTileBoundaries) { - //Add tile location information - if (pSC->cColumn == 0) { - bVertTileBoundary = FALSE; - tileY = 0; - } - bOneMBLeftVertTB = bOneMBRightVertTB = FALSE; - if(tileY > 0 && tileY <= pSC->WMISCP.cNumOfSliceMinus1H && (pSC->cColumn - 1) == pSC->WMISCP.uiTileY[tileY]) - bOneMBRightVertTB = TRUE; - if(tileY < pSC->WMISCP.cNumOfSliceMinus1H && pSC->cColumn == pSC->WMISCP.uiTileY[tileY + 1]) { - bVertTileBoundary = TRUE; - tileY++; - } - else - bVertTileBoundary = FALSE; - if(tileY < pSC->WMISCP.cNumOfSliceMinus1H && (pSC->cColumn + 1) == pSC->WMISCP.uiTileY[tileY + 1]) - bOneMBLeftVertTB = TRUE; - - if (pSC->cRow == 0) { - bHoriTileBoundary = FALSE; - tileX = 0; - } - else if(mbY != pSC->cRow && tileX < pSC->WMISCP.cNumOfSliceMinus1V && pSC->cRow == pSC->WMISCP.uiTileX[tileX + 1]) { - bHoriTileBoundary = TRUE; - tileX++; - } - else if(mbY != pSC->cRow) - bHoriTileBoundary = FALSE; - } - else { - bVertTileBoundary = FALSE; - bHoriTileBoundary = FALSE; - bOneMBLeftVertTB = FALSE; - bOneMBRightVertTB = FALSE; - } - mbX = pSC->cColumn, mbY = pSC->cRow; - - //================================================================ - // 400_Y, 444_YUV - for(i = 0; i < iNumChromaFullPlanes; ++i) - { - PixelI* const p0 = pSC->p0MBbuffer[i];//(0 == i ? pSC->pY0 : (1 == i ? pSC->pU0 : pSC->pV0)); - PixelI* const p1 = pSC->p1MBbuffer[i];//(0 == i ? pSC->pY1 : (1 == i ? pSC->pU1 : pSC->pV1)); - - //================================ - // first level overlap - if(OL_NONE != olOverlap) - { - /* Corner operations */ - if ((top || bHoriTileBoundary) && (left || bVertTileBoundary)) - strPre4(p1 + 0, p1 + 1, p1 + 2, p1 + 3); - if ((top || bHoriTileBoundary) && (right || bVertTileBoundary)) - strPre4(p1 - 59, p1 - 60, p1 - 57, p1 - 58); - if ((bottom || bHoriTileBoundary) && (left || bVertTileBoundary)) - strPre4(p0 + 48 + 10, p0 + 48 + 11, p0 + 48 + 8, p0 + 48 + 9); - if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary)) - strPre4(p0 - 1, p0 - 2, p0 - 3, p0 - 4); - if(!right && !bottom) - { - if (top || bHoriTileBoundary) - { - - for (j = ((left || bVertTileBoundary) ? 0 : -64); j < 192; j += 64) - { - p = p1 + j; - strPre4(p + 5, p + 4, p + 64, p + 65); - strPre4(p + 7, p + 6, p + 66, p + 67); - p = NULL; - } - } - else - { - for (j = ((left || bVertTileBoundary) ? 0 : -64); j < 192; j += 64) - { - strPre4x4Stage1Split(p0 + 48 + j, p1 + j, 0); - } - } - - if (left || bVertTileBoundary) - { - if (!top && !bHoriTileBoundary) - { - strPre4(p0 + 58, p0 + 56, p1 + 0, p1 + 2); - strPre4(p0 + 59, p0 + 57, p1 + 1, p1 + 3); - } - - for (j = -64; j < -16; j += 16) - { - p = p1 + j; - strPre4(p + 74, p + 72, p + 80, p + 82); - strPre4(p + 75, p + 73, p + 81, p + 83); - p = NULL; - } - } - else - { - for (j = -64; j < -16; j += 16) - { - strPre4x4Stage1(p1 + j, 0); - } - } - - strPre4x4Stage1(p1 + 0, 0); - strPre4x4Stage1(p1 + 16, 0); - strPre4x4Stage1(p1 + 32, 0); - strPre4x4Stage1(p1 + 64, 0); - strPre4x4Stage1(p1 + 80, 0); - strPre4x4Stage1(p1 + 96, 0); - strPre4x4Stage1(p1 + 128, 0); - strPre4x4Stage1(p1 + 144, 0); - strPre4x4Stage1(p1 + 160, 0); - } - - if (bottom || bHoriTileBoundary) - { - for (j = ((left || bVertTileBoundary) ? 48 : -16); j < (right ? -16 : 240); j += 64) - { - p = p0 + j; - strPre4(p + 15, p + 14, p + 74, p + 75); - strPre4(p + 13, p + 12, p + 72, p + 73); - p = NULL; - } - } - - if ((right || bVertTileBoundary) && !bottom) - { - if (!top && !bHoriTileBoundary) - { - strPre4(p0 - 1, p0 - 3, p1 - 59, p1 - 57); - strPre4(p0 - 2, p0 - 4, p1 - 60, p1 - 58); - } - for (j = -64; j < -16; j += 16) - { - p = p1 + j; - strPre4(p + 15, p + 13, p + 21, p + 23); - strPre4(p + 14, p + 12, p + 20, p + 22); - p = NULL; - } - } - } - - //================================ - // first level transform - if (!top) - { - for (j = (left ? 48 : -16); j < (right ? 48 : 240); j += 64) - { - strDCT4x4Stage1(p0 + j); - } - } - - if (!bottom) - { - for (j = (left ? 0 : -64); j < (right ? 0 : 192); j += 64) - { - strDCT4x4Stage1(p1 + j + 0); - strDCT4x4Stage1(p1 + j + 16); - strDCT4x4Stage1(p1 + j + 32); - } - } - - //================================ - // second level overlap - if (OL_TWO == olOverlap) - { - /* Corner operations */ - if ((top || bHoriTileBoundary) && (left || bVertTileBoundary)) - strPre4(p1 + 0, p1 + 64, p1 + 0 + 16, p1 + 64 + 16); - if ((top || bHoriTileBoundary) && (right || bVertTileBoundary)) - strPre4(p1 - 128, p1 - 64, p1 - 128 + 16, p1 - 64 + 16); - if ((bottom || bHoriTileBoundary) && (left || bVertTileBoundary)) - strPre4(p0 + 32, p0 + 96, p0 + 32 + 16, p0 + 96 + 16); - if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary)) - strPre4(p0 - 96, p0 - 32, p0 - 96 + 16, p0 - 32 + 16); - if ((leftORright || bVertTileBoundary) && (!topORbottom && !bHoriTileBoundary)) - { - if (left || bVertTileBoundary) { - j = 0; - strPre4(p0 + j + 32, p0 + j + 48, p1 + j + 0, p1 + j + 16); - strPre4(p0 + j + 96, p0 + j + 112, p1 + j + 64, p1 + j + 80); - } - if (right || bVertTileBoundary) { - j = -128; - strPre4(p0 + j + 32, p0 + j + 48, p1 + j + 0, p1 + j + 16); - strPre4(p0 + j + 96, p0 + j + 112, p1 + j + 64, p1 + j + 80); - } - } - - if (!leftORright && !bVertTileBoundary) - { - if (topORbottom || bHoriTileBoundary) - { - if (top || bHoriTileBoundary) { - p = p1; - strPre4(p - 128, p - 64, p + 0, p + 64); - strPre4(p - 112, p - 48, p + 16, p + 80); - p = NULL; - } - if (bottom || bHoriTileBoundary) { - p = p0 + 32; - strPre4(p - 128, p - 64, p + 0, p + 64); - strPre4(p - 112, p - 48, p + 16, p + 80); - p = NULL; - } - } - else - { - strPre4x4Stage2Split(p0, p1); - } - } - } - - //================================ - // second level transform - if (!topORleft){ - if (pSC->m_param.bScaledArith) { - strNormalizeEnc(p0 - 256, (i != 0)); - } - strDCT4x4SecondStage(p0 - 256); - } - } - - //================================================================ - // 420_UV - for(i = 0; i < (YUV_420 == cfColorFormat? 2 : 0); ++i) - { - PixelI* const p0 = pSC->p0MBbuffer[1 + i];//(0 == i ? pSC->pU0 : pSC->pV0); - PixelI* const p1 = pSC->p1MBbuffer[1 + i];//(0 == i ? pSC->pU1 : pSC->pV1); - - //================================ - // first level overlap (420_UV) - if (OL_NONE != olOverlap) - { - /* Corner operations */ - if ((top || bHoriTileBoundary) && (left || bVertTileBoundary)) - strPre4(p1 + 0, p1 + 1, p1 + 2, p1 + 3); - if ((top || bHoriTileBoundary) && (right || bVertTileBoundary)) - strPre4(p1 - 27, p1 - 28, p1 - 25, p1 - 26); - if ((bottom || bHoriTileBoundary) && (left || bVertTileBoundary)) - strPre4(p0 + 16 + 10, p0 + 16 + 11, p0 + 16 + 8, p0 + 16 + 9); - if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary)) - strPre4(p0 - 1, p0 - 2, p0 - 3, p0 - 4); - if(!right && !bottom) - { - if (top || bHoriTileBoundary) - { - - for (j = ((left || bVertTileBoundary) ? 0 : -32); j < 32; j += 32) - { - p = p1 + j; - strPre4(p + 5, p + 4, p + 32, p + 33); - strPre4(p + 7, p + 6, p + 34, p + 35); - p = NULL; - } - } - else - { - for (j = ((left || bVertTileBoundary) ? 0: -32); j < 32; j += 32) - { - strPre4x4Stage1Split(p0 + 16 + j, p1 + j, 32); - } - } - - if (left || bVertTileBoundary) - { - if (!top && !bHoriTileBoundary) - { - strPre4(p0 + 26, p0 + 24, p1 + 0, p1 + 2); - strPre4(p0 + 27, p0 + 25, p1 + 1, p1 + 3); - } - - strPre4(p1 + 10, p1 + 8, p1 + 16, p1 + 18); - strPre4(p1 + 11, p1 + 9, p1 + 17, p1 + 19); - } - else if (!bVertTileBoundary) - { - strPre4x4Stage1(p1 - 32, 32); - } - - strPre4x4Stage1(p1, 32); - } - - if (bottom || bHoriTileBoundary) - { - for (j = ((left || bVertTileBoundary) ? 16: -16); j < (right ? -16: 32); j += 32) - { - p = p0 + j; - strPre4(p + 15, p + 14, p + 42, p + 43); - strPre4(p + 13, p + 12, p + 40, p + 41); - p = NULL; - } - } - - if ((right || bVertTileBoundary) && !bottom) - { - if (!top && !bHoriTileBoundary) - { - strPre4(p0 - 1, p0 - 3, p1 - 27, p1 - 25); - strPre4(p0 - 2, p0 - 4, p1 - 28, p1 - 26); - } - - strPre4(p1 - 17, p1 - 19, p1 - 11, p1 - 9); - strPre4(p1 - 18, p1 - 20, p1 - 12, p1 - 10); - } - } - - //================================ - // first level transform (420_UV) - if (!top) - { - for (j = (left ? 16 : -16); j < (right ? 16 : 48); j += 32) - { - strDCT4x4Stage1(p0 + j); - } - } - - if (!bottom) - { - for (j = (left ? 0 : -32); j < (right ? 0 : 32); j += 32) - { - strDCT4x4Stage1(p1 + j); - } - } - - //================================ - // second level overlap (420_UV) - if (OL_TWO == olOverlap) - { - if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_DIFF(p1 - 64 + 0, *(p1 - 64 + 32)); - - if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary)) - iPredBefore[i][0] = *(p1 + 0); - if ((right || bVertTileBoundary) && (top || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_DIFF(p1 - 64 + 32, iPredBefore[i][0]); - - if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_DIFF(p0 - 64 + 16, *(p0 - 64 + 48)); - - if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) - iPredBefore[i][1] = *(p0 + 16); - if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_DIFF(p0 - 64 + 48, iPredBefore[i][1]); - - if ((leftORright || bVertTileBoundary) && !topORbottom && !bHoriTileBoundary) - { - if (left || bVertTileBoundary) - strPre2(p0 + 0 + 16, p1 + 0); - if (right || bVertTileBoundary) - strPre2(p0 + -32 + 16, p1 + -32); - } - - if (!leftORright) - { - if ((topORbottom || bHoriTileBoundary) && !bVertTileBoundary) - { - if (top || bHoriTileBoundary) - strPre2(p1 - 32, p1); - if (bottom || bHoriTileBoundary) - strPre2(p0 + 16 - 32, p0 + 16); - } - else if (!topORbottom && !bHoriTileBoundary && !bVertTileBoundary) - strPre2x2(p0 - 16, p0 + 16, p1 - 32, p1); - } - if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_ADD(p1 - 64 + 0, *(p1 - 64 + 32)); - if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary)) - iPredAfter[i][0] = *(p1 + 0); - if ((right || bVertTileBoundary) && (top || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_ADD(p1 - 64 + 32, iPredAfter[i][0]); - if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_ADD(p0 - 64 + 16, *(p0 - 64 + 48)); - if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) - iPredAfter[i][1] = *(p0 + 16); - if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_ADD(p0 - 64 + 48, iPredAfter[i][1]); - } - - //================================ - // second level transform (420_UV) - if (!topORleft) - { - if (!pSC->m_param.bScaledArith) { - strDCT2x2dn(p0 - 64, p0 - 32, p0 - 48, p0 - 16); - } - else { - strDCT2x2dnEnc(p0 - 64, p0 - 32, p0 - 48, p0 - 16); - } - } - } - - //================================================================ - // 422_UV - for(i = 0; i < (YUV_422 == cfColorFormat? 2 : 0); ++i) - { - PixelI* const p0 = pSC->p0MBbuffer[1 + i];//(0 == i ? pSC->pU0 : pSC->pV0); - PixelI* const p1 = pSC->p1MBbuffer[1 + i];//(0 == i ? pSC->pU1 : pSC->pV1); - - //================================ - // first level overlap (422_UV) - if (OL_NONE != olOverlap) - { - /* Corner operations */ - if ((top || bHoriTileBoundary) && (left || bVertTileBoundary)) - strPre4(p1 + 0, p1 + 1, p1 + 2, p1 + 3); - if ((top || bHoriTileBoundary) && (right || bVertTileBoundary)) - strPre4(p1 - 59, p1 - 60, p1 - 57, p1 - 58); - if ((bottom || bHoriTileBoundary) && (left || bVertTileBoundary)) - strPre4(p0 + 48 + 10, p0 + 48 + 11, p0 + 48 + 8, p0 + 48 + 9); - if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary)) - strPre4(p0 - 1, p0 - 2, p0 - 3, p0 - 4); - if(!right && !bottom) - { - if (top || bHoriTileBoundary) - { - - for (j = ((left || bVertTileBoundary) ? 0 : -64); j < 64; j += 64) - { - p = p1 + j; - strPre4(p + 5, p + 4, p + 64, p + 65); - strPre4(p + 7, p + 6, p + 66, p + 67); - p = NULL; - } - } - else - { - for (j = ((left || bVertTileBoundary) ? 0: -64); j < 64; j += 64) - { - strPre4x4Stage1Split(p0 + 48 + j, p1 + j, 0); - } - } - - if (left || bVertTileBoundary) - { - if (!top && !bHoriTileBoundary) - { - strPre4(p0 + 58, p0 + 56, p1 + 0, p1 + 2); - strPre4(p0 + 59, p0 + 57, p1 + 1, p1 + 3); - } - - for (j = 0; j < 48; j += 16) - { - p = p1 + j; - strPre4(p + 10, p + 8, p + 16, p + 18); - strPre4(p + 11, p + 9, p + 17, p + 19); - p = NULL; - } - } - else if (!bVertTileBoundary) - { - for (j = -64; j < -16; j += 16) - { - strPre4x4Stage1(p1 + j, 0); - } - } - - strPre4x4Stage1(p1 + 0, 0); - strPre4x4Stage1(p1 + 16, 0); - strPre4x4Stage1(p1 + 32, 0); - } - - if (bottom || bHoriTileBoundary) - { - for (j = ((left || bVertTileBoundary) ? 48: -16); j < (right ? -16: 112); j += 64) - { - p = p0 + j; - strPre4(p + 15, p + 14, p + 74, p + 75); - strPre4(p + 13, p + 12, p + 72, p + 73); - p = NULL; - } - } - - if ((right || bVertTileBoundary) && !bottom) - { - if (!top && !bHoriTileBoundary) - { - strPre4(p0 - 1, p0 - 3, p1 - 59, p1 - 57); - strPre4(p0 - 2, p0 - 4, p1 - 60, p1 - 58); - } - - for (j = -64; j < -16; j += 16) - { - p = p1 + j; - strPre4(p + 15, p + 13, p + 21, p + 23); - strPre4(p + 14, p + 12, p + 20, p + 22); - p = NULL; - } - } - } - - //================================ - // first level transform (422_UV) - if (!top) - { - for (j = (left ? 48 : -16); j < (right ? 48 : 112); j += 64) - { - strDCT4x4Stage1(p0 + j); - } - } - - if (!bottom) - { - for (j = (left ? 0 : -64); j < (right ? 0 : 64); j += 64) - { - strDCT4x4Stage1(p1 + j + 0); - strDCT4x4Stage1(p1 + j + 16); - strDCT4x4Stage1(p1 + j + 32); - } - } - - //================================ - // second level overlap (422_UV) - if (OL_TWO == olOverlap) - { - if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_DIFF(p1 - 128 + 0, *(p1 - 128 + 64)); - - if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary)) - iPredBefore[i][0] = *(p1 + 0); - if ((right || bVertTileBoundary) && (top || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_DIFF(p1 - 128 + 64, iPredBefore[i][0]); - - if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_DIFF(p0 - 128 + 48, *(p0 - 128 + 112)); - - if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) - iPredBefore[i][1] = *(p0 + 48); - if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_DIFF(p0 - 128 + 112, iPredBefore[i][1]); - - if (!bottom) - { - if (leftORright || bVertTileBoundary) - { - if (!top && !bHoriTileBoundary) - { - if (left || bVertTileBoundary) - strPre2(p0 + 48 + 0, p1 + 0); - - if (right || bVertTileBoundary) - strPre2(p0 + 48 + -64, p1 + -64); - } - - if (left || bVertTileBoundary) - strPre2(p1 + 16, p1 + 16 + 16); - - if (right || bVertTileBoundary) - strPre2(p1 + -48, p1 + -48 + 16); - } - - if (!leftORright && !bVertTileBoundary) - { - if (top || bHoriTileBoundary) - strPre2(p1 - 64, p1); - else - strPre2x2(p0 - 16, p0 + 48, p1 - 64, p1); - - strPre2x2(p1 - 48, p1 + 16, p1 - 32, p1 + 32); - } - } - - if ((bottom || bHoriTileBoundary) && (!leftORright && !bVertTileBoundary)) - strPre2(p0 - 16, p0 + 48); - - if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_ADD(p1 - 128 + 0, *(p1 - 128 + 64)); - - if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary)) - iPredAfter[i][0] = *(p1 + 0); - if ((right || bVertTileBoundary) && (top || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_ADD(p1 - 128 + 64, iPredAfter[i][0]); - - if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_ADD(p0 - 128 + 48, *(p0 - 128 + 112)); - - if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) - iPredAfter[i][1] = *(p0 + 48); - if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_ADD(p0 - 128 + 112, iPredAfter[i][1]); - } - - //================================ - // second level transform (422_UV) - if (!topORleft) - { - if (!pSC->m_param.bScaledArith) { - strDCT2x2dn(p0 - 128, p0 - 64, p0 - 112, p0 - 48); - strDCT2x2dn(p0 - 96, p0 - 32, p0 - 80, p0 - 16); - } - else { - strDCT2x2dnEnc(p0 - 128, p0 - 64, p0 - 112, p0 - 48); - strDCT2x2dnEnc(p0 - 96, p0 - 32, p0 - 80, p0 - 16); - } - - // 1D lossless HT - p0[- 96] -= p0[-128]; - p0[-128] += ((p0[-96] + 1) >> 1); - } - } - assert(NULL == p); -} - diff --git a/Src/JxrDecode/Jxr/strInvTransform.c b/Src/JxrDecode/Jxr/strInvTransform.c deleted file mode 100644 index 7cd982a2..00000000 --- a/Src/JxrDecode/Jxr/strInvTransform.c +++ /dev/null @@ -1,1888 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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" -#include "strcodec.h" -#include "decode.h" - -/** rotation by -pi/8 **/ -#define IROTATE1(a, b) (a) -= (((b) + 1) >> 1), (b) += (((a) + 1) >> 1) // this works well too -#define IROTATE2(a, b) (a) -= (((b)*3 + 4) >> 3), (b) += (((a)*3 + 4) >> 3) // this works well too - -/** local functions **/ -static Void invOddOdd(PixelI *, PixelI *, PixelI *, PixelI *); -static Void invOddOddPost(PixelI *, PixelI *, PixelI *, PixelI *); -static Void invOdd(PixelI *, PixelI *, PixelI *, PixelI *); -static Void strHSTdec(PixelI *, PixelI *, PixelI *, PixelI *); -static Void strHSTdec1(PixelI *, PixelI *); -static Void strHSTdec1_alternate(PixelI *, PixelI *); -static Void strHSTdec1_edge(PixelI *pa, PixelI *pd); - -/** IDCT stuff **/ -/** reordering should be combined with zigzag scan **/ -/** data order before IDCT **/ -/** 0 8 4 6 **/ -/** 2 10 14 12 **/ -/** 1 11 15 13 **/ -/** 9 3 7 5 **/ -/** data order after IDCT **/ -/** 0 1 2 3 **/ -/** 4 5 6 7 **/ -/** 8 9 10 11 **/ -/** 12 13 14 15 **/ -Void strIDCT4x4Stage1(PixelI* p) -{ - /** top left corner, butterfly => butterfly **/ - strDCT2x2up(p + 0, p + 1, p + 2, p + 3); - - /** top right corner, -pi/8 rotation => butterfly **/ - invOdd(p + 5, p + 4, p + 7, p + 6); - - /** bottom left corner, butterfly => -pi/8 rotation **/ - invOdd(p + 10, p + 8, p + 11, p + 9); - - /** bottom right corner, -pi/8 rotation => -pi/8 rotation **/ - invOddOdd(p + 15, p + 14, p + 13, p + 12); - - /** butterfly **/ - //FOURBUTTERFLY(p, 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15); - FOURBUTTERFLY_HARDCODED1(p); -} - -Void strIDCT4x4Stage2(PixelI* p) -{ - /** bottom left corner, butterfly => -pi/8 rotation **/ - invOdd(p + 32, p + 48, p + 96, p + 112); - - /** top right corner, -pi/8 rotation => butterfly **/ - invOdd(p + 128, p + 192, p + 144, p + 208); - - /** bottom right corner, -pi/8 rotation => -pi/8 rotation **/ - invOddOdd(p + 160, p + 224, p + 176, p + 240); - - /** top left corner, butterfly => butterfly **/ - strDCT2x2up(p + 0, p + 64, p + 16, p + 80); - - /** butterfly **/ - FOURBUTTERFLY(p, 0, 192, 48, 240, 64, 128, 112, 176, 16, 208, 32, 224, 80, 144, 96, 160); -} - -Void strNormalizeDec(PixelI* p, Bool bChroma) -{ - int i; - if (!bChroma) { - //for (i = 0; i < 256; i += 16) { - // p[i] <<= 2; - //} - } - else { - for (i = 0; i < 256; i += 16) { - p[i] += p[i]; - } - } -} - -/** 2x2 DCT with post-scaling - for use on decoder side **/ -Void strDCT2x2dnDec(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 * 2; - *pb = b * 2; - *pc = c * 2; - *pd = d * 2; -} - - -/** post filter stuff **/ -/** 2-point post for boundaries **/ -Void strPost2(PixelI * a, PixelI * b) -{ - *b += ((*a + 4) >> 3); - *a += ((*b + 2) >> 2); - *b += ((*a + 4) >> 3); -} - -Void strPost2_alternate(PixelI * pa, PixelI * pb) -{ - PixelI a, b; - a = *pa; - b = *pb; - - /** rotate **/ - b += ((a + 2) >> 2); - a += ((b + 1) >> 1); - a += (b >> 5); - a += (b >> 9); - a += (b >> 13); - - b += ((a + 2) >> 2); - - *pa = a; - *pb = b; -} - -Void strPost2x2(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd) -{ - PixelI a, b, c, d; - a = *pa; - b = *pb; - c = *pc; - d = *pd; - - /** butterflies **/ - a += d; - b += c; - d -= (a + 1) >> 1; - c -= (b + 1) >> 1; - - /** rotate **/ - b += ((a + 2) >> 2); - a += ((b + 1) >> 1); - b += ((a + 2) >> 2); - - /** butterflies **/ - d += (a + 1) >> 1; - c += (b + 1) >> 1; - a -= d; - b -= c; - - *pa = a; - *pb = b; - *pc = c; - *pd = d; -} - -Void strPost2x2_alternate(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd) -{ - PixelI a, b, c, d; - a = *pa; - b = *pb; - c = *pc; - d = *pd; - - /** butterflies **/ - a += d; - b += c; - d -= (a + 1) >> 1; - c -= (b + 1) >> 1; - - /** rotate **/ - b += ((a + 2) >> 2); - a += ((b + 1) >> 1); - a += (b >> 5); - a += (b >> 9); - a += (b >> 13); - b += ((a + 2) >> 2); - - /** butterflies **/ - d += (a + 1) >> 1; - c += (b + 1) >> 1; - a -= d; - b -= c; - - *pa = a; - *pb = b; - *pc = c; - *pd = d; -} - -/** 4-point post for boundaries **/ -Void strPost4(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd) -{ - PixelI a, b, c, d; - a = *pa; - b = *pb; - c = *pc; - d = *pd; - - a += d, b += c; - d -= ((a + 1) >> 1), c -= ((b + 1) >> 1); - - IROTATE1(c, d); - - d += ((a + 1) >> 1), c += ((b + 1) >> 1); - a -= d - ((d * 3 + 16) >> 5), b -= c - ((c * 3 + 16) >> 5); - d += ((a * 3 + 8) >> 4), c += ((b * 3 + 8) >> 4); - a += ((d * 3 + 16) >> 5), b += ((c * 3 + 16) >> 5); - - *pa = a; - *pb = b; - *pc = c; - *pd = d; -} - -Void strPost4_alternate(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd) -{ - PixelI a, b, c, d; - a = *pa; - b = *pb; - c = *pc; - d = *pd; - - a += d, b += c; - d -= ((a + 1) >> 1), c -= ((b + 1) >> 1); - - strHSTdec1_edge(&a, &d); strHSTdec1_edge(&b, &c); - IROTATE1(c, d); - d += ((a + 1) >> 1), c += ((b + 1) >> 1); - - a -= d, b -= c; - - *pa = a; - *pb = b; - *pc = c; - *pd = d; -} - -/***************************************************************************************** - Input data offsets: - (15)(14)|(10+64)(11+64) p0 (15)(14)|(74)(75) - (13)(12)|( 8+64)( 9+64) (13)(12)|(72)(73) - --------+-------------- --------+-------- - ( 5)( 4)|( 0+64) (1+64) p1 ( 5)( 4)|(64)(65) - ( 7)( 6)|( 2+64) (3+64) ( 7)( 6)|(66)(67) -*****************************************************************************************/ -Void DCCompensate (PixelI *a, PixelI *b, PixelI *c, PixelI *d, int iDC) -{ - iDC = iDC>>1; - *a -= iDC; - *d -= iDC; - *b += iDC; - *c += iDC; -} - -#ifndef max -#define max(a,b) (((a) > (b)) ? (a) : (b)) -#endif - -#ifndef min -#define min(a,b) (((a) < (b)) ? (a) : (b)) -#endif - -int ClipDCL(int iDCL, int iAltDCL) -{ - int iClipDCL = 0; - if (iDCL > 0) { - if (iAltDCL > 0) - iClipDCL = min(iDCL, iAltDCL); - else - iClipDCL = 0; - } - else if (iDCL < 0) { - if (iAltDCL < 0) - iClipDCL = max(iDCL, iAltDCL); - else - iClipDCL = 0; - } - return iClipDCL; -} - -Void strPost4x4Stage1Split(PixelI *p0, PixelI *p1, Int iOffset, Int iHPQP, Bool bHPAbsent) -{ - int iDCLAlt1, iDCLAlt2, iDCLAlt3, iDCLAlt0; - int iDCL1, iDCL2, iDCL3, iDCL0; - int iTmp1, iTmp2, iTmp3, iTmp0; - - PixelI *p2 = p0 + 72 - iOffset; - PixelI *p3 = p1 + 64 - iOffset; - p0 += 12; - p1 += 4; - - /** buttefly **/ - strDCT2x2dn(p0 + 0, p2 + 0, p1 + 0, p3 + 0); - strDCT2x2dn(p0 + 1, p2 + 1, p1 + 1, p3 + 1); - strDCT2x2dn(p0 + 2, p2 + 2, p1 + 2, p3 + 2); - strDCT2x2dn(p0 + 3, p2 + 3, p1 + 3, p3 + 3); - - /** bottom right corner: -pi/8 rotation => -pi/8 rotation **/ - invOddOddPost(p3 + 0, p3 + 1, p3 + 2, p3 + 3); - - /** anti diagonal corners: rotation by -pi/8 **/ - IROTATE1(p1[2], p1[3]); - IROTATE1(p1[0], p1[1]); - IROTATE1(p2[1], p2[3]); - IROTATE1(p2[0], p2[2]); - - /** butterfly **/ - strHSTdec1(p0 + 0, p3 + 0); - strHSTdec1(p0 + 1, p3 + 1); - strHSTdec1(p0 + 2, p3 + 2); - strHSTdec1(p0 + 3, p3 + 3); - strHSTdec(p0 + 0, p2 + 0, p1 + 0, p3 + 0); - strHSTdec(p0 + 1, p2 + 1, p1 + 1, p3 + 1); - strHSTdec(p0 + 2, p2 + 2, p1 + 2, p3 + 2); - strHSTdec(p0 + 3, p2 + 3, p1 + 3, p3 + 3); - - iTmp0 = (*(p0 +0) + *(p1 +0) + *(p2 +0) + *(p3 +0))>>1; - iTmp1 = (*(p0 +1) + *(p1 +1) + *(p2 +1) + *(p3 +1))>>1; - iTmp2 = (*(p0 +2) + *(p1 +2) + *(p2 +2) + *(p3 +2))>>1; - iTmp3 = (*(p0 +3) + *(p1 +3) + *(p2 +3) + *(p3 +3))>>1; - iDCL0 = (iTmp0 * 595 + 65536)>>17; //Approximating 27/5947 - iDCL1 = (iTmp1 * 595 + 65536)>>17; - iDCL2 = (iTmp2 * 595 + 65536)>>17; - iDCL3 = (iTmp3 * 595 + 65536)>>17; - if ((abs(iDCL0) < iHPQP && iHPQP > 20) || bHPAbsent) { - iDCLAlt0 = (*(p0 +0) - *(p1 +0) - *(p2 +0) + *(p3 +0))>>1; - iDCL0 = ClipDCL (iDCL0, iDCLAlt0); - DCCompensate (p0 + 0, p2 + 0, p1 + 0, p3 + 0, iDCL0); - } - if ((abs(iDCL1) < iHPQP && iHPQP > 20) || bHPAbsent) { - iDCLAlt1 = (*(p0 +1) - *(p1 +1) - *(p2 +1) + *(p3 +1))>>1; - iDCL1 = ClipDCL (iDCL1, iDCLAlt1); - DCCompensate (p0 + 1, p2 + 1, p1 + 1, p3 + 1, iDCL1); - } - if ((abs(iDCL2) < iHPQP && iHPQP > 20) || bHPAbsent) { - iDCLAlt2 = (*(p0 +2) - *(p1 +2) - *(p2 +2) + *(p3 +2))>>1; - iDCL2 = ClipDCL (iDCL2, iDCLAlt2); - DCCompensate (p0 + 2, p2 + 2, p1 + 2, p3 + 2, iDCL2); - } - if ((abs(iDCL3) < iHPQP && iHPQP > 20) || bHPAbsent) { - iDCLAlt3 = (*(p0 +3) - *(p1 +3) - *(p2 +3) + *(p3 +3))>>1; - iDCL3 = ClipDCL (iDCL3, iDCLAlt3); - DCCompensate (p0 + 3, p2 + 3, p1 + 3, p3 + 3, iDCL3); - } -} - -Void strPost4x4Stage1(PixelI* p, Int iOffset, Int iHPQP, Bool bHPAbsent) -{ - strPost4x4Stage1Split(p, p + 16, iOffset, iHPQP, bHPAbsent); -} - -Void strPost4x4Stage1Split_alternate(PixelI *p0, PixelI *p1, Int iOffset) -{ - PixelI *p2 = p0 + 72 - iOffset; - PixelI *p3 = p1 + 64 - iOffset; - p0 += 12; - p1 += 4; - - /** buttefly **/ - strDCT2x2dn(p0 + 0, p2 + 0, p1 + 0, p3 + 0); - strDCT2x2dn(p0 + 1, p2 + 1, p1 + 1, p3 + 1); - strDCT2x2dn(p0 + 2, p2 + 2, p1 + 2, p3 + 2); - strDCT2x2dn(p0 + 3, p2 + 3, p1 + 3, p3 + 3); - - /** bottom right corner: -pi/8 rotation => -pi/8 rotation **/ - invOddOddPost(p3 + 0, p3 + 1, p3 + 2, p3 + 3); - - /** anti diagonal corners: rotation by -pi/8 **/ - IROTATE1(p1[2], p1[3]); - IROTATE1(p1[0], p1[1]); - IROTATE1(p2[1], p2[3]); - IROTATE1(p2[0], p2[2]); - - /** butterfly **/ - strHSTdec1_alternate(p0 + 0, p3 + 0); - strHSTdec1_alternate(p0 + 1, p3 + 1); - strHSTdec1_alternate(p0 + 2, p3 + 2); - strHSTdec1_alternate(p0 + 3, p3 + 3); - strHSTdec(p0 + 0, p2 + 0, p1 + 0, p3 + 0); - strHSTdec(p0 + 1, p2 + 1, p1 + 1, p3 + 1); - strHSTdec(p0 + 2, p2 + 2, p1 + 2, p3 + 2); - strHSTdec(p0 + 3, p2 + 3, p1 + 3, p3 + 3); -} - -Void strPost4x4Stage1_alternate(PixelI* p, Int iOffset) -{ - strPost4x4Stage1Split_alternate(p, p + 16, iOffset); -} - -/***************************************************************************************** - Input data offsets: - (15)(14)|(10+32)(11+32) p0 (15)(14)|(42)(43) - (13)(12)|( 8+32)( 9+32) (13)(12)|(40)(41) - --------+-------------- --------+-------- - ( 5)( 4)|( 0+32) (1+32) p1 ( 5)( 4)|(32)(33) - ( 7)( 6)|( 2+32) (3+32) ( 7)( 6)|(34)(35) -*****************************************************************************************/ - -/***************************************************************************************** - Input data offsets: - ( -96)(-32)|(32)( 96) p0 - ( -80)(-16)|(48)(112) - -----------+------------ - (-128)(-64)|( 0)( 64) p1 - (-112)(-48)|(16)( 80) -*****************************************************************************************/ -Void strPost4x4Stage2Split(PixelI* p0, PixelI* p1) -{ - /** buttefly **/ - strDCT2x2dn(p0 - 96, p0 + 96, p1 - 112, p1 + 80); - strDCT2x2dn(p0 - 32, p0 + 32, p1 - 48, p1 + 16); - strDCT2x2dn(p0 - 80, p0 + 112, p1 - 128, p1 + 64); - strDCT2x2dn(p0 - 16, p0 + 48, p1 - 64, p1 + 0); - - /** bottom right corner: -pi/8 rotation => -pi/8 rotation **/ - invOddOddPost(p1 + 0, p1 + 64, p1 + 16, p1 + 80); - - /** anti diagonal corners: rotation by -pi/8 **/ - IROTATE1(p0[ 48], p0[ 32]); - IROTATE1(p0[112], p0[ 96]); - IROTATE1(p1[-64], p1[-128]); - IROTATE1(p1[-48], p1[-112]); - - /** butterfly **/ - strHSTdec1(p0 - 96, p1 + 80); - strHSTdec1(p0 - 32, p1 + 16); - strHSTdec1(p0 - 80, p1 + 64); - strHSTdec1(p0 - 16, p1 + 0); - - strHSTdec(p0 - 96, p1 - 112, p0 + 96, p1 + 80); - strHSTdec(p0 - 32, p1 - 48, p0 + 32, p1 + 16); - strHSTdec(p0 - 80, p1 - 128, p0 + 112, p1 + 64); - strHSTdec(p0 - 16, p1 - 64, p0 + 48, p1 + 0); -} - -Void strPost4x4Stage2Split_alternate(PixelI* p0, PixelI* p1) -{ - /** buttefly **/ - strDCT2x2dn(p0 - 96, p0 + 96, p1 - 112, p1 + 80); - strDCT2x2dn(p0 - 32, p0 + 32, p1 - 48, p1 + 16); - strDCT2x2dn(p0 - 80, p0 + 112, p1 - 128, p1 + 64); - strDCT2x2dn(p0 - 16, p0 + 48, p1 - 64, p1 + 0); - - /** bottom right corner: -pi/8 rotation => -pi/8 rotation **/ - invOddOddPost(p1 + 0, p1 + 64, p1 + 16, p1 + 80); - - /** anti diagonal corners: rotation by -pi/8 **/ - IROTATE1(p0[ 48], p0[ 32]); - IROTATE1(p0[112], p0[ 96]); - IROTATE1(p1[-64], p1[-128]); - IROTATE1(p1[-48], p1[-112]); - - /** butterfly **/ - strHSTdec1_alternate(p0 - 96, p1 + 80); - strHSTdec1_alternate(p0 - 32, p1 + 16); - strHSTdec1_alternate(p0 - 80, p1 + 64); - strHSTdec1_alternate(p0 - 16, p1 + 0); - - strHSTdec(p0 - 96, p1 - 112, p0 + 96, p1 + 80); - strHSTdec(p0 - 32, p1 - 48, p0 + 32, p1 + 16); - strHSTdec(p0 - 80, p1 - 128, p0 + 112, p1 + 64); - strHSTdec(p0 - 16, p1 - 64, p0 + 48, p1 + 0); -} - -/** - Hadamard+Scale transform - for some strange reason, breaking up the function into two blocks, strHSTdec1 and strHSTdec - seems to work faster -**/ -static Void strHSTdec1(PixelI *pa, PixelI *pd) -{ - /** different realization : does rescaling as well! **/ - PixelI a, d; - a = *pa; - d = *pd; - - a += d; - d = (a >> 1) - d; - a += (d * 3 + 0) >> 3; - d += (a * 3 + 0) >> 4; - //a += (d * 3 + 4) >> 3; - - *pa = a; - *pd = d; -} - -static Void strHSTdec1_alternate(PixelI *pa, PixelI *pd) -{ - /** different realization : does rescaling as well! **/ - PixelI a, d; - a = *pa; - d = *pd; - - a += d; - d = (a >> 1) - d; - a += (d * 3 + 0) >> 3; - d += (a * 3 + 0) >> 4; - //a += (d * 3 + 4) >> 3; - - d += (a >> 7); - d -= (a >> 10); - - *pa = a; - *pd = d; -} - -static Void strHSTdec1_edge (PixelI *pa, PixelI *pd) -{ - /** different realization as compared to scaling operator for 2D case **/ - PixelI a, d; - a = *pa; - d = *pd; - - a += d; - d = (a >> 1) - d; - a += (d * 3 + 0) >> 3; - d += (a * 3 + 0) >> 4; - - //Scaling modification of adding 7/1024 in 2 steps (without multiplication by 7). - d += (a >> 7); - d -= (a >> 10); - - a += (d * 3 + 4) >> 3; - d -= (a >> 1); - a += d; - // End new operations - - *pa = a; - *pd = -d; // Negative sign needed here for 1D scaling case to ensure correct scaling. -} - -static Void strHSTdec(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd) -{ - /** different realization : does rescaling as well! **/ - PixelI a, b, c, d; - a = *pa; - b = *pb; - c = *pc; - d = *pd; - - b -= c; - a += (d * 3 + 4) >> 3; - - d -= (b >> 1); - c = ((a - b) >> 1) - c; - *pc = d; - *pd = c; - *pa = a - c, *pb = b + d; -} - -/** Kron(Rotate(pi/8), Rotate(pi/8)) **/ -static Void invOddOdd(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd) -{ - PixelI a, b, c, d, t1, t2; - a = *pa; - b = *pb; - c = *pc; - d = *pd; - - /** butterflies **/ - d += a; - c -= b; - a -= (t1 = d >> 1); - b += (t2 = c >> 1); - - /** rotate pi/4 **/ - a -= (b * 3 + 3) >> 3; - b += (a * 3 + 3) >> 2; - a -= (b * 3 + 4) >> 3; - - /** butterflies **/ - b -= t2; - a += t1; - c += b; - d -= a; - - /** sign flips **/ - *pa = a; - *pb = -b; - *pc = -c; - *pd = d; -} - -/** Kron(Rotate(pi/8), Rotate(pi/8)) **/ -static Void invOddOddPost(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd) -{ - PixelI a, b, c, d, t1, t2; - a = *pa; - b = *pb; - c = *pc; - d = *pd; - - /** butterflies **/ - d += a; - c -= b; - a -= (t1 = d >> 1); - b += (t2 = c >> 1); - - /** rotate pi/4 **/ - a -= (b * 3 + 6) >> 3; - b += (a * 3 + 2) >> 2; - a -= (b * 3 + 4) >> 3; - - /** butterflies **/ - b -= t2; - a += t1; - c += b; - d -= a; - - *pa = a; - *pb = b; - *pc = c; - *pd = d; -} - - -/** Kron(Rotate(-pi/8), [1 1; 1 -1]/sqrt(2)) **/ -/** [D C A B] => [a b c d] **/ -Void invOdd(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd) -{ - PixelI a, b, c, d; - a = *pa; - b = *pb; - c = *pc; - d = *pd; - - /** butterflies **/ - b += d; - a -= c; - d -= (b) >> 1; - c += (a + 1) >> 1; - - /** rotate pi/8 **/ - IROTATE2(a, b); - IROTATE2(c, d); - - /** butterflies **/ - c -= (b + 1) >> 1; - d = ((a + 1) >> 1) - d; - b += c; - a -= d; - - *pa = a; - *pb = b; - *pc = c; - *pd = d; -} - -/************************************************************************* - Top-level function to inverse tranform possible part of a macroblock -*************************************************************************/ -Int invTransformMacroblock(CWMImageStrCodec * pSC) -{ - const OVERLAP olOverlap = pSC->WMISCP.olOverlap; - const COLORFORMAT cfColorFormat = pSC->m_param.cfColorFormat; - // const BITDEPTH_BITS bdBitDepth = pSC->WMII.bdBitDepth; - const Bool left = (pSC->cColumn == 0), right = (pSC->cColumn == pSC->cmbWidth); - const Bool top = (pSC->cRow == 0), bottom = (pSC->cRow == pSC->cmbHeight); - const Bool topORbottom = (top || bottom), leftORright = (left || right); - const Bool topORleft = (top || left), bottomORright = (bottom || right); - const size_t mbWidth = pSC->cmbWidth, mbX = pSC->cColumn; - PixelI * p = NULL;// * pt = NULL; - size_t i; - const size_t iChannels = (cfColorFormat == YUV_420 || cfColorFormat == YUV_422) ? 1 : pSC->m_param.cNumChannels; - const size_t tScale = pSC->m_Dparam->cThumbnailScale; - Int j = 0; - - Int qp[MAX_CHANNELS], dcqp[MAX_CHANNELS], iStrength = (1 << pSC->WMII.cPostProcStrength); - // ERR_CODE result = ICERR_OK; - - Bool bHPAbsent = (pSC->WMISCP.sbSubband == SB_NO_HIGHPASS || pSC->WMISCP.sbSubband == SB_DC_ONLY); - - if(pSC->WMII.cPostProcStrength > 0){ - // threshold for post processing - for(i = 0; i < iChannels; i ++){ - qp[i] = pSC->pTile[pSC->cTileColumn].pQuantizerLP[i][pSC->MBInfo.iQIndexLP].iQP * iStrength * (olOverlap == OL_NONE ? 2 : 1); - dcqp[i] = pSC->pTile[pSC->cTileColumn].pQuantizerDC[i][0].iQP * iStrength; - } - - if(left) // a new MB row - slideOneMBRow(pSC->pPostProcInfo, pSC->m_param.cNumChannels, mbWidth, top, bottom); // previous current row becomes previous row - } - - //================================================================ - // 400_Y, 444_YUV - for (i = 0; i < iChannels && tScale < 16; ++i) - { - PixelI* const p0 = pSC->p0MBbuffer[i]; - PixelI* const p1 = pSC->p1MBbuffer[i]; - - Int iHPQP = 255; - if (!bHPAbsent) - iHPQP = pSC->pTile[pSC->cTileColumn].pQuantizerHP[i][pSC->MBInfo.iQIndexHP].iQP; - - //================================ - // second level inverse transform - if (!bottomORright) - { - if(pSC->WMII.cPostProcStrength > 0) - updatePostProcInfo(pSC->pPostProcInfo, p1, mbX, i); // update postproc info before IDCT - - strIDCT4x4Stage2(p1); - if (pSC->m_param.bScaledArith) { - strNormalizeDec(p1, (i != 0)); - } - } - - //================================ - // second level inverse overlap - if (OL_TWO == olOverlap) - { - if (leftORright && (!topORbottom)) - { - j = left ? 0 : -128; - strPost4(p0 + j + 32, p0 + j + 48, p1 + j + 0, p1 + j + 16); - strPost4(p0 + j + 96, p0 + j + 112, p1 + j + 64, p1 + j + 80); - } - - if (!leftORright) - { - if (topORbottom) - { - p = top ? p1 : p0 + 32; - strPost4(p - 128, p - 64, p + 0, p + 64); - strPost4(p - 112, p - 48, p + 16, p + 80); - p = NULL; - } - else - { - strPost4x4Stage2Split(p0, p1); - } - } - } - - if(pSC->WMII.cPostProcStrength > 0) - postProcMB(pSC->pPostProcInfo, p0, p1, mbX, i, dcqp[i]); // second stage deblocking - - //================================ - // first level inverse transform - if(tScale >= 4) // bypass first level transform for 4:1 and smaller thumbnail - continue; - - if (!top) - { - for (j = (left ? 32 : -96); j < (right ? 32 : 160); j += 64) - { - strIDCT4x4Stage1(p0 + j + 0); - strIDCT4x4Stage1(p0 + j + 16); - } - } - - if (!bottom) - { - for (j = (left ? 0 : -128); j < (right ? 0 : 128); j += 64) - { - strIDCT4x4Stage1(p1 + j + 0); - strIDCT4x4Stage1(p1 + j + 16); - } - } - - //================================ - // first level inverse overlap - if (OL_NONE != olOverlap) - { - if (leftORright) - { - j = left ? 0 + 10 : -64 + 14; - if (!top) - { - p = p0 + 16 + j; - strPost4(p + 0, p - 2, p + 6, p + 8); - strPost4(p + 1, p - 1, p + 7, p + 9); - strPost4(p + 16, p + 14, p + 22, p + 24); - strPost4(p + 17, p + 15, p + 23, p + 25); - p = NULL; - } - if (!bottom) - { - p = p1 + j; - strPost4(p + 0, p - 2, p + 6, p + 8); - strPost4(p + 1, p - 1, p + 7, p + 9); - p = NULL; - } - if (!topORbottom) - { - strPost4(p0 + 48 + j + 0, p0 + 48 + j - 2, p1 - 10 + j, p1 - 8 + j); - strPost4(p0 + 48 + j + 1, p0 + 48 + j - 1, p1 - 9 + j, p1 - 7 + j); - } - } - - if (top) - { - for (j = (left ? 0 : -192); j < (right ? -64 : 64); j += 64) - { - p = p1 + j; - strPost4(p + 5, p + 4, p + 64, p + 65); - strPost4(p + 7, p + 6, p + 66, p + 67); - p = NULL; - - strPost4x4Stage1(p1 + j, 0, iHPQP, bHPAbsent); - } - } - else if (bottom) - { - for (j = (left ? 0 : -192); j < (right ? -64 : 64); j += 64) - { - strPost4x4Stage1(p0 + 16 + j, 0, iHPQP, bHPAbsent); - strPost4x4Stage1(p0 + 32 + j, 0, iHPQP, bHPAbsent); - - p = p0 + 48 + j; - strPost4(p + 15, p + 14, p + 74, p + 75); - strPost4(p + 13, p + 12, p + 72, p + 73); - p = NULL; - } - } - else - { - for (j = (left ? 0 : -192); j < (right ? -64 : 64); j += 64) - { - strPost4x4Stage1(p0 + 16 + j, 0, iHPQP, bHPAbsent); - strPost4x4Stage1(p0 + 32 + j, 0, iHPQP, bHPAbsent); - strPost4x4Stage1Split(p0 + 48 + j, p1 + j, 0, iHPQP, bHPAbsent); - strPost4x4Stage1(p1 + j, 0, iHPQP, bHPAbsent); - } - } - } - - if(pSC->WMII.cPostProcStrength > 0 && (!topORleft)) - postProcBlock(pSC->pPostProcInfo, p0, p1, mbX, i, qp[i]); // destairing and first stage deblocking - } - - //================================================================ - // 420_UV - for (i = 0; i < (YUV_420 == cfColorFormat? 2U : 0U) && tScale < 16; ++i) - { - PixelI* const p0 = pSC->p0MBbuffer[1 + i];//(0 == i ? pSC->pU0 : pSC->pV0); - PixelI* const p1 = pSC->p1MBbuffer[1 + i];//(0 == i ? pSC->pU1 : pSC->pV1); - - Int iHPQP = 255; - if (!bHPAbsent) - iHPQP = pSC->pTile[pSC->cTileColumn].pQuantizerHP[i][pSC->MBInfo.iQIndexHP].iQP; - - //======================================== - // second level inverse transform (420_UV) - if (!bottomORright) - { - if (!pSC->m_param.bScaledArith) { - strDCT2x2dn(p1, p1 + 32, p1 + 16, p1 + 48); - } - else { - strDCT2x2dnDec(p1, p1 + 32, p1 + 16, p1 + 48); - } - } - - //======================================== - // second level inverse overlap (420_UV) - if (OL_TWO == olOverlap) - { - if (leftORright && !topORbottom) - { - j = (left ? 0 : -32); - strPost2(p0 + j + 16, p1 + j); - } - - if (!leftORright) - { - if (topORbottom) - { - p = (top ? p1 : p0 + 16); - strPost2(p - 32, p); - p = NULL; - } - else{ - strPost2x2(p0 - 16, p0 + 16, p1 - 32, p1); - } - } - } - - //======================================== - // first level inverse transform (420_UV) - if(tScale >= 4) // bypass first level transform for 4:1 and smaller thumbnail - continue; - - if (!top) - { - for (j = (left ? 16 : -16); j < (right ? 16 : 48); j += 32) - { - strIDCT4x4Stage1(p0 + j); - } - } - - if (!bottom) - { - for (j = (left ? 0 : -32); j < (right ? 0 : 32); j += 32) - { - strIDCT4x4Stage1(p1 + j); - } - } - - //======================================== - // first level inverse overlap (420_UV) - if (OL_NONE != olOverlap) - { - if(!left && !top) - { - if (bottom) - { - for (j = -48; j < (right ? -16 : 16); j += 32) - { - p = p0 + j; - strPost4(p + 15, p + 14, p + 42, p + 43); - strPost4(p + 13, p + 12, p + 40, p + 41); - p = NULL; - } - } - else - { - for (j = -48; j < (right ? -16 : 16); j += 32) - { - strPost4x4Stage1Split(p0 + j, p1 - 16 + j, 32, iHPQP, bHPAbsent); - } - } - - if (right) - { - if (!bottom) - { - strPost4(p0 - 2 , p0 - 4 , p1 - 28, p1 - 26); - strPost4(p0 - 1 , p0 - 3 , p1 - 27, p1 - 25); - } - - strPost4(p0 - 18, p0 - 20, p0 - 12, p0 - 10); - strPost4(p0 - 17, p0 - 19, p0 - 11, p0 - 9); - } - else - { - strPost4x4Stage1(p0 - 32, 32, iHPQP, bHPAbsent); - } - - strPost4x4Stage1(p0 - 64, 32, iHPQP, bHPAbsent); - } - else if (top) - { - for (j = (left ? 0: -64); j < (right ? -32: 0); j += 32) - { - p = p1 + j + 4; - strPost4(p + 1, p + 0, p + 28, p + 29); - strPost4(p + 3, p + 2, p + 30, p + 31); - p = NULL; - } - } - else if (left) - { - if (!bottom) - { - strPost4(p0 + 26, p0 + 24, p1 + 0, p1 + 2); - strPost4(p0 + 27, p0 + 25, p1 + 1, p1 + 3); - } - - strPost4(p0 + 10, p0 + 8, p0 + 16, p0 + 18); - strPost4(p0 + 11, p0 + 9, p0 + 17, p0 + 19); - } - } - } - - //================================================================ - // 422_UV - for (i = 0; i < (YUV_422 == cfColorFormat? 2U : 0U) && tScale < 16; ++i) - { - PixelI* const p0 = pSC->p0MBbuffer[1 + i];//(0 == i ? pSC->pU0 : pSC->pV0); - PixelI* const p1 = pSC->p1MBbuffer[1 + i];//(0 == i ? pSC->pU1 : pSC->pV1); - - Int iHPQP = 255; - if (!bHPAbsent) - iHPQP = pSC->pTile[pSC->cTileColumn].pQuantizerHP[i][pSC->MBInfo.iQIndexHP].iQP; - - //======================================== - // second level inverse transform (422_UV) - if ((!bottomORright) && pSC->m_Dparam->cThumbnailScale < 16) - { - // 1D lossless HT - p1[0] -= ((p1[32] + 1) >> 1); - p1[32] += p1[0]; - - if (!pSC->m_param.bScaledArith) { - strDCT2x2dn(p1 + 0, p1 + 64, p1 + 16, p1 + 80); - strDCT2x2dn(p1 + 32, p1 + 96, p1 + 48, p1 + 112); - } - else { - strDCT2x2dnDec(p1 + 0, p1 + 64, p1 + 16, p1 + 80); - strDCT2x2dnDec(p1 + 32, p1 + 96, p1 + 48, p1 + 112); - } - } - - //======================================== - // second level inverse overlap (422_UV) - if (OL_TWO == olOverlap) - { - if (!bottom) - { - if (leftORright) - { - if (!top) - { - j = (left ? 0 : -64); - strPost2(p0 + 48 + j, p1 + j); - } - - j = (left ? 16 : -48); - strPost2(p1 + j, p1 + j + 16); - } - else - { - if (top) - { - strPost2(p1 - 64, p1); - } - else - { - strPost2x2(p0 - 16, p0 + 48, p1 - 64, p1); - } - - strPost2x2(p1 - 48, p1 + 16, p1 - 32, p1 + 32); - } - } - else if (!leftORright) - { - strPost2(p0 - 16, p0 + 48); - } - } - - //======================================== - // first level inverse transform (422_UV) - if(tScale >= 4) // bypass first level transform for 4:1 and smaller thumbnail - continue; - - if (!top) - { - for (j = (left ? 48 : -16); j < (right ? 48 : 112); j += 64) - { - strIDCT4x4Stage1(p0 + j); - } - } - - if (!bottom) - { - for (j = (left ? 0 : -64); j < (right ? 0 : 64); j += 64) - { - strIDCT4x4Stage1(p1 + j + 0); - strIDCT4x4Stage1(p1 + j + 16); - strIDCT4x4Stage1(p1 + j + 32); - } - } - - //======================================== - // first level inverse overlap (422_UV) - if (OL_NONE != olOverlap) - { - if (!top) - { - if (leftORright) - { - j = (left ? 32 + 10 : -32 + 14); - - p = p0 + j; - strPost4(p + 0, p - 2, p + 6, p + 8); - strPost4(p + 1, p - 1, p + 7, p + 9); - - p = NULL; - } - - for (j = (left ? 0 : -128); j < (right ? -64 : 0); j += 64) - { - strPost4x4Stage1(p0 + j + 32, 0, iHPQP, bHPAbsent); - } - } - - if (!bottom) - { - if (leftORright) - { - j = (left ? 0 + 10 : -64 + 14); - - p = p1 + j; - strPost4(p + 0, p - 2, p + 6, p + 8); - strPost4(p + 1, p - 1, p + 7, p + 9); - - p += 16; - strPost4(p + 0, p - 2, p + 6, p + 8); - strPost4(p + 1, p - 1, p + 7, p + 9); - - p = NULL; - } - - for (j = (left ? 0 : -128); j < (right ? -64 : 0); j += 64) - { - strPost4x4Stage1(p1 + j + 0, 0, iHPQP, bHPAbsent); - strPost4x4Stage1(p1 + j + 16, 0, iHPQP, bHPAbsent); - } - } - - if (topORbottom) - { - p = (top ? p1 + 5 : p0 + 48 + 13); - for (j = (left ? 0 : -128); j < (right ? -64 : 0); j += 64) - { - strPost4(p + j + 0, p + j - 1, p + j + 59, p + j + 60); - strPost4(p + j + 2, p + j + 1, p + j + 61, p + j + 62); - } - p = NULL; - } - else - { - if (leftORright) - { - j = (left ? 0 + 0 : -64 + 4); - strPost4(p0 + j + 48 + 10 + 0, p0 + j + 48 + 10 - 2, p1 + j + 0, p1 + j + 2); - strPost4(p0 + j + 48 + 10 + 1, p0 + j + 48 + 10 - 1, p1 + j + 1, p1 + j + 3); - } - - for (j = (left ? 0 : -128); j < (right ? -64 : 0); j += 64) - { - strPost4x4Stage1Split(p0 + j + 48, p1 + j + 0, 0, iHPQP, bHPAbsent); - } - } - } - } - - return ICERR_OK; -} - -Int invTransformMacroblock_alteredOperators_hard(CWMImageStrCodec * pSC) -{ - const OVERLAP olOverlap = pSC->WMISCP.olOverlap; - const COLORFORMAT cfColorFormat = pSC->m_param.cfColorFormat; - // const BITDEPTH_BITS bdBitDepth = pSC->WMII.bdBitDepth; - const Bool left = (pSC->cColumn == 0), right = (pSC->cColumn == pSC->cmbWidth); - const Bool top = (pSC->cRow == 0), bottom = (pSC->cRow == pSC->cmbHeight); - const Bool topORbottom = (top || bottom), leftORright = (left || right); - const Bool topORleft = (top || left), bottomORright = (bottom || right); - Bool leftAdjacentColumn = (pSC->cColumn == 1), rightAdjacentColumn = (pSC->cColumn == pSC->cmbWidth - 1); - // Bool topAdjacentRow = (pSC->cRow == 1), bottomAdjacentRow = (pSC->cRow == pSC->cmbHeight - 1); - const size_t mbWidth = pSC->cmbWidth; - PixelI * p = NULL;// * pt = NULL; - size_t i; - const size_t iChannels = (cfColorFormat == YUV_420 || cfColorFormat == YUV_422) ? 1 : pSC->m_param.cNumChannels; - const size_t tScale = pSC->m_Dparam->cThumbnailScale; - Int j = 0; - - Int qp[MAX_CHANNELS], dcqp[MAX_CHANNELS], iStrength = (1 << pSC->WMII.cPostProcStrength); - // ERR_CODE result = ICERR_OK; - -#define mbX pSC->mbX -#define mbY pSC->mbY -#define tileX pSC->tileX -#define tileY pSC->tileY -#define bVertTileBoundary pSC->bVertTileBoundary -#define bHoriTileBoundary pSC->bHoriTileBoundary -#define bOneMBLeftVertTB pSC->bOneMBLeftVertTB -#define bOneMBRightVertTB pSC->bOneMBRightVertTB -#define iPredBefore pSC->iPredBefore -#define iPredAfter pSC->iPredAfter - - if (pSC->WMISCP.bUseHardTileBoundaries) { - //Add tile location information - if (pSC->cColumn == 0) { - bVertTileBoundary = FALSE; - tileY = 0; - } - bOneMBLeftVertTB = bOneMBRightVertTB = FALSE; - if(tileY > 0 && tileY <= pSC->WMISCP.cNumOfSliceMinus1H && (pSC->cColumn - 1) == pSC->WMISCP.uiTileY[tileY]) - bOneMBRightVertTB = TRUE; - if(tileY < pSC->WMISCP.cNumOfSliceMinus1H && pSC->cColumn == pSC->WMISCP.uiTileY[tileY + 1]) { - bVertTileBoundary = TRUE; - tileY++; - } - else - bVertTileBoundary = FALSE; - if(tileY < pSC->WMISCP.cNumOfSliceMinus1H && (pSC->cColumn + 1) == pSC->WMISCP.uiTileY[tileY + 1]) - bOneMBLeftVertTB = TRUE; - - if (pSC->cRow == 0) { - bHoriTileBoundary = FALSE; - tileX = 0; - } - else if(mbY != pSC->cRow && tileX < pSC->WMISCP.cNumOfSliceMinus1V && pSC->cRow == pSC->WMISCP.uiTileX[tileX + 1]) { - bHoriTileBoundary = TRUE; - tileX++; - } - else if(mbY != pSC->cRow) - bHoriTileBoundary = FALSE; - } - else { - bVertTileBoundary = FALSE; - bHoriTileBoundary = FALSE; - bOneMBLeftVertTB = FALSE; - bOneMBRightVertTB = FALSE; - } - mbX = pSC->cColumn, mbY = pSC->cRow; - - if(pSC->WMII.cPostProcStrength > 0){ - // threshold for post processing - for(i = 0; i < iChannels; i ++){ - qp[i] = pSC->pTile[pSC->cTileColumn].pQuantizerLP[i][pSC->MBInfo.iQIndexLP].iQP * iStrength * (olOverlap == OL_NONE ? 2 : 1); - dcqp[i] = pSC->pTile[pSC->cTileColumn].pQuantizerDC[i][0].iQP * iStrength; - } - - if(left) // a new MB row - slideOneMBRow(pSC->pPostProcInfo, pSC->m_param.cNumChannels, mbWidth, top, bottom); // previous current row becomes previous row - } - - //================================================================ - // 400_Y, 444_YUV - for (i = 0; i < iChannels && tScale < 16; ++i) - { - PixelI* const p0 = pSC->p0MBbuffer[i]; - PixelI* const p1 = pSC->p1MBbuffer[i]; - - //================================ - // second level inverse transform - if (!bottomORright) - { - if(pSC->WMII.cPostProcStrength > 0) - updatePostProcInfo(pSC->pPostProcInfo, p1, mbX, i); // update postproc info before IDCT - - strIDCT4x4Stage2(p1); - if (pSC->m_param.bScaledArith) { - strNormalizeDec(p1, (i != 0)); - } - } - - //================================ - // second level inverse overlap - if (OL_TWO == olOverlap) - { - /* Corner operations */ - if ((top || bHoriTileBoundary) && (left || bVertTileBoundary)) - strPost4_alternate(p1 + 0, p1 + 64, p1 + 0 + 16, p1 + 64 + 16); - if ((top || bHoriTileBoundary) && (right || bVertTileBoundary)) - strPost4_alternate(p1 - 128, p1 - 64, p1 - 128 + 16, p1 - 64 + 16); - if ((bottom || bHoriTileBoundary) && (left || bVertTileBoundary)) - strPost4_alternate(p0 + 32, p0 + 96, p0 + 32 + 16, p0 + 96 + 16); - if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary)) - strPost4_alternate(p0 - 96, p0 - 32, p0 - 96 + 16, p0 - 32 + 16); - if ((leftORright || bVertTileBoundary) && (!topORbottom && !bHoriTileBoundary)) - { - if (left || bVertTileBoundary) { - j = 0; - strPost4_alternate(p0 + j + 32, p0 + j + 48, p1 + j + 0, p1 + j + 16); - strPost4_alternate(p0 + j + 96, p0 + j + 112, p1 + j + 64, p1 + j + 80); - } - if (right || bVertTileBoundary) { - j = -128; - strPost4_alternate(p0 + j + 32, p0 + j + 48, p1 + j + 0, p1 + j + 16); - strPost4_alternate(p0 + j + 96, p0 + j + 112, p1 + j + 64, p1 + j + 80); - } - } - - if (!leftORright) - { - if ((topORbottom || bHoriTileBoundary) && !bVertTileBoundary) - { - if (top || bHoriTileBoundary) { - p = p1; - strPost4_alternate(p - 128, p - 64, p + 0, p + 64); - strPost4_alternate(p - 112, p - 48, p + 16, p + 80); - p = NULL; - } - if (bottom || bHoriTileBoundary) { - p = p0 + 32; - strPost4_alternate(p - 128, p - 64, p + 0, p + 64); - strPost4_alternate(p - 112, p - 48, p + 16, p + 80); - p = NULL; - } - } - - if (!topORbottom && !bHoriTileBoundary && !bVertTileBoundary) - strPost4x4Stage2Split_alternate(p0, p1); - } - } - - if(pSC->WMII.cPostProcStrength > 0) - postProcMB(pSC->pPostProcInfo, p0, p1, mbX, i, dcqp[i]); // second stage deblocking - - //================================ - // first level inverse transform - if(tScale >= 4) // bypass first level transform for 4:1 and smaller thumbnail - continue; - - if (!top) - { - for (j = (left ? 32 : -96); j < (right ? 32 : 160); j += 64) - { - strIDCT4x4Stage1(p0 + j + 0); - strIDCT4x4Stage1(p0 + j + 16); - } - } - - if (!bottom) - { - for (j = (left ? 0 : -128); j < (right ? 0 : 128); j += 64) - { -// if(tScale == 2 && bdBitDepth != BD_1){ -// MIPgen(p1 + j + 0); -// MIPgen(p1 + j + 16); -// } - strIDCT4x4Stage1(p1 + j + 0); - strIDCT4x4Stage1(p1 + j + 16); - } - } - - //================================ - // first level inverse overlap - if (OL_NONE != olOverlap) - { - if (leftORright || bVertTileBoundary) - { - /* Corner operations */ - if ((top || bHoriTileBoundary) && (left || bVertTileBoundary)) - strPost4_alternate(p1 + 0, p1 + 1, p1 + 2, p1 + 3); - if ((top || bHoriTileBoundary) && (right || bVertTileBoundary)) - strPost4_alternate(p1 - 59, p1 - 60, p1 - 57, p1 - 58); - if ((bottom || bHoriTileBoundary) && (left || bVertTileBoundary)) - strPost4_alternate(p0 + 48 + 10, p0 + 48 + 11, p0 + 48 + 8, p0 + 48 + 9); - if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary)) - strPost4_alternate(p0 - 1, p0 - 2, p0 - 3, p0 - 4); - if (left || bVertTileBoundary) { - j = 0 + 10; - if (!top) - { - p = p0 + 16 + j; - strPost4_alternate(p + 0, p - 2, p + 6, p + 8); - strPost4_alternate(p + 1, p - 1, p + 7, p + 9); - strPost4_alternate(p + 16, p + 14, p + 22, p + 24); - strPost4_alternate(p + 17, p + 15, p + 23, p + 25); - p = NULL; - } - if (!bottom) - { - p = p1 + j; - strPost4_alternate(p + 0, p - 2, p + 6, p + 8); - strPost4_alternate(p + 1, p - 1, p + 7, p + 9); - p = NULL; - } - if (!topORbottom && !bHoriTileBoundary) - { - strPost4_alternate(p0 + 48 + j + 0, p0 + 48 + j - 2, p1 - 10 + j, p1 - 8 + j); - strPost4_alternate(p0 + 48 + j + 1, p0 + 48 + j - 1, p1 - 9 + j, p1 - 7 + j); - } - } - if (right || bVertTileBoundary) { - j = -64 + 14; - if (!top) - { - p = p0 + 16 + j; - strPost4_alternate(p + 0, p - 2, p + 6, p + 8); - strPost4_alternate(p + 1, p - 1, p + 7, p + 9); - strPost4_alternate(p + 16, p + 14, p + 22, p + 24); - strPost4_alternate(p + 17, p + 15, p + 23, p + 25); - p = NULL; - } - if (!bottom) - { - p = p1 + j; - strPost4_alternate(p + 0, p - 2, p + 6, p + 8); - strPost4_alternate(p + 1, p - 1, p + 7, p + 9); - p = NULL; - } - if (!topORbottom && !bHoriTileBoundary) - { - strPost4_alternate(p0 + 48 + j + 0, p0 + 48 + j - 2, p1 - 10 + j, p1 - 8 + j); - strPost4_alternate(p0 + 48 + j + 1, p0 + 48 + j - 1, p1 - 9 + j, p1 - 7 + j); - } - } - } - - if (top || bHoriTileBoundary) - { - for (j = (left ? 0 : -192); j < (right ? -64 : 64); j += 64) - { - if (!bVertTileBoundary || j != -64) { - p = p1 + j; - strPost4_alternate(p + 5, p + 4, p + 64, p + 65); - strPost4_alternate(p + 7, p + 6, p + 66, p + 67); - p = NULL; - - strPost4x4Stage1_alternate(p1 + j, 0); - } - } - } - - if (bottom || bHoriTileBoundary) - { - for (j = (left ? 0 : -192); j < (right ? -64 : 64); j += 64) - { - if (!bVertTileBoundary || j != -64) { - strPost4x4Stage1_alternate(p0 + 16 + j, 0); - strPost4x4Stage1_alternate(p0 + 32 + j, 0); - - p = p0 + 48 + j; - strPost4_alternate(p + 15, p + 14, p + 74, p + 75); - strPost4_alternate(p + 13, p + 12, p + 72, p + 73); - p = NULL; - } - } - } - - if (!top && !bottom && !bHoriTileBoundary) - { - for (j = (left ? 0 : -192); j < (right ? -64 : 64); j += 64) - { - if (!bVertTileBoundary || j != -64) { - strPost4x4Stage1_alternate(p0 + 16 + j, 0); - strPost4x4Stage1_alternate(p0 + 32 + j, 0); - strPost4x4Stage1Split_alternate(p0 + 48 + j, p1 + j, 0); - strPost4x4Stage1_alternate(p1 + j, 0); - } - } - } - } - - if(pSC->WMII.cPostProcStrength > 0 && (!topORleft)) - postProcBlock(pSC->pPostProcInfo, p0, p1, mbX, i, qp[i]); // destairing and first stage deblocking - } - - //================================================================ - // 420_UV - for (i = 0; i < (YUV_420 == cfColorFormat? 2U : 0U) && tScale < 16; ++i) - { - PixelI* const p0 = pSC->p0MBbuffer[1 + i];//(0 == i ? pSC->pU0 : pSC->pV0); - PixelI* const p1 = pSC->p1MBbuffer[1 + i];//(0 == i ? pSC->pU1 : pSC->pV1); - - //======================================== - // second level inverse transform (420_UV) - if (!bottomORright) - { - if (!pSC->m_param.bScaledArith) { - strDCT2x2dn(p1, p1 + 32, p1 + 16, p1 + 48); - } - else { - strDCT2x2dnDec(p1, p1 + 32, p1 + 16, p1 + 48); - } - } - - //======================================== - // second level inverse overlap (420_UV) - if (OL_TWO == olOverlap) - { - if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_DIFF(p1 - 64 + 0, *(p1 - 64 + 32)); - if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary)) - iPredBefore[i][0] = *(p1 + 0); - if ((right || bVertTileBoundary) && (top || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_DIFF(p1 - 64 + 32, iPredBefore[i][0]); - if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_DIFF(p0 - 64 + 16, *(p0 - 64 + 48)); - if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) - iPredBefore[i][1] = *(p0 + 16); - if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_DIFF(p0 - 64 + 48, iPredBefore[i][1]); - - if ((leftORright || bVertTileBoundary) && !topORbottom && !bHoriTileBoundary) - { - if (left || bVertTileBoundary) - strPost2_alternate(p0 + 0 + 16, p1 + 0); - if (right || bVertTileBoundary) - strPost2_alternate(p0 + -32 + 16, p1 + -32); - } - - if (!leftORright) - { - if ((topORbottom || bHoriTileBoundary) && !bVertTileBoundary) - { - if (top || bHoriTileBoundary) - strPost2_alternate(p1 - 32, p1); - if (bottom || bHoriTileBoundary) - strPost2_alternate(p0 + 16 - 32, p0 + 16); - } - else if (!topORbottom && !bHoriTileBoundary && !bVertTileBoundary) { - strPost2x2_alternate(p0 - 16, p0 + 16, p1 - 32, p1); - } - } - if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_ADD(p1 - 64 + 0, *(p1 - 64 + 32)); - if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary)) - iPredAfter[i][0] = *(p1 + 0); - if ((right || bVertTileBoundary) && (top || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_ADD(p1 - 64 + 32, iPredAfter[i][0]); - if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_ADD(p0 - 64 + 16, *(p0 - 64 + 48)); - if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) - iPredAfter[i][1] = *(p0 + 16); - if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_ADD(p0 - 64 + 48, iPredAfter[i][1]); - } - - //======================================== - // first level inverse transform (420_UV) - if(tScale >= 4) // bypass first level transform for 4:1 and smaller thumbnail - continue; - - if (!top) - { - // In order to allow correction operation of corner chroma overlap operators (fixed) - // processing of left most MB column must be delayed by one MB - // Thus left MB not processed until leftAdjacentColumn = 1 - for (j = ((left) ? 48 : ((leftAdjacentColumn || bOneMBRightVertTB) ? -48 : -16)); j < ((right || bVertTileBoundary) ? 16 : 48); j += 32) - { - strIDCT4x4Stage1(p0 + j); - } - } - - if (!bottom) - { - // In order to allow correction operation of corner chroma overlap operators (fixed) - // processing of left most MB column must be delayed by one MB - // Thus left MB not processed until leftAdjacentColumn = 1 - for (j = ((left) ? 32 : ((leftAdjacentColumn || bOneMBRightVertTB) ? -64 : -32)); j < ((right || bVertTileBoundary) ? 0 : 32); j += 32) - { - strIDCT4x4Stage1(p1 + j); - } - } - - //======================================== - // first level inverse overlap (420_UV) - if (OL_NONE != olOverlap) - { - /* Corner operations */ - /* Change because the top-left corner ICT will not have happened until leftAdjacentColumn ==1 */ - if ((top || bHoriTileBoundary) && (leftAdjacentColumn || bOneMBRightVertTB)) - strPost4_alternate(p1 - 64 + 0, p1 - 64 + 1, p1 - 64 + 2, p1 - 64 + 3); - if ((top || bHoriTileBoundary) && (right || bVertTileBoundary)) - strPost4_alternate(p1 - 27, p1 - 28, p1 - 25, p1 - 26); - /* Change because the bottom-left corner ICT will not have happened until leftAdjacentColumn ==1 */ - if ((bottom || bHoriTileBoundary) && (leftAdjacentColumn || bOneMBRightVertTB)) - strPost4_alternate(p0 - 64 + 16 + 10, p0 - 64 + 16 + 11, p0 - 64 + 16 + 8, p0 - 64 + 16 + 9); - if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary)) - strPost4_alternate(p0 - 1, p0 - 2, p0 - 3, p0 - 4); - if(!left && !top) - { - /* Change because the vertical 1-D overlap operations of the left edge pixels cannot be performed until leftAdjacentColumn ==1 */ - if (leftAdjacentColumn || bOneMBRightVertTB) - { - if (!bottom && !bHoriTileBoundary) - { - strPost4_alternate(p0 - 64 + 26, p0 - 64 + 24, p1 - 64 + 0, p1 - 64 + 2); - strPost4_alternate(p0 - 64 + 27, p0 - 64 + 25, p1 - 64 + 1, p1 - 64 + 3); - } - - strPost4_alternate(p0 - 64 + 10, p0 - 64 + 8, p0 - 64 + 16, p0 - 64 + 18); - strPost4_alternate(p0 - 64 + 11, p0 - 64 + 9, p0 - 64 + 17, p0 - 64 + 19); - } - if (bottom || bHoriTileBoundary) - { - p = p0 + -48; - strPost4_alternate(p + 15, p + 14, p + 42, p + 43); - strPost4_alternate(p + 13, p + 12, p + 40, p + 41); - p = NULL; - - if (!right && !bVertTileBoundary) - { - p = p0 + -16; - strPost4_alternate(p + 15, p + 14, p + 42, p + 43); - strPost4_alternate(p + 13, p + 12, p + 40, p + 41); - p = NULL; - } - } - else - { - strPost4x4Stage1Split_alternate(p0 + -48, p1 - 16 + -48, 32); - - if (!right && !bVertTileBoundary) - strPost4x4Stage1Split_alternate(p0 + -16, p1 - 16 + -16, 32); - } - - if (right || bVertTileBoundary) - { - if (!bottom && !bHoriTileBoundary) - { - strPost4_alternate(p0 - 2 , p0 - 4 , p1 - 28, p1 - 26); - strPost4_alternate(p0 - 1 , p0 - 3 , p1 - 27, p1 - 25); - } - - strPost4_alternate(p0 - 18, p0 - 20, p0 - 12, p0 - 10); - strPost4_alternate(p0 - 17, p0 - 19, p0 - 11, p0 - 9); - } - else - { - strPost4x4Stage1_alternate(p0 - 32, 32); - } - - strPost4x4Stage1_alternate(p0 - 64, 32); - } - - if (top || bHoriTileBoundary) - { - if (!left) - { - p = p1 + -64 + 4; - strPost4_alternate(p + 1, p + 0, p + 28, p + 29); - strPost4_alternate(p + 3, p + 2, p + 30, p + 31); - p = NULL; - } - - if (!left && !right && !bVertTileBoundary) - { - p = p1 + -32 + 4; - strPost4_alternate(p + 1, p + 0, p + 28, p + 29); - strPost4_alternate(p + 3, p + 2, p + 30, p + 31); - p = NULL; - } - } - } - } - - //================================================================ - // 422_UV - for (i = 0; i < (YUV_422 == cfColorFormat? 2U : 0U) && tScale < 16; ++i) - { - PixelI* const p0 = pSC->p0MBbuffer[1 + i];//(0 == i ? pSC->pU0 : pSC->pV0); - PixelI* const p1 = pSC->p1MBbuffer[1 + i];//(0 == i ? pSC->pU1 : pSC->pV1); - - //======================================== - // second level inverse transform (422_UV) - if ((!bottomORright) && pSC->m_Dparam->cThumbnailScale < 16) - { - // 1D lossless HT - p1[0] -= ((p1[32] + 1) >> 1); - p1[32] += p1[0]; - - if (!pSC->m_param.bScaledArith) { - strDCT2x2dn(p1 + 0, p1 + 64, p1 + 16, p1 + 80); - strDCT2x2dn(p1 + 32, p1 + 96, p1 + 48, p1 + 112); - } - else { - strDCT2x2dnDec(p1 + 0, p1 + 64, p1 + 16, p1 + 80); - strDCT2x2dnDec(p1 + 32, p1 + 96, p1 + 48, p1 + 112); - } - } - - //======================================== - // second level inverse overlap (422_UV) - if (OL_TWO == olOverlap) - { - if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_DIFF(p1 - 128 + 0, *(p1 - 128 + 64)); - - if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary)) - iPredBefore[i][0] = *(p1 + 0); - if ((right || bVertTileBoundary) && (top || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_DIFF(p1 - 128 + 64, iPredBefore[i][0]); - - if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_DIFF(p0 - 128 + 48, *(p0 - 128 + 112)); - - if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) - iPredBefore[i][1] = *(p0 + 48); - if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_DIFF(p0 - 128 + 112, iPredBefore[i][1]); - - if (!bottom) - { - if (leftORright || bVertTileBoundary) - { - if (!top && !bHoriTileBoundary) - { - if (left || bVertTileBoundary) - strPost2_alternate(p0 + 48 + 0, p1 + 0); - - if (right || bVertTileBoundary) - strPost2_alternate(p0 + 48 + -64, p1 + -64); - } - - if (left || bVertTileBoundary) - strPost2_alternate(p1 + 16, p1 + 16 + 16); - - if (right || bVertTileBoundary) - strPost2_alternate(p1 + -48, p1 + -48 + 16); - } - - if (!leftORright && !bVertTileBoundary) - { - if (top || bHoriTileBoundary) - strPost2_alternate(p1 - 64, p1); - else - strPost2x2_alternate(p0 - 16, p0 + 48, p1 - 64, p1); - - strPost2x2_alternate(p1 - 48, p1 + 16, p1 - 32, p1 + 32); - } - } - - if ((bottom || bHoriTileBoundary) && (!leftORright && !bVertTileBoundary)) - strPost2_alternate(p0 - 16, p0 + 48); - - if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_ADD(p1 - 128 + 0, *(p1 - 128 + 64)); - - if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary)) - iPredAfter[i][0] = *(p1 + 0); - if ((right || bVertTileBoundary) && (top || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_ADD(p1 - 128 + 64, iPredAfter[i][0]); - - if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_ADD(p0 - 128 + 48, *(p0 - 128 + 112)); - - if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) - iPredAfter[i][1] = *(p0 + 48); - if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary)) - COMPUTE_CORNER_PRED_ADD(p0 - 128 + 112, iPredAfter[i][1]); - } - - //======================================== - // first level inverse transform (422_UV) - if(tScale >= 4) // bypass first level transform for 4:1 and smaller thumbnail - continue; - - if (!top) - { - // Need to delay processing of left column until leftAdjacentColumn = 1 for corner overlap operators - // Since 422 has no vertical downsampling, no top MB delay of processing is necessary - for (j = (left ? 112 : ((leftAdjacentColumn || bOneMBRightVertTB) ? -80 : -16)); j < ((right || bVertTileBoundary) ? 48 : 112); j += 64) - { - strIDCT4x4Stage1(p0 + j); - } - } - - if (!bottom) - { - // Need to delay processing of left column until leftAdjacentColumn = 1 for corner overlap operators - // Since 422 has no vertical downsampling, no top MB delay of processing is necessary - for (j = (left ? 64 : ((leftAdjacentColumn || bOneMBRightVertTB) ? -128 : -64)); j < ((right || bVertTileBoundary) ? 0 : 64); j += 64) - { - strIDCT4x4Stage1(p1 + j + 0); - strIDCT4x4Stage1(p1 + j + 16); - strIDCT4x4Stage1(p1 + j + 32); - } - } - - //======================================== - // first level inverse overlap (422_UV) - if (OL_NONE != olOverlap) - { - /* Corner operations */ - if ((top || bHoriTileBoundary) && (leftAdjacentColumn || bOneMBRightVertTB)) - strPost4_alternate(p1 - 128 + 0, p1 - 128 + 1, p1 - 128 + 2, p1 - 128 + 3); - if ((top || bHoriTileBoundary) && (right || bVertTileBoundary)) - strPost4_alternate(p1 - 59, p1 - 60, p1 - 57, p1 - 58); - if ((bottom || bHoriTileBoundary) && (leftAdjacentColumn || bOneMBRightVertTB)) - strPost4_alternate(p0 - 128 + 48 + 10, p0 - 128 + 48 + 11, p0 - 128 + 48 + 8, p0 - 128 + 48 + 9); - if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary)) - strPost4_alternate(p0 - 1, p0 - 2, p0 - 3, p0 - 4); - if (!top) - { - // Need to delay processing of left column until leftAdjacentColumn = 1 for corner overlap operators - if (leftAdjacentColumn || bOneMBRightVertTB) { - p = p0 + 32 + 10 - 128; - strPost4_alternate(p + 0, p - 2, p + 6, p + 8); - strPost4_alternate(p + 1, p - 1, p + 7, p + 9); - p = NULL; - } - - if (right || bVertTileBoundary) { - p = p0 + -32 + 14; - strPost4_alternate(p + 0, p - 2, p + 6, p + 8); - strPost4_alternate(p + 1, p - 1, p + 7, p + 9); - p = NULL; - } - - for (j = (left ? 0 : -128); j < ((right || bVertTileBoundary) ? -64 : 0); j += 64) - strPost4x4Stage1_alternate(p0 + j + 32, 0); - } - - if (!bottom) - { - // Need to delay processing of left column until leftAdjacentColumn = 1 for corner overlap operators - if (leftAdjacentColumn || bOneMBRightVertTB) - { - p = p1 + 0 + 10 - 128; - strPost4_alternate(p + 0, p - 2, p + 6, p + 8); - strPost4_alternate(p + 1, p - 1, p + 7, p + 9); - p += 16; - strPost4_alternate(p + 0, p - 2, p + 6, p + 8); - strPost4_alternate(p + 1, p - 1, p + 7, p + 9); - p = NULL; - } - - if (right || bVertTileBoundary) - { - p = p1 + -64 + 14; - strPost4_alternate(p + 0, p - 2, p + 6, p + 8); - strPost4_alternate(p + 1, p - 1, p + 7, p + 9); - p += 16; - strPost4_alternate(p + 0, p - 2, p + 6, p + 8); - strPost4_alternate(p + 1, p - 1, p + 7, p + 9); - p = NULL; - } - - for (j = (left ? 0 : -128); j < ((right || bVertTileBoundary) ? -64 : 0); j += 64) - { - strPost4x4Stage1_alternate(p1 + j + 0, 0); - strPost4x4Stage1_alternate(p1 + j + 16, 0); - } - } - - if (topORbottom || bHoriTileBoundary) - { - if (top || bHoriTileBoundary) { - p = p1 + 5; - for (j = (left ? 0 : -128); j < ((right || bVertTileBoundary) ? -64 : 0); j += 64) - { - strPost4_alternate(p + j + 0, p + j - 1, p + j + 59, p + j + 60); - strPost4_alternate(p + j + 2, p + j + 1, p + j + 61, p + j + 62); - } - p = NULL; - } - - if (bottom || bHoriTileBoundary) { - p = p0 + 48 + 13; - for (j = (left ? 0 : -128); j < ((right || bVertTileBoundary) ? -64 : 0); j += 64) - { - strPost4_alternate(p + j + 0, p + j - 1, p + j + 59, p + j + 60); - strPost4_alternate(p + j + 2, p + j + 1, p + j + 61, p + j + 62); - } - p = NULL; - } - } - else - { - // Need to delay processing of left column until leftAdjacentColumn = 1 for corner overlap operators - if (leftAdjacentColumn || bOneMBRightVertTB) - { - j = 0 + 0 - 128; - strPost4_alternate(p0 + j + 48 + 10 + 0, p0 + j + 48 + 10 - 2, p1 + j + 0, p1 + j + 2); - strPost4_alternate(p0 + j + 48 + 10 + 1, p0 + j + 48 + 10 - 1, p1 + j + 1, p1 + j + 3); - } - - if (right || bVertTileBoundary) - { - j = -64 + 4; - strPost4_alternate(p0 + j + 48 + 10 + 0, p0 + j + 48 + 10 - 2, p1 + j + 0, p1 + j + 2); - strPost4_alternate(p0 + j + 48 + 10 + 1, p0 + j + 48 + 10 - 1, p1 + j + 1, p1 + j + 3); - } - - for (j = (left ? 0 : -128); j < ((right || bVertTileBoundary) ? -64 : 0); j += 64) - strPost4x4Stage1Split_alternate(p0 + j + 48, p1 + j + 0, 0); - } - } - } - - return ICERR_OK; -} diff --git a/Src/JxrDecode/Jxr/strPredQuant.c b/Src/JxrDecode/Jxr/strPredQuant.c deleted file mode 100644 index 6ff81679..00000000 --- a/Src/JxrDecode/Jxr/strPredQuant.c +++ /dev/null @@ -1,306 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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!!! - } - } -} diff --git a/Src/JxrDecode/Jxr/strPredQuantDec.c b/Src/JxrDecode/Jxr/strPredQuantDec.c deleted file mode 100644 index b53bad66..00000000 --- a/Src/JxrDecode/Jxr/strPredQuantDec.c +++ /dev/null @@ -1,547 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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); - } - //} -} - diff --git a/Src/JxrDecode/Jxr/strPredQuantEnc.c b/Src/JxrDecode/Jxr/strPredQuantEnc.c deleted file mode 100644 index 73970cec..00000000 --- a/Src/JxrDecode/Jxr/strPredQuantEnc.c +++ /dev/null @@ -1,511 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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); - } - } -} - diff --git a/Src/JxrDecode/Jxr/strTransform.c b/Src/JxrDecode/Jxr/strTransform.c deleted file mode 100644 index 0d73d3a1..00000000 --- a/Src/JxrDecode/Jxr/strTransform.c +++ /dev/null @@ -1,85 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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]); -} diff --git a/Src/JxrDecode/Jxr/strTransform.h b/Src/JxrDecode/Jxr/strTransform.h deleted file mode 100644 index c66b754b..00000000 --- a/Src/JxrDecode/Jxr/strTransform.h +++ /dev/null @@ -1,50 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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 diff --git a/Src/JxrDecode/Jxr/strcodec.c b/Src/JxrDecode/Jxr/strcodec.c deleted file mode 100644 index 58fc0f40..00000000 --- a/Src/JxrDecode/Jxr/strcodec.c +++ /dev/null @@ -1,1293 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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 "jxr_defines.h" -#include "strcodec.h" -#include "perfTimer.h" - -#ifdef MEM_TRACE -#define TRACE_MALLOC 1 -#define TRACE_NEW 0 -#define TRACE_HEAP 0 -#include "memtrace.h" -#endif - -//================================================================ -// Quantization index tables -//================================================================ -const int blkOffset[16] = { 0, 64, 16, 80, 128, 192, 144, 208, 32, 96, 48, 112, 160, 224, 176, 240 }; -const int blkOffsetUV[4] = { 0, 32, 16, 48 }; -const int blkOffsetUV_422[8] = { 0, 64, 16, 80, 32, 96, 48, 112 }; - -const int dctIndex[3][16] = { /** permutation matrix tailored to the transform, nothing to do with ZZS **/ - {0,5,1,6, 10,12,8,14, 2,4,3,7, 9,13,11,15}, //AC 444 - {0,5,1,6, 10,12,8,14, 2,4,3,7, 9,13,11,15}, //AC 420 - {0,128,64,208, 32,240,48,224, 16,192,80,144, 112,176,96,160 }, //DC 444 -}; - -//================================================================ -// Color conversion index table -//================================================================ -const U8 idxCC[16][16] = -{ - {0x00, 0x01, 0x05, 0x04, 0x40, 0x41, 0x45, 0x44, 0x80, 0x81, 0x85, 0x84, 0xc0, 0xc1, 0xc5, 0xc4, }, - {0x02, 0x03, 0x07, 0x06, 0x42, 0x43, 0x47, 0x46, 0x82, 0x83, 0x87, 0x86, 0xc2, 0xc3, 0xc7, 0xc6, }, - {0x0a, 0x0b, 0x0f, 0x0e, 0x4a, 0x4b, 0x4f, 0x4e, 0x8a, 0x8b, 0x8f, 0x8e, 0xca, 0xcb, 0xcf, 0xce, }, - {0x08, 0x09, 0x0d, 0x0c, 0x48, 0x49, 0x4d, 0x4c, 0x88, 0x89, 0x8d, 0x8c, 0xc8, 0xc9, 0xcd, 0xcc, }, - - {0x10, 0x11, 0x15, 0x14, 0x50, 0x51, 0x55, 0x54, 0x90, 0x91, 0x95, 0x94, 0xd0, 0xd1, 0xd5, 0xd4, }, - {0x12, 0x13, 0x17, 0x16, 0x52, 0x53, 0x57, 0x56, 0x92, 0x93, 0x97, 0x96, 0xd2, 0xd3, 0xd7, 0xd6, }, - {0x1a, 0x1b, 0x1f, 0x1e, 0x5a, 0x5b, 0x5f, 0x5e, 0x9a, 0x9b, 0x9f, 0x9e, 0xda, 0xdb, 0xdf, 0xde, }, - {0x18, 0x19, 0x1d, 0x1c, 0x58, 0x59, 0x5d, 0x5c, 0x98, 0x99, 0x9d, 0x9c, 0xd8, 0xd9, 0xdd, 0xdc, }, - - {0x20, 0x21, 0x25, 0x24, 0x60, 0x61, 0x65, 0x64, 0xa0, 0xa1, 0xa5, 0xa4, 0xe0, 0xe1, 0xe5, 0xe4, }, - {0x22, 0x23, 0x27, 0x26, 0x62, 0x63, 0x67, 0x66, 0xa2, 0xa3, 0xa7, 0xa6, 0xe2, 0xe3, 0xe7, 0xe6, }, - {0x2a, 0x2b, 0x2f, 0x2e, 0x6a, 0x6b, 0x6f, 0x6e, 0xaa, 0xab, 0xaf, 0xae, 0xea, 0xeb, 0xef, 0xee, }, - {0x28, 0x29, 0x2d, 0x2c, 0x68, 0x69, 0x6d, 0x6c, 0xa8, 0xa9, 0xad, 0xac, 0xe8, 0xe9, 0xed, 0xec, }, - - {0x30, 0x31, 0x35, 0x34, 0x70, 0x71, 0x75, 0x74, 0xb0, 0xb1, 0xb5, 0xb4, 0xf0, 0xf1, 0xf5, 0xf4, }, - {0x32, 0x33, 0x37, 0x36, 0x72, 0x73, 0x77, 0x76, 0xb2, 0xb3, 0xb7, 0xb6, 0xf2, 0xf3, 0xf7, 0xf6, }, - {0x3a, 0x3b, 0x3f, 0x3e, 0x7a, 0x7b, 0x7f, 0x7e, 0xba, 0xbb, 0xbf, 0xbe, 0xfa, 0xfb, 0xff, 0xfe, }, - {0x38, 0x39, 0x3d, 0x3c, 0x78, 0x79, 0x7d, 0x7c, 0xb8, 0xb9, 0xbd, 0xbc, 0xf8, 0xf9, 0xfd, 0xfc, }, -}; - -const U8 idxCC_420[8][8] = -{ - {0x00, 0x01, 0x05, 0x04, 0x20, 0x21, 0x25, 0x24, }, - {0x02, 0x03, 0x07, 0x06, 0x22, 0x23, 0x27, 0x26, }, - {0x0a, 0x0b, 0x0f, 0x0e, 0x2a, 0x2b, 0x2f, 0x2e, }, - {0x08, 0x09, 0x0d, 0x0c, 0x28, 0x29, 0x2d, 0x2c, }, - - {0x10, 0x11, 0x15, 0x14, 0x30, 0x31, 0x35, 0x34, }, - {0x12, 0x13, 0x17, 0x16, 0x32, 0x33, 0x37, 0x36, }, - {0x1a, 0x1b, 0x1f, 0x1e, 0x3a, 0x3b, 0x3f, 0x3e, }, - {0x18, 0x19, 0x1d, 0x1c, 0x38, 0x39, 0x3d, 0x3c, }, -}; - -/************************************************************************* - gGDISignature -*************************************************************************/ -const Char gGDISignature[] = { 'W', 'M', 'P', 'H', 'O', 'T', 'O', '\0' }; - -// check if enough memory allocated for the image buffer -Int checkImageBuffer(CWMImageStrCodec * pSC, size_t cWidth, size_t cRows) -{ - const BITDEPTH_BITS bd = pSC->WMISCP.bYUVData ? - BD_32S : pSC->WMII.bdBitDepth; - const COLORFORMAT cf = pSC->WMISCP.bYUVData ? - pSC->m_param.cfColorFormat : pSC->WMII.cfColorFormat; - size_t cBytes; - Bool bLessThan64Bit = sizeof(void *) < 8; - - if (cf == YUV_420) - cRows = (cRows + 1) / 2; - if (cRows > pSC->WMIBI.cLine) - return ICERR_ERROR; - - if (cf == YUV_422 || cf == YUV_420) - cWidth = (cWidth + 1) / 2; - - if (bLessThan64Bit && (cWidth >> ((sizeof(size_t) * 8 - 5)))) { - /** potential overflow - 32 bit pointers insufficient to address cache **/ - /** this uses 2 macroblock row constraint, which is tighter than ensuring rollover doesn't occur below **/ - return ICERR_ERROR; - } - - cBytes = pSC->WMISCP.bYUVData ? cWidth * sizeof(PixelI) * - (cf == YUV_420 ? 6 : (cf == YUV_422 ? 4 : (cf == YUV_444 ? 3 : 1))) : - (bd == BD_1 ? (pSC->WMII.cBitsPerUnit * cWidth + 7) / 8 : (pSC->WMII.cBitsPerUnit + 7) / 8 * cWidth); - - return (cBytes > pSC->WMIBI.cbStride ? ICERR_ERROR : ICERR_OK); -} - -Void writeQPIndex(BitIOInfo * pIO, U8 uiIndex, U32 cBits) -{ - if (uiIndex == 0) - putBit16(pIO, 1, 1); // default QP - else { - putBit16(pIO, 0, 1); // non default QP - putBit16(pIO, uiIndex - 1, cBits); - } -} - -U8 readQPIndex(BitIOInfo * pIO, U32 cBits) -{ - if (getBit16(pIO, 1)) - return 0; // default QP - - return (U8)getBit16(pIO, cBits) + 1; -} - -Void getTilePos(CWMImageStrCodec* pSC, size_t mbX, size_t mbY) -{ - if (mbX == 0) { // left image boundary - pSC->cTileColumn = 0; - } - else if (pSC->cTileColumn < pSC->WMISCP.cNumOfSliceMinus1V && mbX == pSC->WMISCP.uiTileX[pSC->cTileColumn + 1]) { // left tile boundary - pSC->cTileColumn++; - } - - if (mbY == 0) { // top image boundary - pSC->cTileRow = 0; - } - else if (pSC->cTileRow < pSC->WMISCP.cNumOfSliceMinus1H && mbY == pSC->WMISCP.uiTileY[pSC->cTileRow + 1]) { // top tile boundary - pSC->cTileRow++; - } - - pSC->m_bCtxLeft = (mbX == pSC->WMISCP.uiTileX[pSC->cTileColumn]); - pSC->m_bCtxTop = (mbY == pSC->WMISCP.uiTileY[pSC->cTileRow]); - - pSC->m_bResetContext = pSC->m_bResetRGITotals = (((mbX - pSC->WMISCP.uiTileX[pSC->cTileColumn]) & 0xf) == 0); - if (pSC->cTileColumn == pSC->WMISCP.cNumOfSliceMinus1V) { // last tile column - if (mbX + 1 == pSC->cmbWidth) - pSC->m_bResetContext = TRUE; - } - else if (mbX + 1 == pSC->WMISCP.uiTileX[pSC->cTileColumn + 1]) - pSC->m_bResetContext = TRUE; -} - -//================================================================ -// utility functions for 2 macro block rows -//================================================================ -Void initMRPtr(CWMImageStrCodec* pSC) -{ - size_t j, jend = (pSC->m_pNextSC != NULL); - - for (j = 0; j <= jend; j++) { - memcpy(pSC->p0MBbuffer, pSC->a0MBbuffer, sizeof(pSC->p0MBbuffer)); - memcpy(pSC->p1MBbuffer, pSC->a1MBbuffer, sizeof(pSC->p1MBbuffer)); - pSC = pSC->m_pNextSC; - } -} - -Void advanceMRPtr(CWMImageStrCodec* pSC) -{ - const COLORFORMAT cf = pSC->m_param.cfColorFormat; - const int cpChroma = cblkChromas[cf] * 16; - size_t i, j, jend = (pSC->m_pNextSC != NULL); - - assert(pSC->m_bSecondary == FALSE); - for (j = 0; j <= jend; j++) { - int cpStride = 16 * 16; - for (i = 0; i < pSC->m_param.cNumChannels; i++) { - pSC->pPlane[i] = pSC->p0MBbuffer[i]; - - pSC->p0MBbuffer[i] += cpStride; - pSC->p1MBbuffer[i] += cpStride; - - cpStride = cpChroma; - } - pSC = pSC->m_pNextSC; - } -} - -/* advance to next MB row */ -Void advanceOneMBRow(CWMImageStrCodec *pSC) -{ - size_t i, j, jend = (pSC->m_pNextSC != NULL); - CWMIPredInfo *pPredInfo; - - for (j = 0; j <= jend; j++) { - for (i = 0; i < pSC->m_param.cNumChannels; i++) { // swap current row and previous row - pPredInfo = pSC->PredInfo[i]; - pSC->PredInfo[i] = pSC->PredInfoPrevRow[i]; - pSC->PredInfoPrevRow[i] = pPredInfo; - } - pSC = pSC->m_pNextSC; - } -} - -Void swapMRPtr(CWMImageStrCodec* pSC) -{ - PixelI *pTemp[MAX_CHANNELS]; - size_t j, jend = (pSC->m_pNextSC != NULL); - - for (j = 0; j <= jend; j++) { - memcpy(pTemp, pSC->a0MBbuffer, sizeof(pSC->a0MBbuffer)); - memcpy(pSC->a0MBbuffer, pSC->a1MBbuffer, sizeof(pSC->a0MBbuffer)); - memcpy(pSC->a1MBbuffer, pTemp, sizeof(pSC->a0MBbuffer)); - pSC = pSC->m_pNextSC; - } -} - -//================================================================ -// Empty function to fill slot -//================================================================ -Int IDPEmpty(CWMImageStrCodec* pSC) -{ - UNREFERENCED_PARAMETER(pSC); - - return ICERR_OK; -} - -ERR WMPAlloc(void** ppv, size_t cb) -{ - *ppv = calloc(1, cb); - return *ppv ? WMP_errSuccess : WMP_errOutOfMemory; -} - -ERR WMPFree(void** ppv) -{ - if (*ppv) - { - free(*ppv); - *ppv = NULL; - } - - return WMP_errSuccess; -} - -//================================================================ -// Streaming I/O functions -//================================================================ -ERR CreateWS_File(struct WMPStream** ppWS, const char* szFilename, const char* szMode) -{ - ERR err = WMP_errSuccess; - struct WMPStream* pWS = NULL; - - Call(WMPAlloc((void**)ppWS, sizeof(**ppWS))); - pWS = *ppWS; - - pWS->Close = CloseWS_File; - pWS->EOS = EOSWS_File; - - pWS->Read = ReadWS_File; - pWS->Write = WriteWS_File; - //pWS->GetLine = GetLineWS_File; - - pWS->SetPos = SetPosWS_File; - pWS->GetPos = GetPosWS_File; - -#ifdef _WIN32 - FailIf(0 != fopen_s(&pWS->state.file.pFile, szFilename, szMode), WMP_errFileIO); -#else - pWS->state.file.pFile = fopen(szFilename, szMode); - FailIf(NULL == pWS->state.file.pFile, WMP_errFileIO); -#endif - -Cleanup: - return err; -} - -ERR CloseWS_File(struct WMPStream** ppWS) -{ - ERR err = WMP_errSuccess; - struct WMPStream* pWS = *ppWS; - - fclose(pWS->state.file.pFile); - Call(WMPFree((void**)ppWS)); - -Cleanup: - return err; -} - -Bool EOSWS_File(struct WMPStream* pWS) -{ - return feof(pWS->state.file.pFile); -} - -ERR ReadWS_File(struct WMPStream* pWS, void* pv, size_t cb) -{ - // ERR err = WMP_errSuccess; - - return (fread(pv, cb, 1, pWS->state.file.pFile) == 1) ? WMP_errSuccess : WMP_errFileIO; -} - -ERR WriteWS_File(struct WMPStream* pWS, const void* pv, size_t cb) -{ - ERR err = WMP_errSuccess; - - if (0 != cb) - { - FailIf(1 != fwrite(pv, cb, 1, pWS->state.file.pFile), WMP_errFileIO); - } - -Cleanup: - return err; -} - -ERR SetPosWS_File(struct WMPStream* pWS, size_t offPos) -{ - ERR err = WMP_errSuccess; - - FailIf(0 != fseek(pWS->state.file.pFile, (long)offPos, SEEK_SET), WMP_errFileIO); - -Cleanup: - return err; -} - -ERR GetPosWS_File(struct WMPStream* pWS, size_t* poffPos) -{ - ERR err = WMP_errSuccess; - long lOff = 0; - - FailIf(-1 == (lOff = ftell(pWS->state.file.pFile)), WMP_errFileIO); - *poffPos = (size_t)lOff; - -Cleanup: - return err; -} - -//---------------------------------------------------------------- -ERR CreateWS_Memory(struct WMPStream** ppWS, void* pv, size_t cb) -{ - ERR err = WMP_errSuccess; - struct WMPStream* pWS = NULL; - - Call(WMPAlloc((void**)ppWS, sizeof(**ppWS))); - pWS = *ppWS; - - pWS->state.buf.pbBuf = pv; - pWS->state.buf.cbBuf = cb; - pWS->state.buf.cbCur = 0; - - pWS->Close = CloseWS_Memory; - pWS->EOS = EOSWS_Memory; - - pWS->Read = ReadWS_Memory; - pWS->Write = WriteWS_Memory; - - pWS->SetPos = SetPosWS_Memory; - pWS->GetPos = GetPosWS_Memory; - -Cleanup: - return err; -} - -ERR CloseWS_Memory(struct WMPStream** ppWS) -{ - ERR err = WMP_errSuccess; - - Call(WMPFree((void**)ppWS)); - -Cleanup: - return err; -} - -Bool EOSWS_Memory(struct WMPStream* pWS) -{ - return pWS->state.buf.cbBuf <= pWS->state.buf.cbCur; -} - -ERR ReadWS_Memory(struct WMPStream* pWS, void* pv, size_t cb) -{ - ERR err = WMP_errSuccess; - - // FailIf(pWS->state.buf.cbBuf < pWS->state.buf.cbCur, WMP_errBufferOverflow); - if (pWS->state.buf.cbBuf < pWS->state.buf.cbCur) - return err; - - FailIf(pWS->state.buf.cbCur + cb < pWS->state.buf.cbCur, WMP_errBufferOverflow); - if (pWS->state.buf.cbBuf < pWS->state.buf.cbCur + cb) - { - cb = pWS->state.buf.cbBuf - pWS->state.buf.cbCur; - } - - memcpy(pv, pWS->state.buf.pbBuf + pWS->state.buf.cbCur, cb); - pWS->state.buf.cbCur += cb; - -Cleanup: - return err; -} - -ERR WriteWS_Memory(struct WMPStream* pWS, const void* pv, size_t cb) -{ - ERR err = WMP_errSuccess; - - FailIf(pWS->state.buf.cbCur + cb < pWS->state.buf.cbCur, WMP_errBufferOverflow); - FailIf(pWS->state.buf.cbBuf < pWS->state.buf.cbCur + cb, WMP_errBufferOverflow); - - memcpy(pWS->state.buf.pbBuf + pWS->state.buf.cbCur, pv, cb); - pWS->state.buf.cbCur += cb; - -Cleanup: - return err; -} - -ERR SetPosWS_Memory(struct WMPStream* pWS, size_t offPos) -{ - ERR err = WMP_errSuccess; - - //While the following condition is possibly useful, failure occurs - //at the end of a file since packets beyond the end may be accessed - //FailIf(pWS->state.buf.cbBuf < offPos, WMP_errBufferOverflow); - pWS->state.buf.cbCur = offPos; - - //Cleanup: - return err; -} - -ERR GetPosWS_Memory(struct WMPStream* pWS, size_t* poffPos) -{ - *poffPos = pWS->state.buf.cbCur; - - return WMP_errSuccess; -} - -//================================================================= -// Linked list based WMPStream -// - for indefinite size, multiple stream out -// - reads not supported in this mode -//================================================================= -ERR CreateWS_List(struct WMPStream** ppWS) -{ - ERR err = WMP_errSuccess; - struct WMPStream* pWS = NULL; - - Call(WMPAlloc((void**)ppWS, sizeof(**ppWS) + PACKETLENGTH + sizeof(void *))); - pWS = *ppWS; - - pWS->state.buf.pbBuf = (U8 *)pWS + sizeof(**ppWS) + sizeof(void *); // first buffer points here - - memset(pWS->state.buf.pbBuf - sizeof(void *), 0, sizeof(void *)); - pWS->state.buf.cbBuf = PACKETLENGTH; - pWS->state.buf.cbCur = 0; - pWS->state.buf.cbBufCount = 0; - - pWS->Close = CloseWS_List; - pWS->EOS = NULL; // doesn't get called - - pWS->Read = ReadWS_List; - pWS->Write = WriteWS_List; - - pWS->SetPos = SetPosWS_List; - pWS->GetPos = GetPosWS_List; - - //printf ("create buffer %d: %x\n", pWS->state.buf.cbBufCount, pWS->state.buf.pbBuf); - -Cleanup: - return err; -} - -ERR CloseWS_List(struct WMPStream** ppWS) -{ - ERR err = WMP_errSuccess; - - if (ppWS) { - U8 *pBuf = (U8 *)(ppWS[0] + 1); // pointer to buffer - U8 *pNext = (U8 *)(((void **)pBuf)[0]); - while (pNext) { - //struct WMPStream *pWS = ppWS[0]; - pBuf = pNext; - pNext = (U8 *)(((void **)(pBuf))[0]); - //printf ("delete buffer %x\n", pBuf); - Call(WMPFree((void**)&pBuf)); - } - } - Call(WMPFree((void**)ppWS)); - -Cleanup: - return err; -} - -ERR ReadWS_List(struct WMPStream* pWS, void* pv, size_t cb) -{ - ERR err = WMP_errSuccess; - - FailIf(pWS->state.buf.cbCur + cb < pWS->state.buf.cbCur, WMP_errBufferOverflow); - if (pWS->state.buf.cbBuf < pWS->state.buf.cbCur + PACKETLENGTH * pWS->state.buf.cbBufCount + cb) - { - cb = pWS->state.buf.cbBuf - pWS->state.buf.cbCur - PACKETLENGTH * pWS->state.buf.cbBufCount; - } - - while (cb) { - size_t cl = PACKETLENGTH - pWS->state.buf.cbCur; - if (cl > cb) - cl = cb; - memcpy(pv, pWS->state.buf.pbBuf + pWS->state.buf.cbCur, cl); - pWS->state.buf.cbCur += cl; - pv = (void *)((U8 *)pv + cl); - cb -= cl; - if (pWS->state.buf.cbCur == PACKETLENGTH) { - pWS->state.buf.pbBuf = (U8 *)((void **)(pWS->state.buf.pbBuf - sizeof(void *)))[0] + sizeof(void *); - pWS->state.buf.cbCur = 0; - pWS->state.buf.cbBufCount++; - - //printf ("read buffer %d: %x\n", pWS->state.buf.cbBufCount, pWS->state.buf.pbBuf); - } - } - -Cleanup: - return err; -} - -ERR WriteWS_List(struct WMPStream* pWS, const void* pv, size_t cb) -{ - ERR err = WMP_errSuccess; - - FailIf(pWS->state.buf.cbCur + cb < pWS->state.buf.cbCur, WMP_errBufferOverflow); - FailIf(pWS->state.buf.cbBuf < pWS->state.buf.cbCur + cb, WMP_errBufferOverflow); - - while (cb) { - size_t cl = PACKETLENGTH - pWS->state.buf.cbCur; - if (cl > cb) - cl = cb; - memcpy(pWS->state.buf.pbBuf + pWS->state.buf.cbCur, pv, cl); - pWS->state.buf.cbCur += cl; - pv = (const void *)((U8 *)pv + cl); - cb -= cl; - if (pWS->state.buf.cbCur == PACKETLENGTH) { // allocate next packet in list - U8 *pBuf = NULL; - void **pPtrLoc = (void **)(pWS->state.buf.pbBuf - sizeof(void *)); - Call(WMPAlloc((void **)&pBuf, PACKETLENGTH + sizeof(void *))); - pPtrLoc[0] = (void *)pBuf; - pWS->state.buf.pbBuf = pBuf + sizeof(void *); - pWS->state.buf.cbBuf += PACKETLENGTH; - memset(pBuf, 0, sizeof(void *)); - pWS->state.buf.cbCur = 0; - pWS->state.buf.cbBufCount++; - - //printf ("create buffer %d: %x\n", pWS->state.buf.cbBufCount, pWS->state.buf.pbBuf); - } - } - -Cleanup: - return err; -} - -ERR SetPosWS_List(struct WMPStream* pWS, size_t offPos) -{ - ERR err = WMP_errSuccess; - - // get the first buffer - U8 *pBuf = (U8 *)(pWS + 1); // pointer to buffer - pWS->state.buf.cbCur = 0; - pWS->state.buf.cbBufCount = 0; - - while (offPos >= PACKETLENGTH && pBuf != NULL) { - pBuf = (U8 *)(((void **)pBuf)[0]); - offPos -= PACKETLENGTH; - pWS->state.buf.cbBufCount++; - } - - if (pBuf == NULL) - goto Cleanup; - - pWS->state.buf.cbCur = offPos; - pWS->state.buf.pbBuf = pBuf + sizeof(void *); - //printf ("seek buffer %d: %x\n", pWS->state.buf.cbBufCount, pWS->state.buf.pbBuf); - -Cleanup: - return err; -} - -ERR GetPosWS_List(struct WMPStream* pWS, size_t* poffPos) -{ - *poffPos = pWS->state.buf.cbCur + PACKETLENGTH * pWS->state.buf.cbBufCount; - - return WMP_errSuccess; -} - -//================================================================ -// Simple BitIO access functions -//================================================================ -// init SimpleBitIO -ERR attach_SB(SimpleBitIO* pSB, struct WMPStream* pWS) -{ - pSB->pWS = pWS; - pSB->cbRead = 0; - pSB->bAccumulator = 0; - pSB->cBitLeft = 0; - - return WMP_errSuccess; -} - -// extract upto 32bit from input stream -U32 getBit32_SB(SimpleBitIO* pSB, U32 cBits) -{ - U32 rc = 0; - - while (pSB->cBitLeft < cBits) - { - rc <<= pSB->cBitLeft; - rc |= pSB->bAccumulator >> (8 - pSB->cBitLeft); - - cBits -= pSB->cBitLeft; - - pSB->pWS->Read(pSB->pWS, &pSB->bAccumulator, 1); - pSB->cbRead++; - pSB->cBitLeft = 8; - } - - rc <<= cBits; - rc |= pSB->bAccumulator >> (8 - cBits); - pSB->bAccumulator <<= cBits; - pSB->cBitLeft -= cBits; - - return rc; -} - -// ignore input to byte boundary -Void flushToByte_SB(SimpleBitIO* pSB) -{ - pSB->bAccumulator = 0; - pSB->cBitLeft = 0; -} - -// return read byte count -U32 getByteRead_SB(SimpleBitIO* pSB) -{ - return pSB->cbRead; -} - -ERR detach_SB(SimpleBitIO* pSB) -{ - assert(0 == pSB->cBitLeft); - pSB->pWS = NULL; - - return WMP_errSuccess; -} - -//================================================================ -// Memory access functions -//================================================================ -#if (defined(WIN32) && !defined(UNDER_CE)) || (defined(UNDER_CE) && defined(_ARM_)) -// WinCE ARM and Desktop x86 -#else -// other platform -#ifdef _BIG__ENDIAN_ -#define _byteswap_ulong(x) (x) -#else // _BIG__ENDIAN_ -U32 _byteswap_ulong(U32 bits) -{ - U32 r = (bits & 0xffu) << 24; - r |= (bits << 8) & 0xff0000u; - r |= ((bits >> 8) & 0xff00u); - r |= ((bits >> 24) & 0xffu); - - return r; -} -#endif // _BIG__ENDIAN_ -#endif - -U32 load4BE(void* pv) -{ -#ifdef _BIG__ENDIAN_ - #ifdef _NO_UNALIGNED_LOAD_ - U32 v; - memcpy(&v, pv, 4); - return v; - #else - return (*(U32*)pv); - #endif -#else // _BIG__ENDIAN_ -#if defined(__EMSCRIPTEN__) - U32 v; - const U8* pb = (const U8*)pv; - v = ((U32)(*(pb + 0)) << 24) | ((U32)(*(pb + 1)) << 16) | ((U32)(*(pb + 2)) << 8) | (*(pb + 3)); - return v; -#else -#if defined(_M_IA64) || defined(_ARM_) - U32 v; - v = ((U16 *)pv)[0]; - v |= ((U32)((U16 *)pv)[1]) << 16; - return _byteswap_ulong(v); -#else // _M_IA64 - #ifdef _NO_UNALIGNED_LOAD_ - U32 v; - memcpy(&v, pv, 4); - return _byteswap_ulong(v); - #else - return _byteswap_ulong(*(U32*)pv); - #endif -#endif // _M_IA64 -#endif -#endif // _BIG__ENDIAN_ -} - -#define LOAD16 load4BE - -#ifdef _BIG__ENDIAN_ -#define WRITESWAP_ENDIAN(a) ((a)>>16) -#else // _BIG__ENDIAN_ -#define WRITESWAP_ENDIAN(a) _byteswap_ulong(a) -#endif // _BIG__ENDIAN_ - -//================================================================ -// Bit I/O functions -//================================================================ -Int allocateBitIOInfo(CWMImageStrCodec* pSC) -{ - U32 cNumBitIO; - SUBBAND sbSubband = pSC->WMISCP.sbSubband; - - pSC->cSB = (sbSubband == SB_DC_ONLY ? 1 : (sbSubband == SB_NO_HIGHPASS ? 2 : (sbSubband == SB_NO_FLEXBITS ? 3 : 4))); - - // # of additional BitIOs other than pSC->pIOHeader - if (!pSC->m_param.bIndexTable) { // pure streaming mode, no index table, no additional BitIO! - assert(pSC->WMISCP.bfBitstreamFormat == SPATIAL && pSC->WMISCP.cNumOfSliceMinus1H + pSC->WMISCP.cNumOfSliceMinus1V == 0); - cNumBitIO = 0; - } - else if (pSC->WMISCP.bfBitstreamFormat == SPATIAL) - cNumBitIO = pSC->WMISCP.cNumOfSliceMinus1V + 1; - else - cNumBitIO = (pSC->WMISCP.cNumOfSliceMinus1V + 1) * pSC->cSB; - - if (cNumBitIO > MAX_TILES * 4) - return ICERR_ERROR; - - // allocate additional BitIos - if (cNumBitIO > 0) { - U32 i = 0; - size_t cb = sizeof(BitIOInfo) * cNumBitIO + (PACKETLENGTH * 4 - 1) + PACKETLENGTH * 4 * cNumBitIO; - U8* pb = (U8*)malloc(cb); - - if (NULL == pb) return ICERR_ERROR; - memset(pb, 0, cb); - - pSC->m_ppBitIO = (BitIOInfo**)pb; - pb += sizeof(BitIOInfo) * cNumBitIO; - - pb = (U8*)ALIGNUP(pb, PACKETLENGTH * 4) + PACKETLENGTH * 2; - for (i = 0; i < cNumBitIO; ++i) { - pSC->m_ppBitIO[i] = (BitIOInfo*)pb; - pb += PACKETLENGTH * 4; - } - - // allocate index table - if (cNumBitIO > MAX_TILES * 4 || pSC->WMISCP.cNumOfSliceMinus1H >= MAX_TILES) - return ICERR_ERROR; - pSC->pIndexTable = malloc((size_t)cNumBitIO * (pSC->WMISCP.cNumOfSliceMinus1H + 1) * sizeof(size_t)); - if (NULL == pSC->pIndexTable) return ICERR_ERROR; - } - - pSC->cNumBitIO = cNumBitIO; - - return ICERR_OK; -} - -Int setBitIOPointers(CWMImageStrCodec* pSC) -{ - if (pSC->cNumBitIO > 0) { - U32 i; - - for (i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i++) { - CCodingContext * pContext = &pSC->m_pCodingContext[i]; - if (pSC->WMISCP.bfBitstreamFormat == SPATIAL) { - pContext->m_pIODC = pContext->m_pIOLP = pContext->m_pIOAC = pContext->m_pIOFL = pSC->m_ppBitIO[i]; - } - else { - U32 j = pSC->cSB; - - pContext->m_pIODC = pSC->m_ppBitIO[i * j]; - if (j > 1) - pContext->m_pIOLP = pSC->m_ppBitIO[i * j + 1]; - if (j > 2) - pContext->m_pIOAC = pSC->m_ppBitIO[i * j + 2]; - if (j > 3) - pContext->m_pIOFL = pSC->m_ppBitIO[i * j + 3]; - } - } - } - else { // streamimg mode - CCodingContext * pContext = &pSC->m_pCodingContext[0]; - pContext->m_pIODC = pContext->m_pIOLP = pContext->m_pIOAC = pContext->m_pIOFL = pSC->pIOHeader; - } - - return ICERR_OK; -} - -Int allocateTileInfo(CWMImageStrCodec * pSC) -{ - size_t i; - - if (pSC->WMISCP.cNumOfSliceMinus1V >= MAX_TILES) - return ICERR_ERROR; - pSC->pTile = (CWMITile *)malloc((pSC->WMISCP.cNumOfSliceMinus1V + 1) * sizeof(CWMITile)); - if (pSC->pTile == NULL) - return ICERR_ERROR; - memset(pSC->pTile, 0, (pSC->WMISCP.cNumOfSliceMinus1V + 1) * sizeof(CWMITile)); - - for (i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i++) - pSC->pTile[i].cNumQPHP = pSC->pTile[i].cNumQPLP = 1, pSC->pTile[i].cBitsHP = pSC->pTile[i].cBitsLP = 0; - - return ICERR_OK; -} - -Void freeTileInfo(CWMImageStrCodec * pSC) -{ - size_t iTile; - - if ((pSC->m_param.uQPMode & 1) != 0) // not DC uniform - { - for (iTile = 0; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile++) - freeQuantizer(pSC->pTile[iTile].pQuantizerDC); - } - else - { - freeQuantizer(pSC->pTile[0].pQuantizerDC); - } - - if (pSC->WMISCP.sbSubband != SB_DC_ONLY) - { - if ((pSC->m_param.uQPMode & 2) != 0) // not LP uniform - { - for (iTile = 0; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile++) - freeQuantizer(pSC->pTile[iTile].pQuantizerLP); - } - else - { - freeQuantizer(pSC->pTile[0].pQuantizerLP); - } - } - - if (pSC->WMISCP.sbSubband != SB_DC_ONLY && pSC->WMISCP.sbSubband != SB_NO_HIGHPASS) - { - if ((pSC->m_param.uQPMode & 4) != 0) // not HP uniform - { - for (iTile = 0; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile++) - freeQuantizer(pSC->pTile[iTile].pQuantizerHP); - } - else - { - freeQuantizer(pSC->pTile[0].pQuantizerHP); - } - } - - if (pSC->pTile != NULL) - free(pSC->pTile); -} - -Int allocateQuantizer(CWMIQuantizer * pQuantizer[MAX_CHANNELS], size_t cChannel, size_t cQP) -{ - size_t iCh; - - if (cQP > 16 || cChannel > MAX_CHANNELS) - return ICERR_ERROR; - pQuantizer[0] = (CWMIQuantizer *)malloc(cQP * sizeof(CWMIQuantizer) * cChannel); - if (pQuantizer[0] == NULL) - return ICERR_ERROR; - - for (iCh = 1; iCh < cChannel; iCh++) - pQuantizer[iCh] = pQuantizer[iCh - 1] + cQP; - - return ICERR_OK; -} - -Void freeQuantizer(CWMIQuantizer * pQuantizer[MAX_CHANNELS]) -{ - if (pQuantizer[0] != NULL) - free(pQuantizer[0]); -} - -Void formatQuantizer(CWMIQuantizer * pQuantizer[MAX_CHANNELS], U8 cChMode, size_t cCh, size_t iPos, Bool bShiftedUV, - Bool bScaledArith) -{ - size_t iCh; - - for (iCh = 0; iCh < cCh; iCh++) { - if (iCh > 0) - { - if (cChMode == 0) // uniform - { - pQuantizer[iCh][iPos] = pQuantizer[0][iPos]; - } - else if (cChMode == 1) // mixed - { - pQuantizer[iCh][iPos] = pQuantizer[1][iPos]; - } - } - remapQP(pQuantizer[iCh] + iPos, (iCh > 0 && bShiftedUV == TRUE) ? SHIFTZERO - 1 : SHIFTZERO, bScaledArith); - } -} - -Void setUniformQuantizer(CWMImageStrCodec * pSC, size_t sb) -{ - size_t iCh, iTile; - - for (iCh = 0; iCh < pSC->m_param.cNumChannels; iCh++) - for (iTile = 1; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile++) - if (sb == 0) // DC - pSC->pTile[iTile].pQuantizerDC[iCh] = pSC->pTile[0].pQuantizerDC[iCh]; - else if (sb == 1) // LP - pSC->pTile[iTile].pQuantizerLP[iCh] = pSC->pTile[0].pQuantizerLP[iCh]; - else // HP - pSC->pTile[iTile].pQuantizerHP[iCh] = pSC->pTile[0].pQuantizerHP[iCh]; -} - -Void useDCQuantizer(CWMImageStrCodec * pSC, size_t iTile) -{ - size_t iCh; - - for (iCh = 0; iCh < pSC->m_param.cNumChannels; iCh++) - pSC->pTile[iTile].pQuantizerLP[iCh][0] = *pSC->pTile[iTile].pQuantizerDC[iCh]; -} - -Void useLPQuantizer(CWMImageStrCodec * pSC, size_t cQP, size_t iTile) -{ - size_t iCh, iQP; - - for (iCh = 0; iCh < pSC->m_param.cNumChannels; iCh++) - for (iQP = 0; iQP < cQP; iQP++) - pSC->pTile[iTile].pQuantizerHP[iCh][iQP] = pSC->pTile[iTile].pQuantizerLP[iCh][iQP]; -} - -U8 dquantBits(U8 cQP) -{ - return (cQP < 2 ? 0 : (cQP < 4 ? 1 : (cQP < 6 ? 2 : (cQP < 10 ? 3 : 4)))); -} - -#ifndef ARMOPT_BITIO -U32 peekBit16(BitIOInfo* pIO, U32 cBits) -{ - PEEKBIT16(pIO, cBits); -} - -U32 flushBit16(BitIOInfo* pIO, U32 cBits) -{ - FLUSHBIT16(pIO, cBits); -} - -U32 getBit16(BitIOInfo* pIO, U32 cBits) -{ - U32 uiRet = peekBit16(pIO, cBits); - flushBit16(pIO, cBits); - - return uiRet; -} - -U32 getBool16(BitIOInfo* pIO) -{ - U32 uiRet = peekBit16(pIO, 1); - flushBit16(pIO, 1); - return uiRet; -} - -/** this function returns cBits if zero is read, or a signed value if first cBits are not all zero **/ -I32 getBit16s(BitIOInfo* pIO, U32 cBits) -{ - U32 uiRet = peekBit16(pIO, cBits + 1); - if (uiRet < 2) { - flushBit16(pIO, cBits); - return 0; - } - else { - flushBit16(pIO, cBits + 1); - if (uiRet & 1) - return (-(I32)(uiRet >> 1)); - else - return (I32)(uiRet >> 1); - } -} - -U32 getBit32(BitIOInfo* pIO, U32 cBits) -{ - U32 uiRet = 0; - - assert(0 <= (I32)cBits && cBits <= 32); - - if (16 < cBits) - { - uiRet = getBit16(pIO, 16); - cBits -= 16; - uiRet <<= cBits; - } - - uiRet |= getBit16(pIO, cBits); - - return uiRet; -} - -U32 flushToByte(BitIOInfo* pIO) -{ - return flushBit16(pIO, (16 - pIO->cBitsUsed) & 7); -} -#endif // ARMOPT_BITIO - -//---------------------------------------------------------------- -Void putBit16z(BitIOInfo* pIO, U32 uiBits, U32 cBits) -{ - assert(cBits <= 16); - assert(0 == uiBits >> cBits); - - pIO->uiAccumulator = (pIO->uiAccumulator << cBits) | uiBits; - pIO->cBitsUsed += cBits; - - *(U16*)pIO->pbCurrent = (U16)WRITESWAP_ENDIAN(pIO->uiAccumulator << (32 - pIO->cBitsUsed)); - - pIO->pbCurrent = MASKPTR(pIO->pbCurrent + ((pIO->cBitsUsed >> 3) & 2), pIO->iMask); - pIO->cBitsUsed &= 16 - 1; -} - -Void putBit16(BitIOInfo* pIO, U32 uiBits, U32 cBits) -{ - assert(cBits <= 16); - - uiBits &= ~(-1 << cBits); - putBit16z(pIO, uiBits, cBits); -} - -Void putBit32(BitIOInfo* pIO, U32 uiBits, U32 cBits) -{ - assert(0 <= (I32)cBits && cBits <= 32); - - if (16 < cBits) - { - putBit16(pIO, uiBits >> (cBits - 16), 16); - cBits -= 16; - } - - putBit16(pIO, uiBits, cBits); -} - -Void fillToByte(BitIOInfo* pIO) -{ - putBit16z(pIO, 0, (16 - pIO->cBitsUsed) & 7); -} - -//---------------------------------------------------------------- -U32 getBit16_S(CWMImageStrCodec* pSC, BitIOInfo* pIO, U32 cBits) -{ - U32 rc = getBit16(pIO, cBits); - readIS_L1(pSC, pIO); - - return rc; -} - -U32 putBit16_S(CWMImageStrCodec* pSC, BitIOInfo* pIO, U32 uiBits, U32 cBits) -{ - putBit16(pIO, uiBits, cBits); - writeIS_L1(pSC, pIO); - - return 0; -} - - -//---------------------------------------------------------------- -// Query buffered data size held in BitIOInfo -// Write() for Enc, Read() for Dec -//---------------------------------------------------------------- -U32 getSizeRead(BitIOInfo* pIO) -{ - return (U32)(UINTPTR_T)(pIO->pbStart + PACKETLENGTH * 2 - pIO->pbCurrent) - pIO->cBitsUsed / 8; -} - -U32 getSizeWrite(BitIOInfo* pIO) -{ - return (U32)(UINTPTR_T)(pIO->pbCurrent + (pIO->pbStart <= pIO->pbCurrent ? 0 : PACKETLENGTH * 2) - pIO->pbStart) + pIO->cBitsUsed / 8; -} - -//---------------------------------------------------------------- -// Query stream offset from attached BitIO object for dec -//---------------------------------------------------------------- -U32 getPosRead(BitIOInfo* pIO) -{ - size_t cbCached = (pIO->pbStart + PACKETLENGTH * 2 - pIO->pbCurrent) - pIO->cBitsUsed / 8; - return (U32)(pIO->offRef - cbCached); -} - -//================================================================ -// Block I/O functions -//================================================================ -#ifndef ARMOPT_BITIO -ERR attachISRead(BitIOInfo* pIO, struct WMPStream* pWS, CWMImageStrCodec* pSC) -{ - UNREFERENCED_PARAMETER(pSC); - - pWS->GetPos(pWS, &pIO->offRef); - - pIO->pbStart = (U8*)pIO - PACKETLENGTH * 2; - pIO->pbCurrent = pIO->pbStart; - - PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); - pWS->SetPos(pWS, pIO->offRef); - pWS->Read(pWS, pIO->pbStart, PACKETLENGTH * 2); - PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); - pIO->offRef += PACKETLENGTH * 2; - - pIO->uiAccumulator = load4BE(pIO->pbStart); - - pIO->cBitsUsed = 0; - pIO->iMask = ~(PACKETLENGTH * 2); - pIO->iMask &= ~1; - - pIO->pWS = pWS; - return WMP_errSuccess; -} - -ERR readIS(CWMImageStrCodec* pSC, BitIOInfo* pIO) -{ - ERR err = WMP_errSuccess; - - UNREFERENCED_PARAMETER(pSC); - - if (PACKET1(pIO->pbStart, pIO->pbCurrent, PACKETLENGTH)) - { - struct WMPStream *pWS = pIO->pWS; - - PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); - //Call(0 != pIO->pWS->Read(pIO->pWS, pIO->pbStart, PACKETLENGTH)); - // TODO: add error checking code - pWS->SetPos(pWS, pIO->offRef); - pWS->Read(pWS, pIO->pbStart, PACKETLENGTH); - pIO->offRef += PACKETLENGTH; - PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); - - // make shadow copy for first 4B - pIO->uiShadow = *(U32*)pIO->pbStart; // TODO: does this need to be made endianess-aware? - - // reposition pbPacket pointer - pIO->pbStart = MASKPTR(pIO->pbStart + PACKETLENGTH, pIO->iMask); - } - - //Cleanup: - return err; -} - -ERR detachISRead(CWMImageStrCodec* pSC, BitIOInfo* pIO) -{ - ERR err = WMP_errSuccess; - - struct WMPStream* pWS = pIO->pWS; - size_t cbRemain = 0; - - // we can ONLY detach IStream at byte boundary - flushToByte(pIO); - assert(0 == (pIO->cBitsUsed % 8)); - Call(readIS_L1(pSC, pIO)); - - // set stream to right offset, undo buffering - cbRemain = (pIO->pbStart + PACKETLENGTH * 2) - (pIO->pbCurrent + pIO->cBitsUsed / 8); - pWS->SetPos(pWS, pIO->offRef - cbRemain); - - pIO->pWS = NULL; -Cleanup: - return err; -} -#endif // ARMOPT_BITIO - -//---------------------------------------------------------------- -ERR attachISWrite(BitIOInfo* pIO, struct WMPStream* pWS) -{ - pWS->GetPos(pWS, &pIO->offRef); - - pIO->pbStart = (U8*)pIO - PACKETLENGTH * 2; - pIO->pbCurrent = pIO->pbStart; - - pIO->uiAccumulator = 0; - pIO->cBitsUsed = 0; - pIO->iMask = ~(PACKETLENGTH * 2); - - pIO->pWS = pWS; - return WMP_errSuccess; -} - -// write out packet if we have >=1 packet data filled -ERR writeIS(CWMImageStrCodec* pSC, BitIOInfo* pIO) -{ - ERR err = WMP_errSuccess; - - UNREFERENCED_PARAMETER(pSC); - - if (PACKET1(pIO->pbStart, pIO->pbCurrent, PACKETLENGTH)) - { - PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); - err = pIO->pWS->Write(pIO->pWS, pIO->pbStart, PACKETLENGTH); - PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); - Call(err); - - // reposition pbStart pointer - pIO->pbStart = MASKPTR(pIO->pbStart + PACKETLENGTH, pIO->iMask); - } - -Cleanup: - return err; -} - -// write out partially filled buffer and detach bitIO from IStream -ERR detachISWrite(CWMImageStrCodec* pSC, BitIOInfo* pIO) -{ - ERR err = WMP_errSuccess; - - // we can ONLY detach IStream at byte boundary - assert(0 == (pIO->cBitsUsed % 8)); - Call(writeIS_L1(pSC, pIO)); - - PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); - err = pIO->pWS->Write(pIO->pWS, pIO->pbStart, pIO->pbCurrent + pIO->cBitsUsed / 8 - pIO->pbStart); - PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); - Call(err); - - pIO->pWS = NULL; -Cleanup: - return err; -} - -//========================= -// Performance Measurement -//========================= -#ifndef DISABLE_PERF_MEASUREMENT - -void OutputIndivPerfTimer(struct PERFTIMERSTATE *pPerfTimer, - char *pszTimerName, - char *pszDescription, - float fltMegaPixels) -{ - PERFTIMERRESULTS rResults; - Bool fResult; - - fResult = FALSE; - printf("%s (%s): ", pszTimerName, pszDescription); - if (pPerfTimer) - { - fResult = PerfTimerGetResults(pPerfTimer, &rResults); - if (fResult) - { - printf("%.3f milliseconds, %.6f MP/sec\n", (float)rResults.iElapsedTime / 1000000, - 1000000000 * fltMegaPixels / rResults.iElapsedTime); - if (rResults.iZeroTimeIntervals > 0) - { - printf(" *** WARNING: %d time intervals were measured as zero. " - "This perf timer has insufficient precision!\n\n", - (int)rResults.iZeroTimeIntervals); - } - } - } - if (FALSE == fResult) - printf("Results not available!\n"); -} - - -void OutputPerfTimerReport(CWMImageStrCodec *pState) -{ - float fltMegaPixels; - - assert(pState->m_fMeasurePerf); - - printf("***************************************************************************\n"); - printf("* Perf Report\n"); - printf("***************************************************************************\n\n"); - - fltMegaPixels = (float)pState->WMII.cWidth * pState->WMII.cHeight / 1000000; - printf("Image Width = %d, Height = %d, total MegaPixels = %.1f MP\n", - (int)pState->WMII.cWidth, (int)pState->WMII.cHeight, fltMegaPixels); - - OutputIndivPerfTimer(pState->m_ptEncDecPerf, "m_ptEncDecPerf", "excl I/O", fltMegaPixels); - OutputIndivPerfTimer(pState->m_ptEndToEndPerf, "m_ptEndToEndPerf", "incl I/O", fltMegaPixels); -} - -#endif // DISABLE_PERF_MEASUREMENT diff --git a/Src/JxrDecode/Jxr/strcodec.h b/Src/JxrDecode/Jxr/strcodec.h deleted file mode 100644 index 0cc97069..00000000 --- a/Src/JxrDecode/Jxr/strcodec.h +++ /dev/null @@ -1,678 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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 - -#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 // UNREFERENCED_PARAMETER - -#ifdef UNDER_CE -#define PLATFORM_WCE -#include "arm.h" -#endif - -#if defined(__ANSI__) || defined(__GNUC__) -#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 _WIN32 - 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); diff --git a/Src/JxrDecode/Jxr/strdec.c b/Src/JxrDecode/Jxr/strdec.c deleted file mode 100644 index 5823f15f..00000000 --- a/Src/JxrDecode/Jxr/strdec.c +++ /dev/null @@ -1,3628 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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 "jxr_defines.h" -#include "strcodec.h" -#include "decode.h" -#include "strTransform.h" -#include -#include "perfTimer.h" -#include "JXRGlue.h" - -#ifdef MEM_TRACE -#define TRACE_MALLOC 1 -#define TRACE_NEW 0 -#define TRACE_HEAP 0 -#include "memtrace.h" -#endif - -#ifdef X86OPT_INLINE -#define _FORCEINLINE __forceinline -#else // X86OPT_INLINE -#define _FORCEINLINE -#endif // X86OPT_INLINE - -#if defined(WMP_OPT_SSE2) || defined(WMP_OPT_CC_DEC) || defined(WMP_OPT_TRFM_DEC) -void StrDecOpt(CWMImageStrCodec* pSC); -#endif // OPT defined - -Int processMacroblockDec(CWMImageStrCodec *); - -U8 readQuantizerSB(U8 pQPIndex[MAX_CHANNELS], SimpleBitIO * pIO, size_t cChannel) -{ - U8 cChMode = 0; - - if(cChannel >= MAX_CHANNELS) - return 0; - - if(cChannel > 1) - cChMode = (U8)getBit32_SB(pIO, 2); // Channel mode - - pQPIndex[0] = (U8)getBit32_SB(pIO, 8); // Y - - if(cChMode == 1) // MIXED - pQPIndex[1] = (U8)getBit32_SB(pIO, 8); // UV - else if(cChMode > 0){ // INDEPENDENT - size_t i; - - for(i = 1; i < cChannel; i ++) -#pragma prefast(suppress: __WARNING_UNRELATED_LOOP_TERMINATION_NO_SIZEEXPR, "PREfast false alarm: 1 <= i < MAX_CHANNELS, no buffer over/underrun!") - pQPIndex[i] = (U8)getBit32_SB(pIO, 8); // UV - } - - return cChMode; -} - -U8 readQuantizer(CWMIQuantizer * pQuantizer[MAX_CHANNELS], BitIOInfo * pIO, size_t cChannel, size_t iPos) -{ - U8 cChMode = 0; - - if(cChannel > 1) - cChMode = (U8)getBit16(pIO, 2); // Channel mode - - pQuantizer[0][iPos].iIndex = (U8)getBit16(pIO, 8); // Y - - if(cChMode == 1) // MIXED - pQuantizer[1][iPos].iIndex = (U8)getBit16(pIO, 8); // UV - else if(cChMode > 0){ // INDEPENDENT - size_t i; - - for(i = 1; i < cChannel; i ++) - pQuantizer[i][iPos].iIndex = (U8)getBit16(pIO, 8); // UV - } - - return cChMode; -} - -// packet header: 00000000 00000000 00000001 ?????xxx -// xxx: 000(spatial) 001(DC) 010(AD) 011(AC) 100(FL) 101-111(reserved) -// ?????: (iTileY * cNumOfSliceV + iTileX) % 32 -Int readPacketHeader(BitIOInfo * pIO, U8 ptPacketType, U8 pID) -{ - UNREFERENCED_PARAMETER( ptPacketType ); - UNREFERENCED_PARAMETER( pID ); - if(getBit16(pIO, 8) != 0 || getBit16(pIO, 8) != 0 || getBit16(pIO, 8) != 1) - return ICERR_ERROR; - getBit16(pIO, 8); - return ICERR_OK; -} - -Int readTileHeaderDC(CWMImageStrCodec * pSC, BitIOInfo * pIO) -{ - if((pSC->m_param.uQPMode & 1) != 0){ // not DC uniform - size_t iTile; - CWMITile * pTile = pSC->pTile + pSC->cTileColumn; - - if(pSC->cTileRow + pSC->cTileColumn == 0) // allocate DC QP info - for(iTile = 0; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile ++) - if(allocateQuantizer(pSC->pTile[iTile].pQuantizerDC, pSC->m_param.cNumChannels, 1) != ICERR_OK) - return ICERR_ERROR; - - pTile->cChModeDC = readQuantizer(pTile->pQuantizerDC, pIO, pSC->m_param.cNumChannels, 0); - formatQuantizer(pTile->pQuantizerDC, pTile->cChModeDC, pSC->m_param.cNumChannels, 0, TRUE, pSC->m_param.bScaledArith); - } - - return ICERR_OK; -} - -Int readTileHeaderLP(CWMImageStrCodec * pSC, BitIOInfo * pIO) -{ - if(pSC->WMISCP.sbSubband != SB_DC_ONLY && (pSC->m_param.uQPMode & 2) != 0){ // not LP uniform - CWMITile * pTile = pSC->pTile + pSC->cTileColumn; - U8 i; - - pTile->bUseDC = (getBit16(pIO, 1) == 1 ? TRUE : FALSE); - pTile->cBitsLP = 0; - pTile->cNumQPLP = 1; - - if(pSC->cTileRow > 0) - freeQuantizer(pTile->pQuantizerLP); - - if(pTile->bUseDC == TRUE){ - if(allocateQuantizer(pTile->pQuantizerLP, pSC->m_param.cNumChannels, pTile->cNumQPLP) != ICERR_OK) - return ICERR_ERROR; - useDCQuantizer(pSC, pSC->cTileColumn); - } - else{ - pTile->cNumQPLP = (U8)getBit16(pIO, 4) + 1; - pTile->cBitsLP = dquantBits(pTile->cNumQPLP); - - if(allocateQuantizer(pTile->pQuantizerLP, pSC->m_param.cNumChannels, pTile->cNumQPLP) != ICERR_OK) - return ICERR_ERROR; - - for(i = 0; i < pTile->cNumQPLP; i ++){ - pTile->cChModeLP[i] = readQuantizer(pTile->pQuantizerLP, pIO, pSC->m_param.cNumChannels, i); - formatQuantizer(pTile->pQuantizerLP, pTile->cChModeLP[i], pSC->m_param.cNumChannels, i, TRUE, pSC->m_param.bScaledArith); - } - } - } - - return ICERR_OK; -} - -Int readTileHeaderHP(CWMImageStrCodec * pSC, BitIOInfo * pIO) -{ - if(pSC->WMISCP.sbSubband != SB_DC_ONLY && pSC->WMISCP.sbSubband != SB_NO_HIGHPASS && (pSC->m_param.uQPMode & 4) != 0){ // not HP uniform - CWMITile * pTile = pSC->pTile + pSC->cTileColumn; - U8 i; - - pTile->bUseLP = (getBit16(pIO, 1) == 1 ? TRUE : FALSE); - pTile->cBitsHP = 0; - pTile->cNumQPHP = 1; - - if(pSC->cTileRow > 0) - freeQuantizer(pTile->pQuantizerHP); - - if(pTile->bUseLP == TRUE){ - pTile->cNumQPHP = pTile->cNumQPLP; - if(allocateQuantizer(pTile->pQuantizerHP, pSC->m_param.cNumChannels, pTile->cNumQPHP) != ICERR_OK) - return ICERR_ERROR; - useLPQuantizer(pSC, pTile->cNumQPHP, pSC->cTileColumn); - } - else{ - pTile->cNumQPHP = (U8)getBit16(pIO, 4) + 1; - pTile->cBitsHP = dquantBits(pTile->cNumQPHP); - - if(allocateQuantizer(pTile->pQuantizerHP, pSC->m_param.cNumChannels, pTile->cNumQPHP) != ICERR_OK) - return ICERR_ERROR; - - for(i = 0; i < pTile->cNumQPHP; i ++){ - pTile->cChModeHP[i] = readQuantizer(pTile->pQuantizerHP, pIO, pSC->m_param.cNumChannels, i); - formatQuantizer(pTile->pQuantizerHP, pTile->cChModeHP[i], pSC->m_param.cNumChannels, i, FALSE, pSC->m_param.bScaledArith); - } - } - } - - return ICERR_OK; -} - -Int readPackets(CWMImageStrCodec * pSC) -{ - if(pSC->cColumn == 0 && pSC->cRow == pSC->WMISCP.uiTileY[pSC->cTileRow]){ // start of a new horizontal slice - size_t k; - - if (pSC->m_bSecondary) { - if(pSC->cNumBitIO > 0){ - for(k = 0; k <= pSC->WMISCP.cNumOfSliceMinus1V; k ++){ - // reset coding contexts - ResetCodingContextDec(&pSC->m_pCodingContext[k]); - } - } - else{ // for multiple decoding calls! - ResetCodingContextDec(&pSC->m_pCodingContext[0]); - } - } - else { - // get sizes of each packet and update index table - for(k = 0; k < pSC->cNumBitIO; k ++){ - if(pSC->ppWStream != NULL){ // new API - unsigned cBands = (pSC->WMISCP.bfBitstreamFormat == SPATIAL ? 1 : pSC->cSB); - struct WMPStream ** ppWS = pSC->ppWStream + (pSC->WMISCP.cNumOfSliceMinus1V + 1) * pSC->cTileRow * cBands - + k / cBands * cBands + (k % cBands); - - if(pSC->cTileRow > 0 && pSC->m_ppBitIO[k]->pWS != NULL) // attached to the same packet of the tile on top - detachISRead(pSC, pSC->m_ppBitIO[k]); // detach it - - if(ppWS[0] != NULL) - attachISRead(pSC->m_ppBitIO[k], ppWS[0], pSC); // need to attach it - } - else{ - if(pSC->cTileRow > 0) - detachISRead(pSC, pSC->m_ppBitIO[k]); - pSC->WMISCP.pWStream->SetPos(pSC->WMISCP.pWStream, pSC->pIndexTable[pSC->cNumBitIO * pSC->cTileRow + k] + pSC->cHeaderSize); - attachISRead(pSC->m_ppBitIO[k], pSC->WMISCP.pWStream, pSC); - } - } - - if(pSC->cNumBitIO == 0){ - detachISRead(pSC, pSC->pIOHeader); - if(pSC->ppWStream != NULL){// new API - attachISRead(pSC->pIOHeader, pSC->ppWStream[0], pSC); // need to attach it - } - else{ - pSC->WMISCP.pWStream->SetPos(pSC->WMISCP.pWStream, pSC->cHeaderSize); - attachISRead(pSC->pIOHeader, pSC->WMISCP.pWStream, pSC); - } - } - - for(k = 0; k <= pSC->WMISCP.cNumOfSliceMinus1V; k ++){ - U8 pID = (U8)((pSC->cTileRow * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + k) & 0x1F); - - // read packet header - if(pSC->WMISCP.bfBitstreamFormat == SPATIAL){ - BitIOInfo * pIO = (pSC->cNumBitIO == 0 ? pSC->pIOHeader : pSC->m_ppBitIO[k]); - - if(pIO->pWS == NULL || readPacketHeader(pIO, 0, pID) != ICERR_OK) - return ICERR_ERROR; - pSC->m_pCodingContext[k].m_iTrimFlexBits = (pSC->m_param.bTrimFlexbitsFlag) ? getBit16(pIO, 4) : 0; - } - else{ - if(pSC->m_ppBitIO[k * pSC->cSB + 0] == NULL || readPacketHeader(pSC->m_ppBitIO[k * pSC->cSB + 0], 1, pID) != ICERR_OK) - return ICERR_ERROR; - if(pSC->cSB > 1){ - if(pSC->m_ppBitIO[k * pSC->cSB + 1] == NULL || readPacketHeader(pSC->m_ppBitIO[k * pSC->cSB + 1], 2, pID) != ICERR_OK) - return ICERR_ERROR; - } - if(pSC->cSB > 2){ - if(pSC->m_ppBitIO[k * pSC->cSB + 2] == NULL || readPacketHeader(pSC->m_ppBitIO[k * pSC->cSB + 2], 3, pID) != ICERR_OK) - return ICERR_ERROR; -// readTileHeaderHP(pSC, pSC->m_ppBitIO[k * pSC->cSB + 2]); - } - if(pSC->cSB > 3){ - if(pSC->m_ppBitIO[k * pSC->cSB + 3] == NULL) - return ICERR_ERROR; - readPacketHeader(pSC->m_ppBitIO[k * pSC->cSB + 3], 4, pID); // bad flexbits packet doesn't generate an error - pSC->m_pCodingContext[k].m_iTrimFlexBits = (pSC->m_param.bTrimFlexbitsFlag) ? getBit16(pSC->m_ppBitIO[k * pSC->cSB + 3], 4) : 0; - } - } - - // reset coding contexts - ResetCodingContextDec(&pSC->m_pCodingContext[k]); - } - } - } - - if(pSC->m_bCtxLeft && pSC->m_bCtxTop && pSC->m_bSecondary == FALSE){ - CCodingContext *pContext = &pSC->m_pCodingContext[pSC->cTileColumn]; - - readTileHeaderDC(pSC, pContext->m_pIODC); - if(pSC->m_pNextSC != NULL) - readTileHeaderDC(pSC->m_pNextSC, pContext->m_pIODC); - if(pSC->cSB > 1){ - readTileHeaderLP(pSC, pContext->m_pIOLP); - if(pSC->m_pNextSC != NULL) - readTileHeaderLP(pSC->m_pNextSC, pContext->m_pIOLP); - } - if(pSC->cSB > 2){ - readTileHeaderHP(pSC, pContext->m_pIOAC); - if(pSC->m_pNextSC != NULL) - readTileHeaderHP(pSC->m_pNextSC, pContext->m_pIOAC); - } - } - - return ICERR_OK; -} - -/* inverse transform and overlap possible part of a macroblock */ -Int processMacroblockDec(CWMImageStrCodec * pSC) -{ - const OVERLAP olOverlap = pSC->WMISCP.olOverlap; - // const Bool left = (pSC->cColumn == 0); - const Bool /*top = (pSC->cRow == 0),*/ bottom = (pSC->cRow == pSC->cmbHeight); - const Bool bottomORright = (bottom || pSC->cColumn == pSC->cmbWidth); - // const size_t mbWidth = pSC->cmbWidth, mbX = pSC->cColumn; - // Int iQIndex = 0; - ERR_CODE result = ICERR_OK; - size_t j, jend = (pSC->m_pNextSC != NULL); - - for (j = 0; j <= jend; j++) { - if(!bottomORright){ - CCodingContext *pContext; - - getTilePos(pSC, pSC->cColumn, pSC->cRow); - - if(jend){ - pSC->m_pNextSC->cTileColumn = pSC->cTileColumn; - pSC->m_pNextSC->cTileRow = pSC->cTileRow; - } - - pContext = &pSC->m_pCodingContext[pSC->cTileColumn]; - - if(readPackets(pSC) != ICERR_OK) - return ICERR_ERROR; - - // check if we need to do entropy decode - if(!pSC->m_Dparam->bDecodeFullFrame){ - if(pSC->cColumn == pSC->WMISCP.uiTileX[pSC->cTileColumn]){ // switching to a new tile - size_t rLeft = pSC->m_Dparam->cROILeftX, rRight = pSC->m_Dparam->cROIRightX; - size_t rTop = pSC->m_Dparam->cROITopY, rBottom = pSC->m_Dparam->cROIBottomY; - size_t rExt = (olOverlap == OL_NONE ? 0 : olOverlap == OL_ONE ? 2 : 10); - size_t tLeft = pSC->cColumn * 16, tTop = pSC->WMISCP.uiTileY[pSC->cTileRow] * 16; - size_t tRight = (pSC->cTileColumn != pSC->WMISCP.cNumOfSliceMinus1V ? pSC->WMISCP.uiTileX[pSC->cTileColumn + 1] : pSC->cmbWidth) * 16; - size_t tBottom = (pSC->cTileRow != pSC->WMISCP.cNumOfSliceMinus1H ? pSC->WMISCP.uiTileY[pSC->cTileRow + 1] : pSC->cmbHeight) * 16; - - // tile overlaps with ROI? - pContext->m_bInROI = ((rLeft >= tRight + rExt || rTop >= tBottom + rExt || tLeft > rRight + rExt || - tTop > rBottom + rExt || pSC->cRow * 16 > rBottom + rExt) ? FALSE : TRUE); - } - } - - if(pSC->m_Dparam->bDecodeFullFrame || pContext->m_bInROI){ - if ((result = DecodeMacroblockDC(pSC, pContext, (Int)pSC->cColumn, (Int)pSC->cRow)) != ICERR_OK) - return result; - - if(pSC->m_Dparam->bDecodeLP){ - if ((result = DecodeMacroblockLowpass(pSC, pContext, (Int)pSC->cColumn, (Int)pSC->cRow)) != ICERR_OK) - return result; - } - - predDCACDec(pSC); - - dequantizeMacroblock(pSC); - - if(pSC->m_Dparam->bDecodeHP){ - if ((result = DecodeMacroblockHighpass(pSC, pContext, (Int)pSC->cColumn, (Int)pSC->cRow)) != ICERR_OK) - return result; - predACDec(pSC); - } - - /* keep necessary info for future prediction */ - updatePredInfo(pSC, &pSC->MBInfo, (Int)pSC->cColumn, pSC->m_param.cfColorFormat); - } - } - - if((!pSC->m_Dparam->bDecodeFullFrame) && - ((pSC->cColumn * 16 > pSC->m_Dparam->cROIRightX + 25) || (pSC->cColumn * 16 + 25 < pSC->m_Dparam->cROILeftX) - || (pSC->cRow * 16 > pSC->m_Dparam->cROIBottomY + 25) || (pSC->cRow * 16 + 25 < pSC->m_Dparam->cROITopY))) - { - // do nothing - } - else { - pSC->Transform(pSC); - } - - if (jend) { - pSC->m_pNextSC->cRow = pSC->cRow; - pSC->m_pNextSC->cColumn = pSC->cColumn; - pSC = pSC->m_pNextSC; - } - } - - return result; -} - -//================================================================ -// Inverse Color Conversion -//#define _ICC1(r, g, b) (g^=b^=g^=b, r^=g^=r^=g, b += ((g) >> 1), r += ((g) >> 1), g -= (b+3*r+2) >> 2) -//#define _ICC(r, g, b) (g^=b^=g^=b, r^=g^=r^=g, b += ((g) >> 1), r += ((g) >> 1), g -= (b+3*r+2) >> 2) -//================================================================ -//#define _ICC1(r, g, b) r -= (g >> 1), g += r, r -= ((b + 1) >> 1), b += r -//#define _ICC(r, g, b) r -= (g >> 1), g += r, r -= (b >> 1), b += r - -#define _ICC(r, g, b) (g -= ((r + 0) >> 1), r -= ((b + 1) >> 1) - g, b += r) -#define _ICC_CMYK(c, m, y, k) (k -= ((m + 1) >> 1), m -= (c >> 1) - k, c -= ((y + 1) >> 1) - m, y += c) - -#define _CLIP2(l, v, h) ((v) < (l) ? (l) : ((h) < (v) ? (h) : (v))) -#define _CLIP8(v) ((U8)_CLIP2(0, v, 255)) -#define _CLIP16(v) ((I16)_CLIP2(-32768, v, 32767)) -#define _CLIPU16(v) ((U16)_CLIP2(0, v, 65535)) - -///#define min(a,b) (((a) < (b)) ? (a) : (b)) - -//inverseConvert: Inverse conversion from float RGB to RGBE -static _FORCEINLINE void inverseConvert (PixelI iF, U8 *pRGB, U8 *pE) -{ - if (iF <= 0) { - *pRGB = *pE = 0; - } - else if ((iF >> 7) > 1) { - /** normal form **/ - *pE = (U8) (iF >> 7); //+ 1; - *pRGB = (iF & 0x7f) | 0x80; - } - else { - /** denormal form **/ - *pE = 1; - *pRGB = (U8) iF; - } -} - -//#ifdef __ANSI__ -//#define max(a,b) ((a) > (b) ? (a) : (b)) -//#endif // __ANSI__ - -static _FORCEINLINE void inverseConvertRGBE (PixelI iFr, PixelI iFg, PixelI iFb, U8 *pR, U8 *pG, U8 *pB, U8 *pE) -{ - U8 iShift; - - U8 pR_E, pG_E, pB_E; - - inverseConvert (iFr, pR, &pR_E); - inverseConvert (iFg, pG, &pG_E); - inverseConvert (iFb, pB, &pB_E); - - *pE = MAX(MAX(pR_E, pG_E), pB_E); - - if(*pE > pR_E){ - iShift = (*pE - pR_E); - *pR = (U8)((((int)*pR) * 2 + 1) >> (iShift + 1)); - } - if(*pE > pG_E){ - iShift = (*pE - pG_E); - *pG = (U8)((((int)*pG) * 2 + 1) >> (iShift + 1)); - } - if(*pE > pB_E){ - iShift = (*pE - pB_E); - *pB = (U8)((((int)*pB) * 2 + 1) >> (iShift + 1)); - } -} - - -//pixel to float 32! -static _FORCEINLINE float pixel2float(PixelI _h, const char _c, const unsigned char _lm) -{ - union uif - { - I32 i; - float f; - } x; - - I32 s, iTempH, m, e, lmshift = (1 << _lm); - - // assert (_c <= 127); - - iTempH = (I32) _h ; - s = (iTempH >> 31); - iTempH = (iTempH ^ s) - s; // abs(iTempH) - - e = (U32) iTempH >> _lm;// & ((1 << (31 - _lm)) - 1); - m = (iTempH & (lmshift - 1)) | lmshift; // actual mantissa, with normalizer - if (e == 0) { // denormal land - m ^= lmshift; // normalizer removed - e = 1; // actual exponent - } - - e += (127 - _c); - while (m < lmshift && e > 1 && m > 0) { // denormal originally, see if normal is possible - e--; - m <<= 1; - } - if (m < lmshift) // truly denormal - e = 0; - else - m ^= lmshift; - m <<= (23 - _lm); - - x.i = (s & 0x80000000) | (e << 23) | m; - - return x.f; -} - -//convert Half-16 to internal format, only need to handle sign bit -static _FORCEINLINE U16 backwardHalf (PixelI hHalf) -{ - PixelI s; - s = hHalf >> 31; - hHalf = ((hHalf & 0x7fff) ^ s) - s; // don't worry about overflow - return (U16) hHalf; -} - - -Void interpolateUV(CWMImageStrCodec * pSC) -{ - const COLORFORMAT cfExt = pSC->WMII.cfColorFormat; - const size_t cWidth = pSC->cmbWidth * 16; - PixelI * pSrcU = pSC->a0MBbuffer[1], * pSrcV = pSC->a0MBbuffer[2]; - PixelI * pDstU = pSC->pResU, * pDstV = pSC->pResV; - size_t iRow, iColumn; - size_t iIdxS = 0, iIdxD = 0; - - if(pSC->m_param.cfColorFormat == YUV_422){ // 422 => 444, interpolate horizontally - for(iRow = 0; iRow < 16; iRow ++){ - for(iColumn = 0; iColumn < cWidth; iColumn += 2){ - iIdxS = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7]; - iIdxD = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; - - // copy over - pDstU[iIdxD] = pSrcU[iIdxS]; - pDstV[iIdxD] = pSrcV[iIdxS]; - - if(iColumn > 0){ - size_t iL = iColumn - 2, iIdxL = ((iL >> 4) << 8) + idxCC[iRow][iL & 15]; - size_t iC = iColumn - 1, iIdxC = ((iC >> 4) << 8) + idxCC[iRow][iC & 15]; - - // interpolate - pDstU[iIdxC] = ((pDstU[iIdxL] + pDstU[iIdxD] + 1) >> 1); - pDstV[iIdxC] = ((pDstV[iIdxL] + pDstV[iIdxD] + 1) >> 1); - } - } - - //last pixel - iIdxS = (((iColumn - 1) >> 4) << 8) + idxCC[iRow][(iColumn - 1) & 15]; - pDstU[iIdxS] = pDstU[iIdxD]; - pDstV[iIdxS] = pDstV[iIdxD]; - } - } - else{ // 420 => 422 or 444, interpolate vertically - const size_t cShift = (cfExt == YUV_422 ? 3 : 4); - - for(iColumn = 0; iColumn < cWidth; iColumn += 2){ - const size_t cMB = ((iColumn >> 4) << (4 + cShift)), cPix = (iColumn >> (4 - cShift)) & ((1 << cShift) - 1); - - for(iRow = 0; iRow < 16; iRow += 2){ - iIdxS = ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7]; - iIdxD = cMB + idxCC[iRow][cPix]; - - // copy over - pDstU[iIdxD] = pSrcU[iIdxS]; - pDstV[iIdxD] = pSrcV[iIdxS]; - - if(iRow > 0){ - size_t iIdxT = cMB + idxCC[iRow - 2][cPix]; - size_t iIdxC = cMB + idxCC[iRow - 1][cPix]; - - // interpolate - pDstU[iIdxC] = ((pDstU[iIdxT] + pDstU[iIdxD] + 1) >> 1); - pDstV[iIdxC] = ((pDstV[iIdxT] + pDstV[iIdxD] + 1) >> 1); - } - } - - //last row - iIdxS = cMB + idxCC[15][cPix]; - if(pSC->cRow == pSC->cmbHeight){ // image boundary - pDstU[iIdxS] = pDstU[iIdxD]; - pDstV[iIdxS] = pDstV[iIdxD]; - } - else{ // need next MB row - size_t iIdxB = ((iColumn >> 4) << 6) + idxCC_420[0][(iColumn >> 1) & 7]; - - pDstU[iIdxS] = ((pSC->a1MBbuffer[1][iIdxB] + pDstU[iIdxD] + 1) >> 1); - pDstV[iIdxS] = ((pSC->a1MBbuffer[2][iIdxB] + pDstV[iIdxD] + 1) >> 1); - } - } - - if(cfExt != YUV_422){ // 420 => 444, interpolate horizontally - for(iRow = 0; iRow < 16; iRow ++){ - for(iColumn = 1; iColumn < cWidth - 2; iColumn += 2){ - size_t iIdxL = (((iColumn - 1) >> 4) << 8) + idxCC[iRow][(iColumn - 1) & 15]; - - iIdxD = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; - iIdxS = (((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]; - - pDstU[iIdxD] = ((pDstU[iIdxS] + pDstU[iIdxL] + 1) >> 1); - pDstV[iIdxD] = ((pDstV[iIdxS] + pDstV[iIdxL] + 1) >> 1); - } - - // last pixel - iIdxD = (((cWidth - 1) >> 4) << 8) + idxCC[iRow][(cWidth - 1) & 15]; - pDstU[iIdxD] = pDstU[iIdxS]; - pDstV[iIdxD] = pDstV[iIdxS]; - } - } - } -} - -// write one MB row of Y_ONLY/CF_ALPHA/YUV_444/N_CHANNEL to output buffer -Void outputNChannel(CWMImageStrCodec * pSC, size_t iFirstRow, size_t iFirstColumn, size_t cWidth, size_t cHeight, size_t iShift, PixelI iBias) -{ - const CWMImageInfo* pII = &pSC->WMII; - const size_t cChannel = pII->cfColorFormat == Y_ONLY ? 1 : pSC->WMISCP.cChannel; - // const U8 cbChannels[BDB_MAX] = {-1, 1, 2, 2, 2, 4, 4, -1, -1, }; - const U8 nLen = pSC->WMISCP.nLenMantissaOrShift; - const I8 nExpBias = pSC->WMISCP.nExpBias; - - PixelI * pChannel[16]; - size_t iChannel, iRow, iColumn; - size_t * pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * 16, iY; - - assert(cChannel <= 16); - - for(iChannel = 0; iChannel < cChannel; iChannel ++) - pChannel[iChannel & 15] = pSC->a0MBbuffer[iChannel]; - - if(pSC->m_bUVResolutionChange) - pChannel[1] = pSC->pResU, pChannel[2] = pSC->pResV; - - switch(pSC->WMII.bdBitDepth){ - case BD_8: - for(iRow = iFirstRow; iRow < cHeight; iRow ++){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - U8 * pDst = (U8 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn]; - - for(iChannel = 0; iChannel < cChannel; iChannel ++){ - PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift); - - pDst[iChannel] = _CLIP8(p); - } - } - } - break; - - case BD_16: - for(iRow = iFirstRow; iRow < cHeight; iRow ++){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - U16 * pDst = (U16 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn]; - - for(iChannel = 0; iChannel < cChannel; iChannel ++){ - PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift); - - p <<= nLen; - pDst[iChannel] = _CLIPU16(p); - } - } - } - break; - - case BD_16S: - for(iRow = iFirstRow; iRow < cHeight; iRow ++){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - I16 * pDst = (I16 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn]; - - for(iChannel = 0; iChannel < cChannel; iChannel ++){ - PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift); - - p <<= nLen; - pDst[iChannel] = _CLIP16(p); - } - } - } - break; - - case BD_16F: - for(iRow = iFirstRow; iRow < cHeight; iRow ++){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - U16 * pDst = (U16 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn]; - - for(iChannel = 0; iChannel < cChannel; iChannel ++){ - PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + iBias) >> iShift); - - pDst[iChannel] = backwardHalf(p); - } - } - } - break; - - case BD_32: - for(iRow = iFirstRow; iRow < cHeight; iRow ++){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - U32 * pDst = (U32 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn]; - - for(iChannel = 0; iChannel < cChannel; iChannel ++){ - PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + iBias) >> iShift); - - p <<= nLen; - pDst[iChannel] = (U32)(p); - } - } - } - break; - - case BD_32S: - for(iRow = iFirstRow; iRow < cHeight; iRow ++){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - I32 * pDst = (I32 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn]; - - for(iChannel = 0; iChannel < cChannel; iChannel ++){ - PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + iBias) >> iShift); - - p <<= nLen; - pDst[iChannel] = (I32)(p); - } - } - } - break; - - case BD_32F: - for(iRow = iFirstRow; iRow < cHeight; iRow ++){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - float * pDst = (float *)pSC->WMIBI.pv + iY + pOffsetX[iColumn]; - - for(iChannel = 0; iChannel < cChannel; iChannel ++){ - PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + iBias) >> iShift); - - pDst[iChannel] = pixel2float (p, nExpBias, nLen); - } - } - } - break; - - default: - assert(0); - break; - } -} - -static void fixup_Y_ONLY_to_Others( - const CWMImageStrCodec* pSC, - const CWMImageBufferInfo* pBI) -{ - const CWMImageInfo* pII = &pSC->WMII; - const CWMIStrCodecParam* pSCP = &pSC->WMISCP; - size_t cWidth = 0, cHeight = 0; - size_t idxY = 0, idxX = 0; - - if (CF_RGB != pII->cfColorFormat || Y_ONLY != pSCP->cfColorFormat) - return; - - cWidth = 0 != pII->cROIWidth ? pII->cROIWidth : pII->cWidth; - cHeight = 0 != pII->cROIHeight ? pII->cROIHeight : pII->cHeight; - -#define fixup(type, nCh) \ -for (idxY = 0; idxY < cHeight; ++idxY) \ -{ \ - type * pT = (type *)((U8*)pBI->pv + pBI->cbStride * idxY); \ - for (idxX = 0; idxX < cWidth; ++idxX) \ - { \ - pT[2] = pT[1] = pT[0]; \ - pT += nCh; \ - } \ -} \ -break - - switch (pII->bdBitDepth) - { - case BD_8: - fixup(U8, (pII->cBitsPerUnit >> 3)); - break; - - case BD_16: - case BD_16S: - case BD_16F: - fixup(U16, (pII->cBitsPerUnit >> 3) / sizeof(U16)); - break; - - case BD_32: - case BD_32S: - case BD_32F: - fixup(U32, (pII->cBitsPerUnit >> 3) / sizeof(float)); - break; - - case BD_5: - case BD_10: - case BD_565: - default: - break; - } -} - -// centralized alpha channel color conversion, small perf penalty -Int outputMBRowAlpha(CWMImageStrCodec * pSC) -{ - if(pSC->WMII.bdBitDepth == BD_8 && pSC->WMISCP.cfColorFormat == CF_RGB) // has been taken care of and optimized out - return ICERR_OK; - - if(pSC->m_bSecondary == FALSE && pSC->m_pNextSC != NULL){ // with alpha channel - const BITDEPTH_BITS bd = pSC->WMII.bdBitDepth; - const PixelI iShift = (pSC->m_param.bScaledArith ? SHIFTZERO + QPFRACBITS : 0); - const size_t cHeight = MIN((pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16); - const size_t cWidth = (pSC->m_Dparam->cROIRightX + 1); - const size_t iFirstRow = ((pSC->cRow - 1) * 16 > pSC->m_Dparam->cROITopY ? 0 : (pSC->m_Dparam->cROITopY & 0xf)), iFirstColumn = pSC->m_Dparam->cROILeftX; - const size_t iAlphaPos = pSC->WMII.cLeadingPadding + (pSC->WMII.cfColorFormat == CMYK ? 4 : 3);//only RGB and CMYK may have interleaved alpha - const PixelI * pA = pSC->m_pNextSC->a0MBbuffer[0]; - const U8 nLen = pSC->WMISCP.nLenMantissaOrShift; - const I8 nExpBias = pSC->WMISCP.nExpBias; - size_t iRow, iColumn; - size_t * pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * 16, iY; - - if (CF_RGB != pSC->WMII.cfColorFormat && CMYK != pSC->WMII.cfColorFormat) - return ICERR_ERROR; - - if(bd == BD_8){ - const PixelI iBias = (1 << (iShift + 7)) + (iShift == 0 ? 0 : (1 << (iShift - 1))); - - for(iRow = iFirstRow; iRow < cHeight; iRow ++) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - PixelI a = ((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift); - ((U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = _CLIP8(a); - } - } - else if(bd == BD_16){ - const PixelI iBias = (1 << (iShift + 15)) + (iShift == 0 ? 0 : (1 << (iShift - 1))); - - for(iRow = iFirstRow; iRow < cHeight; iRow ++) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - PixelI a = (((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift) << nLen); - ((U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = _CLIPU16(a); - } - } - else if(bd == BD_16S){ - const PixelI iBias = (iShift == 0 ? 0 : (1 << (iShift - 1))); - - for(iRow = iFirstRow; iRow < cHeight; iRow ++) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - PixelI a = (((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift) << nLen); - ((I16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = _CLIP16(a); - } - } - else if(bd == BD_16F){ - const PixelI iBias = (iShift == 0 ? 0 : (1 << (iShift - 1))); - - for(iRow = iFirstRow; iRow < cHeight; iRow ++) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - PixelI a = ((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift); - ((U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = backwardHalf(a); - } - } - else if(bd == BD_32S){ - const PixelI iBias = (iShift == 0 ? 0 : (1 << (iShift - 1))); - - for(iRow = iFirstRow; iRow < cHeight; iRow ++) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - PixelI a = (((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift) << nLen); - ((I32 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = a; - } - } - else if(bd == BD_32F){ - const PixelI iBias = (iShift == 0 ? 0 : (1 << (iShift - 1))); - - for(iRow = iFirstRow; iRow < cHeight; iRow ++) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - PixelI a = ((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift); - ((float *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = pixel2float (a, nExpBias, nLen); - } - } - else // not supported - return ICERR_ERROR; - } - - return ICERR_OK; -} - -Int outputMBRow(CWMImageStrCodec * pSC) -{ - const COLORFORMAT cfExt = (pSC->m_param.cfColorFormat == Y_ONLY ? Y_ONLY : pSC->WMII.cfColorFormat); - const BITDEPTH_BITS bd = pSC->WMII.bdBitDepth; - const PixelI iShift = (pSC->m_param.bScaledArith ? SHIFTZERO + QPFRACBITS : 0); - const size_t cHeight = MIN((pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16); - const size_t cWidth = (pSC->m_Dparam->cROIRightX + 1); - const size_t iFirstRow = ((pSC->cRow - 1) * 16 > pSC->m_Dparam->cROITopY ? 0 : (pSC->m_Dparam->cROITopY & 0xf)), iFirstColumn = pSC->m_Dparam->cROILeftX; - const PixelI *pY = pSC->a0MBbuffer[0]; - const PixelI *pU = (pSC->m_bUVResolutionChange ? pSC->pResU : pSC->a0MBbuffer[1]); - const PixelI *pV = (pSC->m_bUVResolutionChange ? pSC->pResV : pSC->a0MBbuffer[2]); - const PixelI *pA = NULL; - const size_t iB = (pSC->WMII.bRGB ? 2 : 0); - const size_t iR = 2 - iB; - const U8 nLen = pSC->WMISCP.nLenMantissaOrShift; - const I8 nExpBias = pSC->WMISCP.nExpBias; - size_t iRow, iColumn, iIdx; - size_t * pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * (cfExt == YUV_420 ? 8 : 16), iY; - - - if (pSC->m_pNextSC) { - assert (pSC->m_param.bScaledArith == pSC->m_pNextSC->m_param.bScaledArith); // will be relaxed later - } - - // guard output buffer - if(checkImageBuffer(pSC, pSC->WMII.oOrientation >= O_RCW ? pSC->WMII.cROIHeight : pSC->WMII.cROIWidth, cHeight - iFirstRow) != ICERR_OK) - return ICERR_ERROR; - - if(pSC->m_bUVResolutionChange) - interpolateUV(pSC); - - if(pSC->WMISCP.bYUVData){ - I32 * pDst = (I32 *)pSC->WMIBI.pv + (pSC->cRow - 1) * - (pSC->m_param.cfColorFormat == YUV_420 ? 8 : 16) * pSC->WMIBI.cbStride / sizeof(I32); - - switch(pSC->m_param.cfColorFormat){ - case Y_ONLY: - case YUV_444: - case NCOMPONENT: - { - PixelI * pChannel[16]; - size_t iChannel; - - const size_t cChannel = pSC->WMII.cfColorFormat == Y_ONLY ? 1 : pSC->WMISCP.cChannel; - assert(cChannel <= 16); - - for(iChannel = 0; iChannel < cChannel; iChannel ++) - pChannel[iChannel & 15] = pSC->a0MBbuffer[iChannel]; - - for(iRow = iFirstRow; iRow < cHeight; iRow ++){ - I32 * pRow = pDst; - for(iColumn = iFirstColumn; iColumn < cWidth; iColumn ++){ - for(iChannel = 0; iChannel < cChannel; iChannel ++){ - PixelI p = pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]]; - - *pRow++ = p; - } - } - pDst += pSC->WMIBI.cbStride / sizeof(I32); - } - } - break; - - case YUV_422: - { - PixelI y0, y1, u, v; - - for(iRow = iFirstRow; iRow < cHeight; iRow ++){ - I32 * pRow = pDst; - for(iColumn = iFirstColumn; iColumn < cWidth; iColumn += 2){ - iIdx = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7]; - u = pU[iIdx], v = pV[iIdx]; - - y0 = pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]]; - y1 = pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]]; - - pRow[0] = u, pRow[1] = y0, pRow[2] = v, pRow[3] = y1; - pRow += 4; - } - pDst += pSC->WMIBI.cbStride / sizeof(I32); - } - } - break; - - case YUV_420: - { - PixelI y0, y1, y2, y3, u, v; - // const size_t iS4[8][4] = {{0, 1, 2, 3}, {2, 3, 0, 1}, {1, 0, 3, 2}, {3, 2, 1, 0}, {1, 3, 0, 2}, {3, 1, 2, 0}, {0, 2, 1, 3}, {2, 0, 3, 1}}; - - for(iRow = iFirstRow; iRow < cHeight; iRow += 2){ - I32 * pRow = pDst; - for(iColumn = iFirstColumn; iColumn < cWidth; iColumn += 2){ - iIdx = ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7]; - u = pU[iIdx], v = pV[iIdx]; - - y0 = pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]]; - y1 = pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]]; - y2 = pY[((iColumn >> 4) << 8) + idxCC[iRow + 1][iColumn & 15]]; - y3 = pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow + 1][(iColumn + 1) & 15]]; - - pRow[0] = y0, pRow[1] = y1, pRow[2] = y2, pRow[3] = y3, pRow[4] = u, pRow[5] = v; - pRow += 6; - } - pDst += pSC->WMIBI.cbStride / sizeof(I32); - } - } - break; - - default: - assert(0); - break; - } - } - else if(bd == BD_8){ - U8 * pDst; - const PixelI iBias1 = 128 << iShift; - const PixelI iBias2 = pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0; - const PixelI iBias = iBias1 + iBias2; - - switch(cfExt){ - case CF_RGB: - { - PixelI r, g, b, a; - - if (pSC->m_pNextSC && pSC->WMISCP.uAlphaMode > 0) { // RGBA - - pA = pSC->m_pNextSC->a0MBbuffer[0]; - - if (pSC->m_param.bScaledArith == FALSE) { - for(iRow = iFirstRow; iRow < cHeight; iRow ++) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; - - g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; - a = pA[iIdx] + iBias; - - _ICC(r, g, b); - - pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; - if ((g | b | r | a) & ~0xff) - pDst[iR] = _CLIP8(r), pDst[1] = _CLIP8(g), pDst[iB] = _CLIP8(b), pDst[3] = _CLIP8(a); - else - pDst[iR] = (U8)r, pDst[1] = (U8)g, pDst[iB] = (U8)b, pDst[3] = (U8)(a); - } - } - else{ - for(iRow = iFirstRow; iRow < cHeight; iRow ++) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; - - g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; - a = pA[iIdx] + iBias; - - _ICC(r, g, b); - - g >>= iShift, b >>= iShift, r >>= iShift, a >>= iShift; - pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; - if ((g | b | r | a) & ~0xff) - pDst[iR] = _CLIP8(r), pDst[1] = _CLIP8(g), pDst[iB] = _CLIP8(b), pDst[3] = _CLIP8(a); - else - pDst[iR] = (U8)r, pDst[1] = (U8)g, pDst[iB] = (U8)b, pDst[3] = (U8)(a); - } - } - } - else { - if (pSC->m_param.bScaledArith == FALSE) { - for(iRow = iFirstRow; iRow < cHeight; iRow ++) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; - - g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; - - _ICC(r, g, b); - - pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; - if ((g | b | r) & ~0xff) - pDst[iR] = _CLIP8(r), pDst[1] = _CLIP8(g), pDst[iB] = _CLIP8(b); - else - pDst[iR] = (U8)r, pDst[1] = (U8)g, pDst[iB] = (U8)b; - } - } - else{ - for(iRow = iFirstRow; iRow < cHeight; iRow ++) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; - - g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; - - _ICC(r, g, b); - - g >>= iShift, b >>= iShift, r >>= iShift; - pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; - if ((g | b | r) & ~0xff) - pDst[iR] = _CLIP8(r), pDst[1] = _CLIP8(g), pDst[iB] = _CLIP8(b); - else - pDst[iR] = (U8)r, pDst[1] = (U8)g, pDst[iB] = (U8)b; - } - } - } - break; - } - - case Y_ONLY: - case YUV_444: - case NCOMPONENT: - outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias); - break; - - case YUV_422: - { - PixelI y0, y1, u, v; - // const ORIENTATION oO = pSC->WMII.oOrientation; - // const size_t i0 = ((oO > O_FLIPV && oO <= O_RCW_FLIPVH) ? 1 : 0), i1 = 1 - i0; - - for(iRow = iFirstRow; iRow < cHeight; iRow ++){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn += 2){ - iIdx = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7]; - u = ((pU[iIdx] + iBias) >> iShift), v = ((pV[iIdx] + iBias) >> iShift); - - y0 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift); - y1 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] + iBias) >> iShift); - - pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> 1] + iY; - if ((y0 | y1 | u | v) & ~0xff)//UYVY - pDst[0] = _CLIP8(u), pDst[1] = _CLIP8(y0), pDst[2] = _CLIP8(v), pDst[3] = _CLIP8(y1); - else - pDst[0] = (U8)u, pDst[1] = (U8)y0, pDst[2] = (U8)v, pDst[3] = (U8)y1; - } - } - } - break; - - case YUV_420: - { - PixelI y0, y1, y2, y3, u, v; - const size_t iS4[8][4] = {{0, 1, 2, 3}, {2, 3, 0, 1}, {1, 0, 3, 2}, {3, 2, 1, 0}, {1, 3, 0, 2}, {3, 1, 2, 0}, {0, 2, 1, 3}, {2, 0, 3, 1}}; - const ORIENTATION oO = pSC->WMII.oOrientation; - const size_t i0 = iS4[oO][0], i1 = iS4[oO][1], i2 = iS4[oO][2], i3 = iS4[oO][3]; - - for(iRow = iFirstRow; iRow < cHeight; iRow += 2){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> 1]; iColumn < cWidth; iColumn += 2){ - iIdx = ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7]; - u = ((pU[iIdx] + iBias) >> iShift), v = ((pV[iIdx] + iBias) >> iShift); - - y0 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift); - y1 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] + iBias) >> iShift); - y2 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow + 1][iColumn & 15]] + iBias) >> iShift); - y3 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow + 1][(iColumn + 1) & 15]] + iBias) >> iShift); - - pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> 1] + iY; - if ((y0 | y1 | y2 | y3 | u | v) & ~0xff) - pDst[i0] = _CLIP8(y0), pDst[i1] = _CLIP8(y1), pDst[i2] = _CLIP8(y2), pDst[i3] = _CLIP8(y3), pDst[4] = _CLIP8(u), pDst[5] = _CLIP8(v); - else - pDst[i0] = (U8)y0, pDst[i1] = (U8)y1, pDst[i2] = (U8)y2, pDst[i3] = (U8)y3, pDst[4] = (U8)u, pDst[5] = (U8)v; - } - } - } - break; - - case CMYK: - { - PixelI c, m, y, k; - PixelI * pK = pSC->a0MBbuffer[3]; - - for(iRow = iFirstRow; iRow < cHeight; iRow++){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++){ - iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; - - m = -pY[iIdx] + iBias1, c = pU[iIdx], y = -pV[iIdx], k = pK[iIdx] + iBias2; - - _ICC_CMYK(c, m, y, k); // color conversion - - c >>= iShift, m >>= iShift, y >>= iShift, k >>= iShift; - - pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; - if ((c | m | y | k) & ~0xff) - pDst[0] = _CLIP8(c), pDst[1] = _CLIP8(m), pDst[2] = _CLIP8(y), pDst[3] = _CLIP8(k); - else - pDst[0] = (U8)c, pDst[1] = (U8)m, pDst[2] = (U8)y, pDst[3] = (U8)k; - } - } - } - break; - - case CF_RGBE: - { - PixelI r, g, b; - - for(iRow = iFirstRow; iRow < cHeight; iRow ++){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; - - g = pY[iIdx] + iBias2, r = -pU[iIdx], b = pV[iIdx]; - - _ICC(r, g, b); - - pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; - - inverseConvertRGBE (r >> iShift, g >> iShift, b >> iShift, pDst, pDst + 1, pDst + 2, pDst + 3); - } - } - } - break; - - default: - assert(0); - break; - } - } - else if(bd == BD_16){ - const PixelI iBias = (((1 << 15) >> nLen) << iShift) + (iShift == 0 ? 0 : (1 << (iShift - 1))); - U16 * pDst; - - switch(cfExt){ - case CF_RGB: - { - PixelI r, g, b; - if (pSC->m_param.bScaledArith == FALSE) { - for(iRow = iFirstRow; iRow < cHeight; iRow ++) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; - - g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; - - _ICC(r, g, b); - - g <<= nLen, b <<= nLen, r <<= nLen; - - pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; - - if ((g | b | r) & ~0xffff) - pDst[0] = _CLIPU16(r), pDst[1] = _CLIPU16(g), pDst[2] = _CLIPU16(b); - else - pDst[0] = (U16)r, pDst[1] = (U16)g, pDst[2] = (U16)b; - } - } - else{ - for(iRow = iFirstRow; iRow < cHeight; iRow ++) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; - - g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; - - _ICC(r, g, b); - - g = (g >> iShift) << nLen, b = (b >> iShift) << nLen, r = (r >> iShift) << nLen; - pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; - if ((g | b | r) & ~0xffff) - pDst[0] = _CLIPU16(r), pDst[1] = _CLIPU16(g), pDst[2] = _CLIPU16(b); - else - pDst[0] = (U16)r, pDst[1] = (U16)g, pDst[2] = (U16)b; - } - } - break; - } - - case Y_ONLY: - case YUV_444: - case NCOMPONENT: - outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias); - break; - - case YUV_422: - { - PixelI y0, y1, u, v; - const ORIENTATION oO = pSC->WMII.oOrientation; - const size_t i0 = ((oO == O_FLIPH || oO == O_FLIPVH || oO == O_RCW_FLIPV || oO == O_RCW_FLIPVH) ? 1 : 0), i1 = 1 - i0; - - for(iRow = iFirstRow; iRow < cHeight; iRow ++){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn += 2){ - iIdx = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7]; - u = ((pU[iIdx] + iBias) >> iShift) << nLen, v = ((pV[iIdx] + iBias) >> iShift) << nLen; - - y0 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift) << nLen; - y1 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] + iBias) >> iShift) << nLen; - - pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> 1] + iY; - if ((y0 | y1 | u | v) & ~0xffff) - { - pDst[i0] = _CLIPU16(u); - pDst[i1] = _CLIPU16(y0); - pDst[2] = _CLIPU16(v); - pDst[3] = _CLIPU16(y1); - } - else - { - pDst[i0] = (U16)(u); - pDst[i1] = (U16)(y0); - pDst[2] = (U16)(v); - pDst[3] = (U16)(y1); - } - } - } - } - break; - - case YUV_420: - { - PixelI y0, y1, y2, y3, u, v; - const size_t iS4[8][4] = {{0, 1, 2, 3}, {2, 3, 0, 1}, {1, 0, 3, 2}, {3, 2, 1, 0}, {1, 3, 0, 2}, {3, 1, 2, 0}, {0, 2, 1, 3}, {2, 0, 3, 1}}; - const ORIENTATION oO = pSC->WMII.oOrientation; - const size_t i0 = iS4[oO][0], i1 = iS4[oO][1], i2 = iS4[oO][2], i3 = iS4[oO][3]; - - for(iRow = iFirstRow; iRow < cHeight; iRow += 2){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> 1]; iColumn < cWidth; iColumn += 2){ - iIdx = ((iColumn >> 3) << 6) + idxCC[iRow][(iColumn >> 1) & 7]; - u = ((pU[iIdx] + iBias) >> iShift) << nLen, v = ((pV[iIdx] + iBias) >> iShift) << nLen; - - y0 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift) << nLen; - y1 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] + iBias) >> iShift) << nLen; - y2 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow + 1][iColumn & 15]] + iBias) >> iShift) << nLen; - y3 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow + 1][(iColumn + 1) & 15]] + iBias) >> iShift) << nLen; - - pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> 1] + iY; - if ((y0 | y1 | y2 | y3 | u | v) & ~0xffff) - { - pDst[i0] = _CLIPU16(y0); - pDst[i1] = _CLIPU16(y1); - pDst[i2] = _CLIPU16(y2); - pDst[i3] = _CLIPU16(y3); - pDst[4] = _CLIPU16(u); - pDst[5] = _CLIPU16(v); - } - else - { - pDst[i0] = (U16)(y0); - pDst[i1] = (U16)(y1); - pDst[i2] = (U16)(y2); - pDst[i3] = (U16)(y3); - pDst[4] = (U16)(u); - pDst[5] = (U16)(v); - } - } - } - } - break; - - case CMYK: - { - PixelI c, m, y, k; - PixelI * pK = pSC->a0MBbuffer[3]; - const PixelI iBias1 = (32768 >> nLen) << iShift; - const PixelI iBias2 = iBias - iBias1; - - for(iRow = iFirstRow; iRow < cHeight; iRow++){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++){ - iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; - - m = -pY[iIdx] + iBias1, c = pU[iIdx], y = -pV[iIdx], k = pK[iIdx] + iBias2; - - _ICC_CMYK(c, m, y, k); // color conversion - - c = (c >> iShift) << nLen, m = (m >> iShift) << nLen, y = (y >> iShift) << nLen, k = (k >> iShift) << nLen; - - pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; - if ((c | m | y | k) & ~0xffff) - pDst[0] = _CLIPU16(c), pDst[1] = _CLIPU16(m), pDst[2] = _CLIPU16(y), pDst[3] = _CLIPU16(k); - else - pDst[0] = (U16)(c), pDst[1] = (U16)(m), pDst[2] = (U16)(y), pDst[3] = (U16)(k); - } - } - } - break; - default: - assert(0); - break; - } - } - else if(bd == BD_16S){ - const PixelI iBias = pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0; - I16 * pDst; - - switch(cfExt){ - case CF_RGB: - { - PixelI r, g, b; - - for(iRow = iFirstRow; iRow < cHeight; iRow ++) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; - - g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; - - _ICC(r, g, b); - - r = (r >> iShift) << nLen, g = (g >> iShift) << nLen, b = (b >> iShift) << nLen; - - pDst = (I16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; - pDst[0] = _CLIP16(r), pDst[1] = _CLIP16(g), pDst[2] = _CLIP16(b); - } - break; - } - - case Y_ONLY: - case YUV_444: - case NCOMPONENT: - outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias); - break; - - case CMYK: - { - PixelI c, m, y, k; - PixelI * pK = pSC->a0MBbuffer[3]; - - for(iRow = iFirstRow; iRow < cHeight; iRow++){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++){ - iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; - - m = -pY[iIdx], c = pU[iIdx], y = -pV[iIdx], k = pK[iIdx] + iBias; - - _ICC_CMYK(c, m, y, k); // color conversion - - c = (c >> iShift) << nLen, m = (m >> iShift) << nLen, y = (y >> iShift) << nLen, k = (k >> iShift) << nLen; - - pDst = (I16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; - pDst[0] = (I16)(c), pDst[1] = (I16)(m), pDst[2] = (I16)(y), pDst[3] = (I16)(k); - } - } - } - break; - - default: - assert(0); - break; - } - } - else if(bd == BD_16F){ - const PixelI iBias = pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0; - U16 *pDst; - - switch (cfExt) - { - case CF_RGB: - { - PixelI r, g, b; - - for(iRow = iFirstRow; iRow < cHeight; iRow ++){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; - - g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; - - _ICC(r, g, b); - - pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; - pDst[0] = backwardHalf(r >> iShift); - pDst[1] = backwardHalf(g >> iShift); - pDst[2] = backwardHalf(b >> iShift); - } - } - break; - } - - case Y_ONLY: - case YUV_444: - case NCOMPONENT: - outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias); - break; - - default: - assert(0); - break; - } - } - else if(bd == BD_32){ - const PixelI iBias = (((1 << 31) >> nLen) << iShift) + (iShift == 0 ? 0 : (1 << (iShift - 1))); - U32 * pDst; - - switch (cfExt) - { - case CF_RGB: - { - PixelI r, g, b; - - for(iRow = iFirstRow; iRow < cHeight; iRow ++){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; - - g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; - - _ICC(r, g, b); - - pDst = (U32 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; - pDst[0] = ((r >> iShift) << nLen); - pDst[1] = ((g >> iShift) << nLen); - pDst[2] = ((b >> iShift) << nLen); - } - } - } - break; - - case Y_ONLY: - case YUV_444: - case NCOMPONENT: - { - outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias); - break; - } - default: - assert(0); - break; - } - } - else if(bd == BD_32S){ - const PixelI iBias = pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0; - int * pDst; - - switch (cfExt) - { - case CF_RGB: - { - PixelI r, g, b; - - for(iRow = iFirstRow; iRow < cHeight; iRow ++){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; - - g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; - - _ICC(r, g, b); - - pDst = (int *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; - pDst[0] = ((r >> iShift) << nLen); - pDst[1] = ((g >> iShift) << nLen); - pDst[2] = ((b >> iShift) << nLen); - } - } - break; - } - - case Y_ONLY: - case YUV_444: - case NCOMPONENT: - outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias); - break; - - default: - assert(0); - break; - } - } - else if(bd == BD_32F){ - const PixelI iBias = pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0; - float * pDst; - - switch (cfExt) - { - case CF_RGB: - { - PixelI r, g, b; - - for(iRow = iFirstRow; iRow < cHeight; iRow ++){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; - - g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; - - _ICC(r, g, b); - - pDst = (float *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; - pDst[0] = pixel2float (r >> iShift, nExpBias, nLen); - pDst[1] = pixel2float (g >> iShift, nExpBias, nLen); - pDst[2] = pixel2float (b >> iShift, nExpBias, nLen); - } - } - break; - } - case Y_ONLY: - case YUV_444: - case NCOMPONENT: - outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias); - break; - - default: - assert(0); - break; - } - } - else if(bd == BD_5){ - const PixelI iBias = (16 << iShift) + (pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0); - PixelI r, g, b; - U16 * pDst; - - assert(cfExt == CF_RGB); - - for(iRow = iFirstRow; iRow < cHeight; iRow ++) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; - - g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; - - _ICC(r, g, b); - - g >>= iShift, b >>= iShift, r >>= iShift; - pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; - if (pSC->m_param.bRBSwapped) - pDst[0] = (U16)_CLIP2(0, b, 31) + (((U16)_CLIP2(0, g, 31)) << 5) + (((U16)_CLIP2(0, r, 31)) << 10); - else - pDst[0] = (U16)_CLIP2(0, r, 31) + (((U16)_CLIP2(0, g, 31)) << 5) + (((U16)_CLIP2(0, b, 31)) << 10); - } - } - else if(bd == BD_565){ - const PixelI iBias = (32 << iShift) + (pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0); - PixelI r, g, b; - U16 * pDst; - - assert(cfExt == CF_RGB); - - for(iRow = iFirstRow; iRow < cHeight; iRow ++) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; - - g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; - - _ICC(r, g, b); - - g >>= iShift, b >>= iShift + 1, r >>= iShift + 1; - pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; - if (pSC->m_param.bRBSwapped) - pDst[0] = (U16)_CLIP2(0, b, 31) + (((U16)_CLIP2(0, g, 63)) << 5) + (((U16)_CLIP2(0, r, 31)) << 11); - else - pDst[0] = (U16)_CLIP2(0, r, 31) + (((U16)_CLIP2(0, g, 63)) << 5) + (((U16)_CLIP2(0, b, 31)) << 11); - } - } - else if(bd == BD_10){ - const PixelI iBias = (512 << iShift) + (pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0); - PixelI r, g, b; - U32 * pDst; - - assert(cfExt == CF_RGB); - - for(iRow = iFirstRow; iRow < cHeight; iRow ++) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){ - iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; - - g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx]; - - _ICC(r, g, b); - - g >>= iShift, b >>= iShift, r >>= iShift; - - pDst = (U32 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY; - if (pSC->m_param.bRBSwapped) - pDst[0] = (U32)_CLIP2(0, b, 1023) + - (((U32)_CLIP2(0, g, 1023)) << 10) + - (((U32)_CLIP2(0, r, 1023)) << 20); - else - pDst[0] = (U32)_CLIP2(0, r, 1023) + - (((U32)_CLIP2(0, g, 1023)) << 10) + - (((U32)_CLIP2(0, b, 1023)) << 20); - } - } - else if(bd == BD_1){ - const size_t iPos = pSC->WMII.cLeadingPadding; - const Int iTh = (iShift > 0) ? (1 << (iShift - 1)) : 1; - assert(cfExt == Y_ONLY && pSC->m_param.cfColorFormat == Y_ONLY); - - if(pSC->WMII.oOrientation < O_RCW) - for(iRow = iFirstRow; iRow < cHeight; iRow ++) { - iY = pOffsetY[iRow] + iPos; - for(iColumn = iFirstColumn; iColumn < cWidth; iColumn ++) { - U8 cByte = ((U8 *)pSC->WMIBI.pv + (pOffsetX[iColumn] >> 3) + iY)[0]; - U8 cShift = (U8)(7 - (pOffsetX[iColumn] & 7)); - ((U8 *)pSC->WMIBI.pv + (pOffsetX[iColumn] >> 3) + iY)[0] ^= // exor is used because we can't assume the byte was originally zero - (((pSC->WMISCP.bBlackWhite + (pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] >= iTh) - + (cByte >> cShift)) & 0x1) << cShift); - } - } - else - for(iRow = iFirstRow; iRow < cHeight; iRow ++) { - iY = pOffsetY[iRow] + iPos; - for(iColumn = iFirstColumn; iColumn < cWidth; iColumn ++) { - U8 cByte = ((U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + (iY >> 3))[0]; - U8 cShift = (U8)(7 - (iY & 7)); // should be optimized out - ((U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + (iY >> 3))[0] ^= // exor is used because we can't assume the byte was originally zero - (((pSC->WMISCP.bBlackWhite + (pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] >= iTh) - + (cByte >> cShift)) & 0x1) << cShift); - } - } - } - - if(pSC->WMISCP.uAlphaMode > 0) - if(outputMBRowAlpha(pSC) != ICERR_OK) - return ICERR_ERROR; - -#ifdef REENTRANT_MODE - pSC->WMIBI.cLinesDecoded = cHeight - iFirstRow; - - if (CF_RGB == pSC->WMII.cfColorFormat && Y_ONLY == pSC->WMISCP.cfColorFormat) - { - const CWMImageInfo* pII = &pSC->WMII; - -#define fixupFullSize(type, nCh) \ -for(iRow = iFirstRow; iRow < cHeight; iRow ++) {\ - size_t iOffsetY;\ - for(iColumn = iFirstColumn, iOffsetY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){\ - type *pT = (type*)(U8 *)pSC->WMIBI.pv + iOffsetY + pOffsetX[iColumn];\ - pT[2] = pT[1] = pT[0]; \ - pT += nCh; \ - } \ -} \ -break - - switch (pII->bdBitDepth) - { - case BD_8: - fixupFullSize(U8, (pII->cBitsPerUnit >> 3)); - break; - - case BD_16: - case BD_16S: - case BD_16F: - fixupFullSize(U16, ((pII->cBitsPerUnit >> 3) / sizeof(U16))); - break; - - case BD_32: - case BD_32S: - case BD_32F: - fixupFullSize(U32, ((pII->cBitsPerUnit >> 3) / sizeof(float))); - break; - - case BD_5: - case BD_10: - case BD_565: - default: - break; - } - } -#endif - - return ICERR_OK; -} - -// Y_ONLY/CF_ALPHA/YUV_444/N_CHANNEL thumbnail decode -Void outputNChannelThumbnail(CWMImageStrCodec * pSC, const PixelI cMul, const size_t rShiftY, size_t iFirstRow, size_t iFirstColumn) -{ - const size_t tScale = pSC->m_Dparam->cThumbnailScale; - const size_t cWidth = (pSC->m_Dparam->cROIRightX + 1); - const size_t cHeight = MIN((pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16); - const size_t cChannel = pSC->WMISCP.cChannel; - const U8 nLen = pSC->WMISCP.nLenMantissaOrShift; - const I8 nExpBias = pSC->WMISCP.nExpBias; - size_t nBits = 0; - PixelI iOffset; - PixelI * pChannel[16]; - size_t iChannel, iRow, iColumn; - size_t * pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * 16 / tScale, iY; - - while((size_t)(1U << nBits) < tScale) - nBits ++; - - assert(cChannel <= 16); - - for(iChannel = 0; iChannel < cChannel; iChannel ++) - pChannel[iChannel & 15] = pSC->a0MBbuffer[iChannel]; - - if(pSC->m_bUVResolutionChange) - pChannel[1] = pSC->pResU, pChannel[2] = pSC->pResV; - - switch(pSC->WMII.bdBitDepth){ - case BD_8: - for(iOffset = (128 << rShiftY) / cMul, iRow = iFirstRow; iRow < cHeight; iRow += tScale){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - U8 * pDst = (U8 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits]; - - for(iChannel = 0; iChannel < cChannel; iChannel ++){ - PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iOffset) * cMul) >> rShiftY; - - pDst[iChannel] = _CLIP8(p); - } - } - } - break; - - case BD_16: - for(iOffset = (32768 << rShiftY) / cMul, iRow = iFirstRow; iRow < cHeight; iRow += tScale){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - U16 * pDst = (U16 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits]; - - for(iChannel = 0; iChannel < cChannel; iChannel ++){ - PixelI p = (((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iOffset) * cMul) >> rShiftY) << nLen; - - pDst[iChannel] = _CLIPU16(p); - } - } - } - break; - - case BD_16S: - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - I16 * pDst = (I16 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits]; - - for(iChannel = 0; iChannel < cChannel; iChannel ++){ - PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] * cMul) >> rShiftY) << nLen; - - pDst[iChannel] = _CLIP16(p); - } - } - } - break; - - case BD_16F: - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - U16 * pDst = (U16 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits]; - - for(iChannel = 0; iChannel < cChannel; iChannel ++){ - PixelI p = (pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] * cMul) >> rShiftY; - - pDst[iChannel] = backwardHalf(p); - } - } - } - break; - case BD_32: - for(iOffset = (((1 << 31) >> nLen) << rShiftY) / cMul, iRow = iFirstRow; iRow < cHeight; iRow += tScale){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - U32 * pDst = (U32 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits]; - - for(iChannel = 0; iChannel < cChannel; iChannel ++){ - PixelI p = (((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iOffset) * cMul) >> rShiftY) << nLen; - - pDst[iChannel] = (U32)(p); - } - } - } - break; - case BD_32S: - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - I32 * pDst = (I32 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits]; - - for(iChannel = 0; iChannel < cChannel; iChannel ++){ - PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] * cMul) >> rShiftY) << nLen; - - pDst[iChannel] = (I32)(p); - } - } - } - break; - case BD_32F: - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - float * pDst = (float *)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits]; - - for(iChannel = 0; iChannel < cChannel; iChannel ++){ - PixelI p = (pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] * cMul) >> rShiftY; - - pDst[iChannel] = pixel2float (p, nExpBias, nLen); - } - } - } - break; - - default: - assert(0); - break; - } -} - -// centralized alpha channel thumbnail, small perf penalty -Int decodeThumbnailAlpha(CWMImageStrCodec * pSC, const size_t nBits, const PixelI cMul, const size_t rShiftY) -{ - if(pSC->m_bSecondary == FALSE && pSC->m_pNextSC != NULL){ // with alpha channel - const size_t tScale = (size_t)(1U << nBits); - const size_t cHeight = MIN((pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16); - const size_t cWidth = (pSC->m_Dparam->cROIRightX + 1); - const size_t iFirstRow = ((((pSC->cRow - 1) * 16 > pSC->m_Dparam->cROITopY ? 0 : (pSC->m_Dparam->cROITopY & 0xf)) + tScale - 1) / tScale * tScale); - const size_t iFirstColumn = (pSC->m_Dparam->cROILeftX + tScale - 1) / tScale * tScale; - const size_t iAlphaPos = pSC->WMII.cLeadingPadding + (pSC->WMII.cfColorFormat == CMYK ? 4 : 3);//only RGB and CMYK may have interleaved alpha - const BITDEPTH_BITS bd = pSC->WMII.bdBitDepth; - const PixelI * pSrc = pSC->m_pNextSC->a0MBbuffer[0]; - const U8 nLen = pSC->m_pNextSC->WMISCP.nLenMantissaOrShift; - const I8 nExpBias = pSC->m_pNextSC->WMISCP.nExpBias; - size_t iRow, iColumn; - size_t * pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * 16 / tScale, iY; - - if (CF_RGB != pSC->WMII.cfColorFormat && CMYK != pSC->WMII.cfColorFormat) - return ICERR_ERROR; - - if(bd == BD_8){ - const PixelI offset = (128 << rShiftY) / cMul; - - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - PixelI a = ((pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + offset) * cMul) >> rShiftY; - - ((U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = _CLIP8(a); - } - } - else if(bd == BD_16){ - const PixelI offset = (32768 << rShiftY) / cMul; - - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - PixelI a = (((pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + offset) * cMul) >> rShiftY) << nLen; - - ((U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = _CLIPU16(a); - } - } - else if(bd == BD_16S){ - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - PixelI a = ((pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] * cMul) >> rShiftY) << nLen; - - ((I16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = _CLIP16(a); - } - } - else if(bd == BD_16F){ - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - PixelI a = (pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] * cMul) >> rShiftY; - - ((U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = backwardHalf(a); - } - } - else if(bd == BD_32S){ - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - PixelI a = ((pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] * cMul) >> rShiftY) << nLen; - - ((I32 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = a; - } - } - else if(bd == BD_32F){ - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - PixelI a = (pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] * cMul) >> rShiftY; - - ((float *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = pixel2float (a, nExpBias, nLen); - } - } - else // not supported - return ICERR_ERROR; - } - - return ICERR_OK; -} - -Int decodeThumbnail(CWMImageStrCodec * pSC) -{ - const size_t tScale = pSC->m_Dparam->cThumbnailScale; - const size_t cHeight = MIN((pSC->m_Dparam->bDecodeFullFrame ? pSC->WMII.cHeight : pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16); - const size_t cWidth = (pSC->m_Dparam->bDecodeFullFrame ? pSC->WMII.cWidth : pSC->m_Dparam->cROIRightX + 1); - const size_t iFirstRow = ((((pSC->cRow - 1) * 16 > pSC->m_Dparam->cROITopY ? 0 : (pSC->m_Dparam->cROITopY & 0xf)) + tScale - 1) / tScale * tScale); - const size_t iFirstColumn = (pSC->m_Dparam->cROILeftX + tScale - 1) / tScale * tScale; - const COLORFORMAT cfInt = pSC->m_param.cfColorFormat; - const COLORFORMAT cfExt = (pSC->m_param.cfColorFormat == Y_ONLY ? Y_ONLY : pSC->WMII.cfColorFormat); - const BITDEPTH_BITS bd = pSC->WMII.bdBitDepth; - const OVERLAP ol = pSC->WMISCP.olOverlap; - const size_t iB = (pSC->WMII.bRGB ? 2 : 0); - const size_t iR = 2 - iB; - - const U8 nLen = pSC->WMISCP.nLenMantissaOrShift; - const I8 nExpBias = pSC->WMISCP.nExpBias; - PixelI offset; - size_t iRow, iColumn, iIdx1, iIdx2, iIdx3 = 0, nBits = 0; - PixelI * pSrcY = pSC->a0MBbuffer[0]; - PixelI * pSrcU = pSC->a0MBbuffer[1], * pSrcV = pSC->a0MBbuffer[2]; - size_t * pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * 16 / tScale, iY; - const PixelI cMul = (tScale >= 16 ? (ol == OL_NONE ? 16 : (ol == OL_ONE ? 23 : 34)) : (tScale >= 4 ? (ol == OL_NONE ? 64 : 93) : 258)); - const size_t rShiftY = 8 + (pSC->m_param.bScaledArith ? (SHIFTZERO + QPFRACBITS) : 0); - const size_t rShiftUV = rShiftY - ((pSC->m_param.bScaledArith && tScale >= 16) ? ((cfInt == YUV_420 || cfInt == YUV_422) ? 2 : 1) : 0); - - while((size_t)(1U << nBits) < tScale) - nBits ++; - - assert(tScale == (size_t)(1U << nBits)); - - // guard output buffer - if(checkImageBuffer(pSC, pSC->WMII.oOrientation < O_RCW ? pSC->WMII.cROIWidth : pSC->WMII.cROIHeight, (cHeight - iFirstRow) / pSC->m_Dparam->cThumbnailScale) != ICERR_OK) - return ICERR_ERROR; - - if((((pSC->cRow - 1) * 16) % tScale) != 0) - return ICERR_OK; - - if(pSC->cRow * 16 <= pSC->m_Dparam->cROITopY || pSC->cRow * 16 > pSC->m_Dparam->cROIBottomY + 16) - return ICERR_OK; - - if((cfInt == YUV_422 || cfInt == YUV_420) && cfExt != Y_ONLY){ - PixelI * pDstU = pSC->pResU, * pDstV = pSC->pResV; - - for(iRow = 0; iRow < 16; iRow += tScale){ - for(iColumn = 0; iColumn < cWidth; iColumn += tScale){ - iIdx1 = (cfInt == YUV_422 ? ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7] : ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7]); - iIdx2 = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; - - // copy over - pDstU[iIdx2] = pSrcU[iIdx1]; - pDstV[iIdx2] = pSrcV[iIdx1]; - } - } - - if(tScale == 4){ - if(cfInt == YUV_420){ - for(iColumn = 0; iColumn < cWidth; iColumn += 8){ - iIdx1 = ((iColumn >> 4) << 8) + idxCC[0][iColumn & 15]; - iIdx2 = ((iColumn >> 4) << 8) + idxCC[4][iColumn & 15]; - iIdx3 = ((iColumn >> 4) << 8) + idxCC[8][iColumn & 15]; - - pDstU[iIdx2] = ((pDstU[iIdx1] + pDstU[iIdx3] + 1) >> 1); - pDstV[iIdx2] = ((pDstV[iIdx1] + pDstV[iIdx3] + 1) >> 1); - - iIdx1 = ((iColumn >> 4) << 8) + idxCC[12][iColumn & 15]; - pDstU[iIdx1] = pDstU[iIdx3]; - pDstV[iIdx1] = pDstV[iIdx3]; - } - } - - for(iRow = 0; iRow < 16; iRow += 4){ - for(iColumn = 0; iColumn < cWidth - 8; iColumn += 8){ - iIdx1 = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]; - iIdx2 = ((iColumn >> 4) << 8) + idxCC[iRow][(iColumn + 4) & 15]; - iIdx3 = ((iColumn >> 4) << 8) + idxCC[iRow][(iColumn + 8) & 15]; - - pDstU[iIdx2] = ((pDstU[iIdx1] + pDstU[iIdx3] + 1) >> 1); - pDstV[iIdx2] = ((pDstV[iIdx1] + pDstV[iIdx3] + 1) >> 1); - } - - iIdx2 = ((iColumn >> 4) << 8) + idxCC[iRow][(iColumn + 4) & 15]; - pDstU[iIdx2] = pDstU[iIdx3]; - pDstV[iIdx2] = pDstV[iIdx3]; - } - } - - pSrcU = pDstU, pSrcV = pDstV; - } - - if(bd == BD_8){ - U8 * pDst; - - offset = (128 << rShiftY) / cMul; - - switch(cfExt){ - case CF_RGB: - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV; - - _ICC(r, g, b); - - pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; - pDst[iB] = _CLIP8(b), pDst[1] = _CLIP8(g), pDst[iR] = _CLIP8(r); - } - } - break; - - case Y_ONLY: - case YUV_444: - case NCOMPONENT: - outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn); - break; - - case CF_RGBE: - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - PixelI g = ((pSrcY[iPos] * cMul) >> rShiftY), r = - ((pSrcU[iPos] * cMul) >> rShiftUV), b = ((pSrcV[iPos] * cMul) >> rShiftUV); - - _ICC(r, g, b); - - pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; - inverseConvertRGBE (r, g, b, pDst, pDst + 1, pDst + 2, pDst + 3); - } - } - break; - - case CMYK: - { - PixelI * pSrcK = pSC->a0MBbuffer[3]; - PixelI iBias1 = (128 << rShiftY) / cMul, iBias2 = (((128 << rShiftUV) / cMul) >> 1); - - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - PixelI m = ((-pSrcY[iPos] + iBias1) * cMul) >> rShiftY, c = (pSrcU[iPos] * cMul) >> rShiftUV, y = -(pSrcV[iPos] * cMul) >> rShiftUV, k = ((pSrcK[iPos] + iBias2) * cMul) >> rShiftUV; - - _ICC_CMYK(c, m, y, k); - - pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; - pDst[0] = _CLIP8(c), pDst[1] = _CLIP8(m), pDst[2] = _CLIP8(y), pDst[3] = _CLIP8(k); - } - } - break; - } - default: - assert(0); - break; - } - } - if(bd == BD_16){ - U16 * pDst; - - offset = (((1 << 15) >> nLen) << rShiftY) / cMul; - - switch(cfExt){ - case CF_RGB: - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV; - - _ICC(r, g, b); - - pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; - r <<= nLen, g <<= nLen, b <<= nLen; - pDst[0] = _CLIPU16(r); - pDst[1] = _CLIPU16(g); - pDst[2] = _CLIPU16(b); - } - } - break; - - case Y_ONLY: - case YUV_444: - case NCOMPONENT: - outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn); - break; - - case CMYK: - { - PixelI * pSrcK = pSC->a0MBbuffer[3]; - PixelI iBias1 = (32768 << rShiftY) / cMul, iBias2 = (((32768 << rShiftUV) / cMul) >> 1); - - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - PixelI m = ((-pSrcY[iPos] + iBias1) * cMul) >> rShiftY, c = (pSrcU[iPos] * cMul) >> rShiftUV, y = -(pSrcV[iPos] * cMul) >> rShiftUV, k = ((pSrcK[iPos] + iBias2) * cMul) >> rShiftUV; - - _ICC_CMYK(c, m, y, k); - - pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; - c <<= nLen, m <<= nLen, y <<= nLen, k <<= nLen; - pDst[0] = _CLIPU16(c); - pDst[1] = _CLIPU16(m); - pDst[2] = _CLIPU16(y); - pDst[3] = _CLIPU16(k); - } - } - break; - } - default: - assert(0); - break; - } - } - if(bd == BD_16S){ - I16 * pDst; - - switch(cfExt){ - case CF_RGB: - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - PixelI g = (pSrcY[iPos] * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV; - - _ICC(r, g, b); - - pDst = (I16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; - r <<= nLen, g <<= nLen, b <<= nLen; - pDst[0] = _CLIP16(r); - pDst[1] = _CLIP16(g); - pDst[2] = _CLIP16(b); - } - } - break; - - case Y_ONLY: - case YUV_444: - case NCOMPONENT: - outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn); - break; - - case CMYK: - { - PixelI * pSrcK = pSC->a0MBbuffer[3]; - - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - PixelI m = -(pSrcY[iPos] * cMul) >> rShiftY, c = (pSrcU[iPos] * cMul) >> rShiftUV, y = -(pSrcV[iPos] * cMul) >> rShiftUV, k = (pSrcK[iPos] * cMul) >> rShiftUV; - - _ICC_CMYK(c, m, y, k); - - pDst = (I16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; - c <<= nLen, m <<= nLen, y <<= nLen, k <<= nLen; - pDst[0] = _CLIP16(c); - pDst[1] = _CLIP16(m); - pDst[2] = _CLIP16(y); - pDst[3] = _CLIP16(k); - } - } - } - break; - - default: - assert(0); - break; - } - } - else if(bd == BD_16F){ - U16 * pDst; - - switch(cfExt){ - case CF_RGB: - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - PixelI g = (pSrcY[iPos] * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV; - - _ICC(r, g, b); - - pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; - pDst[0] = backwardHalf (r); - pDst[1] = backwardHalf (g); - pDst[2] = backwardHalf (b); - } - } - break; - - case Y_ONLY: - case YUV_444: - case NCOMPONENT: - outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn); - break; - - default: - assert(0); - break; - } - } - else if(bd == BD_32){ - U32 * pDst; - - offset = (((1 << 31) >> nLen) << rShiftY) / cMul; - - switch(cfExt){ - case CF_RGB: - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV; - - _ICC(r, g, b); - - pDst = (U32 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; - - pDst[0] = (U32)(r << nLen); - pDst[1] = (U32)(g << nLen); - pDst[2] = (U32)(b << nLen); - } - } - break; - - case Y_ONLY: - case YUV_444: - case NCOMPONENT: - outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn); - break; - - default: - assert(0); - break; - } - } - else if(bd == BD_32S){ - I32 * pDst; - - switch(cfExt){ - case CF_RGB: - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - PixelI g = (pSrcY[iPos] * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV; - - _ICC(r, g, b); - - pDst = (I32 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; - pDst[0] = (I32)(r << nLen); - pDst[1] = (I32)(g << nLen); - pDst[2] = (I32)(b << nLen); - } - } - break; - - case Y_ONLY: - case YUV_444: - case NCOMPONENT: - outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn); - break; - - default: - assert(0); - break; - } - } - - else if(bd == BD_32F){ - float * pDst; - - switch(cfExt){ - case CF_RGB: - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - PixelI g = (pSrcY[iPos] * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV; - - _ICC(r, g, b); - - pDst = (float *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; - pDst[0] = pixel2float (r, nExpBias, nLen); - pDst[1] = pixel2float (g, nExpBias, nLen); - pDst[2] = pixel2float (b, nExpBias, nLen); - } - } - break; - - case Y_ONLY: - case YUV_444: - case NCOMPONENT: - outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn); - break; - - default: - assert(0); - break; - } - } - else if(bd == BD_1){ - const size_t iPos = pSC->WMII.cLeadingPadding; - Bool bBW; - U8 cByte, cShift; - assert(cfExt == Y_ONLY && pSC->m_param.cfColorFormat == Y_ONLY); - - if(pSC->WMII.oOrientation < O_RCW){ - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits] + iPos; iColumn < cWidth; iColumn += tScale){ - bBW = (pSC->WMISCP.bBlackWhite ^ (pSrcY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] > 0)); - cByte = ((U8 *)pSC->WMIBI.pv + (pOffsetX[iColumn >> nBits] >> 3) + iY)[0]; - cShift = (U8)(7 - (pOffsetX[iColumn >> nBits] & 7)); - ((U8 *)pSC->WMIBI.pv + (pOffsetX[iColumn >> nBits] >> 3) + iY)[0] ^= ((((bBW + (cByte >> cShift)) & 0x1)) << cShift); - } - } - else{ - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale) - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits] + iPos; iColumn < cWidth; iColumn += tScale){ - bBW = (pSC->WMISCP.bBlackWhite ^ (pSrcY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] > 0)); - cByte = ((U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + (iY >> 3))[0]; - cShift = (U8)(7 - (iY & 7)); - ((U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + (iY >> 3))[0] ^= ((((bBW + (cByte >> cShift)) & 0x1)) << cShift); - } - } - } - else if(bd == BD_5){ - U16 * pDst; - - offset = (16 << rShiftY) / cMul; - - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV; - - _ICC(r, g, b); - pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; - pDst[0] = (U16)_CLIP2(0, r, 31) + (((U16)_CLIP2(0, g, 31)) << 5) + (((U16)_CLIP2(0, b, 31)) << 10); - } - } - } - else if(bd == BD_565){ - U16 * pDst; - - offset = (32 << rShiftY) / cMul; - - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV; - - _ICC(r, g, b); - r /= 2, b /= 2; - pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; - pDst[0] = (U16)_CLIP2(0, r, 31) + (((U16)_CLIP2(0, g, 63)) << 5) + (((U16)_CLIP2(0, b, 31)) << 11); - } - } - } - else if(bd == BD_10){ - U32 * pDst; - - offset = (512 << rShiftY) / cMul; - - for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){ - for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){ - size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV; - - _ICC(r, g, b); - pDst = (U32 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY; - pDst[0] = (U32)_CLIP2(0, r, 1023) + - (((U32)_CLIP2(0, g, 1023)) << 10) + - (((U32)_CLIP2(0, b, 1023)) << 20); - } - } - } - - if(pSC->WMISCP.uAlphaMode > 0) - if(decodeThumbnailAlpha(pSC, nBits, cMul, rShiftY) != ICERR_OK) - return ICERR_ERROR; - -#ifdef REENTRANT_MODE - pSC->WMIBI.cLinesDecoded = ( cHeight - iFirstRow + tScale - 1 ) / tScale; - if (CF_RGB == pSC->WMII.cfColorFormat && Y_ONLY == pSC->WMISCP.cfColorFormat) - { - const CWMImageInfo* pII = &pSC->WMII; - -#define fixupThumb(type, nCh) \ -for(iRow = iFirstRow; iRow < cHeight; iRow += tScale) {\ - size_t iOffsetY;\ - for(iColumn = iFirstColumn, iOffsetY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){\ - type *pT = (type*)((U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iOffsetY);\ - pT[iB] = pT[1] = pT[iR]; \ - } \ -} \ -break - - switch (pII->bdBitDepth) - { - case BD_8: - fixupThumb(U8, (pII->cBitsPerUnit >> 3)); - break; - - case BD_16: - case BD_16S: - case BD_16F: - fixupThumb(U16, (pII->cBitsPerUnit >> 3) / sizeof(U16)); - break; - - case BD_32: - case BD_32S: - case BD_32F: - fixupThumb(U32, (pII->cBitsPerUnit >> 3) / sizeof(float)); - break; - - case BD_5: - case BD_10: - case BD_565: - default: - break; - } - } -#endif - - return ICERR_OK; -} - -/************************************************************************* - Read variable length byte aligned integer -*************************************************************************/ -static size_t GetVLWordEsc(BitIOInfo* pIO, Int *iEscape) -{ - size_t s; - - if (iEscape) - *iEscape = 0; - - s = getBit32(pIO, 8); - if (s == 0xfd || s == 0xfe || s == 0xff) { - if (iEscape) - *iEscape = (Int) s; - s = 0; - } - else if (s < 0xfb) { - s = (s << 8) | getBit32(pIO, 8); - } - else { - s -= 0xfb; - if (s) { - s = getBit32(pIO, 16) << 16; - s = (s | getBit32(pIO, 16)) << 16; - s <<= 16; - } - s |= (getBit32(pIO, 16) << 16); - s |= getBit32(pIO, 16); - } - return s; -} - -//================================================================ -Int readIndexTable(CWMImageStrCodec * pSC) -{ - BitIOInfo* pIO = pSC->pIOHeader; - readIS_L1(pSC, pIO); - - if(pSC->cNumBitIO > 0){ - size_t *pTable = pSC->pIndexTable; - U32 iEntry = (U32)pSC->cNumBitIO * (pSC->WMISCP.cNumOfSliceMinus1H + 1), i; - - // read index table header [0x0001] - 2 bytes - if (getBit32(pIO, 16) != 1) - return ICERR_ERROR; - - //iBits = getBit16(pIO, 5) + 1; // how many bits per entry - for(i = 0; i < iEntry; i ++){ - readIS_L1(pSC, pIO); - pTable[i] = GetVLWordEsc(pIO, NULL); // escape handling is not important since the respective band is not accessed - } - } - - pSC->cHeaderSize = GetVLWordEsc(pIO, NULL); // escape handling is not important - flushToByte(pIO); - - pSC->cHeaderSize += getPosRead(pSC->pIOHeader); // get header length - - return ICERR_OK; -} - -Int StrIODecInit(CWMImageStrCodec* pSC) -{ - if(allocateBitIOInfo(pSC) != ICERR_OK){ - return ICERR_ERROR; - } - - attachISRead(pSC->pIOHeader, pSC->WMISCP.pWStream, pSC); - - readIndexTable(pSC); - - if(pSC->WMISCP.bVerbose){ - U32 i, j; - - printf("\n%d horizontal tiles:\n", pSC->WMISCP.cNumOfSliceMinus1H + 1); - for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1H; i ++){ - printf(" offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileY[i]); - } - - printf("\n%d vertical tiles:\n", pSC->WMISCP.cNumOfSliceMinus1V + 1); - for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i ++){ - printf(" offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileX[i]); - } - - if(pSC->WMISCP.bfBitstreamFormat == SPATIAL){ - printf("\nSpatial order bitstream\n"); - } - else{ - printf("\nFrequency order bitstream\n"); - } - - if(!pSC->m_param.bIndexTable){ - printf("\nstreaming mode, no index table.\n"); - } - else if(pSC->WMISCP.bfBitstreamFormat == SPATIAL){ - for(j = 0; j <= pSC->WMISCP.cNumOfSliceMinus1H; j ++){ - for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i ++){ - size_t * p = &pSC->pIndexTable[j * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + i]; - if(i + j != pSC->WMISCP.cNumOfSliceMinus1H + pSC->WMISCP.cNumOfSliceMinus1V){ - printf("bitstream size for tile (%d, %d): %d.\n", j, i, (int) (p[1] - p[0])); - } - else{ - printf("bitstream size for tile (%d, %d): unknown.\n", j, i); - } - } - } - } - else{ - for(j = 0; j <= pSC->WMISCP.cNumOfSliceMinus1H; j ++){ - for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i ++){ - size_t * p = &pSC->pIndexTable[(j * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + i) * 4]; - if(i + j != pSC->WMISCP.cNumOfSliceMinus1H + pSC->WMISCP.cNumOfSliceMinus1V){ - printf("bitstream size of (DC, LP, AC, FL) for tile (%d, %d): %d %d %d %d.\n", j, i, - (int) (p[1] - p[0]), (int) (p[2] - p[1]), (int) (p[3] - p[2]), (int) (p[4] - p[3])); - } - else{ - printf("bitstream size of (DC, LP, AC, FL) for tile (%d, %d): %d %d %d unknown.\n", j, i, - (int) (p[1] - p[0]), (int) (p[2] - p[1]), (int) (p[3] - p[2])); - } - } - } - } - } - - return 0; -} - -Void StrIODecTerm(CWMImageStrCodec* pSC) -{ - detachISRead(pSC, pSC->pIOHeader); - - free(pSC->m_ppBitIO); - free(pSC->pIndexTable); -} - -Int initLookupTables(CWMImageStrCodec* pSC) -{ - static const U8 cbChannels[BDB_MAX] = {1, 1, 2, 2, 2, 4, 4, 4, (U8) -1, (U8) -1, (U8) -1 }; - - CWMImageInfo * pII = &pSC->WMII; - size_t cStrideX, cStrideY; - size_t w, h, i, iFirst = 0; - Bool bReverse; - - // lookup tables for rotation and flipping - if(pSC->m_Dparam->cThumbnailScale > 1) // thumbnail - w = pII->cThumbnailWidth, h = pII->cThumbnailHeight; - else - w = pII->cWidth, h = pII->cHeight; - w += (pSC->m_Dparam->cROILeftX + pSC->m_Dparam->cThumbnailScale - 1) / pSC->m_Dparam->cThumbnailScale; - h += (pSC->m_Dparam->cROITopY + pSC->m_Dparam->cThumbnailScale - 1) / pSC->m_Dparam->cThumbnailScale; - - switch(pII->bdBitDepth){ - case BD_16: - case BD_16S: - case BD_5: - case BD_565: - case BD_16F: - cStrideY = pSC->WMIBI.cbStride / 2; - break; - - case BD_32: - case BD_32S: - case BD_32F: - case BD_10: - cStrideY = pSC->WMIBI.cbStride / 4; - break; - - default: //BD_8, BD_1 - cStrideY = pSC->WMIBI.cbStride; - break; - } - - switch(pII->cfColorFormat){ - case YUV_420: - cStrideX = 6; - w >>= 1, h >>= 1; - break; - - case YUV_422: - cStrideX = 4; - w >>= 1; - break; - - default: - cStrideX = (pII->cBitsPerUnit >> 3) / cbChannels[pII->bdBitDepth]; - break; - } - - if(pII->bdBitDepth == BD_1 || pII->bdBitDepth == BD_5 || pII->bdBitDepth == BD_10 || pII->bdBitDepth == BD_565) - cStrideX = 1; - - if(pII->oOrientation > O_FLIPVH) // rotated !! - i =cStrideX, cStrideX = cStrideY, cStrideY = i; - - pSC->m_Dparam->pOffsetX = (size_t *)malloc(w * sizeof(size_t)); - if(pSC->m_Dparam->pOffsetX == NULL || w * sizeof(size_t) < w) - return ICERR_ERROR; - /* - consider a row in the source image. if it becomes a reversed row in the target, or a reversed (upside-down)column - in the target, we have to reverse the offsets. bReverse here tells us when this happened. - */ - bReverse = (pII->oOrientation == O_FLIPH || pII->oOrientation == O_FLIPVH || - pII->oOrientation == O_RCW_FLIPV || pII->oOrientation == O_RCW_FLIPVH); - if(!pSC->m_Dparam->bDecodeFullFrame) // take care of region decode here! - iFirst = (pSC->m_Dparam->cROILeftX + pSC->m_Dparam->cThumbnailScale - 1) / pSC->m_Dparam->cThumbnailScale; - for(i = 0; i + iFirst < w; i ++){ - pSC->m_Dparam->pOffsetX[i + iFirst] = pII->cLeadingPadding + (bReverse ? (pSC->m_Dparam->bDecodeFullFrame ? w : - (pSC->m_Dparam->cROIRightX - pSC->m_Dparam->cROILeftX + pSC->m_Dparam->cThumbnailScale) / pSC->m_Dparam->cThumbnailScale / ((pII->cfColorFormat == YUV_420 || pII->cfColorFormat == YUV_422) ? 2 : 1)) - 1 - i : i) * cStrideX; - } - - pSC->m_Dparam->pOffsetY = (size_t *)malloc(h * sizeof(size_t)); - if(pSC->m_Dparam->pOffsetY == NULL || h * sizeof(size_t) < h) - return ICERR_ERROR; - /* - consider a column in the source image. if it becomes an upside-down column in the target, or a reversed row - in the target, we have to reverse the offsets. bReverse here tells us when this happened. - */ - bReverse = (pII->oOrientation == O_FLIPV || pII->oOrientation == O_FLIPVH || - pII->oOrientation == O_RCW || pII->oOrientation == O_RCW_FLIPV); - if(!pSC->m_Dparam->bDecodeFullFrame) // take care of region decode here! - iFirst = (pSC->m_Dparam->cROITopY + pSC->m_Dparam->cThumbnailScale - 1) / pSC->m_Dparam->cThumbnailScale; - for(i = 0; i + iFirst < h; i ++){ - pSC->m_Dparam->pOffsetY[i + iFirst] = (bReverse ? (pSC->m_Dparam->bDecodeFullFrame ? h : - (pSC->m_Dparam->cROIBottomY - pSC->m_Dparam->cROITopY + pSC->m_Dparam->cThumbnailScale) / pSC->m_Dparam->cThumbnailScale / (pII->cfColorFormat == YUV_420 ? 2 : 1)) - 1 - i : i) * cStrideY; - } - - return ICERR_OK; -} - -Void setROI(CWMImageStrCodec* pSC) -{ - CWMImageInfo * pWMII = &pSC->WMII; - CWMIStrCodecParam * pSCP = &pSC->WMISCP; - - // inscribed image size - pWMII->cWidth -= pSC->m_param.cExtraPixelsLeft + pSC->m_param.cExtraPixelsRight; - pWMII->cHeight -= pSC->m_param.cExtraPixelsTop + pSC->m_param.cExtraPixelsBottom; - - pSC->m_Dparam->bSkipFlexbits = (pSCP->sbSubband == SB_NO_FLEXBITS); - pSC->m_Dparam->bDecodeHP = (pSCP->sbSubband == SB_ALL || pSCP->sbSubband == SB_NO_FLEXBITS); - pSC->m_Dparam->bDecodeLP = (pSCP->sbSubband != SB_DC_ONLY); - pSC->m_Dparam->cThumbnailScale = 1; - while(pSC->m_Dparam->cThumbnailScale * pWMII->cThumbnailWidth < pWMII->cWidth) - pSC->m_Dparam->cThumbnailScale <<= 1; - if(pSC->WMISCP.bfBitstreamFormat == FREQUENCY){ - if(pSC->m_Dparam->cThumbnailScale >= 4) - pSC->m_Dparam->bDecodeHP = FALSE; // no need to decode HP - if(pSC->m_Dparam->cThumbnailScale >= 16) - pSC->m_Dparam->bDecodeLP = FALSE; // only need to decode DC - } - - // original image size - pWMII->cWidth += pSC->m_param.cExtraPixelsLeft + pSC->m_param.cExtraPixelsRight; - pWMII->cHeight += pSC->m_param.cExtraPixelsTop + pSC->m_param.cExtraPixelsBottom; - - /** region decode stuff */ - pSC->m_Dparam->cROILeftX = pWMII->cROILeftX * pSC->m_Dparam->cThumbnailScale + pSC->m_param.cExtraPixelsLeft; - pSC->m_Dparam->cROIRightX = pSC->m_Dparam->cROILeftX + pWMII->cROIWidth * pSC->m_Dparam->cThumbnailScale - 1; - pSC->m_Dparam->cROITopY = pWMII->cROITopY * pSC->m_Dparam->cThumbnailScale + pSC->m_param.cExtraPixelsTop; - pSC->m_Dparam->cROIBottomY = pSC->m_Dparam->cROITopY + pWMII->cROIHeight * pSC->m_Dparam->cThumbnailScale - 1; - if(pSC->m_Dparam->cROIRightX >= pWMII->cWidth) - pSC->m_Dparam->cROIRightX = pWMII->cWidth - 1; - if(pSC->m_Dparam->cROIBottomY >= pWMII->cHeight) - pSC->m_Dparam->cROIBottomY = pWMII->cHeight - 1; - - pSC->m_Dparam->bDecodeFullFrame = (pSC->m_Dparam->cROILeftX + pSC->m_Dparam->cROITopY == 0 && - ((pSC->m_Dparam->cROIRightX + 15) / 16 >= (pWMII->cWidth + 14) / 16) && ((pSC->m_Dparam->cROIBottomY + 15) / 16 >= (pWMII->cHeight + 14) / 16)); - - pSC->m_Dparam->bDecodeFullWidth = (pSC->m_Dparam->cROILeftX == 0 && ((pSC->m_Dparam->cROIRightX + 15) / 16 >= (pWMII->cWidth + 14) / 16)); - - // inscribed image size - pWMII->cWidth -= pSC->m_param.cExtraPixelsLeft + pSC->m_param.cExtraPixelsRight; - pWMII->cHeight -= pSC->m_param.cExtraPixelsTop + pSC->m_param.cExtraPixelsBottom; - - if(pSC->WMISCP.bfBitstreamFormat == FREQUENCY && pWMII->bSkipFlexbits == TRUE) - pSC->m_Dparam->bSkipFlexbits = TRUE; - - pSC->cTileColumn = pSC->cTileRow = 0; -} - -Int StrDecInit(CWMImageStrCodec* pSC) -{ - // CWMImageInfo * pWMII = &pSC->WMII; - COLORFORMAT cfInt = pSC->m_param.cfColorFormat; - COLORFORMAT cfExt = pSC->WMII.cfColorFormat; - size_t i; - - /** color transcoding with resolution change **/ - pSC->m_bUVResolutionChange = ((cfExt != Y_ONLY) && ((cfInt == YUV_420 && cfExt != YUV_420) || - (cfInt == YUV_422 && cfExt != YUV_422))) && !pSC->WMISCP.bYUVData; - if(pSC->m_bUVResolutionChange){ - pSC->pResU = (PixelI *)malloc((cfExt == YUV_422 ? 128 : 256) * pSC->cmbWidth * sizeof(PixelI)); - pSC->pResV = (PixelI *)malloc((cfExt == YUV_422 ? 128 : 256) * pSC->cmbWidth * sizeof(PixelI)); - if(pSC->pResU == NULL || pSC->pResV == NULL || (cfExt == YUV_422 ? 128 : 256) * pSC->cmbWidth * sizeof(PixelI) < pSC->cmbWidth){ - return ICERR_ERROR; - } - } - - if(allocatePredInfo(pSC) != ICERR_OK){ - return ICERR_ERROR; - } - - if(allocateTileInfo(pSC) != ICERR_OK) - return ICERR_ERROR; - - if((pSC->m_param.uQPMode & 1) == 0){ // DC frame uniform quantization - if(allocateQuantizer(pSC->pTile[0].pQuantizerDC, pSC->m_param.cNumChannels, 1) != ICERR_OK) - return ICERR_ERROR; - setUniformQuantizer(pSC, 0); - for(i = 0; i < pSC->m_param.cNumChannels; i ++) - pSC->pTile[0].pQuantizerDC[i]->iIndex = pSC->m_param.uiQPIndexDC[i]; - formatQuantizer(pSC->pTile[0].pQuantizerDC, (pSC->m_param.uQPMode >> 3) & 3, pSC->m_param.cNumChannels, 0, TRUE, pSC->m_param.bScaledArith); - } - - if(pSC->WMISCP.sbSubband != SB_DC_ONLY){ - if((pSC->m_param.uQPMode & 2) == 0){ // LP frame uniform quantization - if(allocateQuantizer(pSC->pTile[0].pQuantizerLP, pSC->m_param.cNumChannels, 1) != ICERR_OK) - return ICERR_ERROR; - setUniformQuantizer(pSC, 1); - if((pSC->m_param.uQPMode & 0x200) == 0) // use DC quantizer - useDCQuantizer(pSC, 0); - else{ - for(i = 0; i < pSC->m_param.cNumChannels; i ++) - pSC->pTile[0].pQuantizerLP[i]->iIndex = pSC->m_param.uiQPIndexLP[i]; - formatQuantizer(pSC->pTile[0].pQuantizerLP, (pSC->m_param.uQPMode >> 5) & 3, pSC->m_param.cNumChannels, 0, TRUE, pSC->m_param.bScaledArith); - } - } - - if(pSC->WMISCP.sbSubband != SB_NO_HIGHPASS){ - if((pSC->m_param.uQPMode & 4) == 0){ // HP frame uniform quantization - if(allocateQuantizer(pSC->pTile[0].pQuantizerHP, pSC->m_param.cNumChannels, 1) != ICERR_OK) - return ICERR_ERROR; - setUniformQuantizer(pSC, 2); - - if((pSC->m_param.uQPMode & 0x400) == 0) // use LP quantizer - useLPQuantizer(pSC, 1, 0); - else{ - for(i = 0; i < pSC->m_param.cNumChannels; i ++) - pSC->pTile[0].pQuantizerHP[i]->iIndex = pSC->m_param.uiQPIndexHP[i]; - formatQuantizer(pSC->pTile[0].pQuantizerHP, (pSC->m_param.uQPMode >> 7) & 3, pSC->m_param.cNumChannels, 0, FALSE, pSC->m_param.bScaledArith); - } - } - } - } - - if(pSC->WMISCP.cNumOfSliceMinus1V >= MAX_TILES || AllocateCodingContextDec(pSC, pSC->WMISCP.cNumOfSliceMinus1V + 1) != ICERR_OK){ - return ICERR_ERROR; - } - - if (pSC->m_bSecondary) { - pSC->pIOHeader = pSC->m_pNextSC->pIOHeader; - pSC->m_ppBitIO = pSC->m_pNextSC->m_ppBitIO; - pSC->cNumBitIO = pSC->m_pNextSC->cNumBitIO; - pSC->cSB = pSC->m_pNextSC->cSB; - } - - setBitIOPointers(pSC); - - return ICERR_OK; -} - -Int StrDecTerm(CWMImageStrCodec* pSC) -{ - size_t j, jend = (pSC->m_pNextSC != NULL); - - for (j = 0; j <= jend; j++) { - if(pSC->m_bUVResolutionChange){ - if(pSC->pResU != NULL) - free(pSC->pResU); - if(pSC->pResV != NULL) - free(pSC->pResV); - } - - freePredInfo(pSC); - - freeTileInfo(pSC); - - FreeCodingContextDec(pSC); - - if (j == 0) { - StrIODecTerm(pSC); - - // free lookup tables for rotation and flipping - if(pSC->m_Dparam->pOffsetX != NULL) - free(pSC->m_Dparam->pOffsetX); - if(pSC->m_Dparam->pOffsetY != NULL) - free(pSC->m_Dparam->pOffsetY); - } - - pSC = pSC->m_pNextSC; - } - - return 0; -} - -/************************************************************************* - Read header of image plane -*************************************************************************/ -Int ReadImagePlaneHeader(CWMImageInfo* pII, CWMIStrCodecParam *pSCP, - CCoreParameters *pSC, SimpleBitIO* pSB) -{ - ERR err = WMP_errSuccess; - - pSC->cfColorFormat = getBit32_SB(pSB, 3); // internal color format - FailIf((pSC->cfColorFormat < Y_ONLY || pSC->cfColorFormat > NCOMPONENT), WMP_errUnsupportedFormat); - pSCP->cfColorFormat = pSC->cfColorFormat; // this should be removed later - pSC->bScaledArith = getBit32_SB(pSB, 1); // lossless mode - - // subbands - pSCP->sbSubband = getBit32_SB(pSB, 4); - -// color parameters - switch (pSC->cfColorFormat) { - case Y_ONLY: - pSC->cNumChannels = 1; - break; - case YUV_420: - pSC->cNumChannels = 3; - getBit32_SB(pSB, 1); - pII->cChromaCenteringX = (U8) getBit32_SB(pSB, 3); - getBit32_SB(pSB, 1); - pII->cChromaCenteringY = (U8) getBit32_SB(pSB, 3); - break; - case YUV_422: - pSC->cNumChannels = 3; - getBit32_SB(pSB, 1); - pII->cChromaCenteringX = (U8) getBit32_SB(pSB, 3); - getBit32_SB(pSB, 4); - break; - case YUV_444: - pSC->cNumChannels = 3; - getBit32_SB(pSB, 4); - getBit32_SB(pSB, 4); - break; - case NCOMPONENT: - pSC->cNumChannels = (Int) getBit32_SB(pSB, 4) + 1; - getBit32_SB(pSB, 4); - break; - case CMYK: - pSC->cNumChannels = 4; - break; - default: - break; - } - -// float and 32s additional parameters - switch (pII->bdBitDepth) { - case BD_16: - case BD_16S: - case BD_32: - case BD_32S: - pSCP->nLenMantissaOrShift = (U8) getBit32_SB(pSB, 8); - break; - case BD_32F: - pSCP->nLenMantissaOrShift = (U8) getBit32_SB(pSB, 8);//float conversion parameters - pSCP->nExpBias = (I8) getBit32_SB(pSB, 8); - break; - default: - break; - } - - // quantization - pSC->uQPMode = 0; - if(getBit32_SB(pSB, 1) == 1) // DC uniform - pSC->uQPMode += (readQuantizerSB(pSC->uiQPIndexDC, pSB, pSC->cNumChannels) << 3); - else - pSC->uQPMode ++; - if(pSCP->sbSubband != SB_DC_ONLY){ - if(getBit32_SB(pSB, 1) == 0){ // don't use DC QP - pSC->uQPMode += 0x200; - if(getBit32_SB(pSB, 1) == 1) // LP uniform - pSC->uQPMode += (readQuantizerSB(pSC->uiQPIndexLP, pSB, pSC->cNumChannels) << 5); - else - pSC->uQPMode += 2; - } - else - pSC->uQPMode += ((pSC->uQPMode & 1) << 1) + ((pSC->uQPMode & 0x18) << 2); - - if(pSCP->sbSubband != SB_NO_HIGHPASS){ - if(getBit32_SB(pSB, 1) == 0){ // don't use LP QP - pSC->uQPMode += 0x400; - if(getBit32_SB(pSB, 1) == 1) // HP uniform - pSC->uQPMode += (readQuantizerSB(pSC->uiQPIndexHP, pSB, pSC->cNumChannels) << 7); - else - pSC->uQPMode += 4; - } - else - pSC->uQPMode += ((pSC->uQPMode & 2) << 1) + ((pSC->uQPMode & 0x60) << 2); - } - } - - if(pSCP->sbSubband == SB_DC_ONLY) - pSC->uQPMode |= 0x200; - else if(pSCP->sbSubband == SB_NO_HIGHPASS) - pSC->uQPMode |= 0x400; - - - FailIf((pSC->uQPMode & 0x600) == 0, WMP_errInvalidParameter); // frame level QPs must be specified independently! - - flushToByte_SB(pSB); // remove this later - -Cleanup: - return WMP_errSuccess == err ? ICERR_OK : ICERR_ERROR; -} - -/************************************************************************* - Read header of image, and header of FIRST PLANE only -*************************************************************************/ -Int ReadWMIHeader( - CWMImageInfo* pII, - CWMIStrCodecParam *pSCP, - CCoreParameters *pSC) -{ - U32 i; - ERR err = WMP_errSuccess; - Bool bTilingPresent, bInscribed, bTileStretch, bAbbreviatedHeader; - struct WMPStream* pWS = pSCP->pWStream; - - SimpleBitIO SB = {0}; - SimpleBitIO* pSB = &SB; - - U8 szMS[8] = {0}; - U32 cbStream = 0; - - // U32 bits = 0; - // Int HEADERSIZE = 0; - - assert(pSC != NULL); - //================================ -// 0 - /** signature **/ - Call(pWS->Read(pWS, szMS, sizeof(szMS))); - FailIf(szMS != (U8 *) strstr((char *) szMS, "WMPHOTO"), WMP_errUnsupportedFormat); - //================================ - Call(attach_SB(pSB, pWS)); - -// 8 - /** codec version and subversion **/ - i = getBit32_SB(pSB, 4); - FailIf((i != CODEC_VERSION), WMP_errIncorrectCodecVersion); - pSC->cVersion = i; - i = getBit32_SB(pSB, 4); // subversion - FailIf((i != CODEC_SUBVERSION && - i != CODEC_SUBVERSION_NEWSCALING_SOFT_TILES && i != CODEC_SUBVERSION_NEWSCALING_HARD_TILES), - WMP_errIncorrectCodecSubVersion); - pSC->cSubVersion = i; - - pSC->bUseHardTileBoundaries = FALSE; - if (pSC->cSubVersion == CODEC_SUBVERSION_NEWSCALING_HARD_TILES) - pSC->bUseHardTileBoundaries = TRUE; - - pSCP->bUseHardTileBoundaries = pSC->bUseHardTileBoundaries; - -// 9 primary parameters - bTilingPresent = (Bool) getBit32_SB(pSB, 1); // tiling present - pSCP->bfBitstreamFormat = getBit32_SB(pSB, 1); // bitstream layout - pII->oOrientation = (ORIENTATION)getBit32_SB(pSB, 3); // presentation orientation - pSC->bIndexTable = getBit32_SB(pSB, 1); - i = getBit32_SB(pSB, 2); // overlap - FailIf((i == 3), WMP_errInvalidParameter); - pSCP->olOverlap = i; - -// 11 some other parameters - bAbbreviatedHeader = (Bool) getBit32_SB(pSB, 1); // short words for size and tiles - pSCP->bdBitDepth = (BITDEPTH) getBit32_SB(pSB, 1); // long word -pSCP->bdBitDepth = BD_LONG; // remove when optimization is done - bInscribed = (Bool) getBit32_SB(pSB, 1); // windowing - pSC->bTrimFlexbitsFlag = (Bool) getBit32_SB(pSB, 1); // trim flexbits flag - bTileStretch = (Bool) getBit32_SB(pSB, 1); // tile stretching flag - pSC->bRBSwapped = (Bool) getBit32_SB(pSB, 1); // red-blue swap flag - getBit32_SB(pSB, 1); // padding / reserved bit - pSC->bAlphaChannel = (Bool) getBit32_SB(pSB, 1); // alpha channel present - -// 10 - informational - pII->cfColorFormat = getBit32_SB(pSB, 4); // source color format - pII->bdBitDepth = getBit32_SB(pSB, 4); // source bit depth - - if(BD_1alt == pII->bdBitDepth) - { - pII->bdBitDepth = BD_1; - pSCP->bBlackWhite = 1; - } - -// 12 - Variable length fields -// size - pII->cWidth = getBit32_SB(pSB, bAbbreviatedHeader ? 16 : 32) + 1; - pII->cHeight = getBit32_SB(pSB, bAbbreviatedHeader ? 16 : 32) + 1; - pSC->cExtraPixelsTop = pSC->cExtraPixelsLeft = pSC->cExtraPixelsBottom = pSC->cExtraPixelsRight = 0; - if (bInscribed == FALSE && (pII->cWidth & 0xf) != 0) - pSC->cExtraPixelsRight = 0x10 - (pII->cWidth & 0xF); - if (bInscribed == FALSE && (pII->cHeight & 0xf) != 0) - pSC->cExtraPixelsBottom = 0x10 - (pII->cHeight & 0xF); - -// tiling - pSCP->cNumOfSliceMinus1V = pSCP->cNumOfSliceMinus1H = 0; - if (bTilingPresent) { - pSCP->cNumOfSliceMinus1V = getBit32_SB(pSB, LOG_MAX_TILES); // # of vertical slices along X axis - pSCP->cNumOfSliceMinus1H = getBit32_SB(pSB, LOG_MAX_TILES); // # of horizontal slices along Y axis - } - FailIf((pSC->bIndexTable == FALSE) && (pSCP->bfBitstreamFormat == FREQUENCY || pSCP->cNumOfSliceMinus1V + pSCP->cNumOfSliceMinus1H > 0), - WMP_errUnsupportedFormat); - -// tile sizes - pSCP->uiTileX[0] = pSCP->uiTileY[0] = 0; - for(i = 0; i < pSCP->cNumOfSliceMinus1V; i ++){ // width in MB of vertical slices, not needed for last slice! - pSCP->uiTileX[i + 1] = (U32) getBit32_SB(pSB, bAbbreviatedHeader ? 8 : 16) + pSCP->uiTileX[i]; - } - for(i = 0; i < pSCP->cNumOfSliceMinus1H; i ++){ // width in MB of vertical slices, not needed for last slice! - pSCP->uiTileY[i + 1] = (U32) getBit32_SB(pSB, bAbbreviatedHeader ? 8 : 16) + pSCP->uiTileY[i]; - } - if (bTileStretch) { // no handling of tile stretching enabled as of now - for (i = 0; i < (pSCP->cNumOfSliceMinus1V + 1) * (pSCP->cNumOfSliceMinus1H + 1); i++) - getBit32_SB(pSB, 8); - } - -// window due to compressed domain processing - if (bInscribed) { - pSC->cExtraPixelsTop = (U8)getBit32_SB(pSB, 6); - pSC->cExtraPixelsLeft = (U8)getBit32_SB(pSB, 6); - pSC->cExtraPixelsBottom = (U8)getBit32_SB(pSB, 6); - pSC->cExtraPixelsRight = (U8)getBit32_SB(pSB, 6); - } - - if(((pII->cWidth + pSC->cExtraPixelsLeft + pSC->cExtraPixelsRight) & 0xf) + ((pII->cHeight + pSC->cExtraPixelsTop + pSC->cExtraPixelsBottom) & 0xf) != 0){ - FailIf((pII->cWidth & 0xf) + (pII->cHeight & 0xf) + pSC->cExtraPixelsLeft + pSC->cExtraPixelsTop != 0, WMP_errInvalidParameter); - FailIf(pII->cWidth <= pSC->cExtraPixelsRight || pII->cHeight <= pSC->cExtraPixelsBottom, WMP_errInvalidParameter); - pII->cWidth -= pSC->cExtraPixelsRight, pII->cHeight -= pSC->cExtraPixelsBottom; - } - - flushToByte_SB(pSB); // redundant - - // read header of first image plane - FailIf(ReadImagePlaneHeader(pII, pSCP, pSC, pSB), WMP_errUnsupportedFormat); - - // maybe UNALIGNED!!! - - //================================ - detach_SB(pSB); - pSCP->cbStream = cbStream - getByteRead_SB(pSB); - - pSCP->uAlphaMode = (pSC->bAlphaChannel ? pSCP->uAlphaMode : 0); - pSCP->cChannel = pSC->cNumChannels; - - if((pII->bdBitDepth == BD_5 || pII->bdBitDepth == BD_10 || pII->bdBitDepth == BD_565) && - (pSCP->cfColorFormat != YUV_444 && pSCP->cfColorFormat != YUV_422 && pSCP->cfColorFormat != YUV_420 && pSCP->cfColorFormat != Y_ONLY)) - return ICERR_ERROR; - -Cleanup: - return WMP_errSuccess == err ? ICERR_OK : ICERR_ERROR; -} - -//---------------------------------------------------------------- -// streaming api init/decode/term -EXTERN_C Int ImageStrDecGetInfo( - CWMImageInfo* pII, - CWMIStrCodecParam *pSCP) -{ - ERR err = WMP_errSuccess; - size_t cMarker; - CCoreParameters aDummy; - // mark position of start of data - Call(pSCP->pWStream->GetPos(pSCP->pWStream, &cMarker)); - Call(ReadWMIHeader(pII, pSCP, &aDummy)); - // rewind to start of data - Call(pSCP->pWStream->SetPos(pSCP->pWStream, cMarker)); - return ICERR_OK; - -Cleanup: - return ICERR_ERROR; -} - -EXTERN_C Int WMPhotoValidate( - CWMImageInfo * pII, - CWMIStrCodecParam * pSCP) -{ - CWMImageInfo cII; - CWMIStrCodecParam cSCP = *pSCP; - size_t cScale = 1; - - if(ImageStrDecGetInfo(&cII, pSCP) != ICERR_OK) - return ICERR_ERROR; - - // copy over un-overwritable ImageInfo parameters - pII->bdBitDepth = cII.bdBitDepth; - pII->cWidth = cII.cWidth; - pII->cHeight = cII.cHeight; - - if(pII->cWidth == 0 || pII->cHeight == 0) - return ICERR_ERROR; - - // copy over overwritable CodecParam parameters - pSCP->bVerbose = cSCP.bVerbose; - pSCP->cbStream = cSCP.cbStream; - pSCP->pWStream = cSCP.pWStream; - if(pSCP->uAlphaMode > 1) // something + alpha - pSCP->uAlphaMode = cSCP.uAlphaMode; // something + alpha to alpha or something transcoding! - - // validate color transcoding - if(pSCP->cfColorFormat == NCOMPONENT) - pII->cfColorFormat = NCOMPONENT; - if(pSCP->cfColorFormat == CMYK && pII->cfColorFormat != Y_ONLY && pII->cfColorFormat != CF_RGB) - pII->cfColorFormat = CMYK; - if(pSCP->cfColorFormat == YUV_422 && pII->cfColorFormat == YUV_420) - pII->cfColorFormat = YUV_422; - if(pSCP->cfColorFormat == YUV_444 && (pII->cfColorFormat == YUV_422 || pII->cfColorFormat == YUV_420)) - pII->cfColorFormat = YUV_444; - if(cII.cfColorFormat == CF_RGB && pII->cfColorFormat != Y_ONLY && - pII->cfColorFormat != NCOMPONENT) // no guarantee that number of channels will be >= 3 - pII->cfColorFormat = cII.cfColorFormat; - if(cII.cfColorFormat == CF_RGBE) - pII->cfColorFormat = CF_RGBE; - - // validate thumbnail parameters - if(pII->cThumbnailWidth == 0 || pII->cThumbnailWidth > pII->cWidth) - pII->cThumbnailWidth = pII->cWidth; - if(pII->cThumbnailHeight == 0 || pII->cThumbnailHeight > pII->cHeight) - pII->cThumbnailHeight = pII->cHeight; - if((pII->cWidth + pII->cThumbnailWidth - 1) / pII->cThumbnailWidth != (pII->cHeight + pII->cThumbnailHeight - 1) / pII->cThumbnailHeight) { - while((pII->cWidth + cScale - 1) / cScale > pII->cThumbnailWidth && - (pII->cHeight + cScale - 1) / cScale > pII->cThumbnailHeight && (cScale << 1)) - cScale <<= 1; - } - else { - cScale = (pII->cWidth + pII->cThumbnailWidth - 1) / pII->cThumbnailWidth; - if (cScale == 0) - cScale = 1; - } - pII->cThumbnailWidth = (pII->cWidth + cScale - 1) / cScale; - pII->cThumbnailHeight = (pII->cHeight + cScale - 1) / cScale; - - // validate region decode parameters - if(pII->cROIHeight == 0 || pII->cROIWidth == 0){ - pII->cROILeftX = pII->cROITopY = 0; - pII->cROIWidth = pII->cThumbnailWidth; - pII->cROIHeight = pII->cThumbnailHeight; - } - if(pII->cROILeftX >= pII->cThumbnailWidth) - pII->cROILeftX = 0; - if(pII->cROITopY >= pII->cThumbnailHeight) - pII->cROITopY = 0; - if(pII->cROILeftX + pII->cROIWidth > pII->cThumbnailWidth) - pII->cROIWidth = pII->cThumbnailWidth - pII->cROILeftX; - if(pII->cROITopY + pII->cROIHeight > pII->cThumbnailHeight) - pII->cROIHeight = pII->cThumbnailHeight - pII->cROITopY; - - return ICERR_OK; -} - -/************************************************************************* - Initialization of CWMImageStrCodec struct -*************************************************************************/ -static Void InitializeStrDec(CWMImageStrCodec *pSC, - const CCoreParameters *pParams, const CWMImageStrCodec *pSCIn) -{ - // copy core parameters - memcpy (&(pSC->m_param), pParams, sizeof (CCoreParameters)); - - pSC->cbStruct = sizeof(*pSC); - pSC->WMII = pSCIn->WMII; - pSC->WMISCP = pSCIn->WMISCP; - - pSC->cRow = 0; - pSC->cColumn = 0; - - pSC->cmbWidth = (pSC->WMII.cWidth + 15) / 16; - pSC->cmbHeight = (pSC->WMII.cHeight + 15) / 16; - - pSC->Load = outputMBRow; // output decoding result (ICC, etc) - pSC->Transform = pParams->cSubVersion == CODEC_SUBVERSION ? - invTransformMacroblock : invTransformMacroblock_alteredOperators_hard; - pSC->TransformCenter = pSC->Transform; - - pSC->ProcessTopLeft = processMacroblockDec; - pSC->ProcessTop = processMacroblockDec; - pSC->ProcessTopRight = processMacroblockDec; - pSC->ProcessLeft = processMacroblockDec; - pSC->ProcessCenter = processMacroblockDec; - pSC->ProcessRight = processMacroblockDec; - pSC->ProcessBottomLeft = processMacroblockDec; - pSC->ProcessBottom = processMacroblockDec; - pSC->ProcessBottomRight = processMacroblockDec; - - pSC->m_pNextSC = NULL; - pSC->m_bSecondary = FALSE; -} - -/************************************************************************* - ImageStrDecInit -*************************************************************************/ -Int ImageStrDecInit( - CWMImageInfo* pII, - CWMIStrCodecParam *pSCP, - CTXSTRCODEC* pctxSC) -{ - static size_t cbChannels[BD_MAX] = {2, 4}; - ERR err = WMP_errSuccess; - - size_t cbChannel = 0, cblkChroma = 0; - size_t cbMacBlockStride = 0, cbMacBlockChroma = 0, cMacBlock = 0; - - CWMImageStrCodec SC = {0}; - CWMImageStrCodec *pSC = NULL, *pNextSC = NULL; - char* pb = NULL; - size_t cb = 0, i; - Bool bLossyTranscoding = FALSE; - Bool bUseHardTileBoundaries = FALSE; //default is soft tile boundaries - Bool bLessThan64Bit = sizeof(void *) < 8; - - *pctxSC = NULL; - - if(WMPhotoValidate(pII, pSCP) != ICERR_OK) - return ICERR_ERROR; - - if(pSCP->sbSubband == SB_ISOLATED) // can not do anything with isolated bitstream - return ICERR_ERROR; - - //================================================ - SC.WMISCP.pWStream = pSCP->pWStream; - if (ReadWMIHeader(&SC.WMII, &SC.WMISCP, &SC.m_param) != ICERR_OK) { - return ICERR_ERROR; - } - - bUseHardTileBoundaries = SC.WMISCP.bUseHardTileBoundaries; - if(SC.WMII.cfColorFormat == CMYK && pII->cfColorFormat == CF_RGB) - bLossyTranscoding = TRUE; - if(pSCP->cfColorFormat != CMYK && (pII->cfColorFormat == CMYK)) - return ICERR_ERROR; - - //================================================ - SC.WMISCP = *pSCP; - SC.WMII = *pII; - - // original image size - SC.WMII.cWidth += SC.m_param.cExtraPixelsLeft + SC.m_param.cExtraPixelsRight; - SC.WMII.cHeight += SC.m_param.cExtraPixelsTop + SC.m_param.cExtraPixelsBottom; - pII->cROILeftX += SC.m_param.cExtraPixelsLeft; - pII->cROITopY += SC.m_param.cExtraPixelsTop; - - //================================================ - cbChannel = cbChannels[SC.WMISCP.bdBitDepth]; - cblkChroma = cblkChromas[SC.m_param.cfColorFormat]; - - cbMacBlockStride = cbChannel * 16 * 16; - cbMacBlockChroma = cbChannel * 16 * cblkChroma; - cMacBlock = (SC.WMII.cWidth + 15) / 16; - - //================================================ - cb = sizeof(*pSC) + (128 - 1) + sizeof(CWMDecoderParameters); - cb += (PACKETLENGTH * 4 - 1) + (PACKETLENGTH * 2 ) + sizeof(*pSC->pIOHeader); - - i = (cbMacBlockStride + cbMacBlockChroma * (SC.m_param.cNumChannels - 1)) * 2; // i <= 2^15 - if (bLessThan64Bit && ((i * (cMacBlock >> 16)) & 0xffffc000)) { - /** potential overflow - 32 bit pointers insufficient to address cache **/ - return ICERR_ERROR; - } - cb += i * cMacBlock; - - pb = malloc(cb); - if(pb == NULL) - return WMP_errOutOfMemory; - memset(pb, 0, cb); - - //================================================ - pSC = (CWMImageStrCodec*)pb; pb += sizeof(*pSC); - if(pSC == NULL) - return ICERR_ERROR; - - // Set up perf timers - PERFTIMER_ONLY(pSC->m_fMeasurePerf = pSCP->fMeasurePerf); - PERFTIMER_NEW(pSC->m_fMeasurePerf, &pSC->m_ptEndToEndPerf); - PERFTIMER_NEW(pSC->m_fMeasurePerf, &pSC->m_ptEncDecPerf); - PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEndToEndPerf); - PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); - PERFTIMER_COPYSTARTTIME(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf, pSC->m_ptEndToEndPerf); - - pSC->m_Dparam = (CWMDecoderParameters*)pb; pb += sizeof(CWMDecoderParameters); - pSC->cbChannel = cbChannel; - //pSC->cNumChannels = SC.WMISCP.cChannel; - pSC->bUseHardTileBoundaries = bUseHardTileBoundaries; - - //================================================ - InitializeStrDec(pSC, &SC.m_param, &SC); - - //================================================ - // 2 Macro Row buffers for each channel - pb = ALIGNUP(pb, 128); - for (i = 0; i < pSC->m_param.cNumChannels; i++) { - pSC->a0MBbuffer[i] = (PixelI*)pb; pb += cbMacBlockStride * pSC->cmbWidth; - pSC->a1MBbuffer[i] = (PixelI*)pb; pb += cbMacBlockStride * pSC->cmbWidth; - cbMacBlockStride = cbMacBlockChroma; - } - - //================================================ - // lay 2 aligned IO buffers just below pIO struct - pb = (char*)ALIGNUP(pb, PACKETLENGTH * 4) + PACKETLENGTH * 2; - pSC->pIOHeader = (BitIOInfo*)pb; pb += sizeof(*pSC->pIOHeader); - - // if interleaved alpha is needed - if (pSC->m_param.bAlphaChannel) { - SimpleBitIO SB = {0}; - cbMacBlockStride = cbChannel * 16 * 16; - - // 1. allocate new pNextSC info - //================================================ - cb = sizeof(*pNextSC) + (128 - 1) + cbMacBlockStride * cMacBlock * 2; - // if primary image is safe to allocate, alpha channel is certainly safe - pb = malloc(cb); - if(pb == NULL) - return WMP_errOutOfMemory; - memset(pb, 0, cb); - //================================================ - pNextSC = (CWMImageStrCodec*)pb; pb += sizeof(*pNextSC); - - // read plane header of second image plane - Call(attach_SB(&SB, pSCP->pWStream)); - InitializeStrDec(pNextSC, &SC.m_param, &SC); - ReadImagePlaneHeader(&pNextSC->WMII, &pNextSC->WMISCP, &pNextSC->m_param, &SB); - detach_SB(&SB); - - // 2. initialize pNextSC - if(pNextSC == NULL) - return ICERR_ERROR; - pNextSC->m_Dparam = pSC->m_Dparam; - pNextSC->cbChannel = cbChannel; - //================================================ - - // 3. initialize arrays -// InitializeStrDec(pNextSC, &SC.m_param, &SC); - pNextSC->m_param.cfColorFormat = Y_ONLY; - pNextSC->m_param.cNumChannels = 1; - pNextSC->m_param.bAlphaChannel = TRUE; - //================================================ - - // 2 Macro Row buffers for each channel - pb = ALIGNUP(pb, 128); - pNextSC->a0MBbuffer[0] = (PixelI*)pb; pb += cbMacBlockStride * pNextSC->cmbWidth; - pNextSC->a1MBbuffer[0] = (PixelI*)pb; - //================================================ - pNextSC->pIOHeader = pSC->pIOHeader; - //================================================ - - // 4. link pSC->pNextSC = pNextSC - pNextSC->m_pNextSC = pSC; - pNextSC->m_bSecondary = TRUE; - - } - else - pSC->WMISCP.uAlphaMode = 0; - - //================================================ - FailIf((StrIODecInit(pSC) != ICERR_OK), WMP_errOutOfMemory); - FailIf((StrDecInit(pSC) != ICERR_OK), WMP_errOutOfMemory); - if (pNextSC) { - // 5. StrEncInit - FailIf((StrDecInit(pNextSC) != ICERR_OK), WMP_errOutOfMemory); - } - - pSC->m_pNextSC = pNextSC; - //================================================ - *pII = pSC->WMII; - *pSCP = pSC->WMISCP; - *pctxSC = (CTXSTRCODEC)pSC; - - if(pSC->WMII.cPostProcStrength){ - initPostProc(pSC->pPostProcInfo, pSC->cmbWidth, pSC->m_param.cNumChannels); - if (pSC->m_param.bAlphaChannel) - initPostProc(pNextSC->pPostProcInfo, pNextSC->cmbWidth, pNextSC->m_param.cNumChannels); - } - - PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); - -Cleanup: - return WMP_errSuccess == err ? ICERR_OK : ICERR_ERROR; -} - -Int ImageStrDecDecode( - CTXSTRCODEC ctxSC, - const CWMImageBufferInfo* pBI -#ifdef REENTRANT_MODE - , size_t *pcDecodedLines -#endif - ) -{ - CWMImageStrCodec* pSC = (CWMImageStrCodec*)ctxSC; - CWMImageStrCodec* pNextSC = pSC->m_pNextSC; - size_t cMBRow, k; - - ImageDataProc ProcessLeft, ProcessCenter, ProcessRight; - ImageDataProc Transform = NULL; - const size_t iChromaElements = (pSC->m_param.cfColorFormat == YUV_420) ? 8 * 8 - : ((pSC->m_param.cfColorFormat == YUV_422) ? 8 * 16 : 16 * 16); - - if (sizeof(*pSC) != pSC->cbStruct) - { - return ICERR_ERROR; - } - - //================================ - PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); - - pSC->WMIBI = *pBI; - -#ifdef REENTRANT_MODE - if (0 == pSC->WMIBI.uiFirstMBRow) - { - setROI(pSC); - if (pNextSC) { - pNextSC->WMIBI = pSC->WMIBI; - setROI(pNextSC); - } - } -#else - setROI(pSC); - if (pNextSC) { - pNextSC->WMIBI = pSC->WMIBI; - setROI(pNextSC); - } -#endif // REENTRANT_MODE - -// optimization flags can be defined only after ROI is set! -#if defined(WMP_OPT_SSE2) || defined(WMP_OPT_CC_DEC) || defined(WMP_OPT_TRFM_DEC) - StrDecOpt(pSC); -#endif // OPT defined - - - - cMBRow = (pSC->m_Dparam->bDecodeFullFrame ? pSC->cmbHeight : ((pSC->m_Dparam->cROIBottomY + 16) >> 4)); - -#ifdef REENTRANT_MODE - if (0 == pSC->WMIBI.uiFirstMBRow) - { - if(initLookupTables(pSC) != ICERR_OK) - return ICERR_ERROR; - if (pNextSC && initLookupTables(pNextSC) != ICERR_OK) - return ICERR_ERROR; - } -#else - if(initLookupTables(pSC) != ICERR_OK) - return ICERR_ERROR; - if (pNextSC && initLookupTables(pNextSC) != ICERR_OK) - return ICERR_ERROR; -#endif // REENTRANT_MODE - -#ifndef REENTRANT_MODE - if(pSC->WMII.bdBitDepth == BD_1){ - size_t i; - - - for(i = 0; i < pSC->WMIBI.cLine; i ++) - memset(pSC->WMIBI.pv, 0, pSC->WMIBI.cbStride); - } -#endif - - //================================ - // top row -#ifdef REENTRANT_MODE -#else - pSC->cRow = 0; - ProcessLeft = pSC->ProcessTopLeft; - ProcessCenter = pSC->ProcessTop; - ProcessRight = pSC->ProcessTopRight; - Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ? - invTransformMacroblock : invTransformMacroblock_alteredOperators_hard; -#endif // REENTRANT_MODE - -#ifdef REENTRANT_MODE - for (pSC->cRow = pSC->WMIBI.uiFirstMBRow; pSC->cRow <= pSC->WMIBI.uiLastMBRow; pSC->cRow++) - { - // const COLORFORMAT cfExt = (pSC->m_param.cfColorFormat == Y_ONLY ? Y_ONLY : pSC->WMII.cfColorFormat); - - if (0 == pSC->cRow) - { - ProcessLeft = pSC->ProcessTopLeft; - ProcessCenter = pSC->ProcessTop; - ProcessRight = pSC->ProcessTopRight; - Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ? - invTransformMacroblock : invTransformMacroblock_alteredOperators_hard; - } - else if (cMBRow == pSC->cRow) - { - //================================ - // bottom row - ProcessLeft = pSC->ProcessBottomLeft; - ProcessCenter = pSC->ProcessBottom; - ProcessRight = pSC->ProcessBottomRight; - Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ? - invTransformMacroblock : invTransformMacroblock_alteredOperators_hard; - } - else { // middle rows - ProcessLeft = pSC->ProcessLeft; - ProcessCenter = pSC->ProcessCenter; - ProcessRight = pSC->ProcessRight; - Transform = pSC->TransformCenter; - } -#else - //================================ - // central rows - for(pSC->cRow = 0; pSC->cRow <= cMBRow; pSC->cRow++) - { -#endif // REENTRANT_MODE - pSC->cColumn = 0; - initMRPtr(pSC); - /** zero out the transform coefficients (pull this out to once per MB row) **/ - memset(pSC->p1MBbuffer[0], 0, sizeof(PixelI) * 16 * 16 * pSC->cmbWidth); - for (k = 1; k < pSC->m_param.cNumChannels; k++) { - memset(pSC->p1MBbuffer[k], 0, sizeof(PixelI) * iChromaElements * pSC->cmbWidth); - } - if (pSC->m_pNextSC != NULL) { // alpha channel - memset(pSC->m_pNextSC->p1MBbuffer[0], 0, sizeof(PixelI) * 16 * 16 * pSC->m_pNextSC->cmbWidth); - } - - if(ProcessLeft(pSC) != ICERR_OK) - return ICERR_ERROR; - advanceMRPtr(pSC); - - pSC->Transform = Transform; - for (pSC->cColumn = 1; pSC->cColumn < pSC->cmbWidth; ++pSC->cColumn) - { - if(ProcessCenter(pSC) != ICERR_OK) - return ICERR_ERROR; - advanceMRPtr(pSC); - } - pSC->Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ? - invTransformMacroblock : invTransformMacroblock_alteredOperators_hard; - - if(ProcessRight(pSC) != ICERR_OK) - return ICERR_ERROR; - - if (pSC->cRow) { - if(pSC->m_Dparam->cThumbnailScale < 2 && (pSC->m_Dparam->bDecodeFullFrame || - ((pSC->cRow * 16 > pSC->m_Dparam->cROITopY) && (pSC->cRow * 16 <= pSC->m_Dparam->cROIBottomY + 16)))) { - if( pSC->Load(pSC) != ICERR_OK ) // bypass CC for thumbnail decode - return ICERR_ERROR; - } - - if(pSC->m_Dparam->cThumbnailScale >= 2) // decode thumbnail - decodeThumbnail(pSC); - } - - advanceOneMBRow(pSC); - swapMRPtr(pSC); -#ifdef REENTRANT_MODE - *pcDecodedLines = pSC->WMIBI.cLinesDecoded; -#else - if (pSC->cRow == cMBRow - 1) { - //================================ - // bottom row - ProcessLeft = pSC->ProcessBottomLeft; - ProcessCenter = pSC->ProcessBottom; - ProcessRight = pSC->ProcessBottomRight; - Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ? - invTransformMacroblock : invTransformMacroblock_alteredOperators_hard; - } - else { - ProcessLeft = pSC->ProcessLeft; - ProcessCenter = pSC->ProcessCenter; - ProcessRight = pSC->ProcessRight; - Transform = pSC->TransformCenter; - } -#endif // REENTRANT_MODE - } - -#ifndef REENTRANT_MODE - fixup_Y_ONLY_to_Others(pSC, pBI); -#endif // REENTRANT_MODE - - PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); - return ICERR_OK; -} - -Int ImageStrDecTerm( - CTXSTRCODEC ctxSC) -{ - CWMImageStrCodec* pSC = (CWMImageStrCodec*)ctxSC; - if (NULL == pSC) - { - return ICERR_OK; - } - if (sizeof(*pSC) != pSC->cbStruct) - { - return ICERR_ERROR; - } - - PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); - - StrDecTerm(pSC); - PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); - PERFTIMER_REPORT(pSC->m_fMeasurePerf, pSC); - PERFTIMER_DELETE(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); - PERFTIMER_DELETE(pSC->m_fMeasurePerf, pSC->m_ptEndToEndPerf); - - free(pSC); - - return ICERR_OK; -} - diff --git a/Src/JxrDecode/Jxr/strdec_x86.c b/Src/JxrDecode/Jxr/strdec_x86.c deleted file mode 100644 index b9a2f13f..00000000 --- a/Src/JxrDecode/Jxr/strdec_x86.c +++ /dev/null @@ -1,1641 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// Copyright © Microsoft Corp. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// • Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// • Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -//*@@@---@@@@****************************************************************** -#include "strcodec.h" -#include "decode.h" -#include "JXRGlue.h" - -#if defined(WMP_OPT_SSE2) -#include -#include - -//================================================================ -static __m128i g_const_d0; -static __m128i g_const_d1; - -__m128i g_const_d3; -__m128i g_const_d4; -__m128i g_const_d0x80; -__m128i g_const_w0x80; -__m128i g_const_b0x80; - -//================================================================ -#if defined(WMP_OPT_CC_DEC) -__declspec(naked) void __stdcall storeRGB24_5( - U8* pbYCoCg, - size_t cbYCoCg, - const U8* pbRGB, - size_t cbRGB, - size_t cmb) -{ -#define DISP 8 - UNREFERENCED_PARAMETER( pbYCoCg ); - UNREFERENCED_PARAMETER( cbYCoCg ); - UNREFERENCED_PARAMETER( pbRGB ); - UNREFERENCED_PARAMETER( cbRGB ); - UNREFERENCED_PARAMETER( cmb ); - __asm { - push ebp - push ebx - push esi - push edi - - mov ebx, [esp + 36] // $ebx = cmb - mov edi, [esp + 28] // $edi = pbRGB - lea ebx, [ebx + ebx * 2] // $ebx = cmb * 3 - mov edx, [esp + 32] // $edx = cbRGB - shl ebx, 4 // $ebx = cmb * 3 * 16 - mov esi, [esp + 20] // $esi = pbYCoCg - add edi, ebx // $edi = pbRGB + 3 * 16 * cmb - mov ebp, [esp + 24] // $ebp = cbYCoCg - neg ebx - - mov eax, esp - and esp, 0xffffff80 - sub esp, 64 * 4 + DISP - - mov [esp], eax // original $esp - mov [esp + 4], edi - } -Loop0: - __asm { - mov edi, [esp + 4] // $edi = pbRGB + 3 * 16 * cmb - - // first 8 pixels - pxor xmm1, xmm1 - pxor xmm5, xmm5 - movdqa xmm0, [esi] - movdqa xmm4, [esi + 16] - psubd xmm1, [esi + ebp] - psubd xmm5, [esi + ebp + 16] - movdqa xmm2, [esi + ebp * 2] - movdqa xmm6, [esi + ebp * 2 + 16] - - paddd xmm0, [g_const_d0x80] - paddd xmm4, [g_const_d0x80] - - // ICC - movdqa xmm3, xmm1 // g -= r >> 1 - movdqa xmm7, xmm5 - psrad xmm3, 1 - psrad xmm7, 1 - psubd xmm0, xmm3 - psubd xmm4, xmm7 - - movdqa xmm3, [g_const_d1] // r -= ((b + 1) >> 1) - g - movdqa xmm7, [g_const_d1] - paddd xmm3, xmm2 - paddd xmm7, xmm6 - paddd xmm1, xmm0 - paddd xmm5, xmm4 - psrad xmm3, 1 - psrad xmm7, 1 - psubd xmm1, xmm3 - psubd xmm5, xmm7 - - paddd xmm2, xmm1 // b += r - paddd xmm6, xmm5 - - pslld xmm0, 8 - pslld xmm2, 16 - pslld xmm4, 8 - pslld xmm6, 16 - por xmm0, xmm1 - por xmm4, xmm5 - por xmm0, xmm2 - por xmm4, xmm6 - - movdqa [esp + DISP + 64 * 0 + 16 * 0], xmm0 - pslld xmm0, 8 - movdqa [esp + DISP + 64 * 0 + 16 * 1], xmm4 - pslld xmm4, 8 - movdqa [esp + DISP + 64 * 0 + 16 * 2], xmm0 - movdqa [esp + DISP + 64 * 0 + 16 * 3], xmm4 - - // second 8 pixels - pxor xmm1, xmm1 - pxor xmm5, xmm5 - movdqa xmm0, [esi + 32] - movdqa xmm4, [esi + 48] - psubd xmm1, [esi + ebp + 32] - psubd xmm5, [esi + ebp + 48] - movdqa xmm2, [esi + ebp * 2 + 32] - movdqa xmm6, [esi + ebp * 2 + 48] - - paddd xmm0, [g_const_d0x80] - paddd xmm4, [g_const_d0x80] - - // ICC - movdqa xmm3, xmm1 // g -= r >> 1 - movdqa xmm7, xmm5 - psrad xmm3, 1 - psrad xmm7, 1 - psubd xmm0, xmm3 - psubd xmm4, xmm7 - - movdqa xmm3, [g_const_d1] // r -= ((b + 1) >> 1) - g - movdqa xmm7, [g_const_d1] - paddd xmm3, xmm2 - paddd xmm7, xmm6 - paddd xmm1, xmm0 - paddd xmm5, xmm4 - psrad xmm3, 1 - psrad xmm7, 1 - psubd xmm1, xmm3 - psubd xmm5, xmm7 - - paddd xmm2, xmm1 // b += r - paddd xmm6, xmm5 - - pslld xmm0, 8 - pslld xmm2, 16 - pslld xmm4, 8 - pslld xmm6, 16 - por xmm0, xmm1 - por xmm4, xmm5 - por xmm0, xmm2 - por xmm4, xmm6 - - movdqa [esp + DISP + 64 * 1 + 16 * 0], xmm0 - pslld xmm0, 8 - movdqa [esp + DISP + 64 * 1 + 16 * 1], xmm4 - pslld xmm4, 8 - movdqa [esp + DISP + 64 * 1 + 16 * 2], xmm0 - movdqa [esp + DISP + 64 * 1 + 16 * 3], xmm4 - - //================ - add esi, 64 - - // first 8 pixels - pxor xmm1, xmm1 - pxor xmm5, xmm5 - movdqa xmm0, [esi] - movdqa xmm4, [esi + 16] - psubd xmm1, [esi + ebp] - psubd xmm5, [esi + ebp + 16] - movdqa xmm2, [esi + ebp * 2] - movdqa xmm6, [esi + ebp * 2 + 16] - - paddd xmm0, [g_const_d0x80] - paddd xmm4, [g_const_d0x80] - - // ICC - movdqa xmm3, xmm1 // g -= r >> 1 - movdqa xmm7, xmm5 - psrad xmm3, 1 - psrad xmm7, 1 - psubd xmm0, xmm3 - psubd xmm4, xmm7 - - movdqa xmm3, [g_const_d1] // r -= ((b + 1) >> 1) - g - movdqa xmm7, [g_const_d1] - paddd xmm3, xmm2 - paddd xmm7, xmm6 - paddd xmm1, xmm0 - paddd xmm5, xmm4 - psrad xmm3, 1 - psrad xmm7, 1 - psubd xmm1, xmm3 - psubd xmm5, xmm7 - - paddd xmm2, xmm1 // b += r - paddd xmm6, xmm5 - - pslld xmm0, 8 - pslld xmm2, 16 - pslld xmm4, 8 - pslld xmm6, 16 - - por xmm0, xmm1 - por xmm4, xmm5 - por xmm0, xmm2 - por xmm4, xmm6 - - movdqa [esp + DISP + 64 * 2 + 16 * 0], xmm0 - pslld xmm0, 8 - movdqa [esp + DISP + 64 * 2 + 16 * 1], xmm4 - pslld xmm4, 8 - movdqa [esp + DISP + 64 * 2 + 16 * 2], xmm0 - movdqa [esp + DISP + 64 * 2 + 16 * 3], xmm4 - - // second 8 pixels - pxor xmm1, xmm1 - pxor xmm5, xmm5 - movdqa xmm0, [esi + 32] - movdqa xmm4, [esi + 48] - psubd xmm1, [esi + ebp + 32] - psubd xmm5, [esi + ebp + 48] - movdqa xmm2, [esi + ebp * 2 + 32] - movdqa xmm6, [esi + ebp * 2 + 48] - - paddd xmm0, [g_const_d0x80] - paddd xmm4, [g_const_d0x80] - - // ICC - movdqa xmm3, xmm1 // g -= r >> 1 - movdqa xmm7, xmm5 - psrad xmm3, 1 - psrad xmm7, 1 - psubd xmm0, xmm3 - psubd xmm4, xmm7 - - movdqa xmm3, [g_const_d1] // r -= ((b + 1) >> 1) - g - movdqa xmm7, [g_const_d1] - paddd xmm3, xmm2 - paddd xmm7, xmm6 - paddd xmm1, xmm0 - paddd xmm5, xmm4 - psrad xmm3, 1 - psrad xmm7, 1 - psubd xmm1, xmm3 - psubd xmm5, xmm7 - - paddd xmm2, xmm1 // b += r - paddd xmm6, xmm5 - - pslld xmm0, 8 - pslld xmm2, 16 - pslld xmm4, 8 - pslld xmm6, 16 - por xmm0, xmm1 - por xmm4, xmm5 - por xmm0, xmm2 - por xmm4, xmm6 - - movdqa [esp + DISP + 64 * 3 + 16 * 0], xmm0 - pslld xmm0, 8 - movdqa [esp + DISP + 64 * 3 + 16 * 1], xmm4 - pslld xmm4, 8 - movdqa [esp + DISP + 64 * 3 + 16 * 2], xmm0 - movdqa [esp + DISP + 64 * 3 + 16 * 3], xmm4 - - //================================ - // RGBX32 -> RGB24 - mov eax, [esp + DISP + 64 * 0 + 4] // ..B1G1R1 - mov ecx, [esp + DISP + 64 * 0 + 32] // B0G0R0.. - shld eax, ecx, 24 // R1B0G0R0 - mov [edi + ebx + 0], eax - mov eax, [esp + DISP + 64 * 0 + 20] // ..B5G5R5 - mov ecx, [esp + DISP + 64 * 0 + 36] // B1G1R1.. - shld eax, ecx, 16 // G5R5B1G1 - mov [edi + ebx + 4], eax - mov eax, [esp + DISP + 64 * 0 + 16] // ..B4G4R4 - mov ecx, [esp + DISP + 64 * 0 + 52] // B5G5R5.. - shld eax, ecx, 8 // B4G4R4B5 - mov [edi + ebx + 8], eax - add edi, edx // $edi = pbRGB += cbRGB - - mov eax, [esp + DISP + 64 * 0 + 4 + 8] // ..B3G3R3 - mov ecx, [esp + DISP + 64 * 0 + 32 + 8] // B2G2R2.. - shld eax, ecx, 24 // R3B2G2R2 - mov [edi + ebx + 0], eax - mov eax, [esp + DISP + 64 * 0 + 20 + 8] // ..B7G7R7 - mov ecx, [esp + DISP + 64 * 0 + 36 + 8] // B3G3R3.. - shld eax, ecx, 16 // G7R7B3G3 - mov [edi + ebx + 4], eax - mov eax, [esp + DISP + 64 * 0 + 16 + 8] // ..B6G6R6 - mov ecx, [esp + DISP + 64 * 0 + 52 + 8] // B7G7R7.. - shld eax, ecx, 8 // B6G6R6B7 - mov [edi + ebx + 8], eax - add edi, edx // $edi = pbRGB += cbRGB - - // RGBX32 -> RGB24 - mov eax, [esp + DISP + 64 * 1 + 4 + 8] // ..B3G3R3 - mov ecx, [esp + DISP + 64 * 1 + 32 + 8] // B2G2R2.. - shld eax, ecx, 24 // R3B2G2R2 - mov [edi + ebx + 0], eax - mov eax, [esp + DISP + 64 * 1 + 20 + 8] // ..B7G7R7 - mov ecx, [esp + DISP + 64 * 1 + 36 + 8] // B3G3R3.. - shld eax, ecx, 16 // G7R7B3G3 - mov [edi + ebx + 4], eax - mov eax, [esp + DISP + 64 * 1 + 16 + 8] // ..B6G6R6 - mov ecx, [esp + DISP + 64 * 1 + 52 + 8] // B7G7R7.. - shld eax, ecx, 8 // B6G6R6B7 - mov [edi + ebx + 8], eax - add edi, edx // $edi = pbRGB += cbRGB - - mov eax, [esp + DISP + 64 * 1 + 4] // ..B1G1R1 - mov ecx, [esp + DISP + 64 * 1 + 32] // B0G0R0.. - shld eax, ecx, 24 // R1B0G0R0 - mov [edi + ebx + 0], eax - mov eax, [esp + DISP + 64 * 1 + 20] // ..B5G5R5 - mov ecx, [esp + DISP + 64 * 1 + 36] // B1G1R1.. - shld eax, ecx, 16 // G5R5B1G1 - mov [edi + ebx + 4], eax - mov eax, [esp + DISP + 64 * 1 + 16] // ..B4G4R4 - mov ecx, [esp + DISP + 64 * 1 + 52] // B5G5R5.. - shld eax, ecx, 8 // B4G4R4B5 - mov [edi + ebx + 8], eax - add edi, edx // $edi = pbRGB += cbRGB - - // RGBX32 -> RGB24 - mov eax, [esp + DISP + 64 * 2 + 4] // ..B1G1R1 - mov ecx, [esp + DISP + 64 * 2 + 32] // B0G0R0.. - shld eax, ecx, 24 // R1B0G0R0 - mov [edi + ebx + 0], eax - mov eax, [esp + DISP + 64 * 2 + 20] // ..B5G5R5 - mov ecx, [esp + DISP + 64 * 2 + 36] // B1G1R1.. - shld eax, ecx, 16 // G5R5B1G1 - mov [edi + ebx + 4], eax - mov eax, [esp + DISP + 64 * 2 + 16] // ..B4G4R4 - mov ecx, [esp + DISP + 64 * 2 + 52] // B5G5R5.. - shld eax, ecx, 8 // B4G4R4B5 - mov [edi + ebx + 8], eax - add edi, edx // $edi = pbRGB += cbRGB - - mov eax, [esp + DISP + 64 * 2 + 4 + 8] // ..B3G3R3 - mov ecx, [esp + DISP + 64 * 2 + 32 + 8] // B2G2R2.. - shld eax, ecx, 24 // R3B2G2R2 - mov [edi + ebx + 0], eax - mov eax, [esp + DISP + 64 * 2 + 20 + 8] // ..B7G7R7 - mov ecx, [esp + DISP + 64 * 2 + 36 + 8] // B3G3R3.. - shld eax, ecx, 16 // G7R7B3G3 - mov [edi + ebx + 4], eax - mov eax, [esp + DISP + 64 * 2 + 16 + 8] // ..B6G6R6 - mov ecx, [esp + DISP + 64 * 2 + 52 + 8] // B7G7R7.. - shld eax, ecx, 8 // B6G6R6B7 - mov [edi + ebx + 8], eax - add edi, edx // $edi = pbRGB += cbRGB - - // RGBX32 -> RGB24 - mov eax, [esp + DISP + 64 * 3 + 4 + 8] // ..B3G3R3 - mov ecx, [esp + DISP + 64 * 3 + 32 + 8] // B2G2R2.. - shld eax, ecx, 24 // R3B2G2R2 - mov [edi + ebx + 0], eax - mov eax, [esp + DISP + 64 * 3 + 20 + 8] // ..B7G7R7 - mov ecx, [esp + DISP + 64 * 3 + 36 + 8] // B3G3R3.. - shld eax, ecx, 16 // G7R7B3G3 - mov [edi + ebx + 4], eax - mov eax, [esp + DISP + 64 * 3 + 16 + 8] // ..B6G6R6 - mov ecx, [esp + DISP + 64 * 3 + 52 + 8] // B7G7R7.. - shld eax, ecx, 8 // B6G6R6B7 - mov [edi + ebx + 8], eax - add edi, edx // $edi = pbRGB += cbRGB - - mov eax, [esp + DISP + 64 * 3 + 4] // ..B1G1R1 - mov ecx, [esp + DISP + 64 * 3 + 32] // B0G0R0.. - shld eax, ecx, 24 // R1B0G0R0 - mov [edi + ebx + 0], eax - mov eax, [esp + DISP + 64 * 3 + 20] // ..B5G5R5 - mov ecx, [esp + DISP + 64 * 3 + 36] // B1G1R1.. - shld eax, ecx, 16 // G5R5B1G1 - mov [edi + ebx + 4], eax - mov eax, [esp + DISP + 64 * 3 + 16] // ..B4G4R4 - mov ecx, [esp + DISP + 64 * 3 + 52] // B5G5R5.. - shld eax, ecx, 8 // B4G4R4B5 - mov [edi + ebx + 8], eax - - //================================ - add esi, 256 - 64 - add ebx, 12 - jnz Loop0 - - //================ - pop esp - pop edi - pop esi - pop ebx - pop ebp - ret 20 - } -} - -Int outputMBRow_RGB24_Lossless_1(CWMImageStrCodec* pSC) -{ -#ifdef REENTRANT_MODE - const size_t cHeight = MIN((pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16); - const size_t iFirstRow = ((pSC->cRow - 1) * 16 > pSC->m_Dparam->cROITopY ? 0 : (pSC->m_Dparam->cROITopY & 0xf)); -#endif - const size_t cbRGB = pSC->WMIBI.cbStride; - const U8* const pbRGB = (U8*)pSC->WMIBI.pv + cbRGB * (pSC->cRow - 1) * 16; - - U8* const pbY = (U8*)pSC->a0MBbuffer[0]; - U8* const pbU = (U8*)pSC->a0MBbuffer[1]; - // U8* const pbV = (U8*)pSC->a0MBbuffer[2]; - - const size_t cmbColumn = (pSC->WMII.cWidth + 15) / 16; - - assert(BD_8 == pSC->WMII.bdBitDepth); - assert(CF_RGB == pSC->WMII.cfColorFormat); - assert(24 == pSC->WMII.cBitsPerUnit); - assert(pSC->WMII.bRGB); - assert(O_NONE == pSC->WMII.oOrientation); - - assert(YUV_444 == pSC->m_param.cfColorFormat); - assert(!pSC->m_param.bScaledArith); - - assert(pSC->m_Dparam->bDecodeFullFrame); - - storeRGB24_5(pbY + 64 * 0, pbU - pbY, pbRGB + cbRGB * 0, cbRGB, cmbColumn); - storeRGB24_5(pbY + 64 * 2, pbU - pbY, pbRGB + cbRGB * 8, cbRGB, cmbColumn); - -#ifdef REENTRANT_MODE - pSC->WMIBI.cLinesDecoded = cHeight - iFirstRow; -#endif - return ICERR_OK; -} - - -__declspec(naked) void __stdcall storeRGB24_3( - U8* pbYCoCg, - size_t cbYCoCg, - const U8* pbRGB, - size_t cbRGB, - size_t cmb, - const U8* Shift) -{ - UNREFERENCED_PARAMETER( pbYCoCg ); - UNREFERENCED_PARAMETER( cbYCoCg ); - UNREFERENCED_PARAMETER( pbRGB ); - UNREFERENCED_PARAMETER( cbRGB ); - UNREFERENCED_PARAMETER( cmb ); - UNREFERENCED_PARAMETER( Shift ); - __asm { - push ebp - push ebx - push esi - push edi - - mov ecx, [esp + 40] // $ecx = Shift - mov ebx, [esp + 36] // $ebx = cmb - mov edi, [esp + 28] // $edi = pbRGB - lea ebx, [ebx + ebx * 2] // $ebx = cmb * 3 - mov edx, [esp + 32] // $edx = cbRGB - shl ebx, 4 // $ebx = cmb * 3 * 16 - mov esi, [esp + 20] // $esi = pbYCoCg - add edi, ebx // $edi = pbRGB + 3 * 16 * cmb - mov ebp, [esp + 24] // $ebp = cbYCoCg - neg ebx - - mov eax, esp - and esp, 0xffffff80 - sub esp, 320 - - mov [esp], eax // original $esp - mov [esp + 4], edi - mov [esp + 8], ecx - } -Loop0: - __asm { - mov edi, [esp + 4] // $edi = pbRGB + 3 * 16 * cmb - - //================ - // first 8 pixels - movdqa xmm0, [esi] - movdqa xmm4, [esi + 16] - movdqa xmm3, [esi + ebp] - movdqa xmm7, [esi + ebp + 16] - movdqa xmm2, [esi + ebp * 2] - movdqa xmm6, [esi + ebp * 2 + 16] - - mov ecx, [esp + 8] - movdqa xmm1, [ecx] - movdqa xmm5, [g_const_d0x80] - pslld xmm5, xmm1 - paddd xmm5, xmm1 - paddd xmm0, xmm5 // bias - paddd xmm4, xmm5 // bias - pxor xmm1, xmm1 - pxor xmm5, xmm5 - psubd xmm1, xmm3 - psubd xmm5, xmm7 - - // ICC - movdqa xmm3, xmm1 // g -= r >> 1 - movdqa xmm7, xmm5 - psrad xmm3, 1 - psrad xmm7, 1 - psubd xmm0, xmm3 - psubd xmm4, xmm7 - - movdqa xmm3, [g_const_d1] // r -= ((b + 1) >> 1) - g - movdqa xmm7, [g_const_d1] - paddd xmm3, xmm2 - paddd xmm7, xmm6 - paddd xmm1, xmm0 - paddd xmm5, xmm4 - psrad xmm3, 1 - psrad xmm7, 1 - psubd xmm1, xmm3 - psubd xmm5, xmm7 - - paddd xmm2, xmm1 // b += r - paddd xmm6, xmm5 - - // clip - movdqa xmm3, [g_const_w0x80] - packssdw xmm0, xmm4 - packssdw xmm1, xmm5 - packssdw xmm2, xmm6 - - mov ecx, [esp + 8] - movdqa xmm4, [ecx] - psraw xmm0, xmm4 - psraw xmm1, xmm4 - psraw xmm2, xmm4 - - psubw xmm0, xmm3 - psubw xmm1, xmm3 - psubw xmm2, xmm3 - - movdqa [esp + 16], xmm0 - movdqa [esp + 32], xmm1 - movdqa [esp + 48], xmm2 - - //================ - // second 8 pixels - movdqa xmm0, [esi + 32] - movdqa xmm4, [esi + 48] - movdqa xmm3, [esi + ebp + 32] - movdqa xmm7, [esi + ebp + 48] - movdqa xmm2, [esi + ebp * 2 + 32] - movdqa xmm6, [esi + ebp * 2 + 48] - - mov ecx, [esp + 8] - movdqa xmm1, [ecx] - movdqa xmm5, [g_const_d0x80] - pslld xmm5, xmm1 - paddd xmm5, xmm1 - paddd xmm0, xmm5 // bias - paddd xmm4, xmm5 // bias - pxor xmm1, xmm1 - pxor xmm5, xmm5 - psubd xmm1, xmm3 - psubd xmm5, xmm7 - - // ICC - movdqa xmm3, xmm1 // g -= r >> 1 - movdqa xmm7, xmm5 - psrad xmm3, 1 - psrad xmm7, 1 - psubd xmm0, xmm3 - psubd xmm4, xmm7 - - movdqa xmm3, [g_const_d1] // r -= ((b + 1) >> 1) - g - movdqa xmm7, [g_const_d1] - paddd xmm3, xmm2 - paddd xmm7, xmm6 - paddd xmm1, xmm0 - paddd xmm5, xmm4 - psrad xmm3, 1 - psrad xmm7, 1 - psubd xmm1, xmm3 - psubd xmm5, xmm7 - - paddd xmm2, xmm1 // b += r - paddd xmm6, xmm5 - - // clip - movdqa xmm3, [g_const_w0x80] - packssdw xmm0, xmm4 - packssdw xmm1, xmm5 - packssdw xmm2, xmm6 - - mov ecx, [esp + 8] - movdqa xmm4, [ecx] - psraw xmm0, xmm4 - psraw xmm1, xmm4 - psraw xmm2, xmm4 - - psubw xmm0, xmm3 - psubw xmm1, xmm3 - psubw xmm2, xmm3 - - //================ - // 16 pixels - movdqa xmm3, [g_const_b0x80] - packsswb xmm0, [esp + 16] - packsswb xmm1, [esp + 32] - packsswb xmm2, [esp + 48] - - psubb xmm0, xmm3 - psubb xmm1, xmm3 - psubb xmm2, xmm3 - - pxor xmm7, xmm7 - movdqa xmm4, xmm0 - movdqa xmm5, xmm1 - movdqa xmm6, xmm2 - - punpckhbw xmm0, xmm7 - punpckhbw xmm1, xmm7 - punpckhbw xmm2, xmm7 - punpcklbw xmm4, xmm7 - punpcklbw xmm5, xmm7 - punpcklbw xmm6, xmm7 - - // spill second 8 pixels - movdqa [esp + 16], xmm4 - movdqa [esp + 32], xmm5 - movdqa [esp + 48], xmm6 - - // first 8 pixels - movdqa xmm4, xmm0 - movdqa xmm5, xmm1 - movdqa xmm6, xmm2 - - punpcklwd xmm0, xmm7 - punpcklwd xmm1, xmm7 - punpcklwd xmm2, xmm7 - - punpckhwd xmm4, xmm7 - punpckhwd xmm5, xmm7 - punpckhwd xmm6, xmm7 - - pslld xmm0, 8 - pslld xmm2, 16 - pslld xmm4, 8 - pslld xmm6, 16 - - por xmm0, xmm1 - por xmm4, xmm5 - por xmm0, xmm2 - por xmm4, xmm6 - - movdqa [esp + 64], xmm0 - pslld xmm0, 8 - movdqa [esp + 80], xmm4 - pslld xmm4, 8 - movdqa [esp + 96], xmm0 - movdqa [esp + 112], xmm4 - - // second 8 pixels - movdqa xmm0, [esp + 16] - movdqa xmm1, [esp + 32] - movdqa xmm2, [esp + 48] - movdqa xmm4, xmm0 - movdqa xmm5, xmm1 - movdqa xmm6, xmm2 - - punpcklwd xmm0, xmm7 - punpcklwd xmm1, xmm7 - punpcklwd xmm2, xmm7 - punpckhwd xmm4, xmm7 - punpckhwd xmm5, xmm7 - punpckhwd xmm6, xmm7 - - pslld xmm0, 8 - pslld xmm2, 16 - pslld xmm4, 8 - pslld xmm6, 16 - por xmm0, xmm1 - por xmm4, xmm5 - por xmm0, xmm2 - por xmm4, xmm6 - - movdqa [esp + 128], xmm0 - pslld xmm0, 8 - movdqa [esp + 144], xmm4 - pslld xmm4, 8 - movdqa [esp + 160], xmm0 - movdqa [esp + 176], xmm4 - - //================================ - add esi, 64 - - //================ - // first 8 pixels - movdqa xmm0, [esi] - movdqa xmm4, [esi + 16] - movdqa xmm3, [esi + ebp] - movdqa xmm7, [esi + ebp + 16] - movdqa xmm2, [esi + ebp * 2] - movdqa xmm6, [esi + ebp * 2 + 16] - - mov ecx, [esp + 8] - movdqa xmm1, [ecx] - movdqa xmm5, [g_const_d0x80] - pslld xmm5, xmm1 - paddd xmm5, xmm1 - paddd xmm0, xmm5 // bias - paddd xmm4, xmm5 // bias - pxor xmm1, xmm1 - pxor xmm5, xmm5 - psubd xmm1, xmm3 - psubd xmm5, xmm7 - - // ICC - movdqa xmm3, xmm1 // g -= r >> 1 - movdqa xmm7, xmm5 - psrad xmm3, 1 - psrad xmm7, 1 - psubd xmm0, xmm3 - psubd xmm4, xmm7 - - movdqa xmm3, [g_const_d1] // r -= ((b + 1) >> 1) - g - movdqa xmm7, [g_const_d1] - paddd xmm3, xmm2 - paddd xmm7, xmm6 - paddd xmm1, xmm0 - paddd xmm5, xmm4 - psrad xmm3, 1 - psrad xmm7, 1 - psubd xmm1, xmm3 - psubd xmm5, xmm7 - - paddd xmm2, xmm1 // b += r - paddd xmm6, xmm5 - - // clip - movdqa xmm3, [g_const_w0x80] - packssdw xmm0, xmm4 - packssdw xmm1, xmm5 - packssdw xmm2, xmm6 - - mov ecx, [esp + 8] - movdqa xmm4, [ecx] - psraw xmm0, xmm4 - psraw xmm1, xmm4 - psraw xmm2, xmm4 - - psubw xmm0, xmm3 - psubw xmm1, xmm3 - psubw xmm2, xmm3 - - movdqa [esp + 16], xmm0 - movdqa [esp + 32], xmm1 - movdqa [esp + 48], xmm2 - - //================ - // second 8 pixels - movdqa xmm0, [esi + 32] - movdqa xmm4, [esi + 48] - movdqa xmm3, [esi + ebp + 32] - movdqa xmm7, [esi + ebp + 48] - movdqa xmm2, [esi + ebp * 2 + 32] - movdqa xmm6, [esi + ebp * 2 + 48] - - mov ecx, [esp + 8] - movdqa xmm1, [ecx] - movdqa xmm5, [g_const_d0x80] - pslld xmm5, xmm1 - paddd xmm5, xmm1 - paddd xmm0, xmm5 // bias - paddd xmm4, xmm5 // bias - pxor xmm1, xmm1 - pxor xmm5, xmm5 - psubd xmm1, xmm3 - psubd xmm5, xmm7 - - // ICC - movdqa xmm3, xmm1 // g -= r >> 1 - movdqa xmm7, xmm5 - psrad xmm3, 1 - psrad xmm7, 1 - psubd xmm0, xmm3 - psubd xmm4, xmm7 - - movdqa xmm3, [g_const_d1] // r -= ((b + 1) >> 1) - g - movdqa xmm7, [g_const_d1] - paddd xmm3, xmm2 - paddd xmm7, xmm6 - paddd xmm1, xmm0 - paddd xmm5, xmm4 - psrad xmm3, 1 - psrad xmm7, 1 - psubd xmm1, xmm3 - psubd xmm5, xmm7 - - paddd xmm2, xmm1 // b += r - paddd xmm6, xmm5 - - // clip - movdqa xmm3, [g_const_w0x80] - packssdw xmm0, xmm4 - packssdw xmm1, xmm5 - packssdw xmm2, xmm6 - - mov ecx, [esp + 8] - movdqa xmm4, [ecx] - psraw xmm0, xmm4 - psraw xmm1, xmm4 - psraw xmm2, xmm4 - - psubw xmm0, xmm3 - psubw xmm1, xmm3 - psubw xmm2, xmm3 - - //================ - // 16 pixels - movdqa xmm3, [g_const_b0x80] - packsswb xmm0, [esp + 16] - packsswb xmm1, [esp + 32] - packsswb xmm2, [esp + 48] - - psubb xmm0, xmm3 - psubb xmm1, xmm3 - psubb xmm2, xmm3 - - pxor xmm7, xmm7 - movdqa xmm4, xmm0 - movdqa xmm5, xmm1 - movdqa xmm6, xmm2 - - punpckhbw xmm0, xmm7 - punpckhbw xmm1, xmm7 - punpckhbw xmm2, xmm7 - punpcklbw xmm4, xmm7 - punpcklbw xmm5, xmm7 - punpcklbw xmm6, xmm7 - - // spill second 8 pixels - movdqa [esp + 16], xmm4 - movdqa [esp + 32], xmm5 - movdqa [esp + 48], xmm6 - - // first 8 pixels - movdqa xmm4, xmm0 - movdqa xmm5, xmm1 - movdqa xmm6, xmm2 - - punpcklwd xmm0, xmm7 - punpcklwd xmm1, xmm7 - punpcklwd xmm2, xmm7 - - punpckhwd xmm4, xmm7 - punpckhwd xmm5, xmm7 - punpckhwd xmm6, xmm7 - - pslld xmm0, 8 - pslld xmm2, 16 - pslld xmm4, 8 - pslld xmm6, 16 - - por xmm0, xmm1 - por xmm4, xmm5 - por xmm0, xmm2 - por xmm4, xmm6 - - movdqa [esp + 192], xmm0 - pslld xmm0, 8 - movdqa [esp + 208], xmm4 - pslld xmm4, 8 - movdqa [esp + 224], xmm0 - movdqa [esp + 240], xmm4 - - // second 8 pixels - movdqa xmm0, [esp + 16] - movdqa xmm1, [esp + 32] - movdqa xmm2, [esp + 48] - movdqa xmm4, xmm0 - movdqa xmm5, xmm1 - movdqa xmm6, xmm2 - - punpcklwd xmm0, xmm7 - punpcklwd xmm1, xmm7 - punpcklwd xmm2, xmm7 - punpckhwd xmm4, xmm7 - punpckhwd xmm5, xmm7 - punpckhwd xmm6, xmm7 - - pslld xmm0, 8 - pslld xmm2, 16 - pslld xmm4, 8 - pslld xmm6, 16 - por xmm0, xmm1 - por xmm4, xmm5 - por xmm0, xmm2 - por xmm4, xmm6 - - movdqa [esp + 256], xmm0 - pslld xmm0, 8 - movdqa [esp + 272], xmm4 - pslld xmm4, 8 - movdqa [esp + 288], xmm0 - movdqa [esp + 304], xmm4 - - // RGBX32 -> RGB24 - mov eax, [esp + 68] // ..B1G1R1 - mov ecx, [esp + 96] // B0G0R0.. - shld eax, ecx, 24 // R1B0G0R0 - mov [edi + ebx + 0], eax - mov eax, [esp + 84] // ..B5G5R5 - mov ecx, [esp + 100] // B1G1R1.. - shld eax, ecx, 16 // G5R5B1G1 - mov [edi + ebx + 4], eax - mov eax, [esp + 80] // ..B4G4R4 - mov ecx, [esp + 116] // B5G5R5.. - shld eax, ecx, 8 // B4G4R4B5 - mov [edi + ebx + 8], eax - add edi, edx // $edi = pbRGB += cbRGB - - mov eax, [esp + 76] // ..B3G3R3 - mov ecx, [esp + 104] // B2G2R2.. - shld eax, ecx, 24 // R3B2G2R2 - mov [edi + ebx + 0], eax - mov eax, [esp + 92] // ..B7G7R7 - mov ecx, [esp + 108] // B3G3R3.. - shld eax, ecx, 16 // G7R7B3G3 - mov [edi + ebx + 4], eax - mov eax, [esp + 88] // ..B6G6R6 - mov ecx, [esp + 124] // B7G7R7.. - shld eax, ecx, 8 // B6G6R6B7 - mov [edi + ebx + 8], eax - add edi, edx // $edi = pbRGB += cbRGB - - // RGBX32 -> RGB24 - mov eax, [esp + 140] // ..B3G3R3 - mov ecx, [esp + 168] // B2G2R2.. - shld eax, ecx, 24 // R3B2G2R2 - mov [edi + ebx + 0], eax - mov eax, [esp + 156] // ..B7G7R7 - mov ecx, [esp + 172] // B3G3R3.. - shld eax, ecx, 16 // G7R7B3G3 - mov [edi + ebx + 4], eax - mov eax, [esp + 152] // ..B6G6R6 - mov ecx, [esp + 188] // B7G7R7.. - shld eax, ecx, 8 // B6G6R6B7 - mov [edi + ebx + 8], eax - add edi, edx // $edi = pbRGB += cbRGB - - mov eax, [esp + 132] // ..B1G1R1 - mov ecx, [esp + 160] // B0G0R0.. - shld eax, ecx, 24 // R1B0G0R0 - mov [edi + ebx + 0], eax - mov eax, [esp + 148] // ..B5G5R5 - mov ecx, [esp + 164] // B1G1R1.. - shld eax, ecx, 16 // G5R5B1G1 - mov [edi + ebx + 4], eax - mov eax, [esp + 144] // ..B4G4R4 - mov ecx, [esp + 180] // B5G5R5.. - shld eax, ecx, 8 // B4G4R4B5 - mov [edi + ebx + 8], eax - add edi, edx // $edi = pbRGB += cbRGB - - // RGBX32 -> RGB24 - mov eax, [esp + 196] // ..B1G1R1 - mov ecx, [esp + 224] // B0G0R0.. - shld eax, ecx, 24 // R1B0G0R0 - mov [edi + ebx + 0], eax - mov eax, [esp + 212] // ..B5G5R5 - mov ecx, [esp + 228] // B1G1R1.. - shld eax, ecx, 16 // G5R5B1G1 - mov [edi + ebx + 4], eax - mov eax, [esp + 208] // ..B4G4R4 - mov ecx, [esp + 244] // B5G5R5.. - shld eax, ecx, 8 // B4G4R4B5 - mov [edi + ebx + 8], eax - add edi, edx // $edi = pbRGB += cbRGB - - mov eax, [esp + 204] // ..B3G3R3 - mov ecx, [esp + 232] // B2G2R2.. - shld eax, ecx, 24 // R3B2G2R2 - mov [edi + ebx + 0], eax - mov eax, [esp + 220] // ..B7G7R7 - mov ecx, [esp + 236] // B3G3R3.. - shld eax, ecx, 16 // G7R7B3G3 - mov [edi + ebx + 4], eax - mov eax, [esp + 216] // ..B6G6R6 - mov ecx, [esp + 252] // B7G7R7.. - shld eax, ecx, 8 // B6G6R6B7 - mov [edi + ebx + 8], eax - add edi, edx // $edi = pbRGB += cbRGB - - // RGBX32 -> RGB24 - mov eax, [esp + 268] // ..B3G3R3 - mov ecx, [esp + 296] // B2G2R2.. - shld eax, ecx, 24 // R3B2G2R2 - mov [edi + ebx + 0], eax - mov eax, [esp + 284] // ..B7G7R7 - mov ecx, [esp + 300] // B3G3R3.. - shld eax, ecx, 16 // G7R7B3G3 - mov [edi + ebx + 4], eax - mov eax, [esp + 280] // ..B6G6R6 - mov ecx, [esp + 316] // B7G7R7.. - shld eax, ecx, 8 // B6G6R6B7 - mov [edi + ebx + 8], eax - add edi, edx // $edi = pbRGB += cbRGB - - mov eax, [esp + 260] // ..B1G1R1 - mov ecx, [esp + 288] // B0G0R0.. - shld eax, ecx, 24 // R1B0G0R0 - mov [edi + ebx + 0], eax - mov eax, [esp + 276] // ..B5G5R5 - mov ecx, [esp + 292] // B1G1R1.. - shld eax, ecx, 16 // G5R5B1G1 - mov [edi + ebx + 4], eax - mov eax, [esp + 272] // ..B4G4R4 - mov ecx, [esp + 308] // B5G5R5.. - shld eax, ecx, 8 // B4G4R4B5 - mov [edi + ebx + 8], eax - add edi, edx // $edi = pbRGB += cbRGB - - //================================ - add esi, 256 - 64 - add ebx, 12 - jnz Loop0 - - //================ - pop esp - pop edi - pop esi - pop ebx - pop ebp - ret 24 - } -} - -Int outputMBRow_RGB24_Lossy_3(CWMImageStrCodec* pSC) -{ -#ifdef REENTRANT_MODE - const size_t cHeight = MIN((pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16); - const size_t iFirstRow = ((pSC->cRow - 1) * 16 > pSC->m_Dparam->cROITopY ? 0 : (pSC->m_Dparam->cROITopY & 0xf)); -#endif - const size_t cbRGB = pSC->WMIBI.cbStride; - const U8* const pbRGB = (U8*)pSC->WMIBI.pv + cbRGB * (pSC->cRow - 1) * 16; - - U8* const pbY = (U8*)pSC->a0MBbuffer[0]; - U8* const pbU = (U8*)pSC->a0MBbuffer[1]; - // U8* const pbV = (U8*)pSC->a0MBbuffer[2]; - - const size_t cmbColumn = (pSC->WMII.cWidth + 15) / 16; - - __declspec(align(16)) U8 Shift[16]; - - assert(BD_8 == pSC->WMII.bdBitDepth); - assert(CF_RGB == pSC->WMII.cfColorFormat); - assert(24 == pSC->WMII.cBitsPerUnit); - assert(pSC->WMII.bRGB); - assert(O_NONE == pSC->WMII.oOrientation); - - assert(YUV_444 == pSC->m_param.cfColorFormat); - - assert(pSC->m_Dparam->bDecodeFullFrame); - - _mm_store_si128((__m128i *) Shift, pSC->m_param.bScaledArith ? g_const_d3 : g_const_d0); - storeRGB24_3(pbY + 64 * 0, pbU - pbY, pbRGB + cbRGB * 0, cbRGB, cmbColumn, - Shift); - storeRGB24_3(pbY + 64 * 2, pbU - pbY, pbRGB + cbRGB * 8, cbRGB, cmbColumn, - Shift); - -#ifdef REENTRANT_MODE - pSC->WMIBI.cLinesDecoded = cHeight - iFirstRow; -#endif - return ICERR_OK; -} -#endif - -//================================================================ -#if defined(WMP_OPT_TRFM_DEC) -FORCE_INLINE Void strDCT2x2up_OPT(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; -} - -FORCE_INLINE Void invOdd_OPT(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd) -{ - PixelI a, b, c, d; - a = *pa; - b = *pb; - c = *pc; - d = *pd; - - /** butterflies **/ - b += d; - a -= c; - d -= (b) >> 1; - c += (a + 1) >> 1; - - /** rotate pi/8 **/ -#define IROTATE2(a, b) (a) -= (((b)*3 + 4) >> 3), (b) += (((a)*3 + 4) >> 3) - IROTATE2(a, b); - IROTATE2(c, d); - - /** butterflies **/ - c -= (b + 1) >> 1; - d = ((a + 1) >> 1) - d; - b += c; - a -= d; - - *pa = a; - *pb = b; - *pc = c; - *pd = d; -} - -FORCE_INLINE Void invOddOdd_OPT(PixelI* pa, PixelI* pb, PixelI* pc, PixelI* pd) -{ - PixelI a, b, c, d, t1, t2; - a = *pa; - b = *pb; - c = *pc; - d = *pd; - - /** butterflies **/ - d += a; - c -= b; - a -= (t1 = d >> 1); - b += (t2 = c >> 1); - - /** rotate pi/4 **/ - a -= (b * 3 + 3) >> 3; - b += (a * 3 + 3) >> 2; - a -= (b * 3 + 4) >> 3; - - /** butterflies **/ - b -= t2; - a += t1; - c += b; - d -= a; - - /** sign flips **/ - *pa = a; - *pb = -b; - *pc = -c; - *pd = d; -} - -FORCE_INLINE Void strDCT2x2dn_SSE2_1(PixelI* p) -{ - __m128i* const pdq = (__m128i*)p; - __m128i a = pdq[0]; - __m128i b = pdq[1]; - const __m128i C = pdq[2]; - __m128i d = pdq[3]; - __m128i t; - __m128i c; - - a = _mm_add_epi32(a, d); - b = _mm_sub_epi32(b, C); - t = _mm_sub_epi32(a, b); - t = _mm_srai_epi32(t, 1); - c = _mm_sub_epi32(t, d); - d = _mm_sub_epi32(t, C); - a = _mm_sub_epi32(a, d); - b = _mm_add_epi32(b, c); - - pdq[0] = a; - pdq[1] = b; - pdq[2] = c; - pdq[3] = d; -} - -Void strIDCT4x4Stage1_OPT_H1(PixelI* p) -{ - /** top left corner, butterfly => butterfly **/ - strDCT2x2up_OPT(p + 0, p + 1, p + 2, p + 3); - - /** top right corner, -pi/8 rotation => butterfly **/ - invOdd_OPT(p + 5, p + 4, p + 7, p + 6); - - /** bottom left corner, butterfly => -pi/8 rotation **/ - invOdd_OPT(p + 10, p + 8, p + 11, p + 9); - - /** bottom right corner, -pi/8 rotation => -pi/8 rotation **/ - invOddOdd_OPT(p + 15, p + 14, p + 13, p + 12); -} - -FORCE_INLINE Void strIDCT4x4Stage1_OPT_H2(PixelI* p) -{ - /** butterfly **/ - strDCT2x2dn_SSE2_1(p); -} - -Void strIDCT4x4Stage1_OPT5(PixelI* p0, PixelI* p1) -{ - _mm_prefetch((char*)(p0 - 96 + 256), _MM_HINT_T0); - strIDCT4x4Stage1_OPT_H1(p0 - 96); - strIDCT4x4Stage1_OPT_H1(p0 - 80); - strIDCT4x4Stage1_OPT_H1(p0 - 32); - strIDCT4x4Stage1_OPT_H1(p0 - 16); - - _mm_prefetch((char*)(p0 - 32 + 256), _MM_HINT_T0); - strIDCT4x4Stage1_OPT_H1(p0 + 32); - strIDCT4x4Stage1_OPT_H1(p0 + 48); - strIDCT4x4Stage1_OPT_H1(p0 + 96); - strIDCT4x4Stage1_OPT_H1(p0 + 112); - - _mm_prefetch((char*)(p0 + 32 + 256), _MM_HINT_T0); - strIDCT4x4Stage1_OPT_H1(p1 - 128); - strIDCT4x4Stage1_OPT_H1(p1 - 112); - strIDCT4x4Stage1_OPT_H1(p1 - 64); - strIDCT4x4Stage1_OPT_H1(p1 - 48); - - _mm_prefetch((char*)(p0 + 96 + 256), _MM_HINT_T0); - strIDCT4x4Stage1_OPT_H1(p1 + 0); - strIDCT4x4Stage1_OPT_H1(p1 + 16); - strIDCT4x4Stage1_OPT_H1(p1 + 64); - strIDCT4x4Stage1_OPT_H1(p1 + 80); - - strIDCT4x4Stage1_OPT_H2(p0 - 96); - strIDCT4x4Stage1_OPT_H2(p0 - 80); - strIDCT4x4Stage1_OPT_H2(p0 - 32); - strIDCT4x4Stage1_OPT_H2(p0 - 16); - strIDCT4x4Stage1_OPT_H2(p0 + 32); - strIDCT4x4Stage1_OPT_H2(p0 + 48); - strIDCT4x4Stage1_OPT_H2(p0 + 96); - strIDCT4x4Stage1_OPT_H2(p0 + 112); - - strIDCT4x4Stage1_OPT_H2(p1 - 128); - strIDCT4x4Stage1_OPT_H2(p1 - 112); - strIDCT4x4Stage1_OPT_H2(p1 - 64); - strIDCT4x4Stage1_OPT_H2(p1 - 48); - strIDCT4x4Stage1_OPT_H2(p1 + 0); - strIDCT4x4Stage1_OPT_H2(p1 + 16); - strIDCT4x4Stage1_OPT_H2(p1 + 64); - strIDCT4x4Stage1_OPT_H2(p1 + 80); -} - -//================================ -__declspec(naked) void __stdcall strPost4x4Stage1_alternate_ASM5(PixelI* p0, PixelI* p1) -{ - UNREFERENCED_PARAMETER( p0 ); - UNREFERENCED_PARAMETER( p1 ); - __asm { - push ebp - push ebx - push esi - push edi - - //================ - // pointer array - mov eax, [esp + 20] // $esi = p0 - mov edx, [esp + 24] // $edi = p1 - mov ecx, 4 * 16 - mov ebx, 4 * 48 - - prefetcht0 [eax + 512] - prefetcht0 [eax + 768] - prefetcht0 [eax + 1024] - prefetcht0 [eax + 1280] - - add edx, ecx - add eax, ebx - - push edx - sub edx, ecx - push edx - push edx - sub edx, ebx - push eax - push eax - sub eax, ecx - push eax - push eax - sub eax, ecx - push eax - sub eax, ecx - - push edx - sub edx, ecx - push edx - sub eax, ecx - push edx - sub edx, ebx - push eax - push eax - sub eax, ecx - push eax - push eax - sub eax, ecx - push eax - sub eax, ecx - - push edx - sub edx, ecx - push edx - sub eax, ecx - push edx - sub edx, ebx - push eax - push eax - sub eax, ecx - push eax - push eax - sub eax, ecx - push eax - sub eax, ecx - - push edx - sub edx, ecx - push edx - sub eax, ecx - push edx - push eax - push eax - sub eax, ecx - push eax - push eax - sub eax, ecx - push eax - - mov ebp, (4 + 4) * -16 - push ebp - } -Loop0: - __asm { - mov esi, [esp + (4 + 4) * 16 + 4 + ebp ] // $esi = p0 - mov edi, [esp + (4 + 4) * 16 + 4 + ebp + 4] // $edi = p1 - - //================ - movdqa xmm2, [esi + 4 * 12] // a = xmm2 - movdqa xmm1, [esi + 4 * 72] // b = xmm1 - movdqa xmm6, [edi + 4 * 4] // c = xmm6 - movdqa xmm7, [edi + 4 * 64] // d = xmm7 - - //================ - // buttefly - paddd xmm2, xmm7 - psubd xmm1, xmm6 - - movdqa xmm0, xmm2 // a = xmm0 - psubd xmm2, xmm1 - psrad xmm2, 1 - movdqa xmm3, xmm2 - - psubd xmm2, xmm7 // c = xmm2 - psubd xmm3, xmm6 // d = xmm3 - paddd xmm1, xmm2 - psubd xmm0, xmm3 - - //================ - // bottom right corner: -pi/8 rotation => -pi/8 rotation - pshufd xmm7, xmm3, 0x3 - movd eax, xmm3 - movd edx, xmm7 - pshufd xmm7, xmm3, 0x1 - movd ebx, xmm7 - pshufd xmm7, xmm3, 0x2 - movd ecx, xmm7 - - add edx, eax - sub ecx, ebx - mov esi, edx - sar esi, 1 - mov edi, ecx - sar edi, 1 - sub eax, esi - add ebx, edi - - lea ebp, [ebx + ebx * 2 + 6] - sar ebp, 3 - sub eax, ebp - lea ebp, [eax + eax * 2 + 2] - sar ebp, 2 - add ebx, ebp - lea ebp, [ebx + ebx * 2 + 4] - sar ebp, 3 - sub eax, ebp - - mov ebp, [esp] - - sub ebx, edi - add eax, esi - add ecx, ebx - sub edx, eax - - mov esi, [esp + (4 + 4) * 16 + 4 + ebp ] // $esi = p0 - mov edi, [esp + (4 + 4) * 16 + 4 + ebp + 4] // $edi = p1 - - movd xmm3, eax - movd xmm4, ebx - movd xmm5, ecx - movd xmm6, edx - punpckldq xmm3, xmm4 - punpckldq xmm5, xmm6 - punpcklqdq xmm3, xmm5 - - //================ - // anti diagonal corners: rotation by -pi/8 - movdqa xmm5, g_const_d1 - movdqa xmm6, g_const_d1 - - pshufd xmm2, xmm2, 0xd8 // 7, 5, 6, 4 - movdqa xmm4, xmm1 // 75, 74, 73, 72 - punpckhqdq xmm1, xmm2 // 7, 5, 75, 74 - punpcklqdq xmm4, xmm2 // 6, 4, 73, 72 - - paddd xmm5, xmm1 - psrad xmm5, 1 - psubd xmm4, xmm5 - - paddd xmm6, xmm4 - psrad xmm6, 1 - paddd xmm1, xmm6 - - movdqa xmm2, xmm4 // 6, 4, 73, 72 - punpckhqdq xmm4, xmm1 // 7, 5, 6, 4 - punpcklqdq xmm2, xmm1 // 75, 74, 73, 72 - pshufd xmm4, xmm4, 0xd8 // 7, 6, 5, 4 - - //================ - // butterfly - // a = xmm0, b = xmm2, c = xmm4, d = xmm3 - paddd xmm0, xmm3 - movdqa xmm1, xmm0 // a = xmm1 - psrad xmm0, 1 - psubd xmm0, xmm3 // d = xmm0 - - movdqa xmm3, xmm0 // d = xmm3 - paddd xmm0, xmm0 - paddd xmm0, xmm3 - psrad xmm0, 3 - paddd xmm1, xmm0 - - movdqa xmm0, xmm1 // a = xmm0 - paddd xmm1, xmm1 - paddd xmm1, xmm0 - psrad xmm1, 4 - paddd xmm3, xmm1 - - movdqa xmm5, xmm0 // a - psrad xmm5, 7 - paddd xmm3, xmm5 // d += (a >> 7) - psrad xmm5, 3 - psubd xmm3, xmm5 // d -= (a >> 10) - - movdqa xmm5, [g_const_d4] - movdqa xmm1, xmm3 // d = xmm1 - psubd xmm2, xmm4 - paddd xmm5, xmm3 - paddd xmm3, xmm3 - paddd xmm3, xmm5 - psrad xmm3, 3 - paddd xmm0, xmm3 - - movdqa xmm3, xmm2 // b = xmm3 - psrad xmm2, 1 - psubd xmm1, xmm2 - - movdqa xmm2, xmm0 // a = xmm2 - psubd xmm0, xmm3 - psrad xmm0, 1 - psubd xmm0, xmm4 // c = xmm0 - - paddd xmm3, xmm1 - psubd xmm2, xmm0 - - //================ - movdqa [edi + 4 * 4], xmm1 - movdqa [edi + 4 * 64], xmm0 - movdqa [esi + 4 * 12], xmm2 - movdqa [esi + 4 * 72], xmm3 - - add ebp, 8 - mov [esp], ebp - jnz Loop0 - - //================ - add esp, (4 + 4) * 16 + 4 - pop edi - pop esi - pop ebx - pop ebp - ret 4 * 2 - } -} - -Int invTransformMacroblock_YUV444_Center5(CWMImageStrCodec * pSC) -{ - const OVERLAP olOverlap = pSC->WMISCP.olOverlap; - int i = 0; - - assert(0 < pSC->cRow && pSC->cRow < pSC->cmbHeight); - assert(0 < pSC->cColumn && pSC->cColumn < pSC->cmbWidth); - - assert(0 == pSC->WMII.cPostProcStrength); - - assert(YUV_444 == pSC->m_param.cfColorFormat); - assert(3 == pSC->m_param.cNumChannels); - - assert(pSC->m_Dparam->bDecodeFullWidth); - assert(1 == pSC->m_Dparam->cThumbnailScale); - - for (i = 0; i < 3; ++i) - { - PixelI* const p0 = pSC->p0MBbuffer[i]; - PixelI* const p1 = pSC->p1MBbuffer[i]; - - //================================ - // second level inverse transform - strIDCT4x4Stage2(p1); - if (pSC->m_param.bScaledArith) { - strNormalizeDec(p1, (i != 0)); - } - - //================================ - // second level inverse overlap - if (OL_TWO <= olOverlap) - { - strPost4x4Stage2Split_alternate(p0, p1); - } - - //================================ - // first level inverse transform - strIDCT4x4Stage1_OPT5(p0, p1); - - //================================ - // first level inverse overlap - if (OL_ONE <= olOverlap) - { - strPost4x4Stage1_alternate_ASM5(p0, p1); - } - } - - return ICERR_OK; -} -#endif -#endif - -//================================================================ -void StrDecOpt(CWMImageStrCodec* pSC) -{ -#if defined(WMP_OPT_SSE2) - if (IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE)) - { - CWMImageInfo* pII = &pSC->WMII; - // CWMIStrCodecParam* pSCP = &pSC->WMISCP; - - g_const_d0 = _mm_setzero_si128(); - g_const_d3 = _mm_set1_epi32(3); - g_const_d1 = _mm_set_epi32(1, 1, 1, 1); - g_const_d4 = _mm_set_epi32(4, 4, 4, 4); - - g_const_d0x80 = _mm_set_epi32(0x80, 0x80, 0x80, 0x80); - g_const_w0x80 = _mm_set_epi16(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80); - g_const_b0x80 = _mm_set_epi8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80); - - if (pSC->WMII.fPaddedUserBuffer && - //pSC->m_Dparam->bDecodeFullFrame && - //((pII->cWidth & 0xf) == 0) && - //(((int) pSC->WMIBI.pv & 0xf) == 0) && - BD_8 == pII->bdBitDepth && - CF_RGB == pII->cfColorFormat && - 24 == pII->cBitsPerUnit && - pII->bRGB && - O_NONE == pII->oOrientation && - YUV_444 == pSC->m_param.cfColorFormat && - pSC->p1MBbuffer[1] - pSC->p1MBbuffer[0] == pSC->p1MBbuffer[2] - pSC->p1MBbuffer[1] && - pSC->m_Dparam->bDecodeFullFrame && - 1) - { -#if defined(WMP_OPT_CC_DEC) - if (pSC->m_param.bScaledArith || pSC->WMISCP.olOverlap != OL_NONE) - { - pSC->Load = outputMBRow_RGB24_Lossy_3; - } - else - { - pSC->Load = outputMBRow_RGB24_Lossless_1; - } -#endif // WMP_OPT_CC_DEC - } - - if (YUV_444 == pSC->m_param.cfColorFormat && - pSC->p1MBbuffer[1] - pSC->p1MBbuffer[0] == pSC->p1MBbuffer[2] - pSC->p1MBbuffer[1] && - pSC->m_Dparam->bDecodeFullWidth && - pSC->m_param.cSubVersion == CODEC_SUBVERSION_NEWSCALING_SOFT_TILES && - 1 == pSC->m_Dparam->cThumbnailScale) - { -#if defined(WMP_OPT_TRFM_DEC) - pSC->TransformCenter = invTransformMacroblock_YUV444_Center5; -#endif - } - - } -#else - UNREFERENCED_PARAMETER( pSC ); -#endif -} - diff --git a/Src/JxrDecode/Jxr/strenc.c b/Src/JxrDecode/Jxr/strenc.c deleted file mode 100644 index 00daf30d..00000000 --- a/Src/JxrDecode/Jxr/strenc.c +++ /dev/null @@ -1,2371 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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 "jxr_defines.h" -#include "strcodec.h" -#include "encode.h" -#include "strTransform.h" -#include -#include "perfTimer.h" - -#ifdef MEM_TRACE -#define TRACE_MALLOC 1 -#define TRACE_NEW 0 -#define TRACE_HEAP 0 -#include "memtrace.h" -#endif - -#ifdef ADI_SYS_OPT -extern char L1WW[]; -#endif - -#ifdef X86OPT_INLINE -#define _FORCEINLINE __forceinline -#else // X86OPT_INLINE -#define _FORCEINLINE -#endif // X86OPT_INLINE - -Int inputMBRow(CWMImageStrCodec *); - -#if defined(WMP_OPT_SSE2) || defined(WMP_OPT_CC_ENC) || defined(WMP_OPT_TRFM_ENC) -void StrEncOpt(CWMImageStrCodec* pSC); -#endif // OPT defined - -#define MINIMUM_PACKET_LENGTH 4 // as long as packet header - skipped if data is not accessed (happens only for flexbits) - -Void writeQuantizer(CWMIQuantizer * pQuantizer[MAX_CHANNELS], BitIOInfo * pIO, U8 cChMode, size_t cChannel, size_t iPos) -{ - if(cChMode > 2) - cChMode = 2; - - if(cChannel > 1) - putBit16(pIO, cChMode, 2); // Channel mode - else - cChMode = 0; - - putBit16(pIO, pQuantizer[0][iPos].iIndex, 8); // Y - - if(cChMode == 1) // MIXED - putBit16(pIO, pQuantizer[1][iPos].iIndex, 8); // UV - else if(cChMode > 0){ // INDEPENDENT - size_t i; - - for(i = 1; i < cChannel; i ++) - putBit16(pIO, pQuantizer[i][iPos].iIndex, 8); // UV - } -} - -// packet header: 00000000 00000000 00000001 ?????xxx -// xxx: 000(spatial) 001(DC) 010(AD) 011(AC) 100(FL) 101-111(reserved) -// ?????: (iTileY * cNumOfSliceV + iTileX) -Void writePacketHeader(BitIOInfo * pIO, U8 ptPacketType, U8 pID) -{ - putBit16(pIO, 0, 8); - putBit16(pIO, 0, 8); - putBit16(pIO, 1, 8); - putBit16(pIO, (pID << 3) + (ptPacketType & 7), 8); -} - -Int writeTileHeaderDC(CWMImageStrCodec * pSC, BitIOInfo * pIO) -{ - size_t iTile, j = (pSC->m_pNextSC == NULL ? 1U : 2U); - - for(; j > 0; j --){ - if((pSC->m_param.uQPMode & 1) != 0){ // not DC uniform - CWMITile * pTile = pSC->pTile + pSC->cTileColumn; - size_t i; - - pTile->cChModeDC = (U8)(rand() & 3); // channel mode, just for concept proofing! - - if(pSC->cTileRow + pSC->cTileColumn == 0) // allocate DC QP info - for(iTile = 0; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile ++) - if(allocateQuantizer(pSC->pTile[iTile].pQuantizerDC, pSC->m_param.cNumChannels, 1) != ICERR_OK) - return ICERR_ERROR; - - for(i = 0; i < pSC->m_param.cNumChannels; i ++) - pTile->pQuantizerDC[i]->iIndex = (U8)((rand() & 0x2f) + 1); // QP indexes, just for concept proofing! - - formatQuantizer(pTile->pQuantizerDC, pTile->cChModeDC, pSC->m_param.cNumChannels, 0, TRUE, pSC->m_param.bScaledArith); - - for(i = 0; i < pSC->m_param.cNumChannels; i ++) - pTile->pQuantizerDC[i]->iOffset = (pTile->pQuantizerDC[i]->iQP >> 1); - - writeQuantizer(pTile->pQuantizerDC, pIO, pTile->cChModeDC, pSC->m_param.cNumChannels, 0); - } - - pSC = pSC->m_pNextSC; - } - - return ICERR_OK; -} - -Int writeTileHeaderLP(CWMImageStrCodec * pSC, BitIOInfo * pIO) -{ - size_t k = (pSC->m_pNextSC == NULL ? 1U : 2U); - - for(; k > 0; k --){ - if(pSC->WMISCP.sbSubband != SB_DC_ONLY && (pSC->m_param.uQPMode & 2) != 0){ // not LP uniform - CWMITile * pTile = pSC->pTile + pSC->cTileColumn; - U8 i; - size_t j; - - pTile->bUseDC = ((rand() & 1) == 0 ? TRUE : FALSE); // use DC quantizer? - putBit16(pIO, pTile->bUseDC == TRUE ? 1 : 0, 1); - pTile->cBitsLP = 0; - - pTile->cNumQPLP = (pTile->bUseDC == TRUE ? 1 : (U8)((rand() & 0xf) + 1)); // # of LP QPs - - if(pSC->cTileRow > 0) - freeQuantizer(pTile->pQuantizerLP); - - if(allocateQuantizer(pTile->pQuantizerLP, pSC->m_param.cNumChannels, pTile->cNumQPLP) != ICERR_OK) - return ICERR_ERROR; - - if(pTile->bUseDC == TRUE) - useDCQuantizer(pSC, pSC->cTileColumn); - else{ - putBit16(pIO, pTile->cNumQPLP - 1, 4); - - pTile->cBitsLP = dquantBits(pTile->cNumQPLP); - - for(i = 0; i < pTile->cNumQPLP; i ++){ - pTile->cChModeLP[i] = (U8)(rand() & 3); // channel mode, just for concept proofing! - - for(j = 0; j < pSC->m_param.cNumChannels; j ++) - pTile->pQuantizerLP[j][i].iIndex = (U8)((rand() & 0xfe) + 1); // QP indexes, just for concept proofing! - formatQuantizer(pTile->pQuantizerLP, pTile->cChModeLP[i], pSC->m_param.cNumChannels, i, TRUE, pSC->m_param.bScaledArith); - writeQuantizer(pTile->pQuantizerLP, pIO, pTile->cChModeLP[i], pSC->m_param.cNumChannels, i); - } - } - } - pSC = pSC->m_pNextSC; - } - - return ICERR_OK; -} - -Int writeTileHeaderHP(CWMImageStrCodec * pSC, BitIOInfo * pIO) -{ - size_t k = (pSC->m_pNextSC == NULL ? 1U : 2U); - - for(; k > 0; k --){ - if(pSC->WMISCP.sbSubband != SB_DC_ONLY && pSC->WMISCP.sbSubband != SB_NO_HIGHPASS && (pSC->m_param.uQPMode & 4) != 0){ // not HP uniform - CWMITile * pTile = pSC->pTile + pSC->cTileColumn; - U8 i; - size_t j; - - pTile->bUseLP = ((rand() & 1) == 0 ? TRUE : FALSE); // use LP quantizer? - putBit16(pIO, pTile->bUseLP == TRUE ? 1 : 0, 1); - pTile->cBitsHP = 0; - - pTile->cNumQPHP = (pTile->bUseLP == TRUE ? pTile->cNumQPLP : (U8)((rand() & 0xf) + 1)); // # of LP QPs - - if(pSC->cTileRow > 0) - freeQuantizer(pTile->pQuantizerHP); - - if(allocateQuantizer(pTile->pQuantizerHP, pSC->m_param.cNumChannels, pTile->cNumQPHP) != ICERR_OK) - return ICERR_ERROR; - - if(pTile->bUseLP == TRUE) - useLPQuantizer(pSC, pTile->cNumQPHP, pSC->cTileColumn); - else{ - putBit16(pIO, pTile->cNumQPHP - 1, 4); - pTile->cBitsHP = dquantBits(pTile->cNumQPHP); - - for(i = 0; i < pTile->cNumQPHP; i ++){ - pTile->cChModeHP[i] = (U8)(rand() & 3); // channel mode, just for concept proofing! - - for(j = 0; j < pSC->m_param.cNumChannels; j ++) - pTile->pQuantizerHP[j][i].iIndex = (U8)((rand() & 0xfe) + 1); // QP indexes, just for concept proofing! - formatQuantizer(pTile->pQuantizerHP, pTile->cChModeHP[i], pSC->m_param.cNumChannels, i, FALSE, pSC->m_param.bScaledArith); - writeQuantizer(pTile->pQuantizerHP, pIO, pTile->cChModeHP[i], pSC->m_param.cNumChannels, i); - } - } - } - pSC = pSC->m_pNextSC; - } - - return ICERR_OK; -} - -Int encodeMB(CWMImageStrCodec * pSC, Int iMBX, Int iMBY) -{ - CCodingContext * pContext = &pSC->m_pCodingContext[pSC->cTileColumn]; - - if(pSC->m_bCtxLeft && pSC->m_bCtxTop && pSC->m_bSecondary == FALSE && pSC->m_param.bTranscode == FALSE){ // write packet headers - U8 pID = (U8)((pSC->cTileRow * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + pSC->cTileColumn) & 0x1F); - - if(pSC->WMISCP.bfBitstreamFormat == SPATIAL) { - writePacketHeader(pContext->m_pIODC, 0, pID); - if (pSC->m_param.bTrimFlexbitsFlag) - putBit16(pContext->m_pIODC, pContext->m_iTrimFlexBits, 4); - writeTileHeaderDC(pSC, pContext->m_pIODC); - writeTileHeaderLP(pSC, pContext->m_pIODC); - writeTileHeaderHP(pSC, pContext->m_pIODC); - } - else{ - writePacketHeader(pContext->m_pIODC, 1, pID); - writeTileHeaderDC(pSC, pContext->m_pIODC); - if(pSC->cSB > 1){ - writePacketHeader(pContext->m_pIOLP, 2, pID); - writeTileHeaderLP(pSC, pContext->m_pIOLP); - } - if(pSC->cSB > 2){ - writePacketHeader(pContext->m_pIOAC, 3, pID); - writeTileHeaderHP(pSC, pContext->m_pIOAC); - } - if(pSC->cSB > 3) { - writePacketHeader(pContext->m_pIOFL, 4, pID); - if (pSC->m_param.bTrimFlexbitsFlag) - putBit16(pContext->m_pIOFL, pContext->m_iTrimFlexBits, 4); - } - } - } - - if(EncodeMacroblockDC(pSC, pContext, iMBX, iMBY) != ICERR_OK) - return ICERR_ERROR; - - if(pSC->WMISCP.sbSubband != SB_DC_ONLY) - if(EncodeMacroblockLowpass(pSC, pContext, iMBX, iMBY) != ICERR_OK) - return ICERR_ERROR; - - if(pSC->WMISCP.sbSubband != SB_DC_ONLY && pSC->WMISCP.sbSubband != SB_NO_HIGHPASS) - if(EncodeMacroblockHighpass(pSC, pContext, iMBX, iMBY) != ICERR_OK) - return ICERR_ERROR; - - if(iMBX + 1 == (int) pSC->cmbWidth && (iMBY + 1 == (int) pSC->cmbHeight || - (pSC->cTileRow < pSC->WMISCP.cNumOfSliceMinus1H && iMBY == (int) pSC->WMISCP.uiTileY[pSC->cTileRow + 1] - 1))) - { // end of a horizontal slice - size_t k, l; - - // get sizes of each packet and update index table - if (pSC->m_pNextSC == NULL || pSC->m_bSecondary) { - for(k = 0; k < pSC->cNumBitIO; k ++){ - fillToByte(pSC->m_ppBitIO[k]); - pSC->ppWStream[k]->GetPos(pSC->ppWStream[k], &l); - pSC->pIndexTable[pSC->cNumBitIO * pSC->cTileRow + k] = l + getSizeWrite(pSC->m_ppBitIO[k]); // offset - } - } - - // reset coding contexts - if(iMBY + 1 != (int) pSC->cmbHeight){ - for(k = 0; k <= pSC->WMISCP.cNumOfSliceMinus1V; k ++) - ResetCodingContextEnc(&pSC->m_pCodingContext[k]); - } - } - - return ICERR_OK; -} - -/************************************************************************* - Top level function for processing a macroblock worth of input -*************************************************************************/ -Int processMacroblock(CWMImageStrCodec *pSC) -{ - Bool topORleft = (pSC->cColumn == 0 || pSC->cRow == 0); - ERR_CODE result = ICERR_OK; - size_t j, jend = (pSC->m_pNextSC != NULL); - - for (j = 0; j <= jend; j++) { - transformMacroblock(pSC); - if(!topORleft){ - getTilePos(pSC, (Int)pSC->cColumn - 1, (Int)pSC->cRow - 1); - if(jend){ - pSC->m_pNextSC->cTileRow = pSC->cTileRow; - pSC->m_pNextSC->cTileColumn = pSC->cTileColumn; - } - if ((result = encodeMB(pSC, (Int)pSC->cColumn - 1, (Int)pSC->cRow - 1)) != ICERR_OK) - return result; - } - - if (jend) { - pSC->m_pNextSC->cRow = pSC->cRow; - pSC->m_pNextSC->cColumn = pSC->cColumn; - pSC = pSC->m_pNextSC; - } - } - - return ICERR_OK; -} - -/************************************************************************* - forwardRGBE: forward conversion from RGBE to RGB -*************************************************************************/ -static _FORCEINLINE PixelI forwardRGBE (PixelI RGB, PixelI E) -{ - PixelI iResult = 0, iAppend = 1; - - if (E == 0) - return 0; - - assert (E!=0); - - E--; - while (((RGB & 0x80) == 0) && (E > 0)) { - RGB = (RGB << 1) + iAppend; - iAppend = 0; - E--; - } - - // result will always be one of 3 cases - // E RGB convert to - // 0 [0.x] [0 x] - // 0 [1.x] [1 x] - // e [1.x] [e+1 x] - if (E == 0) { - iResult = RGB; - } - else { - E++; - iResult = (RGB & 0x7f) + (E << 7); - } - - return iResult; -} - -/************************************************************************* - convert float-32 into float with (c, lm)!! -*************************************************************************/ -static _FORCEINLINE PixelI float2pixel (float f, const char _c, const unsigned char _lm) -{ - union uif - { - I32 i; - float f; - } x; - - PixelI _h, e, e1, m, s; - - if (f == 0) - { - _h = 0; - } - else - { - x.f = f; - - e = (x.i >> 23) & 0x000000ff;//here set e as e, not s! e includes s: [s e] 9 bits [31..23] - m = (x.i & 0x007fffff) | 0x800000; // actual mantissa, with normalizer - if (e == 0) { // denormal-land - m ^= 0x800000; // actual mantissa, removing normalizer - e++; // actual exponent -126 - } - - e1 = e - 127 + _c; // this is basically a division or quantization to a different exponent - // note: _c cannot be greater than 127, so e1 cannot be greater than e - //assert (_c <= 127); - if (e1 <= 1) { // denormal-land - if (e1 < 1) - m >>= (1 - e1); // shift mantissa right to make exponent 1 - e1 = 1; - if ((m & 0x800000) == 0) // if denormal, set e1 to zero else to 1 - e1 = 0; - } - m &= 0x007fffff; - - //for float-22: - _h = (e1 << _lm) + ((m + (1 << (23 - _lm - 1))) >> (23 - _lm));//take 23-bit m, shift (23-lm), get lm-bit m for float22 - s = ((PixelI) x.i) >> 31; - //padding to int-32: - _h = (_h ^ s) - s; - } - - return _h; -} - -/************************************************************************* - convert Half-16 to internal format, only need to handle sign bit -*************************************************************************/ -static _FORCEINLINE PixelI forwardHalf (PixelI hHalf) -{ - PixelI s; - s = hHalf >> 31; - hHalf = ((hHalf & 0x7fff) ^ s) - s; - return hHalf; -} - - -//================================================================ -// Color Conversion -// functions to get image data from input buffer -// this inlcudes necessary color conversion and boundary padding -//================================================================ -#define _CC(r, g, b) (b -= r, r += ((b + 1) >> 1) - g, g += ((r + 0) >> 1)) -#define _CC_CMYK(c, m, y, k) (y -= c, c += ((y + 1) >> 1) - m, m += (c >> 1) - k, k += ((m + 1) >> 1)) - -//================================================================ -// BitIOInfo init/term for encoding -const size_t MAX_MEMORY_SIZE_IN_WORDS = 64 << 20; // 1 << 20 \approx 1 million - -Int StrIOEncInit(CWMImageStrCodec* pSC) -{ - pSC->m_param.bIndexTable = !(pSC->WMISCP.bfBitstreamFormat == SPATIAL && pSC->WMISCP.cNumOfSliceMinus1H + pSC->WMISCP.cNumOfSliceMinus1V == 0); - if(allocateBitIOInfo(pSC) != ICERR_OK){ - return ICERR_ERROR; - } - - attachISWrite(pSC->pIOHeader, pSC->WMISCP.pWStream); - - if(pSC->cNumBitIO > 0){ - size_t i; -#if defined(_WINDOWS_) || defined(UNDER_CE) // tmpnam does not exist in VS2005 WinCE CRT - TCHAR szPath[MAX_PATH]; - DWORD cSize, j, k; -#endif - char * pFilename; - - pSC->ppWStream = (struct WMPStream **)malloc(pSC->cNumBitIO * sizeof(struct WMPStream *)); - if(pSC->ppWStream == NULL) return ICERR_ERROR; - memset(pSC->ppWStream, 0, pSC->cNumBitIO * sizeof(struct WMPStream *)); - - if (pSC->cmbHeight * pSC->cmbWidth * pSC->WMISCP.cChannel >= MAX_MEMORY_SIZE_IN_WORDS) { -#ifdef _WINDOWS_ - pSC->ppTempFile = (TCHAR **)malloc(pSC->cNumBitIO * sizeof(TCHAR *)); - if(pSC->ppTempFile == NULL) return ICERR_ERROR; - memset(pSC->ppTempFile, 0, pSC->cNumBitIO * sizeof(TCHAR *)); -#else - pSC->ppTempFile = (char **)malloc(pSC->cNumBitIO * sizeof(char *)); - if(pSC->ppTempFile == NULL) return ICERR_ERROR; - memset(pSC->ppTempFile, 0, pSC->cNumBitIO * sizeof(char *)); -#endif - } - - for(i = 0; i < pSC->cNumBitIO; i ++){ - if (pSC->cmbHeight * pSC->cmbWidth * pSC->WMISCP.cChannel >= MAX_MEMORY_SIZE_IN_WORDS) { -#if defined(_WINDOWS_) || defined(UNDER_CE) // tmpnam does not exist in VS2005 WinCE CRT - Bool bUnicode = sizeof(TCHAR) == 2; - pSC->ppTempFile[i] = (TCHAR *)malloc(MAX_PATH * sizeof(TCHAR)); - if(pSC->ppTempFile[i] == NULL) return ICERR_ERROR; - - pFilename = (char *)pSC->ppTempFile[i]; - - cSize = GetTempPath(MAX_PATH, szPath); - if(cSize == 0 || cSize >= MAX_PATH) - return ICERR_ERROR; - if(!GetTempFileName(szPath, TEXT("wdp"), 0, pSC->ppTempFile[i])) - return ICERR_ERROR; - - if(bUnicode){ // unicode file name - for(k = j = cSize = 0; cSize < MAX_PATH; cSize ++, j += 2){ - if(pSC->ppTempFile[i][cSize] == '\0') - break; - if(pFilename[j] != '\0') - pFilename[k ++] = pFilename[j]; - if(pFilename[j + 1] != '\0') - pFilename[k ++] = pFilename[j + 1]; - } - pFilename[cSize] = '\0'; - } - -#else //DPK needs to support ANSI - pSC->ppTempFile[i] = (char *)malloc(FILENAME_MAX * sizeof(char)); - if(pSC->ppTempFile[i] == NULL) return ICERR_ERROR; - - if ((pFilename = tmpnam(NULL)) == NULL) - return ICERR_ERROR; - strcpy(pSC->ppTempFile[i], pFilename); -#endif - if(CreateWS_File(pSC->ppWStream + i, pFilename, "w+b") != ICERR_OK) return ICERR_ERROR; - - } - else { - if(CreateWS_List(pSC->ppWStream + i) != ICERR_OK) return ICERR_ERROR; - } - attachISWrite(pSC->m_ppBitIO[i], pSC->ppWStream[i]); - } - } - - return ICERR_OK; -} - -#define PUTBITS putBit16 -/************************************************************************* - Write variable length byte aligned integer -*************************************************************************/ -static Void PutVLWordEsc(BitIOInfo* pIO, Int iEscape, size_t s) -{ - if (iEscape) { - assert(iEscape <= 0xff && iEscape > 0xfc); // fd,fe,ff are the only valid escapes - PUTBITS(pIO, iEscape, 8); - } - else if (s < 0xfb00) { - PUTBITS(pIO, (U32) s, 16); - } - else { - size_t t = s >> 16; - if ((t >> 16) == 0) { - PUTBITS(pIO, 0xfb, 8); - } - else { - t >>= 16; - PUTBITS(pIO, 0xfc, 8); - PUTBITS(pIO, (U32)(t >> 16) & 0xffff, 16); - PUTBITS(pIO, (U32) t & 0xffff, 16); - } - PUTBITS(pIO, (U32) t & 0xffff, 16); - PUTBITS(pIO, (U32) s & 0xffff, 16); - } -} - -/************************************************************************* - Write index table at start (null index table) -*************************************************************************/ -Int writeIndexTableNull(CWMImageStrCodec * pSC) -{ - if(pSC->cNumBitIO == 0){ - BitIOInfo* pIO = pSC->pIOHeader; - fillToByte(pIO); - - /* Profile / Level info */ - PutVLWordEsc(pIO, 0, 4); // 4 bytes - PUTBITS(pIO, 111, 8); // default profile idc - PUTBITS(pIO, 255, 8); // default level idc - PUTBITS(pIO, 1, 16); // LAST_FLAG - } - - return ICERR_OK; -} - -/************************************************************************* - Write index table -*************************************************************************/ -Int writeIndexTable(CWMImageStrCodec * pSC) -{ - if(pSC->cNumBitIO > 0){ - BitIOInfo* pIO = pSC->pIOHeader; - size_t *pTable = pSC->pIndexTable, iSize[4] = { 0 }; - I32 iEntry = (I32)pSC->cNumBitIO * (pSC->WMISCP.cNumOfSliceMinus1H + 1), i, k, l; - - // write index table header [0x0001] - 2 bytes - PUTBITS(pIO, 1, 16); - - for(i = pSC->WMISCP.cNumOfSliceMinus1H; i>= 0 && pSC->bTileExtraction == FALSE; i --){ - for(k = 0; k < (int)pSC->cNumBitIO; ){ - for(l = 0; l < (pSC->WMISCP.bfBitstreamFormat == FREQUENCY && pSC->WMISCP.bProgressiveMode ? pSC->cSB : 1); l ++, k ++) - { - if (i > 0) - pTable[pSC->cNumBitIO * i + k] -= pSC->pIndexTable[pSC->cNumBitIO * (i - 1) + k]; // packet length - iSize[l] += pTable[pSC->cNumBitIO * i + k]; - } - } - } - - iSize[3] = iSize[2] + iSize[1] + iSize[0]; - iSize[2] = iSize[1] + iSize[0]; - iSize[1] = iSize[0]; - iSize[0] = 0; - - for(i = 0; i < iEntry; ){ - for(l = 0; l < (pSC->WMISCP.bfBitstreamFormat == FREQUENCY && pSC->WMISCP.bProgressiveMode ? pSC->cSB : 1); l ++, i ++) - { - writeIS_L1(pSC, pIO); - PutVLWordEsc(pIO, (pTable[i] <= MINIMUM_PACKET_LENGTH) ? 0xff : 0, iSize[l]); - iSize[l] += (pTable[i] <= MINIMUM_PACKET_LENGTH) ? 0 : pTable[i]; - } - } - - writeIS_L1(pSC, pIO); - PutVLWordEsc(pIO, 0xff, 0); // escape to end - fillToByte(pIO); - } - - return ICERR_OK; -} - -Int copyTo(struct WMPStream * pSrc, struct WMPStream * pDst, size_t iBytes) -{ - char pData[PACKETLENGTH]; - - if (iBytes <= MINIMUM_PACKET_LENGTH){ - pSrc->Read(pSrc, pData, iBytes); - return ICERR_OK; - } - - while(iBytes > PACKETLENGTH){ - pSrc->Read(pSrc, pData, PACKETLENGTH); - pDst->Write(pDst, pData, PACKETLENGTH); - iBytes -= PACKETLENGTH; - } - pSrc->Read(pSrc, pData, iBytes); - pDst->Write(pDst, pData, iBytes); - - return ICERR_OK; -} - -Void StrIOEncTerm(CWMImageStrCodec* pSC) -{ - BitIOInfo * pIO = pSC->pIOHeader; - - fillToByte(pIO); - - if(pSC->WMISCP.bVerbose){ - U32 i, j; - - printf("\n%d horizontal tiles:\n", pSC->WMISCP.cNumOfSliceMinus1H + 1); - for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1H; i ++){ - printf(" offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileY[i]); - } - - printf("\n%d vertical tiles:\n", pSC->WMISCP.cNumOfSliceMinus1V + 1); - for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i ++){ - printf(" offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileX[i]); - } - - if(pSC->WMISCP.bfBitstreamFormat == SPATIAL){ - printf("\nSpatial order bitstream\n"); - } - else{ - printf("\nFrequency order bitstream\n"); - } - - if(!pSC->m_param.bIndexTable){ - printf("\nstreaming mode, no index table.\n"); - } - else if(pSC->WMISCP.bfBitstreamFormat == SPATIAL){ - for(j = 0; j <= pSC->WMISCP.cNumOfSliceMinus1H; j ++){ - for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i ++){ - printf("bitstream size for tile (%d, %d): %d.\n", j, i, (int) pSC->pIndexTable[j * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + i]); - } - } - } - else{ - for(j = 0; j <= pSC->WMISCP.cNumOfSliceMinus1H; j ++){ - for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i ++){ - size_t * p = &pSC->pIndexTable[(j * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + i) * 4]; - printf("bitstream size of (DC, LP, AC, FL) for tile (%d, %d): %d %d %d %d.\n", j, i, - (int) p[0], (int) p[1], (int) p[2], (int) p[3]); - } - } - } - } - - writeIndexTable(pSC); // write index table to the header - - detachISWrite(pSC, pIO); - - if(pSC->cNumBitIO > 0){ - size_t i, j, k, l; - struct WMPStream * pDst = pSC->WMISCP.pWStream; - size_t * pTable = pSC->pIndexTable; - - for(i = 0; i < pSC->cNumBitIO; i ++){ - detachISWrite(pSC, pSC->m_ppBitIO[i]); - } - - for(i = 0; i < pSC->cNumBitIO; i ++){ - pSC->ppWStream[i]->SetPos(pSC->ppWStream[i], 0); // seek back for read - } - - for(l = 0; l < (size_t)(pSC->WMISCP.bfBitstreamFormat == FREQUENCY && pSC->WMISCP.bProgressiveMode ? pSC->cSB : 1); l ++){ - for(i = 0, k = l; i <= pSC->WMISCP.cNumOfSliceMinus1H; i ++){ // loop through tiles - for(j = 0; j <= pSC->WMISCP.cNumOfSliceMinus1V; j ++){ - - if(pSC->WMISCP.bfBitstreamFormat == SPATIAL) - copyTo(pSC->ppWStream[j], pDst, pTable[k ++]); - else if (!pSC->WMISCP.bProgressiveMode){ - copyTo(pSC->ppWStream[j * pSC->cSB + 0], pDst, pTable[k ++]); - if(pSC->cSB > 1) - copyTo(pSC->ppWStream[j * pSC->cSB + 1], pDst, pTable[k ++]); - if(pSC->cSB > 2) - copyTo(pSC->ppWStream[j * pSC->cSB + 2], pDst, pTable[k ++]); - if(pSC->cSB > 3) - copyTo(pSC->ppWStream[j * pSC->cSB + 3], pDst, pTable[k ++]); - } - else{ - copyTo(pSC->ppWStream[j * pSC->cSB + l], pDst, pTable[k]); - k += pSC->cSB; - } - } - } - } - - if (pSC->cmbHeight * pSC->cmbWidth * pSC->WMISCP.cChannel >= MAX_MEMORY_SIZE_IN_WORDS){ - for(i = 0; i < pSC->cNumBitIO; i ++){ - if(pSC->ppWStream && pSC->ppWStream[i]){ - if((*(pSC->ppWStream + i))->state.file.pFile){ - fclose((*(pSC->ppWStream + i))->state.file.pFile); -#ifdef _WINDOWS_ - if (DeleteFileA((LPCSTR)pSC->ppTempFile[i]) == 0) - return;// ICERR_ERROR; -#else - if (remove(pSC->ppTempFile[i]) == -1) - return;// ICERR_ERROR; -#endif - } - - if (*(pSC->ppWStream + i)) - free(*(pSC->ppWStream + i)); - } - if(pSC->ppTempFile){ - if(pSC->ppTempFile[i]) - free(pSC->ppTempFile[i]); - } - } - - if(pSC->ppTempFile) - free(pSC->ppTempFile); - } - else{ - for(i = 0; i < pSC->cNumBitIO; i ++){ - if(pSC->ppWStream && pSC->ppWStream[i]) - pSC->ppWStream[i]->Close(pSC->ppWStream + i); - } - } - - free(pSC->ppWStream); - - free(pSC->m_ppBitIO); - free(pSC->pIndexTable); - } -} - -/************************************************************************* - Write header of image plane -*************************************************************************/ -Int WriteImagePlaneHeader(CWMImageStrCodec * pSC) -{ - CWMImageInfo * pII = &pSC->WMII; - CWMIStrCodecParam * pSCP = &pSC->WMISCP; - BitIOInfo* pIO = pSC->pIOHeader; - - PUTBITS(pIO, (Int) pSC->m_param.cfColorFormat, 3); // internal color format - PUTBITS(pIO, (Int) pSC->m_param.bScaledArith, 1); // lossless mode - -// subbands - PUTBITS(pIO, (U32)pSCP->sbSubband, 4); - -// color parameters - switch (pSC->m_param.cfColorFormat) { - case YUV_420: - case YUV_422: - case YUV_444: - PUTBITS(pIO, 0, 4); - PUTBITS(pIO, 0, 4); - break; - case NCOMPONENT: - PUTBITS(pIO, (Int) pSC->m_param.cNumChannels - 1, 4); - PUTBITS(pIO, 0, 4); - break; - default: - break; - } - -// float and 32s additional parameters - switch (pII->bdBitDepth) { - case BD_16: - case BD_16S: - PUTBITS(pIO, pSCP->nLenMantissaOrShift, 8); - break; - case BD_32: - case BD_32S: - if(pSCP->nLenMantissaOrShift == 0) - pSCP->nLenMantissaOrShift = 10;//default - PUTBITS(pIO, pSCP->nLenMantissaOrShift, 8); - break; - case BD_32F: - if(pSCP->nLenMantissaOrShift == 0) - pSCP->nLenMantissaOrShift = 13;//default - PUTBITS(pIO, pSCP->nLenMantissaOrShift, 8);//float conversion parameters - PUTBITS(pIO, pSCP->nExpBias, 8); - break; - default: - break; - } - - // quantization - PUTBITS(pIO, (pSC->m_param.uQPMode & 1) == 1 ? 0 : 1, 1); // DC frame uniform quantization? - if((pSC->m_param.uQPMode & 1) == 0) - writeQuantizer(pSC->pTile[0].pQuantizerDC, pIO, (pSC->m_param.uQPMode >> 3) & 3, pSC->m_param.cNumChannels, 0); - if(pSC->WMISCP.sbSubband != SB_DC_ONLY){ - PUTBITS(pIO, (pSC->m_param.uQPMode & 0x200) == 0 ? 1 : 0, 1); // use DC quantization? - if((pSC->m_param.uQPMode & 0x200) != 0){ - PUTBITS(pIO, (pSC->m_param.uQPMode & 2) == 2 ? 0 : 1, 1); // LP frame uniform quantization? - if((pSC->m_param.uQPMode & 2) == 0) - writeQuantizer(pSC->pTile[0].pQuantizerLP, pIO, (pSC->m_param.uQPMode >> 5) & 3, pSC->m_param.cNumChannels, 0); - } - - if(pSC->WMISCP.sbSubband != SB_NO_HIGHPASS){ - PUTBITS(pIO, (pSC->m_param.uQPMode & 0x400) == 0 ? 1 : 0, 1); // use LP quantization? - if((pSC->m_param.uQPMode & 0x400) != 0){ - PUTBITS(pIO, (pSC->m_param.uQPMode & 4) == 4 ? 0 : 1, 1); // HP frame uniform quantization? - if((pSC->m_param.uQPMode & 4) == 0) - writeQuantizer(pSC->pTile[0].pQuantizerHP, pIO, (pSC->m_param.uQPMode >> 7) & 3, pSC->m_param.cNumChannels, 0); - } - } - } - - fillToByte(pIO); // remove this later - return ICERR_OK; -} - -/************************************************************************* - Write header to buffer -*************************************************************************/ -Int WriteWMIHeader(CWMImageStrCodec * pSC) -{ - CWMImageInfo * pII = &pSC->WMII; - CWMIStrCodecParam * pSCP = &pSC->WMISCP; - CCoreParameters * pCoreParam = &pSC->m_param; - BitIOInfo* pIO = pSC->pIOHeader; - U32 /*iSizeOfSize = 2,*/ i; - // temporary assignments / reserved words - // const Int HEADERSIZE = 0; - Bool bInscribed = FALSE; - Bool bAbbreviatedHeader = (((pII->cWidth + 15) / 16 > 255 || (pII->cHeight + 15) / 16 > 255) ? FALSE : TRUE); - - if(pCoreParam->bTranscode == FALSE) - pCoreParam->cExtraPixelsTop = pCoreParam->cExtraPixelsLeft = pCoreParam->cExtraPixelsRight = pCoreParam->cExtraPixelsBottom = 0; - - // num of extra boundary pixels due to compressed domain processing - bInscribed = (pCoreParam->cExtraPixelsTop || pCoreParam->cExtraPixelsLeft || pCoreParam->cExtraPixelsBottom || pCoreParam->cExtraPixelsRight); - -// 0 - /** signature **/ - for (i = 0; i < 8; PUTBITS(pSC->pIOHeader, gGDISignature[i++], 8)); - -// 8 - /** codec version and subversion **/ - PUTBITS(pIO, CODEC_VERSION, 4); // this should be changed to "profile" in RTM - if (pSC->WMISCP.bUseHardTileBoundaries) - PUTBITS(pIO, CODEC_SUBVERSION_NEWSCALING_HARD_TILES, 4); - else - PUTBITS(pIO, CODEC_SUBVERSION_NEWSCALING_SOFT_TILES, 4); - -// 9 primary parameters - PUTBITS(pIO, (pSCP->cNumOfSliceMinus1V || pSCP->cNumOfSliceMinus1H) ? 1 : 0, 1); // tiling present - PUTBITS(pIO, (Int) pSCP->bfBitstreamFormat, 1); // bitstream layout - PUTBITS(pIO, pII->oOrientation, 3); // m_iRotateFlip - PUTBITS(pIO, pSC->m_param.bIndexTable, 1); // index table present - PUTBITS(pIO, pSCP->olOverlap, 2); // overlap - -// 10 - PUTBITS(pIO, bAbbreviatedHeader, 1); // short words for size and tiles - PUTBITS(pIO, 1, 1); // long word length (use intelligence later) - PUTBITS(pIO, bInscribed, 1); // windowing - PUTBITS(pIO, pSC->m_param.bTrimFlexbitsFlag, 1); // trim flexbits flag sent - PUTBITS(pIO, 0, 1); // tile stretching parameters (not enabled) - PUTBITS(pIO, 0, 2); // reserved bits - PUTBITS(pIO, (Int) pSC->m_param.bAlphaChannel, 1); // alpha channel present - -// 11 - informational - PUTBITS(pIO, (Int) pII->cfColorFormat, 4); // source color format - if(BD_1 == pII->bdBitDepth && pSCP->bBlackWhite) - PUTBITS(pIO, (Int) BD_1alt, 4); // source bit depth - else - PUTBITS(pIO, (Int) pII->bdBitDepth, 4); // source bit depth - -// 12 - Variable length fields -// size - putBit32(pIO, (U32)(pII->cWidth - 1), bAbbreviatedHeader ? 16 : 32); - putBit32(pIO, (U32)(pII->cHeight - 1), bAbbreviatedHeader ? 16 : 32); - -// tiling - if (pSCP->cNumOfSliceMinus1V || pSCP->cNumOfSliceMinus1H) { - PUTBITS(pIO, pSCP->cNumOfSliceMinus1V, LOG_MAX_TILES); // # of vertical slices - PUTBITS(pIO, pSCP->cNumOfSliceMinus1H, LOG_MAX_TILES); // # of horizontal slices - } - -// tile sizes - for(i = 0; i < pSCP->cNumOfSliceMinus1V; i ++){ // width in MB of vertical slices, not needed for last slice! - PUTBITS(pIO, pSCP->uiTileX[i + 1] - pSCP->uiTileX[i], bAbbreviatedHeader ? 8 : 16); - } - for(i = 0; i < pSCP->cNumOfSliceMinus1H; i ++){ // width in MB of horizontal slices, not needed for last slice! - PUTBITS(pIO, pSCP->uiTileY[i + 1] - pSCP->uiTileY[i], bAbbreviatedHeader ? 8 : 16); - } - -// window due to compressed domain processing - if (bInscribed) { - PUTBITS(pIO, (U32)pCoreParam->cExtraPixelsTop, 6); - PUTBITS(pIO, (U32)pCoreParam->cExtraPixelsLeft, 6); - PUTBITS(pIO, (U32)pCoreParam->cExtraPixelsBottom, 6); - PUTBITS(pIO, (U32)pCoreParam->cExtraPixelsRight, 6); - } - fillToByte(pIO); // redundant - - // write image plane headers - WriteImagePlaneHeader(pSC); - - return ICERR_OK; -} - -// streaming codec init/term -Int StrEncInit(CWMImageStrCodec* pSC) -{ - COLORFORMAT cf = pSC->m_param.cfColorFormat; - COLORFORMAT cfE = pSC->WMII.cfColorFormat; - U16 iQPIndexY = 0, iQPIndexYLP = 0, iQPIndexYHP = 0; - U16 iQPIndexU = 0, iQPIndexULP = 0, iQPIndexUHP = 0; - U16 iQPIndexV = 0, iQPIndexVLP = 0, iQPIndexVHP = 0; - size_t i; - Bool b32bit = sizeof(size_t) == 4; - - /** color transcoding with resolution change **/ - pSC->m_bUVResolutionChange = (((cfE == CF_RGB || cfE == YUV_444 || cfE == CMYK || cfE == CF_RGBE) && - (cf == YUV_422 || cf == YUV_420)) - || (cfE == YUV_422 && cf == YUV_420)) && !pSC->WMISCP.bYUVData; - - if(pSC->m_bUVResolutionChange){ - size_t cSize = ((cfE == YUV_422 ? 128 : 256) + (cf == YUV_420 ? 32 : 0)) * pSC->cmbWidth + 256; - - if(b32bit){ // integer overlow/underflow check for 32-bit system - if(((pSC->cmbWidth >> 16) * ((cfE == YUV_422 ? 128 : 256) + (cf == YUV_420 ? 32 : 0))) & 0xffff0000) - return ICERR_ERROR; - if(cSize >= 0x3fffffff) - return ICERR_ERROR; - } - pSC->pResU = (PixelI *)malloc(cSize * sizeof(PixelI)); - pSC->pResV = (PixelI *)malloc(cSize * sizeof(PixelI)); - if(pSC->pResU == NULL || pSC->pResV == NULL){ - return ICERR_ERROR; - } - } - - pSC->cTileColumn = pSC->cTileRow = 0; - - if(allocateTileInfo(pSC) != ICERR_OK) - return ICERR_ERROR; - - if(pSC->m_param.bTranscode == FALSE){ - pSC->m_param.uQPMode = 0x150; // 101010 000 - // 000 == uniform (not per tile) DC, LP, HP - // 101010 == cChMode == 2 == independent (not same) DC, LP, HP - - /** lossless or Y component lossless condition: all subbands present, uniform quantization with QPIndex 1 **/ - pSC->m_param.bScaledArith = !((pSC->m_param.uQPMode & 7) == 0 && - 1 == pSC->WMISCP.uiDefaultQPIndex <= 1 && - pSC->WMISCP.sbSubband == SB_ALL && - pSC->m_bUVResolutionChange == FALSE) && - !pSC->WMISCP.bUnscaledArith; - if (BD_32 == pSC->WMII.bdBitDepth || BD_32S == pSC->WMII.bdBitDepth || BD_32F == pSC->WMII.bdBitDepth) { - pSC->m_param.bScaledArith = FALSE; - } - pSC->m_param.uQPMode |= 0x600; // don't use DC QP for LP, LP QP for HP - - // default QPs - iQPIndexY = pSC->m_param.bAlphaChannel && pSC->m_param.cNumChannels == 1? - pSC->WMISCP.uiDefaultQPIndexAlpha : pSC->WMISCP.uiDefaultQPIndex; - - // determine the U,V index - iQPIndexU = pSC->WMISCP.uiDefaultQPIndexU!=0? - pSC->WMISCP.uiDefaultQPIndexU: iQPIndexY; - iQPIndexV = pSC->WMISCP.uiDefaultQPIndexV!=0? - pSC->WMISCP.uiDefaultQPIndexV: iQPIndexY; - - // determine the QPIndexYLP - iQPIndexYLP = pSC->m_param.bAlphaChannel && pSC->m_param.cNumChannels == 1 ? - pSC->WMISCP.uiDefaultQPIndexAlpha : - (pSC->WMISCP.uiDefaultQPIndexYLP == 0 ? - pSC->WMISCP.uiDefaultQPIndex : pSC->WMISCP.uiDefaultQPIndexYLP); // default to QPIndex if not set - - // determine the QPIndexYHP - iQPIndexYHP = pSC->m_param.bAlphaChannel && pSC->m_param.cNumChannels == 1 ? - pSC->WMISCP.uiDefaultQPIndexAlpha : - (pSC->WMISCP.uiDefaultQPIndexYHP == 0 ? - pSC->WMISCP.uiDefaultQPIndex : pSC->WMISCP.uiDefaultQPIndexYHP); // default to QPIndex if not set - - // determine the U,V LP index - iQPIndexULP = pSC->WMISCP.uiDefaultQPIndexULP!=0? - pSC->WMISCP.uiDefaultQPIndexULP: iQPIndexU; - iQPIndexVLP = pSC->WMISCP.uiDefaultQPIndexVLP!=0? - pSC->WMISCP.uiDefaultQPIndexVLP: iQPIndexV; - - // determine the U,V HP index - iQPIndexUHP = pSC->WMISCP.uiDefaultQPIndexUHP!=0? - pSC->WMISCP.uiDefaultQPIndexUHP: iQPIndexU; - iQPIndexVHP = pSC->WMISCP.uiDefaultQPIndexVHP!=0? - pSC->WMISCP.uiDefaultQPIndexVHP: iQPIndexV; - - // clamp the QPIndex - 0 is lossless mode - if(iQPIndexY < 2) - iQPIndexY = 0; - if (iQPIndexYLP < 2) - iQPIndexYLP = 0; - if (iQPIndexYHP < 2) - iQPIndexYHP = 0; - if(iQPIndexU < 2) - iQPIndexU = 0; - if (iQPIndexULP < 2) - iQPIndexULP = 0; - if (iQPIndexUHP < 2) - iQPIndexUHP = 0; - if(iQPIndexV < 2) - iQPIndexV = 0; - if (iQPIndexVLP < 2) - iQPIndexVLP = 0; - if (iQPIndexVHP < 2) - iQPIndexVHP = 0; - } - - if((pSC->m_param.uQPMode & 1) == 0){ // DC frame uniform quantization - if(allocateQuantizer(pSC->pTile[0].pQuantizerDC, pSC->m_param.cNumChannels, 1) != ICERR_OK) - return ICERR_ERROR; - setUniformQuantizer(pSC, 0); - for(i = 0; i < pSC->m_param.cNumChannels; i ++) - if(pSC->m_param.bTranscode) - pSC->pTile[0].pQuantizerDC[i]->iIndex = pSC->m_param.uiQPIndexDC[i]; - else - pSC->pTile[0].pQuantizerDC[i]->iIndex = pSC->m_param.uiQPIndexDC[i] = (U8)(((i == 0 ? iQPIndexY : (i == 1) ? iQPIndexU: iQPIndexV)) & 0xff); - formatQuantizer(pSC->pTile[0].pQuantizerDC, (pSC->m_param.uQPMode >> 3) & 3, pSC->m_param.cNumChannels, 0, TRUE, pSC->m_param.bScaledArith); - - for(i = 0; i < pSC->m_param.cNumChannels; i ++) - pSC->pTile[0].pQuantizerDC[i]->iOffset = (pSC->pTile[0].pQuantizerDC[i]->iQP >> 1); - } - - if(pSC->WMISCP.sbSubband != SB_DC_ONLY){ - if((pSC->m_param.uQPMode & 2) == 0){ // LP frame uniform quantization - if(allocateQuantizer(pSC->pTile[0].pQuantizerLP, pSC->m_param.cNumChannels, 1) != ICERR_OK) - return ICERR_ERROR; - setUniformQuantizer(pSC, 1); - for(i = 0; i < pSC->m_param.cNumChannels; i ++) - if(pSC->m_param.bTranscode) - pSC->pTile[0].pQuantizerLP[i]->iIndex = pSC->m_param.uiQPIndexLP[i]; - else - pSC->pTile[0].pQuantizerLP[i]->iIndex = pSC->m_param.uiQPIndexLP[i] = (U8)(((i == 0 ? iQPIndexYLP : (i == 1) ? iQPIndexULP: iQPIndexVLP)) & 0xff); - formatQuantizer(pSC->pTile[0].pQuantizerLP, (pSC->m_param.uQPMode >> 5) & 3, pSC->m_param.cNumChannels, 0, TRUE, pSC->m_param.bScaledArith); - } - - if(pSC->WMISCP.sbSubband != SB_NO_HIGHPASS){ - if((pSC->m_param.uQPMode & 4) == 0){ // HP frame uniform quantization - if(allocateQuantizer(pSC->pTile[0].pQuantizerHP, pSC->m_param.cNumChannels, 1) != ICERR_OK) - return ICERR_ERROR; - setUniformQuantizer(pSC, 2); - for(i = 0; i < pSC->m_param.cNumChannels; i ++) - if(pSC->m_param.bTranscode) - pSC->pTile[0].pQuantizerHP[i]->iIndex = pSC->m_param.uiQPIndexHP[i]; - else - pSC->pTile[0].pQuantizerHP[i]->iIndex = pSC->m_param.uiQPIndexHP[i] = (U8)(((i == 0 ? iQPIndexYHP : (i == 1) ? iQPIndexUHP: iQPIndexVHP)) & 0xff); - formatQuantizer(pSC->pTile[0].pQuantizerHP, (pSC->m_param.uQPMode >> 7) & 3, pSC->m_param.cNumChannels, 0, FALSE, pSC->m_param.bScaledArith); - } - } - } - - if(allocatePredInfo(pSC) != ICERR_OK){ - return ICERR_ERROR; - } - - if(pSC->WMISCP.cNumOfSliceMinus1V >= MAX_TILES || AllocateCodingContextEnc (pSC, pSC->WMISCP.cNumOfSliceMinus1V + 1, pSC->WMISCP.uiTrimFlexBits) != ICERR_OK){ - return ICERR_ERROR; - } - - if (pSC->m_bSecondary) { - pSC->pIOHeader = pSC->m_pNextSC->pIOHeader; - pSC->m_ppBitIO = pSC->m_pNextSC->m_ppBitIO; - pSC->cNumBitIO = pSC->m_pNextSC->cNumBitIO; - pSC->cSB = pSC->m_pNextSC->cSB; - pSC->ppWStream = pSC->m_pNextSC->ppWStream; - pSC->pIndexTable = pSC->m_pNextSC->pIndexTable; - setBitIOPointers(pSC); - } - else { - StrIOEncInit(pSC); - setBitIOPointers(pSC); - WriteWMIHeader(pSC); - } - - return ICERR_OK; -} - -static Int StrEncTerm(CTXSTRCODEC ctxSC) -{ - CWMImageStrCodec* pSC = (CWMImageStrCodec*)ctxSC; - size_t j, jend = (pSC->m_pNextSC != NULL); - - for (j = 0; j <= jend; j++) { - if (sizeof(*pSC) != pSC->cbStruct) { - return ICERR_ERROR; - } - - if(pSC->m_bUVResolutionChange){ - if(pSC->pResU != NULL) - free(pSC->pResU); - if(pSC->pResV != NULL) - free(pSC->pResV); - } - - freePredInfo(pSC); - - if (j == 0) - StrIOEncTerm(pSC); - - FreeCodingContextEnc(pSC); - - freeTileInfo(pSC); - - pSC->WMISCP.nExpBias -= 128; // reset - - pSC = pSC->m_pNextSC; - } - - return 0; -} - -U32 setUniformTiling(U32 * pTile, U32 cNumTile, U32 cNumMB) -{ - U32 i, j; - - while((cNumMB + cNumTile - 1) / cNumTile > 65535) // too few tiles - cNumTile ++; - - for(i = cNumTile, j = cNumMB; i > 1; i --){ - pTile[cNumTile - i] = (j + i - 1) / i; - j -= pTile[cNumTile - i]; - } - - return cNumTile; -} - -U32 validateTiling(U32 * pTile, U32 cNumTile, U32 cNumMB) -{ - U32 i, cMBs; - - if(cNumTile == 0) - cNumTile = 1; - if(cNumTile > cNumMB) // too many tiles - cNumTile = 1; - if(cNumTile > MAX_TILES) - cNumTile = MAX_TILES; - - for(i = cMBs = 0; i + 1 < cNumTile; i ++){ - if(pTile[i] == 0 || pTile[i] > 65535){ // invalid tile setting, resetting to uniform tiling - cNumTile = setUniformTiling(pTile, cNumTile, cNumMB); - break; - } - - cMBs += pTile[i]; - - if(cMBs >= cNumMB){ - cNumTile = i + 1; - break; - } - } - - // last tile - if(cNumMB - cMBs > 65536) - cNumTile = setUniformTiling(pTile, cNumTile, cNumMB); - - for(i = 1; i < cNumTile; i ++) - pTile[i] += pTile[i - 1]; - for(i = cNumTile - 1; i > 0; i --) - pTile[i] = pTile[i - 1]; - pTile[0] = 0; - - return cNumTile; -} - -/************************************************************************* - Validate and adjust input params here -*************************************************************************/ -Int ValidateArgs(CWMImageInfo* pII, CWMIStrCodecParam *pSCP) -{ - int i; - Bool bTooNarrowTile = FALSE; - - if(pII->cWidth > (1 << 28) || pII->cHeight > (1 << 28) || pII->cWidth == 0 || pII->cHeight == 0){ - printf("Unsurpported image size!\n"); - return ICERR_ERROR; // unsurpported image size - } - - if (((pSCP->cfColorFormat == YUV_420) || (pSCP->cfColorFormat == YUV_422)) && (pSCP->olOverlap == OL_TWO) && ((Int)(((U32)pII->cWidth + 15) >> 4) < 2)) { - printf("Image width must be at least 2 MB wide for subsampled chroma and two levels of overlap!\n"); - return ICERR_ERROR; - } - - if(pSCP->sbSubband == SB_ISOLATED || pSCP->sbSubband >= SB_MAX) // not allowed - pSCP->sbSubband = SB_ALL; - - if(pII->bdBitDepth == BD_5 && (pII->cfColorFormat != CF_RGB || pII->cBitsPerUnit != 16 || pII->cLeadingPadding != 0)){ - printf("Unsupported BD_5 image format!\n"); - return ICERR_ERROR; // BD_5 must be compact RGB! - } - if(pII->bdBitDepth == BD_565 && (pII->cfColorFormat != CF_RGB || pII->cBitsPerUnit != 16 || pII->cLeadingPadding != 0)){ - printf("Unsupported BD_565 image format!\n"); - return ICERR_ERROR; // BD_5 must be compact RGB! - } - if(pII->bdBitDepth == BD_10 && (pII->cfColorFormat != CF_RGB || pII->cBitsPerUnit != 32 || pII->cLeadingPadding != 0)){ - printf("Unsupported BD_10 image format!\n"); - return ICERR_ERROR; // BD_10 must be compact RGB! - } - - if((pII->bdBitDepth == BD_5 || pII->bdBitDepth == BD_565 || pII->bdBitDepth == BD_10) && - (pSCP->cfColorFormat != YUV_420 && pSCP->cfColorFormat != YUV_422 && pSCP->cfColorFormat != Y_ONLY)) - pSCP->cfColorFormat = YUV_444; - - if(BD_1 == pII->bdBitDepth){ // binary image - if(pII->cfColorFormat != Y_ONLY){ - printf("BD_1 image must be black-and white!\n"); - return ICERR_ERROR; - } - pSCP->cfColorFormat = Y_ONLY; // can only be black white - } - - if(pSCP->bdBitDepth != BD_LONG) - pSCP->bdBitDepth = BD_LONG; // currently only support 32 bit internally - - if(pSCP->uAlphaMode > 1 && (pII->cfColorFormat == YUV_420 || pII->cfColorFormat == YUV_422 - || pII->bdBitDepth == BD_5 || pII->bdBitDepth == BD_10 - || pII->bdBitDepth == BD_1)) - { - printf("Alpha is not supported for this pixel format!\n"); - return ICERR_ERROR; - } - - if((pSCP->cfColorFormat == YUV_420 || pSCP->cfColorFormat == YUV_422) && (pII->bdBitDepth == BD_16F || pII->bdBitDepth == BD_32F || pII->cfColorFormat == CF_RGBE)) - { - printf("Float or RGBE images must be encoded with YUV 444!\n"); - return ICERR_ERROR; - } - - // adjust tiling - pSCP->cNumOfSliceMinus1V = validateTiling(pSCP->uiTileX, pSCP->cNumOfSliceMinus1V + 1, (((U32)pII->cWidth + 15) >> 4)) - 1; - pSCP->cNumOfSliceMinus1H = validateTiling(pSCP->uiTileY, pSCP->cNumOfSliceMinus1H + 1, (((U32)pII->cHeight + 15) >> 4)) - 1; - - if (pSCP->bUseHardTileBoundaries && ((pSCP->cfColorFormat == YUV_420) || (pSCP->cfColorFormat == YUV_422)) && (pSCP->olOverlap == OL_TWO)) { - for (i = 1; i < (int) (pSCP->cNumOfSliceMinus1H + 1); i++) { - if ((Int)(pSCP->uiTileY[i] - pSCP->uiTileY[i - 1]) < 2) { - bTooNarrowTile = TRUE; - break; - } - } - if ((Int)((((U32)pII->cWidth + 15) >> 4) - pSCP->uiTileY[pSCP->cNumOfSliceMinus1H]) < 2) - bTooNarrowTile = TRUE; - } - if (bTooNarrowTile) { - printf("Tile width must be at least 2 MB wide for hard tiles, subsampled chroma, and two levels of overlap!\n"); - return ICERR_ERROR; - } - - if(pSCP->cChannel > MAX_CHANNELS) - return ICERR_ERROR; - - /** supported color transcoding **/ - /** ARGB, RGB => YUV_444, YUV_422, YUV_420, Y_ONLY **/ - /** YUV_444 => YUV_422, YUV_420, Y_ONLY **/ - /** YUV_422 => YUV_420, Y_ONLY **/ - /** YUV_420 => Y_ONLY **/ - - /** unsupported color transcoding **/ - /** Y_ONLY, YUV_420, YUV_422 => YUV_444 **/ - /** Y_ONLY, YUV_420 => YUV_422 **/ - /** Y_ONLY => YUV_420 **/ - if((pII->cfColorFormat == Y_ONLY && pSCP->cfColorFormat != Y_ONLY) || - (pSCP->cfColorFormat == YUV_422 && (pII->cfColorFormat == YUV_420 || pII->cfColorFormat == Y_ONLY)) || - (pSCP->cfColorFormat == YUV_444 && (pII->cfColorFormat == YUV_422 || pII->cfColorFormat == YUV_420 || pII->cfColorFormat == Y_ONLY))){ - pSCP->cfColorFormat = pII->cfColorFormat; // force not to do color transcoding! - } - else if (pII->cfColorFormat == NCOMPONENT) { - pSCP->cfColorFormat = NCOMPONENT; // force not to do color transcoding! - } - if (CMYK == pII->cfColorFormat && pSCP->cfColorFormat == NCOMPONENT) - { - pSCP->cfColorFormat = CMYK; - } - - if(pSCP->cfColorFormat != NCOMPONENT){ - if(pSCP->cfColorFormat == Y_ONLY) - pSCP->cChannel = 1; - else if(pSCP->cfColorFormat == CMYK) - pSCP->cChannel = 4; - else - pSCP->cChannel = 3; - } - - if(pSCP->sbSubband >= SB_MAX) - pSCP->sbSubband = SB_ALL; - - - pII->cChromaCenteringX = 0; - pII->cChromaCenteringY = 0; - - return ICERR_OK; -} - -/************************************************************************* - Initialization of CWMImageStrCodec struct -*************************************************************************/ -static Void InitializeStrEnc(CWMImageStrCodec *pSC, - const CWMImageInfo* pII, const CWMIStrCodecParam *pSCP) -{ - pSC->cbStruct = sizeof(*pSC); - pSC->WMII = *pII; - pSC->WMISCP = *pSCP; - - // set nExpBias - if (pSC->WMISCP.nExpBias == 0) - pSC->WMISCP.nExpBias = 0x84/*4 + 128*/;//default - pSC->WMISCP.nExpBias += 128; // rollover arithmetic - - pSC->cRow = 0; - pSC->cColumn = 0; - - pSC->cmbWidth = (pSC->WMII.cWidth + 15) / 16; - pSC->cmbHeight = (pSC->WMII.cHeight + 15) / 16; - - pSC->Load = inputMBRow; - pSC->Quantize = quantizeMacroblock; - pSC->ProcessTopLeft = processMacroblock; - pSC->ProcessTop = processMacroblock; - pSC->ProcessTopRight = processMacroblock; - pSC->ProcessLeft = processMacroblock; - pSC->ProcessCenter = processMacroblock; - pSC->ProcessRight = processMacroblock; - pSC->ProcessBottomLeft = processMacroblock; - pSC->ProcessBottom = processMacroblock; - pSC->ProcessBottomRight = processMacroblock; - - pSC->m_pNextSC = NULL; - pSC->m_bSecondary = FALSE; -} - -/************************************************************************* - Streaming API init -*************************************************************************/ -Int ImageStrEncInit( - CWMImageInfo* pII, - CWMIStrCodecParam *pSCP, - CTXSTRCODEC* pctxSC) -{ - static size_t cbChannels[BD_MAX] = {2, 4}; - - size_t cbChannel = 0, cblkChroma = 0, i; - size_t cbMacBlockStride = 0, cbMacBlockChroma = 0, cMacBlock = 0; - - CWMImageStrCodec* pSC = NULL, *pNextSC = NULL; - char* pb = NULL; - size_t cb = 0; - Bool b32bit = sizeof(size_t) == 4; - - Int err; - - if(ValidateArgs(pII, pSCP) != ICERR_OK){ - goto ErrorExit; - } - - //================================================ - *pctxSC = NULL; - - //================================================ - cbChannel = cbChannels[pSCP->bdBitDepth]; - cblkChroma = cblkChromas[pSCP->cfColorFormat]; - cbMacBlockStride = cbChannel * 16 * 16; - cbMacBlockChroma = cbChannel * 16 * cblkChroma; - cMacBlock = (pII->cWidth + 15) / 16; - - //================================================ - cb = sizeof(*pSC) + (128 - 1) + (PACKETLENGTH * 4 - 1) + (PACKETLENGTH * 2 ) + sizeof(*pSC->pIOHeader); - i = cbMacBlockStride + cbMacBlockChroma * (pSCP->cChannel - 1); - if(b32bit) // integer overlow/underflow check for 32-bit system - if(((cMacBlock >> 15) * i) & 0xffff0000) - return ICERR_ERROR; - i *= cMacBlock * 2; - cb += i; - - pb = malloc(cb); - if (NULL == pb) - { - goto ErrorExit; - } - memset(pb, 0, cb); - - //================================================ - pSC = (CWMImageStrCodec*)pb; pb += sizeof(*pSC); - - // Set up perf timers - PERFTIMER_ONLY(pSC->m_fMeasurePerf = pSCP->fMeasurePerf); - PERFTIMER_NEW(pSC->m_fMeasurePerf, &pSC->m_ptEndToEndPerf); - PERFTIMER_NEW(pSC->m_fMeasurePerf, &pSC->m_ptEncDecPerf); - PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEndToEndPerf); - PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); - PERFTIMER_COPYSTARTTIME(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf, pSC->m_ptEndToEndPerf); - - pSC->m_param.cfColorFormat = pSCP->cfColorFormat; - pSC->m_param.bAlphaChannel = (pSCP->uAlphaMode == 3); - pSC->m_param.cNumChannels = pSCP->cChannel; - pSC->m_param.cExtraPixelsTop = pSC->m_param.cExtraPixelsBottom - = pSC->m_param.cExtraPixelsLeft = pSC->m_param.cExtraPixelsRight = 0; - - pSC->cbChannel = cbChannel; - - pSC->m_param.bTranscode = pSC->bTileExtraction = FALSE; - - //================================================ - InitializeStrEnc(pSC, pII, pSCP); - - //================================================ - // 2 Macro Row buffers for each channel - pb = ALIGNUP(pb, 128); - for (i = 0; i < pSC->m_param.cNumChannels; i++) { - pSC->a0MBbuffer[i] = (PixelI*)pb; pb += cbMacBlockStride * pSC->cmbWidth; - pSC->a1MBbuffer[i] = (PixelI*)pb; pb += cbMacBlockStride * pSC->cmbWidth; - cbMacBlockStride = cbMacBlockChroma; - } - - //================================================ - // lay 2 aligned IO buffers just below pIO struct - pb = (char*)ALIGNUP(pb, PACKETLENGTH * 4) + PACKETLENGTH * 2; - pSC->pIOHeader = (BitIOInfo*)pb; - - //================================================ - err = StrEncInit(pSC); - if (ICERR_OK != err) - goto ErrorExit; - - // if interleaved alpha is needed - if (pSC->m_param.bAlphaChannel) { - cbMacBlockStride = cbChannel * 16 * 16; - // 1. allocate new pNextSC info - //================================================ - cb = sizeof(*pNextSC) + (128 - 1) + cbMacBlockStride * cMacBlock * 2; - pb = malloc(cb); - if (NULL == pb) - { - goto ErrorExit; - } - memset(pb, 0, cb); - //================================================ - pNextSC = (CWMImageStrCodec*)pb; pb += sizeof(*pNextSC); - - // 2. initialize pNextSC - pNextSC->m_param.cfColorFormat = Y_ONLY; - pNextSC->m_param.cNumChannels = 1; - pNextSC->m_param.bAlphaChannel = TRUE; - pNextSC->cbChannel = cbChannel; - //================================================ - - // 3. initialize arrays - InitializeStrEnc(pNextSC, pII, pSCP); - //================================================ - - // 2 Macro Row buffers for each channel - pb = ALIGNUP(pb, 128); - pNextSC->a0MBbuffer[0] = (PixelI*)pb; pb += cbMacBlockStride * pNextSC->cmbWidth; - pNextSC->a1MBbuffer[0] = (PixelI*)pb; pb += cbMacBlockStride * pNextSC->cmbWidth; - //================================================ - pNextSC->pIOHeader = pSC->pIOHeader; - //================================================ - - // 4. link pSC->pNextSC = pNextSC - pNextSC->m_pNextSC = pSC; - pNextSC->m_bSecondary = TRUE; - - // 5. StrEncInit - StrEncInit(pNextSC); - - // 6. Write header of image plane - WriteImagePlaneHeader(pNextSC); - } - - pSC->m_pNextSC = pNextSC; - //================================================ - *pctxSC = (CTXSTRCODEC)pSC; - - writeIndexTableNull(pSC); -#if defined(WMP_OPT_SSE2) || defined(WMP_OPT_CC_ENC) || defined(WMP_OPT_TRFM_ENC) - StrEncOpt(pSC); -#endif // OPT defined - - PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); - return ICERR_OK; - -ErrorExit: - return ICERR_ERROR; -} - -/************************************************************************* - Streaming API encode -*************************************************************************/ -Int ImageStrEncEncode( - CTXSTRCODEC ctxSC, - const CWMImageBufferInfo* pBI) -{ - CWMImageStrCodec* pSC = (CWMImageStrCodec*)ctxSC; - CWMImageStrCodec* pNextSC = pSC->m_pNextSC; - ImageDataProc ProcessLeft, ProcessCenter, ProcessRight; - - if (sizeof(*pSC) != pSC->cbStruct) - { - return ICERR_ERROR; - } - - //================================ - PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); - - pSC->WMIBI = *pBI; - pSC->cColumn = 0; - initMRPtr(pSC); - if (pNextSC) - pNextSC->WMIBI = *pBI; - - if (0 == pSC->cRow) { - ProcessLeft = pSC->ProcessTopLeft; - ProcessCenter = pSC->ProcessTop; - ProcessRight = pSC->ProcessTopRight; - } - else { - ProcessLeft = pSC->ProcessLeft; - ProcessCenter = pSC->ProcessCenter; - ProcessRight = pSC->ProcessRight; - } - - if( pSC->Load(pSC) != ICERR_OK ) - return ICERR_ERROR; - if(ProcessLeft(pSC) != ICERR_OK) - return ICERR_ERROR; - advanceMRPtr(pSC); - - //================================ - for (pSC->cColumn = 1; pSC->cColumn < pSC->cmbWidth; ++pSC->cColumn) { - if(ProcessCenter(pSC) != ICERR_OK) - return ICERR_ERROR; - advanceMRPtr(pSC); - } - - //================================ - if(ProcessRight(pSC) != ICERR_OK) - return ICERR_ERROR; - if (pSC->cRow) - advanceOneMBRow(pSC); - - ++pSC->cRow; - swapMRPtr(pSC); - - PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); - return ICERR_OK; -} - -/************************************************************************* - Streaming API term -*************************************************************************/ -Int ImageStrEncTerm( - CTXSTRCODEC ctxSC) -{ - CWMImageStrCodec* pSC = (CWMImageStrCodec*)ctxSC; - // CWMImageStrCodec *pNextSC = pSC->m_pNextSC; - - if (sizeof(*pSC) != pSC->cbStruct) - { - return ICERR_ERROR; - } - - //================================ - PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); - pSC->cColumn = 0; - initMRPtr(pSC); - - pSC->ProcessBottomLeft(pSC); - advanceMRPtr(pSC); - - //================================ - for (pSC->cColumn = 1; pSC->cColumn < pSC->cmbWidth; ++pSC->cColumn) { - pSC->ProcessBottom(pSC); - advanceMRPtr(pSC); - } - - //================================ - pSC->ProcessBottomRight(pSC); - - //================================ - StrEncTerm(pSC); - - PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); - PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEndToEndPerf); - PERFTIMER_REPORT(pSC->m_fMeasurePerf, pSC); - PERFTIMER_DELETE(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); - PERFTIMER_DELETE(pSC->m_fMeasurePerf, pSC->m_ptEndToEndPerf); - - free(pSC); - return ICERR_OK; -} - -// centralized UV downsampling -#define DF_ODD ((((d1 + d2 + d3) << 2) + (d2 << 1) + d0 + d4 + 8) >> 4) -Void downsampleUV(CWMImageStrCodec * pSC) -{ - const COLORFORMAT cfInt = pSC->m_param.cfColorFormat; - const COLORFORMAT cfExt = pSC->WMII.cfColorFormat; - PixelI * pSrc, * pDst; - PixelI d0, d1, d2, d3, d4; - size_t iChannel, iRow, iColumn; - - for(iChannel = 1; iChannel < 3; iChannel ++){ - if(cfExt != YUV_422){ // need to do horizontal downsampling, 444 => 422 - const size_t cShift = (cfInt == YUV_422 ? 1 : 0); - - pSrc = (iChannel == 1 ? pSC->pResU : pSC->pResV); - pDst = (cfInt == YUV_422 ? pSC->p1MBbuffer[iChannel] : pSrc); - - for(iRow = 0; iRow < 16; iRow ++){ - d0 = d4 = pSrc[idxCC[iRow][2]], d1 = d3 = pSrc[idxCC[iRow][1]], d2 = pSrc[idxCC[iRow][0]]; // left boundary - - for(iColumn = 0; iColumn + 2 < pSC->cmbWidth * 16; iColumn += 2){ - pDst[((iColumn >> 4) << (8 - cShift)) + idxCC[iRow][(iColumn & 15) >> cShift]] = DF_ODD; - d0 = d2, d1 = d3, d2 = d4; - d3 = pSrc[(((iColumn + 3) >> 4) << 8) + idxCC[iRow][(iColumn + 3) & 0xf]]; - d4 = pSrc[(((iColumn + 4) >> 4) << 8) + idxCC[iRow][(iColumn + 4) & 0xf]]; - } - - d4 = d2; // right boundary - pDst[((iColumn >> 4) << (8 - cShift)) + idxCC[iRow][(iColumn & 15) >> cShift]] = DF_ODD; - } - } - - if(cfInt == YUV_420){ // need to do vertical downsampling - const size_t cShift = (cfExt == YUV_422 ? 0 : 1); - PixelI * pBuf[4]; - size_t mbOff, pxOff; - - pDst = pSC->p1MBbuffer[iChannel]; - pSrc = (iChannel == 1 ? pSC->pResU : pSC->pResV); - pBuf[0] = pSrc + (pSC->cmbWidth << (cfExt == YUV_422 ? 7 : 8)); - pBuf[1] = pBuf[0] + pSC->cmbWidth * 8, pBuf[2] = pBuf[1] + pSC->cmbWidth * 8, pBuf[3] = pBuf[2] + pSC->cmbWidth * 8; - - for(iColumn = 0; iColumn < pSC->cmbWidth * 8; iColumn ++){ - mbOff = (iColumn >> 3) << (7 + cShift); - pxOff = (iColumn & 7) << cShift; - - if(pSC->cRow == 0) // top image boundary - d0 = d4 = pSrc[mbOff + idxCC[2][pxOff]], d1 = d3 = pSrc[mbOff + idxCC[1][pxOff]], d2 = pSrc[mbOff + idxCC[0][pxOff]]; // top MB boundary - else{ - // last row of previous MB row - d0 = pBuf[0][iColumn], d1 = pBuf[1][iColumn], d2 = pBuf[2][iColumn], d3 = pBuf[3][iColumn], d4 = pSrc[mbOff + idxCC[0][pxOff]]; - pSC->p0MBbuffer[iChannel][((iColumn >> 3) << 6) + idxCC_420[7][iColumn & 7]] = DF_ODD; - - // for first row of current MB - d0 = pBuf[2][iColumn], d1 = pBuf[3][iColumn]; - d2 = pSrc[mbOff + idxCC[0][pxOff]], d3 = pSrc[mbOff + idxCC[1][pxOff]], d4 = pSrc[mbOff + idxCC[2][pxOff]]; - } - - for(iRow = 0; iRow < 12; iRow += 2){ - pDst[((iColumn >> 3) << 6) + idxCC_420[iRow >> 1][iColumn & 7]] = DF_ODD; - d0 = d2, d1 = d3, d2 = d4; - d3 = pSrc[mbOff + idxCC[iRow + 3][pxOff]]; - d4 = pSrc[mbOff + idxCC[iRow + 4][pxOff]]; - } - - //last row of current MB - pDst[((iColumn >> 3) << 6) + idxCC_420[6][iColumn & 7]] = DF_ODD; - d0 = d2, d1 = d3, d2 = d4; - d3 = pSrc[mbOff + idxCC[iRow + 3][pxOff]]; - - if(pSC->cRow + 1 == pSC->cmbHeight){ // bottom image boundary - d4 = d2; - pDst[((iColumn >> 3) << 6) + idxCC_420[7][iColumn & 7]] = DF_ODD; - } - else{ - for(iRow = 0; iRow < 4; iRow ++) - pBuf[iRow][iColumn] = pSrc[mbOff + idxCC[iRow + 12][pxOff]]; - } - } - } - } -} - -// centralized horizontal padding -Void padHorizontally(CWMImageStrCodec * pSC) -{ - if(pSC->WMII.cWidth != pSC->cmbWidth * 16){ // horizontal padding is necessary! - const COLORFORMAT cfExt = pSC->WMISCP.bYUVData ? - pSC->m_param.cfColorFormat : pSC->WMII.cfColorFormat; - size_t cFullChannel = pSC->WMISCP.cChannel; - size_t iLast = pSC->WMII.cWidth - 1; - PixelI * pCh[16]; - size_t iChannel, iColumn, iRow; - - if(cfExt == YUV_420 || cfExt == YUV_422 || cfExt == Y_ONLY) - cFullChannel = 1; - - assert(cFullChannel <= 16); - - assert(pSC->WMISCP.cChannel <= 16); - for(iChannel = 0; iChannel < pSC->WMISCP.cChannel; iChannel ++) - pCh[iChannel & 15] = pSC->p1MBbuffer[iChannel & 15]; - - if(pSC->m_bUVResolutionChange) - pCh[1] = pSC->pResU, pCh[2] = pSC->pResV; - - // pad full resoluton channels - for(iRow = 0; iRow < 16; iRow ++){ - const size_t iPosLast = ((iLast >> 4) << 8) + idxCC[iRow][iLast & 0xf]; - for(iColumn = iLast + 1; iColumn < pSC->cmbWidth * 16; iColumn ++){ - const size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - for(iChannel = 0; iChannel < cFullChannel; iChannel ++) - pCh[iChannel & 15][iPos] = pCh[iChannel & 15][iPosLast]; - } - } - - if(cfExt == YUV_422) // pad YUV_422 UV - for(iLast >>= 1, iRow = 0; iRow < 16; iRow ++){ - const size_t iPosLast = ((iLast >> 3) << 7) + idxCC[iRow][iLast & 7]; - for(iColumn = iLast + 1; iColumn < pSC->cmbWidth * 8; iColumn ++){ - const size_t iPos = ((iColumn >> 3) << 7) + idxCC[iRow][iColumn & 7]; - for(iChannel = 1; iChannel < 3; iChannel ++) - pCh[iChannel][iPos] = pCh[iChannel][iPosLast]; - } - } - else if(cfExt == YUV_420) // pad YUV_420 UV - for(iLast >>= 1, iRow = 0; iRow < 8; iRow ++){ - const size_t iPosLast = ((iLast >> 3) << 6) + idxCC_420[iRow][iLast & 7]; - for(iColumn = iLast + 1; iColumn < pSC->cmbWidth * 8; iColumn ++){ - const size_t iPos = ((iColumn >> 3) << 6) + idxCC_420[iRow][iColumn & 7]; - for(iChannel = 1; iChannel < 3; iChannel ++) - pCh[iChannel][iPos] = pCh[iChannel][iPosLast]; - } - } - } -} - -// centralized alpha channel color conversion, small perf penalty -Int inputMBRowAlpha(CWMImageStrCodec* pSC) -{ - if(pSC->m_bSecondary == FALSE && pSC->m_pNextSC != NULL){ // alpha channel is present - const size_t cShift = (pSC->m_pNextSC->m_param.bScaledArith ? (SHIFTZERO + QPFRACBITS) : 0); - const BITDEPTH_BITS bdExt = pSC->WMII.bdBitDepth; - const size_t iAlphaPos = pSC->WMII.cLeadingPadding + (pSC->WMII.cfColorFormat == CMYK ? 4 : 3);//only RGB and CMYK may have interleaved alpha - const size_t cRow = pSC->WMIBI.cLine; - const size_t cColumn = pSC->WMII.cWidth; - const U8 * pSrc0 = (U8 *)pSC->WMIBI.pv; - PixelI * pA = pSC->m_pNextSC->p1MBbuffer[0]; - size_t iRow, iColumn; - - for(iRow = 0; iRow < 16; iRow ++){ - if(bdExt == BD_8){ - const size_t cStride = (pSC->WMII.cBitsPerUnit >> 3); - const U8 * pSrc = pSrc0; - - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride) - pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] = ((PixelI)pSrc[iAlphaPos] - (1 << 7)) << cShift; - } - else if(bdExt == BD_16){ - const size_t cStride = (pSC->WMII.cBitsPerUnit >> 3) / sizeof(U16); - const U8 nLenMantissaOrShift = pSC->m_pNextSC->WMISCP.nLenMantissaOrShift; - const U16 * pSrc = (U16 *)pSrc0; - - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride) - pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] = ((((PixelI)pSrc[iAlphaPos] - (1 << 15)) >> nLenMantissaOrShift) << cShift); - } - else if(bdExt == BD_16S){ - const size_t cStride = (pSC->WMII.cBitsPerUnit >> 3) / sizeof(I16); - const U8 nLenMantissaOrShift = pSC->m_pNextSC->WMISCP.nLenMantissaOrShift; - const I16 * pSrc = (I16 *)pSrc0; - - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride) - pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] = (((PixelI)pSrc[iAlphaPos] >> nLenMantissaOrShift) << cShift); - } - else if(bdExt == BD_16F){ - const size_t cStride = (pSC->WMII.cBitsPerUnit >> 3) / sizeof(U16); - const I16 * pSrc = (I16 *)pSrc0; - - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride) - pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] = forwardHalf (pSrc[iAlphaPos]) << cShift; - } - else if(bdExt == BD_32S){ - const size_t cStride = (pSC->WMII.cBitsPerUnit >> 3) / sizeof(I32); - const U8 nLenMantissaOrShift = pSC->m_pNextSC->WMISCP.nLenMantissaOrShift; - const I32 * pSrc = (I32 *)pSrc0; - - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride) - pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] = (((PixelI)pSrc[iAlphaPos] >> nLenMantissaOrShift) << cShift); - } - else if(bdExt == BD_32F){ - const size_t cStride = (pSC->WMII.cBitsPerUnit >> 3) / sizeof(float); - const U8 nLen = pSC->m_pNextSC->WMISCP.nLenMantissaOrShift; - const I8 nExpBias = pSC->m_pNextSC->WMISCP.nExpBias; - const float * pSrc = (float *)pSrc0; - - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride) - pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] = float2pixel (pSrc[iAlphaPos], nExpBias, nLen) << cShift; - } - else // not supported - return ICERR_ERROR; - - if(iRow + 1 < cRow) // vertical padding! - pSrc0 += pSC->WMIBI.cbStride; - - for(iColumn = cColumn; iColumn < pSC->cmbWidth * 16; iColumn ++) // horizontal padding - pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] = pA[(((cColumn - 1) >> 4) << 8) + idxCC[iRow][(cColumn - 1) & 0xf]]; - } - } - - return ICERR_OK; -} - -// input one MB row of image data from input buffer -Int inputMBRow(CWMImageStrCodec* pSC) -{ - const size_t cShift = (pSC->m_param.bScaledArith ? (SHIFTZERO + QPFRACBITS) : 0); - const BITDEPTH_BITS bdExt = pSC->WMII.bdBitDepth; - COLORFORMAT cfExt = pSC->WMII.cfColorFormat; - const COLORFORMAT cfInt = pSC->m_param.cfColorFormat; - const size_t cPixelStride = (pSC->WMII.cBitsPerUnit >> 3); - const size_t iRowStride = - (cfExt == YUV_420 || (pSC->WMISCP.bYUVData && pSC->m_param.cfColorFormat==YUV_420)) ? 2 : 1; - const size_t cRow = pSC->WMIBI.cLine; - const size_t cColumn = pSC->WMII.cWidth; - const size_t iB = (pSC->WMII.bRGB ? 2 : 0); - const size_t iR = 2 - iB; - const U8 * pSrc0 = (U8 *)pSC->WMIBI.pv; - const U8 nLen = pSC->WMISCP.nLenMantissaOrShift; - const I8 nExpBias = pSC->WMISCP.nExpBias; - - PixelI *pY = pSC->p1MBbuffer[0], *pU = pSC->p1MBbuffer[1], *pV = pSC->p1MBbuffer[2]; - size_t iRow, iColumn, iPos; - - // guard input buffer - if(checkImageBuffer(pSC, cColumn, cRow) != ICERR_OK) - return ICERR_ERROR; - - if(pSC->m_bUVResolutionChange) // will do downsampling somewhere else! - pU = pSC->pResU, pV = pSC->pResV; - else if(cfInt == Y_ONLY) // xxx to Y_ONLY transcoding! - pU = pV = pY; // write pY AFTER pU and pV so Y will overwrite U&V - - for(iRow = 0; iRow < 16; iRow += iRowStride){ - if (pSC->WMISCP.bYUVData){ - I32 * pSrc = (I32 *)pSrc0 + pSC->WMII.cLeadingPadding; - - switch(pSC->m_param.cfColorFormat){ - case Y_ONLY: - case YUV_444: - case NCOMPONENT: - { - const size_t cChannel = pSC->m_param.cNumChannels; - PixelI * pChannel[16]; - size_t iChannel; - - assert(cChannel <= 16); - for(iChannel = 0; iChannel < cChannel; iChannel ++) - pChannel[iChannel & 15] = pSC->p1MBbuffer[iChannel & 15]; - if(pSC->m_bUVResolutionChange) - pChannel[1] = pSC->pResU, pChannel[2] = pSC->pResV; - - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cChannel){ - iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - for(iChannel = 0; iChannel < cChannel; iChannel ++) - pChannel[iChannel & 15][iPos] = (PixelI)pSrc[iChannel & 15]; - } - } - break; - - case YUV_422: - for(iColumn = 0; iColumn < cColumn; iColumn += 2, pSrc += 4){ - if(cfInt != Y_ONLY){ - iPos = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7]; - pU[iPos] = (PixelI)pSrc[0]; - pV[iPos] = (PixelI)pSrc[2]; - } - - pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] = (PixelI)pSrc[1]; - pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] = (PixelI)pSrc[3]; - } - break; - - case YUV_420: - for(iColumn = 0; iColumn < cColumn; iColumn += 2, pSrc += 6){ - if(cfInt != Y_ONLY){ - iPos = ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7]; - pU[iPos] = (PixelI)pSrc[4]; - pV[iPos] = (PixelI)pSrc[5]; - } - - pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] = (PixelI)pSrc[0]; - pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] = (PixelI)pSrc[1]; - pY[((iColumn >> 4) << 8) + idxCC[iRow + 1][iColumn & 15]] = (PixelI)pSrc[2]; - pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow + 1][(iColumn + 1) & 15]] = (PixelI)pSrc[3]; - } - break; - - default: - assert(0); - break; - } - } - else if(bdExt == BD_8){ - const U8 * pSrc = pSrc0 + pSC->WMII.cLeadingPadding; - const PixelI iOffset = (128 << cShift); - - switch(cfExt){ - case CF_RGB: - assert (pSC->m_bSecondary == FALSE); - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cPixelStride){ - PixelI r = ((PixelI)pSrc[iR]) << cShift, g = ((PixelI)pSrc[1]) << cShift, b = ((PixelI)pSrc[iB]) << cShift; - - _CC(r, g, b); // color conversion - - iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g - iOffset; - } - break; - - case Y_ONLY: - case YUV_444: - case NCOMPONENT: - { - const size_t cChannel = pSC->m_param.cNumChannels; - PixelI * pChannel[16]; - size_t iChannel; - - assert(cChannel <= 16); - for(iChannel = 0; iChannel < cChannel; iChannel ++) - pChannel[iChannel & 15] = pSC->p1MBbuffer[iChannel & 15]; - if(pSC->m_bUVResolutionChange) - pChannel[1] = pSC->pResU, pChannel[2] = pSC->pResV; - - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cPixelStride){ - iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - for(iChannel = 0; iChannel < cChannel; iChannel ++) - pChannel[iChannel & 15][iPos] = (((PixelI)pSrc[iChannel & 15]) << cShift) - iOffset; - } - break; - } - - case CF_RGBE: - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cPixelStride){ - PixelI iExp = (PixelI)pSrc[3]; - PixelI r = forwardRGBE (pSrc[0], iExp) << cShift; - PixelI g = forwardRGBE (pSrc[1], iExp) << cShift; - PixelI b = forwardRGBE (pSrc[2], iExp) << cShift; - - _CC(r, g, b); - - iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g; - } - break; - - case CMYK: - { - PixelI * pK = (cfInt == CMYK ? pSC->p1MBbuffer[3] : pY); // CMYK -> YUV_xxx transcoding! - - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cPixelStride){ - PixelI c = ((PixelI)pSrc[0]) << cShift; - PixelI m = ((PixelI)pSrc[1]) << cShift; - PixelI y = ((PixelI)pSrc[2]) << cShift; - PixelI k = ((PixelI)pSrc[3]) << cShift; - - _CC_CMYK(c, m, y, k); - - iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - pU[iPos] = c, pV[iPos] = -y, pK[iPos] = k, pY[iPos] = iOffset - m; - } - break; - } - - case YUV_422: - for(iColumn = 0; iColumn < cColumn; iColumn += 2, pSrc += cPixelStride){ - if(cfInt != Y_ONLY){ - iPos = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7]; - pU[iPos] = (((PixelI)pSrc[0]) << cShift) - iOffset; - pV[iPos] = (((PixelI)pSrc[2]) << cShift) - iOffset; - } - - pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] = (((PixelI)pSrc[1]) << cShift) - iOffset; - pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] = (((PixelI)pSrc[3]) << cShift) - iOffset; - } - break; - - case YUV_420: - for(iColumn = 0; iColumn < cColumn; iColumn += 2, pSrc += cPixelStride){ - if(cfInt != Y_ONLY){ - iPos = ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7]; - pU[iPos] = (((PixelI)pSrc[4]) << cShift) - iOffset; - pV[iPos] = (((PixelI)pSrc[5]) << cShift) - iOffset; - } - - pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] = (((PixelI)pSrc[0]) << cShift) - iOffset; - pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] = (((PixelI)pSrc[1]) << cShift) - iOffset; - pY[((iColumn >> 4) << 8) + idxCC[iRow + 1][iColumn & 15]] = (((PixelI)pSrc[2]) << cShift) - iOffset; - pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow + 1][(iColumn + 1) & 15]] = (((PixelI)pSrc[3]) << cShift) - iOffset; - } - break; - - default: - assert(0); - break; - } - } - else if(bdExt == BD_16){ - const U16 * pSrc = (U16 *)pSrc0 + pSC->WMII.cLeadingPadding; - const size_t cStride = cPixelStride / sizeof(U16); - const PixelI iOffset = ((1 << 15) >> nLen) << cShift; - - switch(cfExt){ - case CF_RGB: - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){ - PixelI r = ((PixelI)pSrc[0] >> nLen) << cShift, g = ((PixelI)pSrc[1] >> nLen) << cShift, b = ((PixelI)pSrc[2] >> nLen) << cShift; - - _CC(r, g, b); // color conversion - - iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g - iOffset; - } - break; - - case Y_ONLY: - case YUV_444: - case NCOMPONENT: - { - const size_t cChannel = pSC->WMISCP.cChannel; - size_t iChannel; - - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){ - iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - for(iChannel = 0; iChannel < cChannel; iChannel ++) - pSC->p1MBbuffer[iChannel][iPos] = (((PixelI)pSrc[iChannel] >> nLen) << cShift) - iOffset; - } - break; - } - - case CMYK: - { - PixelI * pK = (cfInt == CMYK ? pSC->p1MBbuffer[3] : pY); // CMYK -> YUV_xxx transcoding! - - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){ - PixelI c = ((PixelI)pSrc[0] >> nLen) << cShift; - PixelI m = ((PixelI)pSrc[1] >> nLen) << cShift; - PixelI y = ((PixelI)pSrc[2] >> nLen) << cShift; - PixelI k = ((PixelI)pSrc[3] >> nLen) << cShift; - - _CC_CMYK(c, m, y, k); - - iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - pU[iPos] = c, pV[iPos] = -y, pK[iPos] = k, pY[iPos] = iOffset - m; - } - break; - } - - case YUV_422: - for(iColumn = 0; iColumn < cColumn; iColumn += 2, pSrc += cStride){ - if(cfInt != Y_ONLY){ - iPos = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7]; - pU[iPos] = (((PixelI)pSrc[0]) << cShift) - iOffset; - pV[iPos] = (((PixelI)pSrc[2]) << cShift) - iOffset; - } - - pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] = (((PixelI)pSrc[1]) << cShift) - iOffset; - pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] = (((PixelI)pSrc[3]) << cShift) - iOffset; - } - break; - - case YUV_420: - for(iColumn = 0; iColumn < cColumn; iColumn += 2, pSrc += cStride){ - if(cfInt != Y_ONLY){ - iPos = ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7]; - pU[iPos] = (((PixelI)pSrc[4]) << cShift) - iOffset; - pV[iPos] = (((PixelI)pSrc[5]) << cShift) - iOffset; - } - - pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] = (((PixelI)pSrc[0]) << cShift) - iOffset; - pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] = (((PixelI)pSrc[1]) << cShift) - iOffset; - pY[((iColumn >> 4) << 8) + idxCC[iRow + 1][iColumn & 15]] = (((PixelI)pSrc[2]) << cShift) - iOffset; - pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow + 1][(iColumn + 1) & 15]] = (((PixelI)pSrc[3]) << cShift) - iOffset; - } - break; - - default: - assert(0); - break; - } - } - else if(bdExt == BD_16S){ - const I16 * pSrc = (I16 *)pSrc0 + pSC->WMII.cLeadingPadding; - const size_t cStride = cPixelStride / sizeof(I16); - - switch(cfExt){ - case CF_RGB: - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){ - PixelI r = ((PixelI)pSrc[0] >> nLen) << cShift, g = ((PixelI)pSrc[1] >> nLen) << cShift, b = ((PixelI)pSrc[2] >> nLen) << cShift; - - _CC(r, g, b); // color conversion - - iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g; - } - break; - - case Y_ONLY: - case YUV_444: - case NCOMPONENT: - { - const size_t cChannel = pSC->WMISCP.cChannel; - size_t iChannel; - - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){ - iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - for(iChannel = 0; iChannel < cChannel; iChannel ++) - pSC->p1MBbuffer[iChannel][iPos] = (((PixelI)pSrc[iChannel] >> nLen) << cShift); - } - } - break; - - case CMYK: - { - PixelI * pK = (cfInt == CMYK ? pSC->p1MBbuffer[3] : pY); // CMYK -> YUV_xxx transcoding! - - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){ - PixelI c = ((PixelI)pSrc[0] >> nLen) << cShift; - PixelI m = ((PixelI)pSrc[1] >> nLen) << cShift; - PixelI y = ((PixelI)pSrc[2] >> nLen) << cShift; - PixelI k = ((PixelI)pSrc[3] >> nLen) << cShift; - - _CC_CMYK(c, m, y, k); - - iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - pU[iPos] = c, pV[iPos] = -y, pK[iPos] = k, pY[iPos] = -m; - } - } - break; - - default: - assert(0); - break; - } - } - else if(bdExt == BD_16F){ - const I16 * pSrc = (I16 *)pSrc0 + pSC->WMII.cLeadingPadding; - const size_t cStride = cPixelStride / sizeof(U16); - - switch(cfExt){ - case CF_RGB: - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){ - PixelI r = forwardHalf (pSrc[0]) << cShift; - PixelI g = forwardHalf (pSrc[1]) << cShift; - PixelI b = forwardHalf (pSrc[2]) << cShift; - - _CC(r, g, b); // color conversion - - iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g; - } - break; - - case Y_ONLY: - case YUV_444: - case NCOMPONENT: - { - const size_t cChannel = pSC->WMISCP.cChannel; // check xxx => Y_ONLY transcoding! - size_t iChannel; - - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){ - iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - for(iChannel = 0; iChannel < cChannel; iChannel ++) - pSC->p1MBbuffer[iChannel][iPos] = forwardHalf (pSrc[iChannel]) << cShift; - } - } - break; - - default: - assert(0); - break; - } - } - else if(bdExt == BD_32){ - const U32 * pSrc = (U32 *)pSrc0 + pSC->WMII.cLeadingPadding; - const size_t cStride = cPixelStride / sizeof(U32); - const PixelI iOffset = ((1 << 31) >> nLen) << cShift; - - switch(cfExt){ - case CF_RGB: - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){ - PixelI r = (pSrc[0] >> nLen) << cShift, g = (pSrc[1] >> nLen) << cShift, b = (pSrc[2] >> nLen) << cShift; - - _CC(r, g, b); // color conversion - - iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g - iOffset; - } - break; - - case Y_ONLY: - case YUV_444: - case NCOMPONENT: - { - const size_t cChannel = pSC->WMISCP.cChannel; - size_t iChannel; - - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){ - iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - for(iChannel = 0; iChannel < cChannel; iChannel ++) - pSC->p1MBbuffer[iChannel][iPos] = (pSrc[iChannel] >> nLen) << cShift; - } - break; - } - - default: - assert(0); - break; - } - } - else if(bdExt == BD_32S){ - const I32 * pSrc = (I32 *)pSrc0 + pSC->WMII.cLeadingPadding; - const size_t cStride = cPixelStride / sizeof(I32); - - switch(cfExt){ - case CF_RGB: - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){ - PixelI r = (pSrc[0] >> nLen)<< cShift, g = (pSrc[1] >> nLen)<< cShift, b = (pSrc[2] >> nLen)<< cShift; - - _CC(r, g, b); // color conversion - - iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g; - } - break; - - case Y_ONLY: - case YUV_444: - case NCOMPONENT: - { - const size_t cChannel = pSC->WMISCP.cChannel; // check xxx => Y_ONLY transcoding! - size_t iChannel; - - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){ - iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - for(iChannel = 0; iChannel < cChannel; iChannel ++) - pSC->p1MBbuffer[iChannel][iPos] = (pSrc[iChannel] >> nLen) << cShift; - } - } - break; - - default: - assert(0); - break; - } - } - else if(bdExt == BD_32F){ - const float * pSrc = (float *)pSrc0 + pSC->WMII.cLeadingPadding; - const size_t cStride = cPixelStride / sizeof(float); - - switch(cfExt){ - case CF_RGB: - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){ - PixelI r = float2pixel (pSrc[0], nExpBias, nLen) << cShift; - PixelI g = float2pixel (pSrc[1], nExpBias, nLen) << cShift; - PixelI b = float2pixel (pSrc[2], nExpBias, nLen) << cShift; - - _CC(r, g, b); // color conversion - - iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g; - } - break; - - case Y_ONLY: - case YUV_444: - case NCOMPONENT: - { - const size_t cChannel = pSC->WMISCP.cChannel; - size_t iChannel; - - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){ - iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - for(iChannel = 0; iChannel < cChannel; iChannel ++) - pSC->p1MBbuffer[iChannel][iPos] = float2pixel (pSrc[iChannel], nExpBias, nLen) << cShift; - } - } - break; - default: - assert(0); - break; - } - } - else if(bdExt == BD_5){ // RGB 555, work for both big endian and small endian! - const U8 * pSrc = pSrc0; - const PixelI iOffset = (16 << cShift); - - assert(cfExt == CF_RGB); - - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cPixelStride){ - PixelI r = (PixelI)pSrc[0], g = (PixelI)pSrc[1], b = ((g >> 2) & 0x1F) << cShift; - - g = ((r >> 5) + ((g & 3) << 3)) << cShift, r = (r & 0x1F) << cShift; - - _CC(r, g, b); // color conversion - - iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g - iOffset; - } - } - else if(bdExt == BD_565){ // RGB 555, work for both big endian and small endian! - const U8 * pSrc = pSrc0; - const PixelI iOffset = (32 << cShift); - - assert(cfExt == CF_RGB); - - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cPixelStride){ - PixelI r = (PixelI)pSrc[0], g = (PixelI)pSrc[1], b = (g >> 3) << (cShift + 1); - - g = ((r >> 5) + ((g & 7) << 3)) << cShift, r = (r & 0x1F) << (cShift + 1); - - _CC(r, g, b); // color conversion - - iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g - iOffset; - } - } - else if(bdExt == BD_10){ //RGB 101010, work for both big endian and small endian! - const U8 * pSrc = pSrc0; - const PixelI iOffset = (512 << cShift); - - assert(cfExt == CF_RGB); - - for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cPixelStride){ - PixelI r = (PixelI)pSrc[0], g = (PixelI)pSrc[1], b = (PixelI)pSrc[2]; - - r = (r + ((g & 3) << 8)) << cShift, g = ((g >> 2) + ((b & 0xF) << 6)) << cShift; - b = ((b >> 4) + (((PixelI)pSrc[3] & 0x3F) << 4)) << cShift; - - _CC(r, g, b); // color conversion - - iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]; - pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g - iOffset; - } - } - else if(bdExt == BD_1){ - assert(cfExt == Y_ONLY); - for(iColumn = 0; iColumn < cColumn; iColumn ++) { - pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] = ((pSC->WMISCP.bBlackWhite + (pSrc0[iColumn >> 3] >> (7 - (iColumn & 7)))) & 1) << cShift; - } - } - - if(iRow + iRowStride < cRow) // centralized vertical padding! - pSrc0 += pSC->WMIBI.cbStride; - } - - padHorizontally(pSC); // centralized horizontal padding - - // centralized down-sampling - if(pSC->m_bUVResolutionChange) - downsampleUV(pSC); - - // centralized alpha channel handdling - if (pSC->WMISCP.uAlphaMode == 3) - if(inputMBRowAlpha(pSC) != ICERR_OK) - return ICERR_ERROR; - - return ICERR_OK; -} - - diff --git a/Src/JxrDecode/Jxr/strenc_x86.c b/Src/JxrDecode/Jxr/strenc_x86.c deleted file mode 100644 index a552fec5..00000000 --- a/Src/JxrDecode/Jxr/strenc_x86.c +++ /dev/null @@ -1,409 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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" - -#if defined(WMP_OPT_SSE2) -#include -#include - -//================================ -__m128i g_const_d1; -__m128i g_const_d0x400; -__m128i g_const_d0x7f8; - -//================================ -#if defined(WMP_OPT_CC_ENC) -__declspec(naked) void __stdcall RGB24_6( - const U8* pbRGB, - size_t cbRGB, - U8* pbYCoCg, - size_t cbYCoCg, - size_t cmb) -{ - UNREFERENCED_PARAMETER( pbRGB ); - UNREFERENCED_PARAMETER( cbRGB ); - UNREFERENCED_PARAMETER( pbYCoCg ); - UNREFERENCED_PARAMETER( cbYCoCg ); - UNREFERENCED_PARAMETER( cmb ); - __asm { - push ebp - push ebx - push esi - push edi - - mov ebp, [esp + 36] // $ebp = cmb - mov edx, [esp + 20] // $edx = pbRGB - lea ebp, [ebp + ebp * 2] // $ebp = cmb * 3 - mov ecx, [esp + 24] // $ecx = cbRGB - shl ebp, 4 // $ebp = cmb * 3 * 16 - mov edi, [esp + 28] // $edi = pbYCoCg - add edx, ebp // $edx = pbRGB + 3 * 16 * cmb - mov ebx, [esp + 32] // $ebx = cbYCoCg - neg ebp - - mov eax, esp - and esp, 0xffffff80 - sub esp, 64 + 4 * 6 - - mov [esp], ecx // cbRGB - mov [esp + 4], edx // pbRGB + 3 * 16 * cmb - mov [esp + 8], edi // pbYCoCg - mov dword ptr [esp + 12], 4 // cLoop0 = 4 - mov [esp + 16], ebp // -3 * 16 * cmb - mov [esp + 20], eax // original $esp - movdqa xmm3, [g_const_d1] - } -Loop0: - __asm mov edi, [esp + 8] // $edi = pbYCoCg - __asm mov ebp, [esp + 16] // $ebp = -3 * 16 * cmb - -Loop1: - __asm { - mov esi, [esp + 4] // $esi = pbRGB + 3 * 16 * cmb - - //================ - // scanline 0 - mov eax, [esi + ebp] - mov edx, [esi + ebp + 4] - mov ecx, [esi + ebp + 8] - add esi, [esp] // $esi += cbRGB - - mov [esp + 24], eax - shrd eax, edx, 24 - shrd edx, ecx, 16 - shr ecx, 8 - mov [esp + 24 + 4], eax - mov [esp + 24 + 20], edx - mov [esp + 24 + 16], ecx - - // scanline 1 - mov eax, [esi + ebp] - mov edx, [esi + ebp + 4] - mov ecx, [esi + ebp + 8] - add esi, [esp] - - mov [esp + 24 + 8], eax - shrd eax, edx, 24 - shrd edx, ecx, 16 - shr ecx, 8 - mov [esp + 24 + 12], eax - mov [esp + 24 + 28], edx - mov [esp + 24 + 24], ecx - - // scanline 2 - mov eax, [esi + ebp] - mov edx, [esi + ebp + 4] - mov ecx, [esi + ebp + 8] - add esi, [esp] - - mov [esp + 24 + 40], eax - shrd eax, edx, 24 - shrd edx, ecx, 16 - shr ecx, 8 - mov [esp + 24 + 44], eax - mov [esp + 24 + 60], edx - mov [esp + 24 + 56], ecx - - // scanline 3 - mov eax, [esi + ebp] - mov edx, [esi + ebp + 4] - mov ecx, [esi + ebp + 8] - add esi, [esp] - - mov [esp + 24 + 32], eax - shrd eax, edx, 24 - shrd edx, ecx, 16 - shr ecx, 8 - mov [esp + 24 + 36], eax - mov [esp + 24 + 52], edx - mov [esp + 24 + 48], ecx - - //================ - // CC 0,1 - movdqa xmm0, [esp + 24] - movdqa xmm4, [esp + 24 + 16] - movdqa xmm7, [g_const_d0x7f8] - movdqa xmm1, xmm0 - movdqa xmm5, xmm4 - movdqa xmm2, xmm0 - movdqa xmm6, xmm4 - - pslld xmm0, 3 - pslld xmm4, 3 - psrad xmm5, 5 - psrad xmm1, 5 - psrad xmm2, 13 - psrad xmm6, 13 - pand xmm0, xmm7 // R - pand xmm4, xmm7 - pand xmm1, xmm7 // G - pand xmm5, xmm7 - pand xmm2, xmm7 // B - pand xmm6, xmm7 - - psubd xmm2, xmm0 // b -= r - psubd xmm6, xmm4 - movntdq [edi + ebx * 2], xmm2 - movntdq [edi + ebx * 2 + 16], xmm6 - - paddd xmm2, xmm3 // r += ((b + 1) >> 1) - g - paddd xmm6, xmm3 - psubd xmm0, xmm1 - psubd xmm4, xmm5 - psrad xmm2, 1 - psrad xmm6, 1 - paddd xmm0, xmm2 - paddd xmm4, xmm6 - - movdqa xmm2, xmm0 // g += r >> 1 - movdqa xmm6, xmm4 - movdqa xmm7, [g_const_d0x400] - psrad xmm2, 1 - psrad xmm6, 1 - paddd xmm1, xmm2 - paddd xmm5, xmm6 - - pxor xmm2, xmm2 - pxor xmm6, xmm6 - psubd xmm1, xmm7 // g -= offset - psubd xmm5, xmm7 - psubd xmm2, xmm0 // r = -r - psubd xmm6, xmm4 - - movntdq [edi], xmm1 - movntdq [edi + 16], xmm5 - movntdq [edi + ebx], xmm2 - movntdq [edi + ebx + 16], xmm6 - - //================ - // CC 2,3 - movdqa xmm4, [esp + 24 + 48] - movdqa xmm0, [esp + 24 + 32] - movdqa xmm7, [g_const_d0x7f8] - movdqa xmm1, xmm0 - movdqa xmm5, xmm4 - movdqa xmm2, xmm0 - movdqa xmm6, xmm4 - - pslld xmm0, 3 - pslld xmm4, 3 - psrad xmm1, 5 - psrad xmm5, 5 - psrad xmm2, 13 - psrad xmm6, 13 - pand xmm0, xmm7 // R - pand xmm4, xmm7 - pand xmm1, xmm7 // G - pand xmm5, xmm7 - pand xmm2, xmm7 // B - pand xmm6, xmm7 - - psubd xmm2, xmm0 // b -= r - psubd xmm6, xmm4 - movntdq [edi + ebx * 2 + 32], xmm2 - movntdq [edi + ebx * 2 + 48], xmm6 - - paddd xmm2, xmm3 // r += ((b + 1) >> 1) - g - paddd xmm6, xmm3 - psubd xmm0, xmm1 - psubd xmm4, xmm5 - psrad xmm2, 1 - psrad xmm6, 1 - paddd xmm0, xmm2 - paddd xmm4, xmm6 - - movdqa xmm2, xmm0 // g += r >> 1 - movdqa xmm6, xmm4 - movdqa xmm7, [g_const_d0x400] - psrad xmm2, 1 - psrad xmm6, 1 - paddd xmm1, xmm2 - paddd xmm5, xmm6 - - pxor xmm2, xmm2 - pxor xmm6, xmm6 - psubd xmm1, xmm7 // g -= offset - psubd xmm5, xmm7 - psubd xmm2, xmm0 // r = -r - psubd xmm6, xmm4 - - movntdq [edi + 32], xmm1 - movntdq [edi + 48], xmm5 - movntdq [edi + ebx + 32], xmm2 - movntdq [edi + ebx + 48], xmm6 - - //================ - add edi, 256 // pbYCoCg += 256 - add ebp, 12 // pbRGB += 12 - jnz Loop1 - - //================ - add dword ptr [esp + 8], 64 // pbYCoCg += 64 - sub dword ptr [esp + 12], 1 // --cLoop0 - mov [esp + 4], esi // pbRGB += cbRGB * 4 - jnz Loop0 - - //================ - mov esp, [esp + 20] - pop edi - pop esi - pop ebx - pop ebp - ret 20 - } -} - -Int inputMBRow_RGB24_6(CWMImageStrCodec* pSC) -{ - const U8* const pbRGB = (U8*)pSC->WMIBI.pv; - const size_t cbRGB = pSC->WMIBI.cbStride; - - U8* const pbY = (U8*)pSC->p1MBbuffer[0]; - U8* const pbU = (U8*)pSC->p1MBbuffer[1]; - // U8* const pbV = (U8*)pSC->p1MBbuffer[2]; - - const size_t cmbColumn = (pSC->WMII.cWidth + 15) / 16; - - assert(BD_8 == pSC->WMII.bdBitDepth); - assert(CF_RGB == pSC->WMII.cfColorFormat); - assert(24 == pSC->WMII.cBitsPerUnit); - assert(pSC->WMII.bRGB); - assert(pSC->m_param.bScaledArith); - assert(pbU - pbY == pbV - pbU); - - RGB24_6(pbRGB + cbRGB * 0, cbRGB, pbY, pbU - pbY, cmbColumn); - return ICERR_OK; -} -#endif - -//================================ -#if defined(WMP_OPT_QT) -#if 0 -Int quantizeMacroblock(CWMImageStrCodec* pSC) -{ - assert(BD_8 == pSC->WMII.bdBitDepth); - assert(YUV_444 == pSC->m_param.cfColorFormat); - assert(pSC->m_param.bScaledArith); - assert(3 == pSC->m_param.cNumChannels); - assert(SB_ALL == pSC->WMISCP.sbSubband); - - CWMITile* pTile = pSC->pTile + pSC->cTileColumn; - CWMIMBInfo* pMBInfo = &pSC->MBInfo; - int iChannel, i, j; - - __m128 owQT[2]; - - - - for (iChannel = 0; iChannel < 3; iChannel ++) { - CWMIQuantizer* pQPDC = pTile->pQuantizerDC[iChannel]; - CWMIQuantizer* pQPLP = pTile->pQuantizerLP[iChannel] + pMBInfo->iQIndexLP; - CWMIQuantizer* pQPHP = pTile->pQuantizerHP[iChannel] + pMBInfo->iQIndexHP; - - __m128 owQT[4] = { - {pQPDC->f1_QP, pQPHP->f1_QP, pQPHP->f1_QP, pQPHP->f1_QP,}, - {pQPLP->f1_QP, pQPHP->f1_QP, pQPHP->f1_QP, pQPHP->f1_QP,}, - }; - - owQT[0].m128_f32[0] = pQPDC->f1_QP; - owQT[0].m128_f32[1] = pQPHP->f1_QP; - owQT[0].m128_f32[2] = pQPHP->f1_QP; - owQT[0].m128_f32[3] = pQPHP->f1_QP; - owQT[1].m128_f32[0] = pQPDC->f1_QP; - owQT[1].m128_f32[1] = pQPHP->f1_QP; - owQT[1].m128_f32[2] = pQPHP->f1_QP; - owQT[1].m128_f32[3] = pQPHP->f1_QP; - - - - - for(j = 0; j < 16; j ++){ - PixelI* pData = pSC->pPlane[iChannel] + blkOffset[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 // 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 - 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 < 3; iChannel ++) { - I32* pDC = pSC->MBInfo.iBlockDC[iChannel]; - PixelI* pData = pSC->pPlane[iChannel]; - - for(i = 0; i < 16; i ++){ - pDC[i] = pData[dctIndex[2][i]]; - } - } - - return 0; -} -#endif -#endif -#endif - - -//================================ -void StrEncOpt(CWMImageStrCodec* pSC) -{ -#if defined(WMP_OPT_SSE2) - if (IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE) && - pSC->WMII.fPaddedUserBuffer && - 1) - { - CWMImageInfo* pII = &pSC->WMII; - // CWMIStrCodecParam* pSCP = &pSC->WMISCP; - - g_const_d1 = _mm_set_epi32(1, 1, 1, 1); - g_const_d0x400 = _mm_set_epi32(0x400, 0x400, 0x400, 0x400); - g_const_d0x7f8 = _mm_set_epi32(0x7f8, 0x7f8, 0x7f8, 0x7f8); - - if (BD_8 == pII->bdBitDepth && - CF_RGB == pII->cfColorFormat && - YUV_444 == pSC->m_param.cfColorFormat && - 24 == pII->cBitsPerUnit && - pII->bRGB && - pSC->m_param.bScaledArith && - pSC->p1MBbuffer[1] - pSC->p1MBbuffer[0] == pSC->p1MBbuffer[2] - pSC->p1MBbuffer[1] && - 1) - { -#if defined(WMP_OPT_CC_ENC) - pSC->Load = inputMBRow_RGB24_6; -#endif - } - - } -#else - UNREFERENCED_PARAMETER( pSC ); -#endif -} - diff --git a/Src/JxrDecode/Jxr/windowsmediaphoto.h b/Src/JxrDecode/Jxr/windowsmediaphoto.h deleted file mode 100644 index 590f5079..00000000 --- a/Src/JxrDecode/Jxr/windowsmediaphoto.h +++ /dev/null @@ -1,515 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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 -#include -#include -#include - -#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 - diff --git a/Src/JxrDecode/Jxr/wmsal.h b/Src/JxrDecode/Jxr/wmsal.h deleted file mode 100644 index ceb0d3ec..00000000 --- a/Src/JxrDecode/Jxr/wmsal.h +++ /dev/null @@ -1,758 +0,0 @@ -/*** -*sal.h - markers for documenting the semantics of APIs -* -* 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. -* -*Purpose: -* sal.h provides a set of annotations to describe how a function uses its -* parameters - the assumptions it makes about them, and the guarantees it makes -* upon finishing. -* -* [Public] -* -****/ - -/* -------------------------------------------------------------------------------- -Introduction - -sal.h provides a set of annotations to describe how a function uses its -parameters - the assumptions it makes about them, and the guarantees it makes -upon finishing. - -Annotations may be placed before either a function parameter's type or its return -type, and describe the function's behavior regarding the parameter or return value. -There are two classes of annotations: buffer annotations and advanced annotations. -Buffer annotations describe how functions use their pointer parameters, and -advanced annotations either describe complex/unusual buffer behavior, or provide -additional information about a parameter that is not otherwise expressible. - -------------------------------------------------------------------------------- -Buffer Annotations - -The most important annotations in sal.h provide a consistent way to annotate -buffer parameters or return values for a function. Each of these annotations describes -a single buffer (which could be a string, a fixed-length or variable-length array, -or just a pointer) that the function interacts with: where it is, how large it is, -how much is initialized, and what the function does with it. - -The appropriate macro for a given buffer can be constructed using the table below. -Just pick the appropriate values from each category, and combine them together -with a leading underscore. Some combinations of values do not make sense as buffer -annotations. Only meaningful annotations can be added to your code; for a list of -these, see the buffer annotation definitions section. - -Only a single buffer annotation should be used for each parameter. - -|------------|------------|---------|--------|----------|----------|---------------| -| Level | Usage | Size | Output | NullTerm | Optional | Parameters | -|------------|------------|---------|--------|----------|----------|---------------| -| <> | <> | <> | <> | _z | <> | <> | -| _deref | _in | _ecount | _full | _nz | _opt | (size) | -| _deref_opt | _out | _bcount | _part | | | (size,length) | -| | _inout | | | | | | -| | | | | | | | -|------------|------------|---------|--------|----------|----------|---------------| - -Level: Describes the buffer pointer's level of indirection from the parameter or -return value 'p'. - -<> : p is the buffer pointer. -_deref : *p is the buffer pointer. p must not be NULL. -_deref_opt : *p may be the buffer pointer. p may be NULL, in which case the rest of -the annotation is ignored. - -Usage: Describes how the function uses the buffer. - -<> : The buffer is not accessed. If used on the return value or with _deref, the -function will provide the buffer, and it will be uninitialized at exit. -Otherwise, the caller must provide the buffer. This should only be used -for alloc and free functions. -_in : The function will only read from the buffer. The caller must provide the -buffer and initialize it. Cannot be used with _deref. -_out : The function will only write to the buffer. If used on the return value or -with _deref, the function will provide the buffer and initialize it. -Otherwise, the caller must provide the buffer, and the function will -initialize it. -_inout : The function may freely read from and write to the buffer. The caller must -provide the buffer and initialize it. If used with _deref, the buffer may -be reallocated by the function. - -Size: Describes the total size of the buffer. This may be less than the space actually -allocated for the buffer, in which case it describes the accessible amount. - -<> : No buffer size is given. If the type specifies the buffer size (such as -with LPSTR and LPWSTR), that amount is used. Otherwise, the buffer is one -element long. Must be used with _in, _out, or _inout. -_ecount : The buffer size is an explicit element count. -_bcount : The buffer size is an explicit byte count. - -Output: Describes how much of the buffer will be initialized by the function. For -_inout buffers, this also describes how much is initialized at entry. Omit this -category for _in buffers; they must be fully initialized by the caller. - -<> : The type specifies how much is initialized. For instance, a function initializing -an LPWSTR must NULL-terminate the string. -_full : The function initializes the entire buffer. -_part : The function initializes part of the buffer, and explicitly indicates how much. - -NullTerm: States if the present of a '\0' marks the end of valid elements in the buffer. -_z : A '\0' indicated the end of the buffer -_nz : The buffer may not be null terminated and a '\0' does not indicate the end of the -buffer. -Optional: Describes if the buffer itself is optional. - -<> : The pointer to the buffer must not be NULL. -_opt : The pointer to the buffer might be NULL. It will be checked before being dereferenced. - -Parameters: Gives explicit counts for the size and length of the buffer. - -<> : There is no explicit count. Use when neither _ecount nor _bcount is used. -(size) : Only the buffer's total size is given. Use with _ecount or _bcount but not _part. -(size,length) : The buffer's total size and initialized length are given. Use with _ecount_part -and _bcount_part. - -------------------------------------------------------------------------------- -Buffer Annotation Examples - -LWSTDAPI_(BOOL) StrToIntExA( -LPCSTR pszString, -- No annotation required, const implies __in. -DWORD dwFlags, -__out int *piRet -- A pointer whose dereference will be filled in. -); - -void MyPaintingFunction( -__in HWND hwndControl, -- An initialized read-only parameter. -__in_opt HDC hdcOptional, -- An initialized read-only parameter that might be NULL. -__inout IPropertyStore *ppsStore -- An initialized parameter that may be freely used --- and modified. -); - -LWSTDAPI_(BOOL) PathCompactPathExA( -__out_ecount(cchMax) LPSTR pszOut, -- A string buffer with cch elements that will --- be NULL terminated on exit. -LPCSTR pszSrc, -- No annotation required, const implies __in. -UINT cchMax, -DWORD dwFlags -); - -HRESULT SHLocalAllocBytes( -size_t cb, -__deref_bcount(cb) T **ppv -- A pointer whose dereference will be set to an --- uninitialized buffer with cb bytes. -); - -__inout_bcount_full(cb) : A buffer with cb elements that is fully initialized at -entry and exit, and may be written to by this function. - -__out_ecount_part(count, *countOut) : A buffer with count elements that will be -partially initialized by this function. The function indicates how much it -initialized by setting *countOut. - -------------------------------------------------------------------------------- -Advanced Annotations - -Advanced annotations describe behavior that is not expressible with the regular -buffer macros. These may be used either to annotate buffer parameters that involve -complex or conditional behavior, or to enrich existing annotations with additional -information. - -__success(expr) f : - indicates whether function f succeeded or not. If is true at exit, -all the function's guarantees (as given by other annotations) must hold. If -is false at exit, the caller should not expect any of the function's guarantees -to hold. If not used, the function must always satisfy its guarantees. Added -automatically to functions that indicate success in standard ways, such as by -returning an HRESULT. - -__nullterminated p : -Pointer p is a buffer that may be read or written up to and including the first -NULL character or pointer. May be used on typedefs, which marks valid (properly -initialized) instances of that type as being NULL-terminated. - -__nullnullterminated p : -Pointer p is a buffer that may be read or written up to and including the first -sequence of two NULL characters or pointers. May be used on typedefs, which marks -valid instances of that type as being double-NULL terminated. - -__reserved v : -Value v must be 0/NULL, reserved for future use. - -__checkReturn v : -Return value v must not be ignored by callers of this function. - -__typefix(ctype) v : -Value v should be treated as an instance of ctype, rather than its declared type. - -__override f : -Specify C#-style 'override' behaviour for overriding virtual methods. - -__callback f : -Function f can be used as a function pointer. - -__format_string p : -Pointer p is a string that contains % markers in the style of printf. - -__blocksOn(resource) f : -Function f blocks on the resource 'resource'. - -__fallthrough : -Annotates switch statement labels where fall-through is desired, to distinguish -from forgotten break statements. - -------------------------------------------------------------------------------- -Advanced Annotation Examples - -__success(return == TRUE) LWSTDAPI_(BOOL) -PathCanonicalizeA(__out_ecount(MAX_PATH) LPSTR pszBuf, LPCSTR pszPath) : -pszBuf is only guaranteed to be NULL-terminated when TRUE is returned. - -typedef __nullterminated WCHAR* LPWSTR : Initialized LPWSTRs are NULL-terminated strings. - -__out_ecount(cch) __typefix(LPWSTR) void *psz : psz is a buffer parameter which will be -a NULL-terminated WCHAR string at exit, and which initially contains cch WCHARs. - -------------------------------------------------------------------------------- -*/ - -#pragma once -#ifndef __specstrings -#define __specstrings - -#ifdef __cplusplus -#ifndef __nothrow -# define __nothrow __declspec(nothrow) -#endif -extern "C" { -#else -#ifndef __nothrow -# define __nothrow -#endif -#endif /* #ifdef __cplusplus */ - -/* -------------------------------------------------------------------------------- -Helper Macro Definitions - -These express behavior common to many of the high-level annotations. -DO NOT USE THESE IN YOUR CODE. -------------------------------------------------------------------------------- -*/ - -/* -The helper annotations are only understood by the compiler version used by various -defect detection tools. When the regular compiler is running, they are defined into -nothing, and do not affect the compiled code. -*/ - -#if !defined(__midl) && defined(_PREFAST_) - -/* -In the primitive __declspec("SAL_*") annotations "SAL" stands for Standard -Annotation Language. These __declspec("SAL_*") annotations are the -primitives the compiler understands and all high-level SpecString MACROs -will decompose into these primivates. -*/ - -#define SPECSTRINGIZE( x ) #x - -/* -__null p -__notnull p -__maybenull p - -Annotates a pointer p. States that pointer p is null. Commonly used -in the negated form __notnull or the possibly null form __maybenull. -*/ - -// #define __null __declspec("SAL_null") -#define __notnull __declspec("SAL_notnull") -#define __maybenull __declspec("SAL_maybenull") - -/* -__readonly l -__notreadonly l -__mabyereadonly l - -Annotates a location l. States that location l is not modified after -this point. If the annotation is placed on the precondition state of -a function, the restriction only applies until the postcondition state -of the function. __maybereadonly states that the annotated location -may be modified, whereas __notreadonly states that a location must be -modified. -*/ - -#define __readonly __declspec("SAL_readonly") -#define __notreadonly __declspec("SAL_notreadonly") -#define __maybereadonly __declspec("SAL_maybereadonly") - -/* -__valid v -__notvalid v -__maybevalid v - -Annotates any value v. States that the value satisfies all properties of -valid values of its type. For example, for a string buffer, valid means -that the buffer pointer is either NULL or points to a NULL-terminated string. -*/ - -#define __valid __declspec("SAL_valid") -#define __notvalid __declspec("SAL_notvalid") -#define __maybevalid __declspec("SAL_maybevalid") - -/* -__readableTo(extent) p - -Annotates a buffer pointer p. If the buffer can be read, extent describes -how much of the buffer is readable. For a reader of the buffer, this is -an explicit permission to read up to that amount, rather than a restriction to -read only up to it. -*/ - -#define __readableTo(extent) __declspec("SAL_readableTo("SPECSTRINGIZE(extent)")") - -/* - -__elem_readableTo(size) - -Annotates a buffer pointer p as being readable to size elements. -*/ - -#define __elem_readableTo(size) __declspec("SAL_readableTo(elementCount("SPECSTRINGIZE(size)"))") - -/* -__byte_readableTo(size) - -Annotates a buffer pointer p as being readable to size bytes. -*/ -#define __byte_readableTo(size) __declspec("SAL_readableTo(byteCount("SPECSTRINGIZE(size)"))") - -/* -__writableTo(extent) p - -Annotates a buffer pointer p. If the buffer can be modified, extent -describes how much of the buffer is writable (usually the allocation -size). For a writer of the buffer, this is an explicit permission to -write up to that amount, rather than a restriction to write only up to it. -*/ -#define __writableTo(size) __declspec("SAL_writableTo("SPECSTRINGIZE(size)")") - -/* -__elem_writableTo(size) - -Annotates a buffer pointer p as being writable to size elements. -*/ -#define __elem_writableTo(size) __declspec("SAL_writableTo(elementCount("SPECSTRINGIZE(size)"))") - -/* -__byte_writableTo(size) - -Annotates a buffer pointer p as being writable to size bytes. -*/ -#define __byte_writableTo(size) __declspec("SAL_writableTo(byteCount("SPECSTRINGIZE(size)"))") - -/* -__deref p - -Annotates a pointer p. The next annotation applies one dereference down -in the type. If readableTo(p, size) then the next annotation applies to -all elements *(p+i) for which i satisfies the size. If p is a pointer -to a struct, the next annotation applies to all fields of the struct. -*/ -#define __deref __declspec("SAL_deref") - -/* -__pre __next_annotation - -The next annotation applies in the precondition state -*/ -#define __pre __declspec("SAL_pre") - -/* -__post __next_annotation - -The next annotation applies in the postcondition state -*/ -#define __post __declspec("SAL_post") - -/* -__precond() - -When is true, the next annotation applies in the precondition state -(currently not enabled) -*/ -#define __precond(expr) __pre - -/* -__postcond() - -When is true, the next annotation applies in the postcondition state -(currently not enabled) -*/ -#define __postcond(expr) __post - -/* -__exceptthat - -Given a set of annotations Q containing __exceptthat maybeP, the effect of -the except clause is to erase any P or notP annotations (explicit or -implied) within Q at the same level of dereferencing that the except -clause appears, and to replace it with maybeP. - -Example 1: __valid __exceptthat __maybenull on a pointer p means that the -pointer may be null, and is otherwise valid, thus overriding -the implicit notnull annotation implied by __valid on -pointers. - -Example 2: __valid __deref __exceptthat __maybenull on an int **p means -that p is not null (implied by valid), but the elements -pointed to by p could be null, and are otherwise valid. -*/ -#define __exceptthat __declspec("SAL_except") -#define __execeptthat __exceptthat - -/* -_refparam - -Added to all out parameter macros to indicate that they are all reference -parameters. -*/ -#define __refparam __deref __notreadonly - -/* -__inner_* - -Helper macros that directly correspond to certain high-level annotations. - -*/ - -/* -Macros to classify the entrypoints and indicate their category. - -Pre-defined control point categories include: RPC, LPC, DeviceDriver, UserToKernel, ISAPI, COM. - -*/ -#define __inner_control_entrypoint(category) __declspec("SAL_entrypoint(controlEntry, "SPECSTRINGIZE(category)")") - -/* -Pre-defined data entry point categories include: Registry, File, Network. -*/ -#define __inner_data_entrypoint(category) __declspec("SAL_entrypoint(dataEntry, "SPECSTRINGIZE(category)")") - -#define __inner_success(expr) __declspec("SAL_success("SPECSTRINGIZE(expr)")") -#define __inner_checkReturn __declspec("SAL_checkReturn") -#define __inner_typefix(ctype) __declspec("SAL_typefix("SPECSTRINGIZE(ctype)")") -#define __inner_override __declspec("__override") -#define __inner_callback __declspec("__callback") -#define __inner_blocksOn(resource) __declspec("SAL_blocksOn("SPECSTRINGIZE(resource)")") -#define __inner_fallthrough_dec __inline __nothrow void __FallThrough() {} -#define __inner_fallthrough __FallThrough(); - -#else -// This conflicts with gcc definition of __null. -// #define __null -#define __notnull -#define __maybenull -#define __readonly -#define __notreadonly -#define __maybereadonly -#define __valid -#define __notvalid -#define __maybevalid -#define __readableTo(extent) -#define __elem_readableTo(size) -#define __byte_readableTo(size) -#define __writableTo(size) -#define __elem_writableTo(size) -#define __byte_writableTo(size) -#define __deref -#define __pre -#define __post -#define __precond(expr) -#define __postcond(expr) -#define __exceptthat -#define __execeptthat -#define __inner_success(expr) -#define __inner_checkReturn -#define __inner_typefix(ctype) -#define __inner_override -#define __inner_callback -#define __inner_blocksOn(resource) -#define __inner_fallthrough_dec -#define __inner_fallthrough -#define __refparam -#define __inner_control_entrypoint(category) -#define __inner_data_entrypoint(category) -#endif /* #if !defined(__midl) && defined(_PREFAST_) */ - -/* -------------------------------------------------------------------------------- -Buffer Annotation Definitions - -Any of these may be used to directly annotate functions, but only one should -be used for each parameter. To determine which annotation to use for a given -buffer, use the table in the buffer annotations section. -------------------------------------------------------------------------------- -*/ - -#define __ecount(size) __notnull __elem_writableTo(size) -#define __bcount(size) __notnull __byte_writableTo(size) -//#define __in __pre __valid __pre __deref __readonly -#define __in_win __pre __valid __pre __deref __readonly - -#define __in_ecount(size) __in_win __pre __elem_readableTo(size) -#define __in_bcount(size) __in_win __pre __byte_readableTo(size) -#define __in_z __in_win __pre __nullterminated -#define __in_ecount_z(size) __in_ecount(size) __pre __nullterminated -#define __in_bcount_z(size) __in_bcount(size) __pre __nullterminated -#define __in_nz __in_win -#define __in_ecount_nz(size) __in_ecount(size) -#define __in_bcount_nz(size) __in_bcount(size) - -//#define __out __ecount(1) __post __valid __refparam -#define __out_win __ecount(1) __post __valid __refparam - -#define __out_ecount(size) __ecount(size) __post __valid __refparam -#define __out_bcount(size) __bcount(size) __post __valid __refparam -#define __out_ecount_part(size,length) __out_ecount(size) __post __elem_readableTo(length) -#define __out_bcount_part(size,length) __out_bcount(size) __post __byte_readableTo(length) -#define __out_ecount_full(size) __out_ecount_part(size,size) -#define __out_bcount_full(size) __out_bcount_part(size,size) -#define __out_z __post __valid __refparam __post __nullterminated -#define __out_z_opt __post __valid __refparam __post __nullterminated __exceptthat __maybenull -#define __out_ecount_z(size) __ecount(size) __post __valid __refparam __post __nullterminated -#define __out_bcount_z(size) __bcount(size) __post __valid __refparam __post __nullterminated -#define __out_ecount_part_z(size,length) __out_ecount_part(size,length) __post __nullterminated -#define __out_bcount_part_z(size,length) __out_bcount_part(size,length) __post __nullterminated -#define __out_ecount_full_z(size) __out_ecount_full(size) __post __nullterminated -#define __out_bcount_full_z(size) __out_bcount_full(size) __post __nullterminated -#define __out_nz __post __valid __refparam __post -#define __out_nz_opt __post __valid __refparam __post __exceptthat __maybenull -#define __out_ecount_nz(size) __ecount(size) __post __valid __refparam -#define __out_bcount_nz(size) __bcount(size) __post __valid __refparam -#define __inout __pre __valid __post __valid __refparam -#define __inout_ecount(size) __out_ecount(size) __pre __valid -#define __inout_bcount(size) __out_bcount(size) __pre __valid -#define __inout_ecount_part(size,length) __out_ecount_part(size,length) __pre __valid __pre __elem_readableTo(length) -#define __inout_bcount_part(size,length) __out_bcount_part(size,length) __pre __valid __pre __byte_readableTo(length) -#define __inout_ecount_full(size) __inout_ecount_part(size,size) -#define __inout_bcount_full(size) __inout_bcount_part(size,size) -#define __inout_z __inout __pre __nullterminated __post __nullterminated -#define __inout_ecount_z(size) __inout_ecount(size) __pre __nullterminated __post __nullterminated -#define __inout_bcount_z(size) __inout_bcount(size) __pre __nullterminated __post __nullterminated -#define __inout_nz __inout -#define __inout_ecount_nz(size) __inout_ecount(size) -#define __inout_bcount_nz(size) __inout_bcount(size) -#define __ecount_opt(size) __ecount(size) __exceptthat __maybenull -#define __bcount_opt(size) __bcount(size) __exceptthat __maybenull -#define __in_opt __in_win __exceptthat __maybenull -#define __in_ecount_opt(size) __in_ecount(size) __exceptthat __maybenull -#define __in_bcount_opt(size) __in_bcount(size) __exceptthat __maybenull -#define __in_z_opt __in_opt __pre __nullterminated -#define __in_ecount_z_opt(size) __in_ecount_opt(size) __pre __nullterminated -#define __in_bcount_z_opt(size) __in_bcount_opt(size) __pre __nullterminated -#define __in_nz_opt __in_opt -#define __in_ecount_nz_opt(size) __in_ecount_opt(size) -#define __in_bcount_nz_opt(size) __in_bcount_opt(size) -#define __out_opt __out_win __exceptthat __maybenull -#define __out_ecount_opt(size) __out_ecount(size) __exceptthat __maybenull -#define __out_bcount_opt(size) __out_bcount(size) __exceptthat __maybenull -#define __out_ecount_part_opt(size,length) __out_ecount_part(size,length) __exceptthat __maybenull -#define __out_bcount_part_opt(size,length) __out_bcount_part(size,length) __exceptthat __maybenull -#define __out_ecount_full_opt(size) __out_ecount_full(size) __exceptthat __maybenull -#define __out_bcount_full_opt(size) __out_bcount_full(size) __exceptthat __maybenull -#define __out_ecount_z_opt(size) __out_ecount_opt(size) __post __nullterminated -#define __out_bcount_z_opt(size) __out_bcount_opt(size) __post __nullterminated -#define __out_ecount_part_z_opt(size,length) __out_ecount_part_opt(size,length) __post __nullterminated -#define __out_bcount_part_z_opt(size,length) __out_bcount_part_opt(size,length) __post __nullterminated -#define __out_ecount_full_z_opt(size) __out_ecount_full_opt(size) __post __nullterminated -#define __out_bcount_full_z_opt(size) __out_bcount_full_opt(size) __post __nullterminated -#define __out_ecount_nz_opt(size) __out_ecount_opt(size) __post __nullterminated -#define __out_bcount_nz_opt(size) __out_bcount_opt(size) __post __nullterminated -#define __inout_opt __inout __exceptthat __maybenull -#define __inout_ecount_opt(size) __inout_ecount(size) __exceptthat __maybenull -#define __inout_bcount_opt(size) __inout_bcount(size) __exceptthat __maybenull -#define __inout_ecount_part_opt(size,length) __inout_ecount_part(size,length) __exceptthat __maybenull -#define __inout_bcount_part_opt(size,length) __inout_bcount_part(size,length) __exceptthat __maybenull -#define __inout_ecount_full_opt(size) __inout_ecount_full(size) __exceptthat __maybenull -#define __inout_bcount_full_opt(size) __inout_bcount_full(size) __exceptthat __maybenull -#define __inout_z_opt __inout_opt __pre __nullterminated __post __nullterminated -#define __inout_ecount_z_opt(size) __inout_ecount_opt(size) __pre __nullterminated __post __nullterminated -#define __inout_ecount_z_opt(size) __inout_ecount_opt(size) __pre __nullterminated __post __nullterminated -#define __inout_bcount_z_opt(size) __inout_bcount_opt(size) -#define __inout_nz_opt __inout_opt -#define __inout_ecount_nz_opt(size) __inout_ecount_opt(size) -#define __inout_bcount_nz_opt(size) __inout_bcount_opt(size) -#define __deref_ecount(size) __ecount(1) __post __elem_readableTo(1) __post __deref __notnull __post __deref __elem_writableTo(size) -#define __deref_bcount(size) __ecount(1) __post __elem_readableTo(1) __post __deref __notnull __post __deref __byte_writableTo(size) -#define __deref_out __deref_ecount(1) __post __deref __valid __refparam -#define __deref_out_ecount(size) __deref_ecount(size) __post __deref __valid __refparam -#define __deref_out_bcount(size) __deref_bcount(size) __post __deref __valid __refparam -#define __deref_out_ecount_part(size,length) __deref_out_ecount(size) __post __deref __elem_readableTo(length) -#define __deref_out_bcount_part(size,length) __deref_out_bcount(size) __post __deref __byte_readableTo(length) -#define __deref_out_ecount_full(size) __deref_out_ecount_part(size,size) -#define __deref_out_bcount_full(size) __deref_out_bcount_part(size,size) -#define __deref_out_z __post __deref __valid __refparam __post __deref __nullterminated -#define __deref_out_ecount_z(size) __deref_out_ecount(size) __post __deref __nullterminated -#define __deref_out_bcount_z(size) __deref_out_ecount(size) __post __deref __nullterminated -#define __deref_out_nz __deref_out -#define __deref_out_ecount_nz(size) __deref_out_ecount(size) -#define __deref_out_bcount_nz(size) __deref_out_ecount(size) -#define __deref_inout __notnull __elem_readableTo(1) __pre __deref __valid __post __deref __valid __refparam -#define __deref_inout_z __deref_inout __pre __deref __nullterminated __post __deref __nullterminated -#define __deref_inout_ecount(size) __deref_inout __pre __deref __elem_writableTo(size) __post __deref __elem_writableTo(size) -#define __deref_inout_bcount(size) __deref_inout __pre __deref __byte_writableTo(size) __post __deref __byte_writableTo(size) -#define __deref_inout_ecount_part(size,length) __deref_inout_ecount(size) __pre __deref __elem_readableTo(length) __post __deref __elem_readableTo(length) -#define __deref_inout_bcount_part(size,length) __deref_inout_bcount(size) __pre __deref __byte_readableTo(length) __post __deref __byte_readableTo(length) -#define __deref_inout_ecount_full(size) __deref_inout_ecount_part(size,size) -#define __deref_inout_bcount_full(size) __deref_inout_bcount_part(size,size) -#define __deref_inout_z __deref_inout __pre __deref __nullterminated __post __deref __nullterminated -#define __deref_inout_ecount_z(size) __deref_inout_ecount(size) __pre __deref __nullterminated __post __deref __nullterminated -#define __deref_inout_bcount_z(size) __deref_inout_ecount(size) __pre __deref __nullterminated __post __deref __nullterminated -#define __deref_inout_nz __deref_inout -#define __deref_inout_ecount_nz(size) __deref_inout_ecount(size) -#define __deref_inout_bcount_nz(size) __deref_inout_ecount(size) -#define __deref_ecount_opt(size) __deref_ecount(size) __post __deref __exceptthat __maybenull -#define __deref_bcount_opt(size) __deref_bcount(size) __post __deref __exceptthat __maybenull -#define __deref_out_opt __deref_out __post __deref __exceptthat __maybenull -#define __deref_out_ecount_opt(size) __deref_out_ecount(size) __post __deref __exceptthat __maybenull -#define __deref_out_bcount_opt(size) __deref_out_bcount(size) __post __deref __exceptthat __maybenull -#define __deref_out_ecount_part_opt(size,length) __deref_out_ecount_part(size,length) __post __deref __exceptthat __maybenull -#define __deref_out_bcount_part_opt(size,length) __deref_out_bcount_part(size,length) __post __deref __exceptthat __maybenull -#define __deref_out_ecount_full_opt(size) __deref_out_ecount_full(size) __post __deref __exceptthat __maybenull -#define __deref_out_bcount_full_opt(size) __deref_out_bcount_full(size) __post __deref __exceptthat __maybenull -#define __deref_out_z_opt __post __deref __valid __refparam __execeptthat __maybenull __post __deref __nullterminated -#define __deref_out_ecount_z_opt(size) __deref_out_ecount_opt(size) __post __deref __nullterminated -#define __deref_out_bcount_z_opt(size) __deref_out_bcount_opt(size) __post __deref __nullterminated -#define __deref_out_nz_opt __deref_out_opt -#define __deref_out_ecount_nz_opt(size) __deref_out_ecount_opt(size) -#define __deref_out_bcount_nz_opt(size) __deref_out_bcount_opt(size) -#define __deref_inout_opt __deref_inout __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull -#define __deref_inout_ecount_opt(size) __deref_inout_ecount(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull -#define __deref_inout_bcount_opt(size) __deref_inout_bcount(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull -#define __deref_inout_ecount_part_opt(size,length) __deref_inout_ecount_part(size,length) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull -#define __deref_inout_bcount_part_opt(size,length) __deref_inout_bcount_part(size,length) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull -#define __deref_inout_ecount_full_opt(size) __deref_inout_ecount_full(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull -#define __deref_inout_bcount_full_opt(size) __deref_inout_bcount_full(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull -#define __deref_inout_z_opt __deref_inout_opt __pre __deref __nullterminated __post __deref __nullterminated -#define __deref_inout_ecount_z_opt(size) __deref_inout_ecount_opt(size) __pre __deref __nullterminated __post __deref __nullterminated -#define __deref_inout_bcount_z_opt(size) __deref_inout_bcount_opt(size) __pre __deref __nullterminated __post __deref __nullterminated -#define __deref_inout_nz_opt __deref_inout_opt -#define __deref_inout_ecount_nz_opt(size) __deref_inout_ecount_opt(size) -#define __deref_inout_bcount_nz_opt(size) __deref_inout_bcount_opt(size) -#define __deref_opt_ecount(size) __deref_ecount(size) __exceptthat __maybenull -#define __deref_opt_bcount(size) __deref_bcount(size) __exceptthat __maybenull -#define __deref_opt_out __deref_out __exceptthat __maybenull -#define __deref_opt_out_z __deref_opt_out __post __deref __nullterminated -#define __deref_opt_out_ecount(size) __deref_out_ecount(size) __exceptthat __maybenull -#define __deref_opt_out_bcount(size) __deref_out_bcount(size) __exceptthat __maybenull -#define __deref_opt_out_ecount_part(size,length) __deref_out_ecount_part(size,length) __exceptthat __maybenull -#define __deref_opt_out_bcount_part(size,length) __deref_out_bcount_part(size,length) __exceptthat __maybenull -#define __deref_opt_out_ecount_full(size) __deref_out_ecount_full(size) __exceptthat __maybenull -#define __deref_opt_out_bcount_full(size) __deref_out_bcount_full(size) __exceptthat __maybenull -#define __deref_opt_inout __deref_inout __exceptthat __maybenull -#define __deref_opt_inout_ecount(size) __deref_inout_ecount(size) __exceptthat __maybenull -#define __deref_opt_inout_bcount(size) __deref_inout_bcount(size) __exceptthat __maybenull -#define __deref_opt_inout_ecount_part(size,length) __deref_inout_ecount_part(size,length) __exceptthat __maybenull -#define __deref_opt_inout_bcount_part(size,length) __deref_inout_bcount_part(size,length) __exceptthat __maybenull -#define __deref_opt_inout_ecount_full(size) __deref_inout_ecount_full(size) __exceptthat __maybenull -#define __deref_opt_inout_bcount_full(size) __deref_inout_bcount_full(size) __exceptthat __maybenull -#define __deref_opt_inout_z __deref_opt_inout __pre __deref __nullterminated __post __deref __nullterminated -#define __deref_opt_inout_ecount_z(size) __deref_opt_inout_ecount(size) __pre __deref __nullterminated __post __deref __nullterminated -#define __deref_opt_inout_bcount_z(size) __deref_opt_inout_bcount(size) __pre __deref __nullterminated __post __deref __nullterminated -#define __deref_opt_inout_nz __deref_opt_inout -#define __deref_opt_inout_ecount_nz(size) __deref_opt_inout_ecount(size) -#define __deref_opt_inout_bcount_nz(size) __deref_opt_inout_bcount(size) -#define __deref_opt_ecount_opt(size) __deref_ecount_opt(size) __exceptthat __maybenull -#define __deref_opt_bcount_opt(size) __deref_bcount_opt(size) __exceptthat __maybenull -#define __deref_opt_out_opt __deref_out_opt __exceptthat __maybenull -#define __deref_opt_out_ecount_opt(size) __deref_out_ecount_opt(size) __exceptthat __maybenull -#define __deref_opt_out_bcount_opt(size) __deref_out_bcount_opt(size) __exceptthat __maybenull -#define __deref_opt_out_ecount_part_opt(size,length) __deref_out_ecount_part_opt(size,length) __exceptthat __maybenull -#define __deref_opt_out_bcount_part_opt(size,length) __deref_out_bcount_part_opt(size,length) __exceptthat __maybenull -#define __deref_opt_out_ecount_full_opt(size) __deref_out_ecount_full_opt(size) __exceptthat __maybenull -#define __deref_opt_out_bcount_full_opt(size) __deref_out_bcount_full_opt(size) __exceptthat __maybenull -#define __deref_opt_out_z_opt __post __deref __valid __refparam __exceptthat __maybenull __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull __post __deref __nullterminated -#define __deref_opt_out_ecount_z_opt(size) __deref_opt_out_ecount_opt(size) __post __deref __nullterminated -#define __deref_opt_out_bcount_z_opt(size) __deref_opt_out_bcount_opt(size) __post __deref __nullterminated -#define __deref_opt_out_nz_opt __deref_opt_out_opt -#define __deref_opt_out_ecount_nz_opt(size) __deref_opt_out_ecount_opt(size) -#define __deref_opt_out_bcount_nz_opt(size) __deref_opt_out_bcount_opt(size) -#define __deref_opt_inout_opt __deref_inout_opt __exceptthat __maybenull -#define __deref_opt_inout_ecount_opt(size) __deref_inout_ecount_opt(size) __exceptthat __maybenull -#define __deref_opt_inout_bcount_opt(size) __deref_inout_bcount_opt(size) __exceptthat __maybenull -#define __deref_opt_inout_ecount_part_opt(size,length) __deref_inout_ecount_part_opt(size,length) __exceptthat __maybenull -#define __deref_opt_inout_bcount_part_opt(size,length) __deref_inout_bcount_part_opt(size,length) __exceptthat __maybenull -#define __deref_opt_inout_ecount_full_opt(size) __deref_inout_ecount_full_opt(size) __exceptthat __maybenull -#define __deref_opt_inout_bcount_full_opt(size) __deref_inout_bcount_full_opt(size) __exceptthat __maybenull -#define __deref_opt_inout_z_opt __deref_opt_inout_opt __pre __deref __nullterminated __post __deref __nullterminated -#define __deref_opt_inout_ecount_z_opt(size) __deref_opt_inout_ecount_opt(size) __pre __deref __nullterminated __post __deref __nullterminated -#define __deref_opt_inout_bcount_z_opt(size) __deref_opt_inout_bcount_opt(size) __pre __deref __nullterminated __post __deref __nullterminated -#define __deref_opt_inout_nz_opt __deref_opt_inout_opt -#define __deref_opt_inout_ecount_nz_opt(size) __deref_opt_inout_ecount_opt(size) -#define __deref_opt_inout_bcount_nz_opt(size) __deref_opt_inout_bcount_opt(size) - -/* -------------------------------------------------------------------------------- -Advanced Annotation Definitions - -Any of these may be used to directly annotate functions, and may be used in -combination with each other or with regular buffer macros. For an explanation -of each annotation, see the advanced annotations section. -------------------------------------------------------------------------------- -*/ - -#define __success(expr) __inner_success(expr) -#define __nullterminated __readableTo(sentinel(0)) -#define __nullnullterminated -#define __reserved __pre __null -#define __checkReturn __inner_checkReturn -#define __typefix(ctype) __inner_typefix(ctype) -#define __override __inner_override -#define __callback __inner_callback -#define __format_string -#define __blocksOn(resource) __inner_blocksOn(resource) -#define __control_entrypoint(category) __inner_control_entrypoint(category) -#define __data_entrypoint(category) __inner_data_entrypoint(category) - -#ifndef __fallthrough -__inner_fallthrough_dec -#define __fallthrough __inner_fallthrough -#endif - -#ifndef __analysis_assume -#ifdef _PREFAST_ -#define __analysis_assume(expr) __assume(expr) -#else -#define __analysis_assume(expr) -#endif -#endif - -#ifdef __cplusplus -} -#endif - -#endif //__specstrings - diff --git a/Src/JxrDecode/Jxr/wmspecstring.h b/Src/JxrDecode/Jxr/wmspecstring.h deleted file mode 100644 index dbb985c3..00000000 --- a/Src/JxrDecode/Jxr/wmspecstring.h +++ /dev/null @@ -1,337 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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 _WMSPECSTRING_H_ -#define _WMSPECSTRING_H_ - -#if (!defined UNDER_CE && !defined NO_WINDOWS && !defined SPECSTRINGS_H) -#define SPECSTRINGS_H -/************************************************************************* -* See specstrings_strict.h for documentation of all user visible macros. -*************************************************************************/ -#if _MSC_VER -#pragma once -#endif -#include "wmsal.h" - -#ifndef __SAL_H_FULL_VER -#define __SAL_H_FULL_VER 140050727 -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* version specific fixes to bring sal.h upto date */ -#if __SAL_H_FULL_VER <= 140050727 - -/* Missing from RTM sal.h */ -#if !defined(__midl) && defined(_PREFAST_) && _MSC_VER >= 1000 - -#define __inexpressible_readableTo(size) __declspec("SAL_readableTo(inexpressibleCount('" SPECSTRINGIZE(size) "'))") -#define __inexpressible_writableTo(size) __declspec("SAL_writableTo(inexpressibleCount('" SPECSTRINGIZE(size) "'))") -#define __inner_bound __declspec("SAL_bound") -#define __inner_range(lb,ub) __declspec("SAL_range(" SPECSTRINGIZE(lb) "," SPECSTRINGIZE(ub) ")") -#define __inner_assume_bound_dec __inline __nothrow void __AssumeBoundInt(__post __inner_bound int i) {i;} -#define __inner_assume_bound(i) __AssumeBoundInt(i); -#define __inner_allocator __declspec("SAL_allocator") -#else -#define __inexpressible_readableTo(size) -#define __inexpressible_writableTo(size) -#define __inner_bound -#define __inner_range(lb,ub) -#define __inner_assume_bound_dec -#define __inner_assume_bound(i) -#define __inner_allocator -#endif - -#define __xcount(size) __notnull __inexpressible_writableTo(size) -#define __in_xcount(size) __in __pre __inexpressible_readableTo(size) -#define __out_xcount(size) __xcount(size) __post __valid __refparam -#define __out_xcount_part(size,length) __out_xcount(size) __post __inexpressible_readableTo(length) -#define __out_xcount_full(size) __out_xcount_part(size,size) -#define __inout_xcount(size) __out_xcount(size) __pre __valid -#define __inout_xcount_part(size,length) __out_xcount_part(size,length) __pre __valid __pre __inexpressible_readableTo(length) -#define __inout_xcount_full(size) __inout_xcount_part(size,size) -#define __xcount_opt(size) __xcount(size) __exceptthat __maybenull -#define __in_xcount_opt(size) __in_xcount(size) __exceptthat __maybenull -#define __out_xcount_opt(size) __out_xcount(size) __exceptthat __maybenull -#define __out_xcount_part_opt(size,length) __out_xcount_part(size,length) __exceptthat __maybenull -#define __out_xcount_full_opt(size) __out_xcount_full(size) __exceptthat __maybenull -#define __inout_xcount_opt(size) __inout_xcount(size) __exceptthat __maybenull -#define __inout_xcount_part_opt(size,length) __inout_xcount_part(size,length) __exceptthat __maybenull -#define __inout_xcount_full_opt(size) __inout_xcount_full(size) __exceptthat __maybenull -#define __deref_xcount(size) __ecount(1) __post __elem_readableTo(1) __post __deref __notnull __post __deref __inexpressible_writableTo(size) -#define __deref_in __in __pre __deref __deref __readonly -#define __deref_in_ecount(size) __deref_in __pre __deref __elem_readableTo(size) -#define __deref_in_bcount(size) __deref_in __pre __deref __byte_readableTo(size) -#define __deref_in_xcount(size) __deref_in __pre __deref __inexpressible_readableTo(size) -#define __deref_out_xcount(size) __deref_xcount(size) __post __deref __valid __refparam -#define __deref_out_xcount_part(size,length) __deref_out_xcount(size) __post __deref __inexpressible_readableTo(length) -#define __deref_out_xcount_full(size) __deref_out_xcount_part(size,size) -#define __deref_out_xcount(size) __deref_xcount(size) __post __deref __valid __refparam -#define __inout_xcount_opt(size) __inout_xcount(size) __exceptthat __maybenull -#define __inout_xcount_part_opt(size,length) __inout_xcount_part(size,length) __exceptthat __maybenull -#define __inout_xcount_full_opt(size) __inout_xcount_full(size) __exceptthat __maybenull -#define __deref_xcount(size) __ecount(1) __post __elem_readableTo(1) __post __deref __notnull __post __deref __inexpressible_writableTo(size) -#define __deref_in __in __pre __deref __deref __readonly -#define __deref_in_ecount(size) __deref_in __pre __deref __elem_readableTo(size) -#define __deref_in_bcount(size) __deref_in __pre __deref __byte_readableTo(size) -#define __deref_in_xcount(size) __deref_in __pre __deref __inexpressible_readableTo(size) -#define __deref_out_xcount(size) __deref_xcount(size) __post __deref __valid __refparam -#define __deref_out_xcount_part(size,length) __deref_out_xcount(size) __post __deref __inexpressible_readableTo(length) -#define __deref_out_xcount_full(size) __deref_out_xcount_part(size,size) -#define __deref_out_xcount(size) __deref_xcount(size) __post __deref __valid __refparam -#define __deref_inout_xcount(size) __deref_inout __pre __deref __inexpressible_writableTo(size) __post __deref __inexpressible_writableTo(size) -#define __deref_inout_xcount_part(size,length) __deref_inout_xcount(size) __pre __deref __inexpressible_readableTo(length) __post __deref __inexpressible_readableTo(length) -#define __deref_inout_xcount_full(size) __deref_inout_xcount_part(size,size) -#define __deref_xcount_opt(size) __deref_xcount(size) __post __deref __exceptthat __maybenull -#define __deref_in_opt __deref_in __pre __deref __exceptthat __maybenull -#define __deref_in_ecount_opt(size) __deref_in_ecount(size) __pre __deref __exceptthat __maybenull -#define __deref_in_bcount_opt(size) __deref_in_bcount(size) __pre __deref __exceptthat __maybenull -#define __deref_in_xcount_opt(size) __deref_in_xcount(size) __pre __deref __exceptthat __maybenull -#define __deref_out_xcount_opt(size) __deref_out_xcount(size) __post __deref __exceptthat __maybenull -#define __deref_out_xcount_part_opt(size,length) __deref_out_xcount_part(size,length) __post __deref __exceptthat __maybenull -#define __deref_out_xcount_full_opt(size) __deref_out_xcount_full(size) __post __deref __exceptthat __maybenull -#define __deref_inout_xcount_opt(size) __deref_inout_xcount(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull -#define __deref_inout_xcount_part_opt(size,length) __deref_inout_xcount_part(size,length) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull -#define __deref_inout_xcount_full_opt(size) __deref_inout_xcount_full(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull -#define __deref_opt_xcount(size) __deref_xcount(size) __exceptthat __maybenull -#define __deref_opt_in __deref_in __exceptthat __maybenull -#define __deref_opt_in_ecount(size) __deref_in_ecount(size) __exceptthat __maybenull -#define __deref_opt_in_bcount(size) __deref_in_bcount(size) __exceptthat __maybenull -#define __deref_opt_in_xcount(size) __deref_in_xcount(size) __exceptthat __maybenull -#define __deref_opt_out_xcount(size) __deref_out_xcount(size) __exceptthat __maybenull -#define __deref_opt_out_xcount_part(size,length) __deref_out_xcount_part(size,length) __exceptthat __maybenull -#define __deref_opt_out_xcount_full(size) __deref_out_xcount_full(size) __exceptthat __maybenull -#define __deref_opt_inout_xcount(size) __deref_inout_xcount(size) __exceptthat __maybenull -#define __deref_opt_inout_xcount_part(size,length) __deref_inout_xcount_part(size,length) __exceptthat __maybenull -#define __deref_opt_inout_xcount_full(size) __deref_inout_xcount_full(size) __exceptthat __maybenull -#define __deref_opt_xcount_opt(size) __deref_xcount_opt(size) __exceptthat __maybenull -#define __deref_opt_in_opt __deref_in_opt __exceptthat __maybenull -#define __deref_opt_in_ecount_opt(size) __deref_in_ecount_opt(size) __exceptthat __maybenull -#define __deref_opt_in_bcount_opt(size) __deref_in_bcount_opt(size) __exceptthat __maybenull -#define __deref_opt_in_xcount_opt(size) __deref_in_xcount_opt(size) __exceptthat __maybenull -#define __deref_opt_out_xcount_opt(size) __deref_out_xcount_opt(size) __exceptthat __maybenull -#define __deref_opt_out_xcount_part_opt(size,length) __deref_out_xcount_part_opt(size,length) __exceptthat __maybenull -#define __deref_opt_out_xcount_full_opt(size) __deref_out_xcount_full_opt(size) __exceptthat __maybenull -#define __deref_opt_inout_xcount_opt(size) __deref_inout_xcount_opt(size) __exceptthat __maybenull -#define __deref_opt_inout_xcount_part_opt(size,length) __deref_inout_xcount_part_opt(size,length) __exceptthat __maybenull -#define __deref_opt_inout_xcount_full_opt(size) __deref_inout_xcount_full_opt(size) __exceptthat __maybenull -/* Must protect redfinitions of macros to workaround rc.exe issues. */ -#ifndef RC_INVOKED -#undef __nullnullterminated -#define __nullnullterminated __xcount("string terminated by two nulls") -#undef __checkReturn -#define __checkReturn __post __inner_checkReturn -#endif -#endif //__SAL_H_FULL_VER <= 140050727 - -/************************************************************************ -New extensions to sal.h follow here. -*************************************************************************/ - -#if (_MSC_VER >= 1000) && !defined(__midl) && defined(_PREFAST_) -#define __file_parser(typ) __declspec("SAL_file_parser(function, " #typ ")") -#define __file_parser_class(typ) __declspec("SAL_file_parser(class, " #typ ")") -#define __file_parser_library(typ) extern int __declspec("SAL_file_parser(library, " #typ ")") __iSALFileParserLibrary##typ; -#define __source_code_content(typ) extern int __declspec("SAL_source_code_content(" #typ ")") __iSAL_Source_Code_Content##typ; -#define __class_code_content(typ) __declspec("SAL_class_code_content(" #typ ")") -#define __analysis_assert(e) __assume(e) -#define __analysis_hint(hint) __declspec("SAL_analysisHint(" #hint ")") -/* Internal defintions */ -#define __inner_data_source(src_raw) __declspec("SAL_untrusted_data_source(" src_raw ")") -#define __inner_this_data_source(src_raw) __declspec("SAL_untrusted_data_source_this(" src_raw ")") -#define __inner_out_validated(typ_raw) __declspec("SAL_post") __declspec("SAL_validated(" typ_raw ")") -#define __inner_this_out_validated(typ_raw) __declspec("SAL_validated_this(" typ_raw ")") -#define __inner_assume_validated_dec __inline __nothrow void __AssumeValidated(__inner_out_validated("BY_DESIGN") const void *p) {p;} -#define __inner_assume_validated(p) __AssumeValidated(p) -#define __inner_transfer(formal) __declspec("SAL_transfer_adt_property_from(" SPECSTRINGIZE(formal) ")") -#define __inner_encoded __declspec("SAL_encoded") - -#define __$adt_prop(adt,prop) __declspec("SAL_adt("#adt","#prop")") -#define __$adt_add_prop(adt,prop) __declspec("SAL_add_adt_property("#adt","#prop")") -#define __$adt_remove_prop(adt,prop) __declspec("SAL_remove_adt_property("#adt","#prop")") -#define __$adt_transfer_prop(arg) __declspec("SAL_transfer_adt_property_from("#arg")") -#define __$adt_type_props(typ) __declspec("SAL_post_type("#typ")") -#define __$volatile __declspec("SAL_volatile") -#define __$nonvolatile __declspec("SAL_nonvolatile") -#define __$possibly_notnulltermiated __declspec("SAL_RequiresZeroTermination(sometimes)") -#else -#define __file_parser(typ) -#define __file_parser_class(typ) -#define __file_parser_library(typ) -#define __source_code_content(typ) -#define __class_code_content(typ) -#define __analysis_assert(e) -#define __analysis_hint(hint) -/* Internal defintions */ -#define __inner_data_source(src_raw) -#define __inner_this_data_source(src_raw) -#define __inner_out_validated(typ_raw) -#define __inner_this_out_validated(typ_raw) -#define __inner_assume_validated_dec -#define __inner_assume_validated(p) -#define __inner_transfer(formal) -#define __inner_encoded -#define __$adt_prop(adt,prop) -#define __$adt_add_prop(adt,prop) -#define __$adt_remove_prop(adt,prop) -#define __$adt_transfer_prop(arg) -#define __$adt_type_props(typ) -#define __$volatile -#define __$nonvolatile -#define __$possibly_notnulltermiated -#endif // #if (_MSC_VER >= 1000) && !defined(__midl) && defined(_PREFAST_) - -#define __field_ecount(size) __notnull __elem_writableTo(size) -#define __field_bcount(size) __notnull __byte_writableTo(size) -#define __field_xcount(size) __notnull __inexpressible_writableTo(size) - -#define __field_ecount_opt(size) __maybenull __elem_writableTo(size) -#define __field_bcount_opt(size) __maybenull __byte_writableTo(size) -#define __field_xcount_opt(size) __maybenull __inexpressible_writableTo(size) - -#define __field_ecount_part(size,init) __notnull __elem_writableTo(size) __elem_readableTo(init) -#define __field_bcount_part(size,init) __notnull __byte_writableTo(size) __byte_readableTo(init) -#define __field_xcount_part(size,init) __notnull __inexpressible_writableTo(size) __inexpressible_readableTo(init) - -#define __field_ecount_part_opt(size,init) __maybenull __elem_writableTo(size) __elem_readableTo(init) -#define __field_bcount_part_opt(size,init) __maybenull __byte_writableTo(size) __byte_readableTo(init) -#define __field_xcount_part_opt(size,init) __maybenull __inexpressible_writableTo(size) __inexpressible_readableTo(init) - -#define __field_ecount_full(size) __field_ecount_part(size,size) -#define __field_bcount_full(size) __field_bcount_part(size,size) -#define __field_xcount_full(size) __field_xcount_part(size,size) - -#define __field_ecount_full_opt(size) __field_ecount_part_opt(size,size) -#define __field_bcount_full_opt(size) __field_bcount_part_opt(size,size) -#define __field_xcount_full_opt(size) __field_xcount_part_opt(size,size) - -#define __struct_bcount(size) __field_bcount(size) -#define __struct_xcount(size) __field_xcount(size) - -#if !defined(__out_awcount) -#define __out_awcount(expr,size) __pre __notnull __byte_writableTo((expr) ? (size) : (size) * 2) __post __valid __refparam -#endif -#if !defined(__in_awcount) -#define __in_awcount(expr,size) __pre __valid __pre __deref __readonly __byte_readableTo((expr) ? (size) : (size) * 2) -#endif - -/* integer related macros */ -#define __allocator __inner_allocator -#define __bound __inner_bound -#define __range(lb,ub) __inner_range(lb,ub) -#define __in_bound __pre __inner_bound -#define __out_bound __post __inner_bound -#define __deref_out_bound __post __deref __inner_bound -#define __in_range(lb,ub) __pre __inner_range(lb,ub) -#define __out_range(lb,ub) __post __inner_range(lb,ub) -#define __deref_in_range(lb,ub) __pre __deref __inner_range(lb,ub) -#define __deref_out_range(lb,ub) __post __deref __inner_range(lb,ub) -#define __field_range(lb,ub) __range(lb,ub) -#define __field_data_source(src_sym) __inner_data_source(#src_sym) - -/* Pentraion review macros */ -#define __in_data_source(src_sym) __pre __inner_data_source(#src_sym) -#define __out_data_source(src_sym) __post __inner_data_source(#src_sym) -#define __out_validated(typ_sym) __inner_out_validated(#typ_sym) -#define __this_out_data_source(src_sym) __inner_this_data_source(#src_sym) -#define __this_out_validated(typ_sym) __inner_this_out_validated(#typ_sym) -#define __transfer(formal) __post __inner_transfer(formal) -#define __rpc_entry __inner_control_entrypoint(RPC) -#define __kernel_entry __inner_control_entrypoint(UserToKernel) -#define __gdi_entry __inner_control_entrypoint(GDI) -#define __encoded_pointer __inner_encoded -#define __encoded_array __inner_encoded -#define __field_encoded_pointer __inner_encoded -#define __field_encoded_array __inner_encoded -#define __type_has_adt_prop(adt,prop) __$adt_prop(adt,prop) -#define __out_has_adt_prop(adt,prop) __post __$adt_add_prop(adt,prop) -#define __out_not_has_adt_prop(adt,prop) __post __$adt_remove_prop(adt,prop) -#define __out_transfer_adt_prop(arg) __post __$adt_transfer_prop(arg) -#define __out_has_type_adt_props(typ) __post __$adt_type_props(typ) - -/* useful PFD related macros */ -#define __possibly_notnulltermiated __post __$possibly_notnulltermiated - -#if defined(_WINDOWS_) -/* Windows Internal */ -#define __volatile __$volatile -#define __nonvolatile __$nonvolatile -#define __deref_volatile __deref __volatile -#define __deref_nonvolatile __deref __nonvolatile -#endif - -/* declare stub functions for macros */ -__inner_assume_validated_dec -__inner_assume_bound_dec - -#define __assume_validated(p) __inner_assume_validated(p) -#define __assume_bound(i) __inner_assume_bound(i) -#ifdef __cplusplus -} -#endif -#include "wmspecstrings_adt.h" -#ifdef _PREFIX_ -/************************************************************************** -* Defintion of __pfx_assume and __pfx_assert. Thse should be the only -* defintions of these functions. -***************************************************************************/ -#if __cplusplus -extern "C" void __pfx_assert(bool, const char *); -extern "C" void __pfx_assume(bool, const char *); -#else -void __pfx_assert(int, const char *); -void __pfx_assume(int, const char *); -#endif -/************************************************************************** -* Redefintion of __analysis_assume and __analysis_assert for PREFIX build -**************************************************************************/ -#undef __analysis_assume -#undef __analysis_assert -#define __analysis_assume(e) (__pfx_assume(e,"pfx_assume"),__assume(e)); -#define __analysis_assert(e) (__pfx_assert(e,"pfx_assert"),__assume(e)); -#endif /* ifdef _PREFIX_ */ - -/************************************************************************** -* This include should always be the last thing in this file. -* Must avoid redfinitions of macros to workaround rc.exe issues. -***************************************************************************/ -#if !(defined(RC_INVOKED) || defined(SORTPP_PASS)) -#include "wmspecstrings_strict.h" -#endif /* if !(defined(RC_INVOKED) || defined(SORTPP_PASS)) */ -#endif /* #ifndef SPECSTRINGS_H */ - -// Some CE versions don't have specstrings.h, some have very old version without -// __specstrings defined. So we handle CE separately in wmasalce.h -#if defined(UNDER_CE) || defined(NO_WINDOWS) -#include "wmspecstringce.h" -#endif - -#endif //_WMSPECSTRING_H_ diff --git a/Src/JxrDecode/Jxr/wmspecstrings_adt.h b/Src/JxrDecode/Jxr/wmspecstrings_adt.h deleted file mode 100644 index c4db70d3..00000000 --- a/Src/JxrDecode/Jxr/wmspecstrings_adt.h +++ /dev/null @@ -1,72 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// Copyright (C) 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 -/************************************************************************* -* DEFINITIONS OF NEW TYPES -*************************************************************************/ -#if !defined(__midl) -#define __$compname_props \ - __type_has_adt_prop(compname,nullterminated) \ - __type_has_adt_prop(compname,valid_schars) \ - __type_has_adt_prop(compname,correct_len) \ - __nullterminated -#if defined(UNICODE) || defined(_UNICODE) -#define __$TCHAR unsigned short -#else -#define __$TCHAR char -#endif -typedef __$compname_props char* ValidCompNameA; -typedef __$compname_props unsigned short* ValidCompNameW; -typedef __$compname_props const unsigned short* ConstValidCompNameW; -typedef __$compname_props __$TCHAR* SAL_ValidCompNameT; -typedef __$compname_props const __$TCHAR* SAL_ConstValidCompNameT; -#undef __$compname_props -#undef __$TCHAR -#endif - -/************************************************************************* -* DEFINITIONS OF INLINE FUNCTIONS FOR CASTING TO THE NEW TYPES : USER -*************************************************************************/ -#if (_MSC_VER >= 1000) && !defined(__midl) && defined(_PREFAST_) -#ifdef __cplusplus -extern "C" { -#endif - void __inline __nothrow __SAL_ValidCompNameA(__out_has_type_adt_props(ValidCompNameA) const void *expr) { expr; } - void __inline __nothrow __SAL_ValidCompNameW(__out_has_type_adt_props(ValidCompNameW) const void *expr) { expr; } -#ifdef __cplusplus -} -#endif -#define __assume_ValidCompNameA(expr) __SAL_ValidCompNameA(expr) -#define __assume_ValidCompNameW(expr) __SAL_ValidCompNameW(expr) -#else -#define __assume_ValidCompNameA(expr) -#define __assume_ValidCompNameW(expr) -#endif - - diff --git a/Src/JxrDecode/Jxr/wmspecstrings_strict.h b/Src/JxrDecode/Jxr/wmspecstrings_strict.h deleted file mode 100644 index 943475fe..00000000 --- a/Src/JxrDecode/Jxr/wmspecstrings_strict.h +++ /dev/null @@ -1,1091 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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. -// -//*@@@---@@@@****************************************************************** - - -/************************************************************************* -* This file documents all the macros approved for use in windows source -* code. It includes some experimental macros which should only be used by -* experts. -* -* DO NOT include this file directly. This file is include after -* specstrings.h. So we can undefine every possible old definition including -* private internal macros people should not be using, as well as macros from -* sal.h. Macros are redefined here in a way to cause syntax errors when used -* incorrectly during a normal build when specstrings.h is included and -* __SPECSTRINGS_STRICT_LEVEL is defined. -* -* There are several levels of strictness, each level includes the behavior of -* all previous levels. -* -* 0 - Disable strict checking -* 1 - Break on unapproved macros and misuse of statement -* macros such as __fallthrough (default) -* 2 - Deprecated some old macros that should not be used -* 3 - Use VS 2005 Source Annotation to make sure every macro -* is used in the right context. For example placing __in on a return -* parameter will result in an error. -************************************************************************/ -#ifndef __SPECSTRINGS_STRICT_LEVEL -#define __SPECSTRINGS_STRICT_LEVEL 1 -#endif -/************************************************************************ -* Introduction -* -* specstrings.h provides a set of annotations to describe how a function uses -* its parameters - the assumptions it makes about them, and the guarantees it -* makes upon finishing. -* -* Annotations must be placed before a function parameter's type or its return -* type. There are two basic classes of common annotations buffer annotations -* and advanced annotations. Buffer annotations describe how functions use -* their pointer parameters, and advanced annotations either describe -* complex/unusual buffer behavior, or provide additional information about a -* parameter that is not otherwise expressible. -* -* Buffer Annotations -* -* The most important annotations in SpecStrings.h provide a consistent way to -* annotate buffer parameters or return values for a function. Each of these -* annotations describes a single buffer (which could be a string, a -* fixed-length or variable-length array, or just a pointer) that the function -* interacts with: where it is, how large it is, how much is initialized, and -* what the function does with it. -* -* The appropriate macro for a given buffer can be constructed using the table -* below. Just pick the appropriate values from each category, and combine -* them together with a leading underscore. Some combinations of values do not -* make sense as buffer annotations. Only meaningful annotations can be added -* to your code; for a list of these, see the buffer annotation definitions -* section. -* -* Only a single buffer annotation should be used for each parameter. -* -* |------------|------------|---------|--------|----------|---------------| -* | Level | Usage | Size | Output | Optional | Parameters | -* |------------|------------|---------|--------|----------|---------------| -* | <> | <> | <> | <> | <> | <> | -* | _deref | _in | _ecount | _full | _opt | (size) | -* | _deref_opt | _out | _bcount | _part | | (size,length) | -* | | _inout | | | | | -* | | | | | | | -* |------------|------------|---------|--------|----------|---------------| -* -* Note: "<>" represents the empty string. -* -* Level: Describes the buffer pointer's level of indirection from the -* parameter or return value 'p'. -* -* <> : p is the buffer pointer. -* _deref : *p is the buffer pointer. p must not be NULL. -* _deref_opt : *p may be the buffer pointer. p may be NULL, in which case the -* rest of the annotation is ignored. -* -* Usage: Describes how the function uses the buffer. -* -* <> : The buffer is not accessed. If used on the return value or with -* _deref, the function will provide the buffer, and it will be uninitialized -* at exit. Otherwise, the caller must provide the buffer. This should only -* be used for alloc and free functions. -* -* _in : The function will only read from the buffer. The caller must provide -* the buffer and initialize it. -* -* _out : The function will only write to the buffer. If used on the return -* value or with _deref, the function will provide the buffer and initialize -* it. Otherwise, the caller must provide the buffer, and the function will -* initialize it. -* -* _inout : The function may freely read from and write to the buffer. The -* caller must provide the buffer and initialize it. If used with _deref, the -* buffer may be reallocated by the function. -* -* Size: Describes the total size of the buffer. This may be less than the -* space actually allocated for the buffer, in which case it describes the -* accessible amount. -* -* <> : No buffer size is given. If the type specifies the buffer size (such -* as with LPSTR and LPWSTR), that amount is used. Otherwise, the buffer is -* one element long. Must be used with _in, _out, or _inout. -* -* _ecount : The buffer size is an explicit element count. -* -* _bcount : The buffer size is an explicit byte count. -* -* Output: Describes how much of the buffer will be initialized by the -* function. For _inout buffers, this also describes how much is initialized -* at entry. Omit this category for _in buffers; they must be fully -* initialized by the caller. -* -* <> : The type specifies how much is initialized. For instance, a function -* initializing an LPWSTR must NULL-terminate the string. -* -* _full : The function initializes the entire buffer. -* -* _part : The function initializes part of the buffer, and explicitly -* indicates how much. -* -* Optional: Describes if the buffer itself is optional. -* -* <> : The pointer to the buffer must not be NULL. -* -* _opt : The pointer to the buffer might be NULL. It will be checked before -* being dereferenced. -* -* Parameters: Gives explicit counts for the size and length of the buffer. -* -* <> : There is no explicit count. Use when neither _ecount nor _bcount is -* used. -* -* (size) : Only the buffer's total size is given. Use with _ecount or _bcount -* but not _part. -* -* (size,length) : The buffer's total size and initialized length are -* given. Use with _ecount_part and _bcount_part. -* -* ---------------------------------------------------------------------------- -* Buffer Annotation Examples -* -* LWSTDAPI_(BOOL) StrToIntExA( -* LPCSTR pszString, // No annotation required, const implies __in. -* DWORD dwFlags, -* __out int *piRet // A pointer whose dereference will be filled in. -* ); -* -* void MyPaintingFunction( -* __in HWND hwndControl, // An initialized read-only parameter. -* __in_opt HDC hdcOptional, // An initialized read-only parameter that -* // might be NULL. -* __inout IPropertyStore *ppsStore // An initialized parameter that -* // may be freely used and modified. -* ); -* -* LWSTDAPI_(BOOL) PathCompactPathExA( -* __out_ecount(cchMax) LPSTR pszOut, // A string buffer with cch elements -* // that will be '\0' terminated -* // on exit. -* LPCSTR pszSrc, // No annotation required, -* // const implies __in. -* UINT cchMax, -* DWORD dwFlags -* ); -* -* HRESULT SHLocalAllocBytes( -* size_t cb, -* __deref_bcount(cb) T **ppv // A pointer whose dereference will be set -* // to an uninitialized buffer with cb bytes. -* ); -* -* __inout_bcount_full(cb) : A buffer with cb elements that is fully -* initialized at entry and exit, and may be written to by this function. -* -* __out_ecount_part(count, *countOut) : A buffer with count elements that -* will be partially initialized by this function. The function indicates how -* much it initialized by setting *countOut. -* -************************************************************************/ -#if (_MSC_VER >= 1400) && !defined(__midl) && !defined(_PREFAST_) && (__SPECSTRINGS_STRICT_LEVEL > 0) -#pragma once -#include -#define __ecount(size) __allowed(on_return) -#define __bcount(size) __allowed(on_return) -#define __xcount(size) __allowed(on_return) -#define __in __allowed(on_parameter) -#define __in_ecount(size) __allowed(on_parameter) -#define __in_bcount(size) __allowed(on_parameter) -#define __in_xcount(size) __allowed(on_parameter) -#define __in_z __allowed(on_parameter) -#define __in_ecount_z(size) __allowed(on_parameter) -#define __in_bcount_z(size) __allowed(on_parameter) -#define __out __allowed(on_parameter) -#define __out_ecount(size) __allowed(on_parameter) -#define __out_bcount(size) __allowed(on_parameter) -#define __out_xcount(size) __allowed(on_parameter) -#define __out_ecount_part(size,len) __allowed(on_parameter) -#define __out_bcount_part(size,len) __allowed(on_parameter) -#define __out_xcount_part(size,len) __allowed(on_parameter) -#define __out_ecount_full(size) __allowed(on_parameter) -#define __out_bcount_full(size) __allowed(on_parameter) -#define __out_xcount_full(size) __allowed(on_parameter) -#define __out_z __allowed(on_parameter) -#define __out_ecount_z(size) __allowed(on_parameter) -#define __out_bcount_z(size) __allowed(on_parameter) -#define __inout __allowed(on_parameter) -#define __inout_ecount(size) __allowed(on_parameter) -#define __inout_bcount(size) __allowed(on_parameter) -#define __inout_xcount(size) __allowed(on_parameter) -#define __inout_ecount_part(size,len) __allowed(on_parameter) -#define __inout_bcount_part(size,len) __allowed(on_parameter) -#define __inout_xcount_part(size,len) __allowed(on_parameter) -#define __inout_ecount_full(size) __allowed(on_parameter) -#define __inout_bcount_full(size) __allowed(on_parameter) -#define __inout_xcount_full(size) __allowed(on_parameter) -#define __inout_z __allowed(on_parameter) -#define __inout_ecount_z(size) __allowed(on_parameter) -#define __inout_bcount_z(size) __allowed(on_parameter) -#define __ecount_opt(size) __allowed(on_parameter) -#define __bcount_opt(size) __allowed(on_parameter) -#define __xcount_opt(size) __allowed(on_parameter) -#define __in_opt __allowed(on_parameter) -#define __in_ecount_opt(size) __allowed(on_parameter) -#define __in_bcount_opt(size) __allowed(on_parameter) -#define __in_z_opt __allowed(on_parameter) -#define __in_ecount_z_opt(size) __allowed(on_parameter) -#define __in_bcount_z_opt(size) __allowed(on_parameter) -#define __in_xcount_opt(size) __allowed(on_parameter) -#define __out_opt __allowed(on_parameter) -#define __out_ecount_opt(size) __allowed(on_parameter) -#define __out_bcount_opt(size) __allowed(on_parameter) -#define __out_xcount_opt(size) __allowed(on_parameter) -#define __out_ecount_part_opt(size,len) __allowed(on_parameter) -#define __out_bcount_part_opt(size,len) __allowed(on_parameter) -#define __out_xcount_part_opt(size,len) __allowed(on_parameter) -#define __out_ecount_full_opt(size) __allowed(on_parameter) -#define __out_bcount_full_opt(size) __allowed(on_parameter) -#define __out_xcount_full_opt(size) __allowed(on_parameter) -#define __out_ecount_z_opt(size) __allowed(on_parameter) -#define __out_bcount_z_opt(size) __allowed(on_parameter) -#define __inout_opt __allowed(on_parameter) -#define __inout_ecount_opt(size) __allowed(on_parameter) -#define __inout_bcount_opt(size) __allowed(on_parameter) -#define __inout_xcount_opt(size) __allowed(on_parameter) -#define __inout_ecount_part_opt(size,len) __allowed(on_parameter) -#define __inout_bcount_part_opt(size,len) __allowed(on_parameter) -#define __inout_xcount_part_opt(size,len) __allowed(on_parameter) -#define __inout_ecount_full_opt(size) __allowed(on_parameter) -#define __inout_bcount_full_opt(size) __allowed(on_parameter) -#define __inout_xcount_full_opt(size) __allowed(on_parameter) -#define __inout_z_opt __allowed(on_parameter) -#define __inout_ecount_z_opt(size) __allowed(on_parameter) -#define __inout_ecount_z_opt(size) __allowed(on_parameter) -#define __inout_bcount_z_opt(size) __allowed(on_parameter) -#define __deref_ecount(size) __allowed(on_parameter) -#define __deref_bcount(size) __allowed(on_parameter) -#define __deref_xcount(size) __allowed(on_parameter) -#define __deref_in __allowed(on_parameter) -#define __deref_in_ecount(size) __allowed(on_parameter) -#define __deref_in_bcount(size) __allowed(on_parameter) -#define __deref_in_xcount(size) __allowed(on_parameter) -#define __deref_out __allowed(on_parameter) -#define __deref_out_ecount(size) __allowed(on_parameter) -#define __deref_out_bcount(size) __allowed(on_parameter) -#define __deref_out_xcount(size) __allowed(on_parameter) -#define __deref_out_ecount_part(size,len) __allowed(on_parameter) -#define __deref_out_bcount_part(size,len) __allowed(on_parameter) -#define __deref_out_xcount_part(size,len) __allowed(on_parameter) -#define __deref_out_ecount_full(size) __allowed(on_parameter) -#define __deref_out_bcount_full(size) __allowed(on_parameter) -#define __deref_out_xcount_full(size) __allowed(on_parameter) -#define __deref_out_z __allowed(on_parameter) -#define __deref_out_ecount_z(size) __allowed(on_parameter) -#define __deref_out_bcount_z(size) __allowed(on_parameter) -#define __deref_out_xcount(size) __allowed(on_parameter) -#define __deref_inout __allowed(on_parameter) -#define __deref_inout_ecount(size) __allowed(on_parameter) -#define __deref_inout_bcount(size) __allowed(on_parameter) -#define __deref_inout_xcount(size) __allowed(on_parameter) -#define __deref_inout_ecount_part(size,len) __allowed(on_parameter) -#define __deref_inout_bcount_part(size,len) __allowed(on_parameter) -#define __deref_inout_xcount_part(size,len) __allowed(on_parameter) -#define __deref_inout_ecount_full(size) __allowed(on_parameter) -#define __deref_inout_bcount_full(size) __allowed(on_parameter) -#define __deref_inout_xcount_full(size) __allowed(on_parameter) -#define __deref_inout_z __allowed(on_parameter) -#define __deref_inout_ecount_z(size) __allowed(on_parameter) -#define __deref_inout_bcount_z(size) __allowed(on_parameter) -#define __deref_ecount_opt(size) __allowed(on_parameter) -#define __deref_bcount_opt(size) __allowed(on_parameter) -#define __deref_xcount_opt(size) __allowed(on_parameter) -#define __deref_in_opt __allowed(on_parameter) -#define __deref_in_ecount_opt(size) __allowed(on_parameter) -#define __deref_in_bcount_opt(size) __allowed(on_parameter) -#define __deref_in_xcount_opt(size) __allowed(on_parameter) -#define __deref_out_opt __allowed(on_parameter) -#define __deref_out_ecount_opt(size) __allowed(on_parameter) -#define __deref_out_bcount_opt(size) __allowed(on_parameter) -#define __deref_out_xcount_opt(size) __allowed(on_parameter) -#define __deref_out_ecount_part_opt(size,len) __allowed(on_parameter) -#define __deref_out_bcount_part_opt(size,len) __allowed(on_parameter) -#define __deref_out_xcount_part_opt(size,len) __allowed(on_parameter) -#define __deref_out_ecount_full_opt(size) __allowed(on_parameter) -#define __deref_out_bcount_full_opt(size) __allowed(on_parameter) -#define __deref_out_xcount_full_opt(size) __allowed(on_parameter) -#define __deref_out_z_opt __allowed(on_parameter) -#define __deref_out_ecount_z_opt(size) __allowed(on_parameter) -#define __deref_out_bcount_z_opt(size) __allowed(on_parameter) -#define __deref_inout_opt __allowed(on_parameter) -#define __deref_inout_ecount_opt(size) __allowed(on_parameter) -#define __deref_inout_bcount_opt(size) __allowed(on_parameter) -#define __deref_inout_xcount_opt(size) __allowed(on_parameter) -#define __deref_inout_ecount_part_opt(size,len) __allowed(on_parameter) -#define __deref_inout_bcount_part_opt(size,len) __allowed(on_parameter) -#define __deref_inout_xcount_part_opt(size,len) __allowed(on_parameter) -#define __deref_inout_ecount_full_opt(size) __allowed(on_parameter) -#define __deref_inout_bcount_full_opt(size) __allowed(on_parameter) -#define __deref_inout_xcount_full_opt(size) __allowed(on_parameter) -#define __deref_inout_z_opt __allowed(on_parameter) -#define __deref_inout_ecount_z_opt(size) __allowed(on_parameter) -#define __deref_inout_bcount_z_opt(size) __allowed(on_parameter) -#define __deref_opt_ecount(size) __allowed(on_parameter) -#define __deref_opt_bcount(size) __allowed(on_parameter) -#define __deref_opt_xcount(size) __allowed(on_parameter) -#define __deref_opt_in __allowed(on_parameter) -#define __deref_opt_in_ecount(size) __allowed(on_parameter) -#define __deref_opt_in_bcount(size) __allowed(on_parameter) -#define __deref_opt_in_xcount(size) __allowed(on_parameter) -#define __deref_opt_out __allowed(on_parameter) -#define __deref_opt_out_ecount(size) __allowed(on_parameter) -#define __deref_opt_out_bcount(size) __allowed(on_parameter) -#define __deref_opt_out_xcount(size) __allowed(on_parameter) -#define __deref_opt_out_ecount_part(size,len) __allowed(on_parameter) -#define __deref_opt_out_bcount_part(size,len) __allowed(on_parameter) -#define __deref_opt_out_xcount_part(size,len) __allowed(on_parameter) -#define __deref_opt_out_ecount_full(size) __allowed(on_parameter) -#define __deref_opt_out_bcount_full(size) __allowed(on_parameter) -#define __deref_opt_out_xcount_full(size) __allowed(on_parameter) -#define __deref_opt_inout __allowed(on_parameter) -#define __deref_opt_inout_ecount(size) __allowed(on_parameter) -#define __deref_opt_inout_bcount(size) __allowed(on_parameter) -#define __deref_opt_inout_xcount(size) __allowed(on_parameter) -#define __deref_opt_inout_ecount_part(size,len) __allowed(on_parameter) -#define __deref_opt_inout_bcount_part(size,len) __allowed(on_parameter) -#define __deref_opt_inout_xcount_part(size,len) __allowed(on_parameter) -#define __deref_opt_inout_ecount_full(size) __allowed(on_parameter) -#define __deref_opt_inout_bcount_full(size) __allowed(on_parameter) -#define __deref_opt_inout_xcount_full(size) __allowed(on_parameter) -#define __deref_opt_inout_z __allowed(on_parameter) -#define __deref_opt_inout_ecount_z(size) __allowed(on_parameter) -#define __deref_opt_inout_bcount_z(size) __allowed(on_parameter) -#define __deref_opt_ecount_opt(size) __allowed(on_parameter) -#define __deref_opt_bcount_opt(size) __allowed(on_parameter) -#define __deref_opt_xcount_opt(size) __allowed(on_parameter) -#define __deref_opt_in_opt __allowed(on_parameter) -#define __deref_opt_in_ecount_opt(size) __allowed(on_parameter) -#define __deref_opt_in_bcount_opt(size) __allowed(on_parameter) -#define __deref_opt_in_xcount_opt(size) __allowed(on_parameter) -#define __deref_opt_out_opt __allowed(on_parameter) -#define __deref_opt_out_ecount_opt(size) __allowed(on_parameter) -#define __deref_opt_out_bcount_opt(size) __allowed(on_parameter) -#define __deref_opt_out_xcount_opt(size) __allowed(on_parameter) -#define __deref_opt_out_ecount_part_opt(size,len) __allowed(on_parameter) -#define __deref_opt_out_bcount_part_opt(size,len) __allowed(on_parameter) -#define __deref_opt_out_xcount_part_opt(size,len) __allowed(on_parameter) -#define __deref_opt_out_ecount_full_opt(size) __allowed(on_parameter) -#define __deref_opt_out_bcount_full_opt(size) __allowed(on_parameter) -#define __deref_opt_out_xcount_full_opt(size) __allowed(on_parameter) -#define __deref_opt_out_z_opt __allowed(on_parameter) -#define __deref_opt_out_ecount_z_opt(size) __allowed(on_parameter) -#define __deref_opt_out_bcount_z_opt(size) __allowed(on_parameter) -#define __deref_opt_inout_opt __allowed(on_parameter) -#define __deref_opt_inout_ecount_opt(size) __allowed(on_parameter) -#define __deref_opt_inout_bcount_opt(size) __allowed(on_parameter) -#define __deref_opt_inout_xcount_opt(size) __allowed(on_parameter) -#define __deref_opt_inout_ecount_part_opt(size,len) __allowed(on_parameter) -#define __deref_opt_inout_bcount_part_opt(size,len) __allowed(on_parameter) -#define __deref_opt_inout_xcount_part_opt(size,len) __allowed(on_parameter) -#define __deref_opt_inout_ecount_full_opt(size) __allowed(on_parameter) -#define __deref_opt_inout_bcount_full_opt(size) __allowed(on_parameter) -#define __deref_opt_inout_xcount_full_opt(size) __allowed(on_parameter) -#define __deref_opt_inout_z_opt __allowed(on_parameter) -#define __deref_opt_inout_ecount_z_opt(size) __allowed(on_parameter) -#define __deref_opt_inout_bcount_z_opt(size) __allowed(on_parameter) -/************************************************************************ -* Advanced Annotations -* -* Advanced annotations describe behavior that is not expressible with the -* regular buffer macros. These may be used either to annotate buffer -* parameters that involve complex or conditional behavior, or to enrich -* existing annotations with additional information. -* -* __success(expr) T f() : indicates whether function f succeeded or -* not. If is true at exit, all the function's guarantees (as given -* by other annotations) must hold. If is false at exit, the caller -* should not expect any of the function's guarantees to hold. If not used, -* the function must always satisfy its guarantees. Added automatically to -* functions that indicate success in standard ways, such as by returning an -* HRESULT. -* -* __out_awcount(expr, size) T *p : Pointer p is a buffer whose size may be -* given in either bytes or elements. If is true, this acts like -* __out_bcount. If is false, this acts like __out_ecount. This -* should only be used to annotate old APIs. -* -* __in_awcount(expr, size) T* p : Pointer p is a buffer whose size may be given -* in either bytes or elements. If is true, this acts like -* __in_bcount. If is false, this acts like __in_ecount. This should -* only be used to annotate old APIs. -* -* __nullterminated T* p : Pointer p is a buffer that may be read or written -* up to and including the first '\0' character or pointer. May be used on -* typedefs, which marks valid (properly initialized) instances of that type -* as being null-terminated. -* -* __nullnullterminated T* p : Pointer p is a buffer that may be read or -* written up to and including the first sequence of two '\0' characters or -* pointers. May be used on typedefs, which marks valid instances of that -* type as being double-null terminated. -* -* __reserved T v : Value v must be 0/NULL, reserved for future use. -* -* __checkReturn T f(); : Return value of f must not be ignored by callers -* of this function. -* -* __typefix(ctype) T v : Value v should be treated as an instance of ctype, -* rather than its declared type when considering validity. -* -* __override T f(); : Specify C#-style 'override' behaviour for overriding -* virtual methods. -* -* __callback T f(); : Function f can be used as a function pointer. -* -* __format_string T p : Pointer p is a string that contains % markers in -* the style of printf. -* -* __blocksOn(resource) f(); : Function f blocks on the resource 'resource'. -* -* __fallthrough : Annotates switch statement labels where fall-through is -* desired, to distinguish from forgotten break statements. -* -* __range(low_bnd, up_bnd) int f(): The return from the function "f" must -* be in the inclusive numeric range [low_bnd, up_bnd]. -* -* __in_range(low_bnd, up_bnd) int i : Precondition that integer i must be -* in the inclusive numeric range [low_bnd, up_bnd]. -* -* __out_range(low_bnd, up_bnd) int i : Postcondition that integer i must be -* in the inclusive numeric range [low_bnd, up_bnd]. -* -* __deref_in_range(low_bnd, up_bnd) int* pi : Precondition that integer *pi -* must be in the inclusive numeric range [low_bnd, up_bnd]. -* -* __deref_out_range(low_bnd, up_bnd) int* pi : Postcondition that integer -* *pi must be in the inclusive numeric range [low_bnd, up_bnd]. -* -* The first argument of a range macro may also be a C relational operator -* (<,>,!=, ==, <=, >=). -* -* __range(rel_op, j) int f(): Postcondition that "f() rel_op j" must be -* true. Note that j may be a expression known only at runtime. -* -* __in_range(rel_op, j) int i : Precondition that "i rel_op j" must be -* true. Note that j may be a expression known only at runtime. -* -* __out_range(rel_op, j) int i : Postcondition that integer "i rel_op j" -* must be true. Note that j may be a expression known only at runtime. -* -* __deref_in_range(rel_op, j) int *pi : Precondition that "*pi rel_op j" -* must be true. Note that j may be a expression known only at runtime. -* -* __deref_out_range(rel_op, j) int *pi : Postcondition that "*pi rel_op j" -* must be true. Note that j may be a expression known only at runtime. -* -* __in_bound int i : Precondition that integer i must be bound, but the -* exact range can't be specified at compile time. __in_range should be -* used if the range can be explicitly stated. -* -* __out_bound int i : Postcondition that integer i must be bound, but the -* exact range can't be specified at compile time. __out_range should be -* used if the range can be explicitly stated. -* -* __deref_out_bound int pi : Postcondition that integer *pi must be bound, -* but the exact range can't be specified at compile time. -* __deref_out_range should be used if the range can be explicitly stated. -* -* __assume_bound(expr); : Assume that the expression is bound to some known -* range. This can be used to suppress integer overflow warnings on integral -* expressions that are known to be bound due to reasons not explicit in the -* code. Use as a statement in the body of a function. -* -* __allocator void f(): Function allocates memory using an integral size -* argument -* -* ---------------------------------------------------------------------------- -* Advanced Annotation Examples -* -* __success(return == TRUE) LWSTDAPI_(BOOL) -* PathCanonicalizeA(__out_ecount(MAX_PATH) LPSTR pszBuf, LPCSTR pszPath); -* // pszBuf is only guaranteed to be null-terminated when TRUE is returned. -* -* // Initialized LPWSTRs are null-terminated strings. -* typedef __nullterminated WCHAR* LPWSTR; -* -* __out_ecount(cch) __typefix(LPWSTR) void *psz; -* // psz is a buffer parameter which will be a null-terminated WCHAR string -* // at exit, and which initially contains cch WCHARs. -* -************************************************************************/ -#define __success(expr) __allowed(on_function_or_typedecl) -#define __out_awcount(expr,size) __allowed(on_parameter) -#define __in_awcount(expr,size) __allowed(on_parameter) -#define __nullterminated __allowed(on_typedecl) -#define __nullnullterminated __allowed(on_typedecl) -#define __reserved __allowed(on_parameter) -#define __checkReturn __allowed(on_function) -#define __typefix(ctype) __allowed(on_parameter_or_return) -#define __override __allowed(on_function) -#define __callback __allowed(on_function) -#define __format_string __allowed(on_parameter_or_return) -#define __blocksOn(resource) __allowed(on_function) -#define __fallthrough __allowed(as_statement) -#define __range(lb,ub) __allowed(on_return) -#define __in_range(lb,ub) __allowed(on_parameter) -#define __out_range(lb,ub) __allowed(on_parameter) -#define __deref_in_range(lb,ub) __allowed(on_parameter) -#define __deref_out_range(lb,ub) __allowed(on_parameter) -#define __field_range(lb,ub) __allowed(on_field) -#define __bound __allowed(on_return) -#define __in_bound __allowed(on_parameter) -#define __out_bound __allowed(on_parameter) -#define __deref_out_bound __allowed(on_parameter) -#define __assume_bound(i) __allowed(as_statement_with_arg(i)) -#define __allocator __allowed(on_function) -/*************************************************************************** -* Expert Macros -***************************************************************************/ -#define __null __allowed(on_typedecl) -#define __notnull __allowed(on_typedecl) -#define __maybenull __allowed(on_typedecl) -#define __exceptthat __allowed(on_typedecl) -/*************************************************************************** -* Macros to classify fields of structures. -* Structure Annotations -* -* The buffer annotations are a convenient way of describing -* relationships between buffers and their size on a function by -* function basis. Very often struct or class data members have similar -* invariants, which can be expressed directly on the type. -* -* Similar to our buffer annotations we can summarize all the various -* structure annotations by one choosing an element from each column of -* this table to build a composite annotation. -* -* +--------------------------------------------------+ -* | Selector | Units | Size/Init | Optional | -* |----------+---------+------------------+----------| -* | __field | _ecount | (size) | empty | -* |----------+---------+------------------+----------| -* | __struct | _bcount | _full(size) | _opt | -* |----------+---------+------------------+----------| -* | | _xcount | _part(size,init) | | -* +--------------------------------------------------+ -* -* Note that empty represents the empty string. Sometime arguments need -* to be "floated" to the left to give us a valid annotation name. For -* example the naive combination __field_ecount(size)_opt is actually -* written as __field_ecount_opt(size). Not all possible combinations -* are currently supported or sensible. See specstrings_strict.h for -* the currently supported set. Those that are supported are documented -* below. -* -*Summary of Elements -* -* Selector -* -* __field -* The annotation should only be placed in front -* of data members of structures and classes. The -* data members are pointers to a block of data. -* The annotations describe properties about the -* size of the block of data. This can be used for -* -* __struct -* The annotation should only be placed at the -* beginning of the definition of a structure or -* class. These annotations are used when a struct -* or class is used as a "header" that is -* allocated inline with a block of data and there -* is no apparent field that represents the tail -* end of the structure. -* -* Units -* -* _ecount -* All size and initialization values are in terms -* of elements of the appropriate type -* -* _bcount -* All size and initialization values are in terms -* of raw byte sizes. -* -* _xcount -* The size or initialization values cannot be -* properly expressed as a simple byte or element -* count, and instead a place holder is used to -* document the relationship. -* -* Size/Init -* All the size/init expressions can contain references to -* other fields in the struct or class. -* -* (size) -* The size of the buffer is determined by the -* expression size. Unless, the type of the buffer -* provides more information nothing is know about -* how much of this data is initialized. For -* example, if the data member happens to be a -* string type such as LPSTR. It is assumed that -* the data is initialized to the first '\0'. -* -* _full(size) -* The size of the buffer is determined by the -* expression size and all the data in the buffer -* is guaranteed to be initialized. -* -* _part(size,init) -* The size of the buffer is determined by the -* expression size and all the data in the buffer -* is guaranteed to be initialized up to init -* elements or bytes. -* -* Optional -* -* empty -* The pointer to the block of memory is never -* NULL -* -* _opt -* The pointer to the block of memory is may be -* NULL -* -* -* // Basic Usage of Struct Annotations -* #include -* #include -* struct buf_s { -* int sz; -* __field_bcount_full(sz) -* char *buf; -* }; -* void InitBuf(__out struct *buf_s b,int sz) { -* b->buf = calloc(sz,sizeof(char)); -* b->sz = sz; -* } -* void WriteBuf(__in FILE *fp,__in struct *buf_s b) { -* fwrite(b->buf,b->sz,sizeof(char),fp); -* } -* void ReadBuf(__in FILE *fp,__inout struct *buf_s b) { -* fread(b->buf,b->sz,sizeof(char),fp); -* } -* -* -* -* // Inline Allocated Buffer -* struct buf_s { -* int sz; -* __field_bcount(sz) -* char buf[1]; -* }; -* void WriteBuf(__in FILE *fp,__in struct *buf_s b) { -* fwrite(&(b->buf),b->sz,sizeof(char),fp); -* } -* void ReadBuf(__in FILE *fp,__inout struct *buf_s b) { -* fread(&(b->buf),b->sz,sizeof(char),fp); -* } -* -* -* -* // Embedded Header Structure -* __struct_bcount(sz) -* struct buf_s { -* int sz; -* }; -* void WriteBuf(__in FILE *fp,__in struct *buf_s b) { -* fwrite(&b,b->sz,sizeof(char),fp); -* } -* void ReadBuf(__in FILE *fp,__inout struct *buf_s b) { -* fread(&b,b->sz,sizeof(char),fp); -* } -* -* -****************************************************************************/ -#define __field_ecount(size) __allowed(on_field) -#define __field_bcount(size) __allowed(on_field) -#define __field_xcount(size) __allowed(on_field) -#define __field_ecount_opt(size) __allowed(on_field) -#define __field_bcount_opt(size) __allowed(on_field) -#define __field_xcount_opt(size) __allowed(on_field) -#define __field_ecount_part(size,init) __allowed(on_field) -#define __field_bcount_part(size,init) __allowed(on_field) -#define __field_xcount_part(size,init) __allowed(on_field) -#define __field_ecount_part_opt(size,init) __allowed(on_field) -#define __field_bcount_part_opt(size,init) __allowed(on_field) -#define __field_xcount_part_opt(size,init) __allowed(on_field) -#define __field_ecount_full(size) __allowed(on_field) -#define __field_bcount_full(size) __allowed(on_field) -#define __field_xcount_full(size) __allowed(on_field) -#define __field_ecount_full_opt(size) __allowed(on_field) -#define __field_bcount_full_opt(size) __allowed(on_field) -#define __field_xcount_full_opt(size) __allowed(on_field) -#define __struct_bcount(size) __allowed(on_struct) -#define __struct_xcount(size) __allowed(on_struct) - -/*************************************************************************** -* Macros to classify the entrypoints and indicate their category. -* -* Pre-defined control point categories include: RPC, KERNEL, GDI. -* -* Pre-defined control point macros include: -* __rpc_entry, __kernel_entry, __gdi_entry. -***************************************************************************/ -#define __control_entrypoint(category) __allowed(on_function) -#define __rpc_entry __allowed(on_function) -#define __kernel_entry __allowed(on_function) -#define __gdi_entry __allowed(on_function) - -/*************************************************************************** -* Macros to track untrusted data and their validation. The list of untrusted -* sources include: -* -* FILE - File reading stream or API -* NETWORK - Socket readers -* INTERNET - WinInet and WinHttp readers -* USER_REGISTRY - HKCU portions of the registry -* USER_MODE - Parameters to kernel entry points -* RPC - Parameters to RPC entry points -* DRIVER - Device driver -***************************************************************************/ -#define __in_data_source(src_sym) __allowed(on_parameter) -#define __out_data_source(src_sym) __allowed(on_parameter) -#define __field_data_source(src_sym) __allowed(on_field) -#define __this_out_data_source(src_syn) __allowed(on_function) - -/************************************************************************** -* Macros to tag file parsing code. Predefined formats include: -* PNG - Portable Network Graphics -* JPEG - Joint Photographic Experts Group -* BMP - Bitmap -* RC_BMP - Resource bitmap -* WMF - Windows Metafile -* EMF - Windows Enhanced Metafile -* GIF - Graphics Interchange Format -* MIME_TYPE - MIME type from header tokens -* MAIL_MONIKER - MAIL information refered by URL moniker -* HTML - HyperText Markup Language -* WMPHOTO - Windows media photo -* OE_VCARD - Outlook Express virtual card -* OE_CONTACT - Outlook Express contact -* MIDI - Musical Instrument Digital Interface -* LDIF - LDAP Data Interchange Format -* AVI - Audio Visual Interchange -* ACM - Audio Compression Manager -**************************************************************************/ -#define __out_validated(filetype_sym) __allowed(on_parameter) -#define __this_out_validated(filetype_sym) __allowed(on_function) -#define __file_parser(filetype_sym) __allowed(on_function) -#define __file_parser_class(filetype_sym) __allowed(on_struct) -#define __file_parser_library(filetype_sym) __allowed(as_global_decl) - -/*************************************************************************** -* Macros to track the code content in the file. The type of code -* contents currently tracked: -* -* NDIS_DRIVER - NDIS Device driver -***************************************************************************/ -#define __source_code_content(codetype_sym) __allowed(as_global_decl) - -/*************************************************************************** -* Macros to track the code content in the class. The type of code -* contents currently tracked: -* -* DCOM - Class implementing DCOM -***************************************************************************/ -#define __class_code_content(codetype_sym) __allowed(on_struct) - -/************************************************************************* -* Macros to tag encoded function pointers -**************************************************************************/ -#define __encoded_pointer -#define __encoded_array -#define __field_encoded_pointer __allowed(on_field) -#define __field_encoded_array __allowed(on_field) - -#define __transfer(formal) __allowed(on_parameter_or_return) -#define __assume_validated(exp) __allowed(as_statement_with_arg(exp)) - -/************************************************************************* -* __analysis_assume(expr) : Expert macro use only when directed. Use this to -* tell static analysis tools like PREfix and PREfast about a non-coded -* assumption that you wish the tools to assume. The assumption will be -* understood by those tools. By default there is no dynamic checking or -* static checking of the assumption in any build. -* -* To obtain dynamic checking wrap this macro in your local version of a debug -* assert. -* Please do not put function calls in the expression because this is not -* supported by all tools: -* __analysis_assume(GetObject () != NULL); // DO NOT DO THIS -* -*************************************************************************/ -#define __analysis_assume(expr) __allowed(as_statement_with_arg(expr)) -#define __analysis_assert(expr) __allowed(as_statement_with_arg(expr)) - -/************************************************************************* -* __analysis_hint(hint_sym) : Expert macro use only when -* directed. Use this to influence certain analysis heuristics -* used by the tools. These hints do not describe the semantics -* of functions but simply direct the tools to act in a certain -* way. -* -* Current hints that are supported are: -* -* INLINE - inline this function during analysis overrides any -* default heuristics -* NOINLINE - do not inline this function during analysis overrides -* and default heuristics -*************************************************************************/ -#define __analysis_hint(hint) __allowed(on_function) - -/************************************************************************* -* Macros to encode abstract properties of values. Used by SALadt.h -*************************************************************************/ -#define __type_has_adt_prop(adt,prop) __allowed(on_typdecl) -#define __out_has_adt_prop(adt,prop) __allowed(on_parameter) -#define __out_not_has_adt_prop(adt,prop) __allowed(on_parameter) -#define __out_transfer_adt_prop(arg) __allowed(on_parameter) -#define __out_has_type_adt_props(typ) __allowed(on_parameter) -#define __assume_ValidCompNameA(expr) __allowed(as_statement_with_arg(expr)) -#define __assume_ValidCompNameW(expr) __allowed(as_statement_with_arg(expr)) - -/************************************************************************* -* Macros used by Prefast for Drivers -* -* __possibly_notnulltermiated : -* -* Used for return values of parameters or functions that do not -* guarantee nullterimination in all cases. -* -*************************************************************************/ -#define __possibly_notnulltermiated __allowed(on_parameter_or_return) - -/************************************************************************* -* Advanced macros -* -* __volatile -* The __volatile annotation identifies a global variable or -* structure field that: -* 1) is not declared volatile; -* 2) is accessed concurrently by multiple threads. -* -* The __deref_volatile annotation identifies a global variable -* or structure field that stores a pointer to some data that: -* 1) is not declared volatile; -* 2) is accessed concurrently by multiple threads. -* -* Prefast uses these annotations to find patterns of code that -* may result in unexpected re-fetching of the global variable -* into a local variable. -* -* We also provide two complimentary annotations __nonvolatile -* and __deref_nonvolatile that could be used to suppress Prefast -* -* re-fetching warnings on variables that are known either: -* 1) not to be in danger of being re-fetched or, -* 2) not to lead to incorrect results if they are re-fetched -* -*************************************************************************/ -#define __volatile __allowed(on_global_or_field) -#define __deref_volatile __allowed(on_global_or_field) -#define __nonvolatile __allowed(on_global_or_field) -#define __deref_nonvolatile __allowed(on_global_or_field) - -/************************************************************************* -* Macros deprecated with strict level greater then 1. -**************************************************************************/ -#if (__SPECSTRINGS_STRICT_LEVEL > 1) -/* Must come before macro defintions */ -#pragma deprecated(__in_nz) -#pragma deprecated(__in_ecount_nz) -#pragma deprecated(__in_bcount_nz) -#pragma deprecated(__out_nz) -#pragma deprecated(__out_nz_opt) -#pragma deprecated(__out_ecount_nz) -#pragma deprecated(__out_bcount_nz) -#pragma deprecated(__inout_nz) -#pragma deprecated(__inout_ecount_nz) -#pragma deprecated(__inout_bcount_nz) -#pragma deprecated(__in_nz_opt) -#pragma deprecated(__in_ecount_nz_opt) -#pragma deprecated(__in_bcount_nz_opt) -#pragma deprecated(__out_ecount_nz_opt) -#pragma deprecated(__out_bcount_nz_opt) -#pragma deprecated(__inout_nz_opt) -#pragma deprecated(__inout_ecount_nz_opt) -#pragma deprecated(__inout_bcount_nz_opt) -#pragma deprecated(__deref_out_nz) -#pragma deprecated(__deref_out_ecount_nz) -#pragma deprecated(__deref_out_bcount_nz) -#pragma deprecated(__deref_inout_nz) -#pragma deprecated(__deref_inout_ecount_nz) -#pragma deprecated(__deref_inout_bcount_nz) -#pragma deprecated(__deref_out_nz_opt) -#pragma deprecated(__deref_out_ecount_nz_opt) -#pragma deprecated(__deref_out_bcount_nz_opt) -#pragma deprecated(__deref_inout_nz_opt) -#pragma deprecated(__deref_inout_ecount_nz_opt) -#pragma deprecated(__deref_inout_bcount_nz_opt) -#pragma deprecated(__deref_opt_inout_nz) -#pragma deprecated(__deref_opt_inout_ecount_nz) -#pragma deprecated(__deref_opt_inout_bcount_nz) -#pragma deprecated(__deref_opt_out_nz_opt) -#pragma deprecated(__deref_opt_out_ecount_nz_opt) -#pragma deprecated(__deref_opt_out_bcount_nz_opt) -#pragma deprecated(__deref_opt_inout_nz_opt) -#pragma deprecated(__deref_opt_inout_ecount_nz_opt) -#pragma deprecated(__deref_opt_inout_bcount_nz_opt) -#pragma deprecated(__deref) -#pragma deprecated(__pre) -#pragma deprecated(__post) -#pragma deprecated(__readableTo) -#pragma deprecated(__writableTo) -#pragma deprecated(__maybevalid) -#pragma deprecated(__data_entrypoint) -#pragma deprecated(__inexpressible_readableTo) -#pragma deprecated(__readonly) -#pragma deprecated(__byte_writableTo) -#pragma deprecated(__byte_readableTo) -#pragma deprecated(__elem_readableTo) -#pragma deprecated(__elem_writableTo) -#pragma deprecated(__valid) -#pragma deprecated(__notvalid) -#pragma deprecated(__refparam) -#pragma deprecated(__precond) -#endif -/* Define soon to be deprecated macros to nops. */ -#define __in_nz -#define __in_ecount_nz(size) -#define __in_bcount_nz(size) -#define __out_nz -#define __out_nz_opt -#define __out_ecount_nz(size) -#define __out_bcount_nz(size) -#define __inout_nz -#define __inout_ecount_nz(size) -#define __inout_bcount_nz(size) -#define __in_nz_opt -#define __in_ecount_nz_opt(size) -#define __in_bcount_nz_opt(size) -#define __out_ecount_nz_opt(size) -#define __out_bcount_nz_opt(size) -#define __inout_nz_opt -#define __inout_ecount_nz_opt(size) -#define __inout_bcount_nz_opt(size) -#define __deref_out_nz -#define __deref_out_ecount_nz(size) -#define __deref_out_bcount_nz(size) -#define __deref_inout_nz -#define __deref_inout_ecount_nz(size) -#define __deref_inout_bcount_nz(size) -#define __deref_out_nz_opt -#define __deref_out_ecount_nz_opt(size) -#define __deref_out_bcount_nz_opt(size) -#define __deref_inout_nz_opt -#define __deref_inout_ecount_nz_opt(size) -#define __deref_inout_bcount_nz_opt(size) -#define __deref_opt_inout_nz -#define __deref_opt_inout_ecount_nz(size) -#define __deref_opt_inout_bcount_nz(size) -#define __deref_opt_out_nz_opt -#define __deref_opt_out_ecount_nz_opt(size) -#define __deref_opt_out_bcount_nz_opt(size) -#define __deref_opt_inout_nz_opt -#define __deref_opt_inout_ecount_nz_opt(size) -#define __deref_opt_inout_bcount_nz_opt(size) -#define __deref -#define __pre -#define __post -#define __readableTo(count) -#define __writableTo(count) -#define __maybevalid -#define __inexpressible_readableTo(string) -#define __data_entrypoint(category) -#define __readonly -#define __byte_writableTo(count) -#define __byte_readableTo(count) -#define __elem_readableTo(count) -#define __elem_writableTo(count) -#define __valid -#define __notvalid -#define __refparam -#define __precond(condition) - -/************************************************************************* -* Definitions to force a compile error when macros are used improperly. -* Relies on VS 2005 source annotations. -*************************************************************************/ -#define __allowed(p) __$allowed_##p -#define __$allowed_as_global_decl /* empty */ -#define __$allowed_as_statement_with_arg(x) \ - __pragma(warning(push)) __pragma(warning(disable : 4548)) \ - do {__noop(x);} while((0,0) __pragma(warning(pop)) ) -#define __$allowed_as_statement __$allowed_as_statement_with_arg(1) - -/************************************************************************** -* This should go away. It's only for __success which we should split into. -* __success and __typdecl_sucess -***************************************************************************/ -#define __$allowed_on_function_or_typedecl /* empty */ -#if (__SPECSTRINGS_STRICT_LEVEL == 1) || (__SPECSTRINGS_STRICT_LEVEL == 2) -#define __$allowed_on_typedecl /* empty */ -#define __$allowed_on_return /* empty */ -#define __$allowed_on_parameter /* empty */ -#define __$allowed_on_function /* empty */ -#define __$allowed_on_struct /* empty */ -#define __$allowed_on_field /* empty */ -#define __$allowed_on_parameter_or_return /* empty */ -#define __$allowed_on_global_or_field /* empty */ -#elif __SPECSTRINGS_STRICT_LEVEL == 3 -#define __$allowed_on_typedecl /* empty */ -/* Define dummy source attributes. Still needs more testing */ -#define __$allowed_on_return [returnvalue: OnReturnOnly] -#define __$allowed_on_parameter [OnParameterOnly] -#define __$allowed_on_function [method: OnFunctionOnly] -#define __$allowed_on_struct [OnStructOnly] -#define __$allowed_on_field [OnFieldOnly] -#define __$allowed_on_parameter_or_return [OnParameterOrReturnOnly] -#define __$allowed_on_global_or_field /* empty */ -#pragma push_macro( "DECL_SA" ) -#pragma push_macro( "SA" ) -#ifdef __cplusplus -#define SA(x) x -#define DECL_SA(name,loc) \ - [repeatable] \ - [source_annotation_attribute( loc )] \ - struct name##Attribute { name##Attribute(); const char* ignored; }; -#else -#define SA(x) SA_##x -#define DECL_SA(name,loc) [source_annotation_attribute( loc )] struct name { const char* ignored; }; typedef struct name name; -#endif /* #endif __cplusplus */ -DECL_SA(OnParameterOnly, SA(Parameter)); -DECL_SA(OnReturnOnly, SA(ReturnValue)); -DECL_SA(OnFunctionOnly, SA(Method)); -DECL_SA(OnStructOnly, SA(Struct)); -DECL_SA(OnFieldOnly, SA(Field)); -DECL_SA(OnParameterOrReturnOnly, SA(Parameter) | SA(ReturnValue)); -#pragma pop_macro( "SA" ) -#pragma pop_macro( "DECL_SA" ) -#endif -#endif diff --git a/Src/JxrDecode/Jxr/wmspecstrings_undef.h b/Src/JxrDecode/Jxr/wmspecstrings_undef.h deleted file mode 100644 index c07773d3..00000000 --- a/Src/JxrDecode/Jxr/wmspecstrings_undef.h +++ /dev/null @@ -1,406 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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. -// -//*@@@---@@@@****************************************************************** - - -#undef __$adt_add_prop -#undef __$adt_prop -#undef __$adt_remove_prop -#undef __$adt_transfer_prop -#undef __$adt_type_props -#undef __$nonvolatile -#undef __$possibly_notnulltermiated -#undef __$volatile -#undef __allocator -#undef __analysis_assert -#undef __analysis_assume -#undef __analysis_hint -#undef __assume_ValidCompNameA -#undef __assume_ValidCompNameW -#undef __assume_bound -#undef __assume_validated -#undef __bcount -#undef __bcount_opt -#undef __blocksOn -#undef __bound -#undef __byte_readableTo -#undef __byte_writableTo -#undef __callback -#undef __checkReturn -#undef __class_code_content -#undef __control_entrypoint -#undef __data_entrypoint -#undef __deref -#undef __deref_bcount -#undef __deref_bcount_opt -#undef __deref_ecount -#undef __deref_ecount_opt -#undef __deref_in -#undef __deref_in_bcount -#undef __deref_in_bcount_opt -#undef __deref_in_ecount -#undef __deref_in_ecount_opt -#undef __deref_in_opt -#undef __deref_in_range -#undef __deref_in_xcount -#undef __deref_in_xcount_opt -#undef __deref_inout -#undef __deref_inout_bcount -#undef __deref_inout_bcount_full -#undef __deref_inout_bcount_full_opt -#undef __deref_inout_bcount_nz -#undef __deref_inout_bcount_nz_opt -#undef __deref_inout_bcount_opt -#undef __deref_inout_bcount_part -#undef __deref_inout_bcount_part_opt -#undef __deref_inout_bcount_z -#undef __deref_inout_bcount_z_opt -#undef __deref_inout_ecount -#undef __deref_inout_ecount_full -#undef __deref_inout_ecount_full_opt -#undef __deref_inout_ecount_nz -#undef __deref_inout_ecount_nz_opt -#undef __deref_inout_ecount_opt -#undef __deref_inout_ecount_part -#undef __deref_inout_ecount_part_opt -#undef __deref_inout_ecount_z -#undef __deref_inout_ecount_z_opt -#undef __deref_inout_nz -#undef __deref_inout_nz_opt -#undef __deref_inout_opt -#undef __deref_inout_xcount -#undef __deref_inout_xcount_full -#undef __deref_inout_xcount_full_opt -#undef __deref_inout_xcount_opt -#undef __deref_inout_xcount_part -#undef __deref_inout_xcount_part_opt -#undef __deref_inout_z -#undef __deref_inout_z_opt -#undef __deref_nonvolatile -#undef __deref_opt_bcount -#undef __deref_opt_bcount_opt -#undef __deref_opt_ecount -#undef __deref_opt_ecount_opt -#undef __deref_opt_in -#undef __deref_opt_in_bcount -#undef __deref_opt_in_bcount_opt -#undef __deref_opt_in_ecount -#undef __deref_opt_in_ecount_opt -#undef __deref_opt_in_opt -#undef __deref_opt_in_xcount -#undef __deref_opt_in_xcount_opt -#undef __deref_opt_inout -#undef __deref_opt_inout_bcount -#undef __deref_opt_inout_bcount_full -#undef __deref_opt_inout_bcount_full_opt -#undef __deref_opt_inout_bcount_nz -#undef __deref_opt_inout_bcount_nz_opt -#undef __deref_opt_inout_bcount_opt -#undef __deref_opt_inout_bcount_part -#undef __deref_opt_inout_bcount_part_opt -#undef __deref_opt_inout_bcount_z -#undef __deref_opt_inout_bcount_z_opt -#undef __deref_opt_inout_ecount -#undef __deref_opt_inout_ecount_full -#undef __deref_opt_inout_ecount_full_opt -#undef __deref_opt_inout_ecount_nz -#undef __deref_opt_inout_ecount_nz_opt -#undef __deref_opt_inout_ecount_opt -#undef __deref_opt_inout_ecount_part -#undef __deref_opt_inout_ecount_part_opt -#undef __deref_opt_inout_ecount_z -#undef __deref_opt_inout_ecount_z_opt -#undef __deref_opt_inout_nz -#undef __deref_opt_inout_nz_opt -#undef __deref_opt_inout_opt -#undef __deref_opt_inout_xcount -#undef __deref_opt_inout_xcount_full -#undef __deref_opt_inout_xcount_full_opt -#undef __deref_opt_inout_xcount_opt -#undef __deref_opt_inout_xcount_part -#undef __deref_opt_inout_xcount_part_opt -#undef __deref_opt_inout_z -#undef __deref_opt_inout_z_opt -#undef __deref_opt_out -#undef __deref_opt_out_bcount -#undef __deref_opt_out_bcount_full -#undef __deref_opt_out_bcount_full_opt -#undef __deref_opt_out_bcount_nz_opt -#undef __deref_opt_out_bcount_opt -#undef __deref_opt_out_bcount_part -#undef __deref_opt_out_bcount_part_opt -#undef __deref_opt_out_bcount_z_opt -#undef __deref_opt_out_ecount -#undef __deref_opt_out_ecount_full -#undef __deref_opt_out_ecount_full_opt -#undef __deref_opt_out_ecount_nz_opt -#undef __deref_opt_out_ecount_opt -#undef __deref_opt_out_ecount_part -#undef __deref_opt_out_ecount_part_opt -#undef __deref_opt_out_ecount_z_opt -#undef __deref_opt_out_nz_opt -#undef __deref_opt_out_opt -#undef __deref_opt_out_xcount -#undef __deref_opt_out_xcount_full -#undef __deref_opt_out_xcount_full_opt -#undef __deref_opt_out_xcount_opt -#undef __deref_opt_out_xcount_part -#undef __deref_opt_out_xcount_part_opt -#undef __deref_opt_out_z_opt -#undef __deref_opt_xcount -#undef __deref_opt_xcount_opt -#undef __deref_out -#undef __deref_out_bcount -#undef __deref_out_bcount_full -#undef __deref_out_bcount_full_opt -#undef __deref_out_bcount_nz -#undef __deref_out_bcount_nz_opt -#undef __deref_out_bcount_opt -#undef __deref_out_bcount_part -#undef __deref_out_bcount_part_opt -#undef __deref_out_bcount_z -#undef __deref_out_bcount_z_opt -#undef __deref_out_bound -#undef __deref_out_ecount -#undef __deref_out_ecount_full -#undef __deref_out_ecount_full_opt -#undef __deref_out_ecount_nz -#undef __deref_out_ecount_nz_opt -#undef __deref_out_ecount_opt -#undef __deref_out_ecount_part -#undef __deref_out_ecount_part_opt -#undef __deref_out_ecount_z -#undef __deref_out_ecount_z_opt -#undef __deref_out_nz -#undef __deref_out_nz_opt -#undef __deref_out_opt -#undef __deref_out_range -#undef __deref_out_range -#undef __deref_out_xcount -#undef __deref_out_xcount -#undef __deref_out_xcount_full -#undef __deref_out_xcount_full_opt -#undef __deref_out_xcount_opt -#undef __deref_out_xcount_part -#undef __deref_out_xcount_part_opt -#undef __deref_out_z -#undef __deref_out_z_opt -#undef __deref_volatile -#undef __deref_xcount -#undef __deref_xcount_opt -#undef __ecount -#undef __ecount_opt -#undef __elem_readableTo -#undef __elem_writableTo -#undef __encoded_array -#undef __encoded_pointer -#undef __exceptthat -#undef __fallthrough -#undef __field_bcount -#undef __field_bcount_full -#undef __field_bcount_full_opt -#undef __field_bcount_opt -#undef __field_bcount_part -#undef __field_bcount_part_opt -#undef __field_data_source -#undef __field_ecount -#undef __field_ecount_full -#undef __field_ecount_full_opt -#undef __field_ecount_opt -#undef __field_ecount_part -#undef __field_ecount_part_opt -#undef __field_encoded_array -#undef __field_encoded_pointer -#undef __field_range -#undef __field_xcount -#undef __field_xcount_full -#undef __field_xcount_full_opt -#undef __field_xcount_opt -#undef __field_xcount_part -#undef __field_xcount_part_opt -#undef __file_parser -#undef __file_parser_class -#undef __file_parser_library -#undef __format_string -#undef __format_string -#undef __gdi_entry -#undef __in -#undef __in_awcount -#undef __in_bcount -#undef __in_bcount_nz -#undef __in_bcount_nz_opt -#undef __in_bcount_opt -#undef __in_bcount_z -#undef __in_bcount_z_opt -#undef __in_bound -#undef __in_data_source -#undef __in_ecount -#undef __in_ecount_nz -#undef __in_ecount_nz_opt -#undef __in_ecount_opt -#undef __in_ecount_z -#undef __in_ecount_z_opt -#undef __in_nz -#undef __in_nz_opt -#undef __in_opt -#undef __in_range -#undef __in_xcount -#undef __in_xcount_opt -#undef __in_z -#undef __in_z_opt -#undef __inexpressible_readableTo -#undef __inexpressible_writableTo -#undef __inner_assume_bound -#undef __inner_assume_bound_dec -#undef __inner_assume_validated -#undef __inner_assume_validated_dec -#undef __inner_blocksOn -#undef __inner_bound -#undef __inner_callback -#undef __inner_checkReturn -#undef __inner_control_entrypoint -#undef __inner_data_entrypoint -#undef __inner_data_source -#undef __inner_encoded -#undef __inner_fallthrough -#undef __inner_fallthrough_dec -#undef __inner_out_validated -#undef __inner_override -#undef __inner_range -#undef __inner_success -#undef __inner_transfer -#undef __inner_typefix -#undef __inout -#undef __inout_bcount -#undef __inout_bcount_full -#undef __inout_bcount_full_opt -#undef __inout_bcount_nz -#undef __inout_bcount_nz_opt -#undef __inout_bcount_opt -#undef __inout_bcount_part -#undef __inout_bcount_part_opt -#undef __inout_bcount_z -#undef __inout_bcount_z_opt -#undef __inout_ecount -#undef __inout_ecount_full -#undef __inout_ecount_full_opt -#undef __inout_ecount_nz -#undef __inout_ecount_nz_opt -#undef __inout_ecount_opt -#undef __inout_ecount_part -#undef __inout_ecount_part_opt -#undef __inout_ecount_z -#undef __inout_ecount_z_opt -#undef __inout_ecount_z_opt -#undef __inout_nz -#undef __inout_nz_opt -#undef __inout_opt -#undef __inout_xcount -#undef __inout_xcount_full -#undef __inout_xcount_full_opt -#undef __inout_xcount_opt -#undef __inout_xcount_part -#undef __inout_xcount_part_opt -#undef __inout_z -#undef __inout_z_opt -#undef __kernel_entry -#undef __maybenull -#undef __maybereadonly -#undef __maybevalid -#undef __nonvolatile -#undef __notnull -#undef __notreadonly -#undef __notvalid -#undef __null -#undef __nullnullterminated -#undef __nullterminated -#undef __out -#undef __out_awcount -#undef __out_bcount -#undef __out_bcount_full -#undef __out_bcount_full_opt -#undef __out_bcount_nz -#undef __out_bcount_nz_opt -#undef __out_bcount_opt -#undef __out_bcount_part -#undef __out_bcount_part_opt -#undef __out_bcount_z -#undef __out_bcount_z_opt -#undef __out_bound -#undef __out_data_source -#undef __out_ecount -#undef __out_ecount_full -#undef __out_ecount_full_opt -#undef __out_ecount_nz -#undef __out_ecount_nz_opt -#undef __out_ecount_opt -#undef __out_ecount_part -#undef __out_ecount_part_opt -#undef __out_ecount_z -#undef __out_ecount_z_opt -#undef __out_has_adt_prop -#undef __out_has_type_adt_props -#undef __out_not_has_adt_prop -#undef __out_nz -#undef __out_nz_opt -#undef __out_opt -#undef __out_range -#undef __out_transfer_adt_prop -#undef __out_validated -#undef __out_xcount -#undef __out_xcount_full -#undef __out_xcount_full_opt -#undef __out_xcount_opt -#undef __out_xcount_part -#undef __out_xcount_part_opt -#undef __out_z -#undef __override -#undef __possibly_notnulltermiated -#undef __post -#undef __postcond -#undef __pre -#undef __precond -#undef __range -#undef __readableTo -#undef __readonly -#undef __refparam -#undef __reserved -#undef __rpc_entry -#undef __source_code_content -#undef __struct_bcount -#undef __struct_xcount -#undef __success -#undef __this_out_data_source -#undef __this_out_validated -#undef __transfer -#undef __type_has_adt_prop -#undef __typefix -#undef __valid -#undef __volatile -#undef __writableTo -#undef __xcount -#undef __xcount_opt diff --git a/Src/JxrDecode/JxrDecode_Config.h.in b/Src/JxrDecode/JxrDecode_Config.h.in new file mode 100644 index 00000000..d3a5414f --- /dev/null +++ b/Src/JxrDecode/JxrDecode_Config.h.in @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: 2017-2022 Carl Zeiss Microscopy GmbH +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#pragma once + +// if the host system is a big-endian system, this is "1", otherwise 0 +#define JXRDECODE_ISBIGENDIANHOST @jxrdecode_ISBIGENDIANHOST@ + +// whether the processor can load integers from an unaligned address, if this +// is 1 it means that we cannot load an integer from an unaligned address (we'd +// get a bus-error if we try), 0 means that the CPU can load from unaligned addresses +#define JXRDECODE_SIGBUS_ON_UNALIGNEDINTEGERS @jxrdecode_CrashOnUnalignedIntegers@ diff --git a/Src/JxrDecode/stdafx.cpp b/Src/JxrDecode/stdafx.cpp deleted file mode 100644 index 38d4a015..00000000 --- a/Src/JxrDecode/stdafx.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-FileCopyrightText: 2017-2022 Carl Zeiss Microscopy GmbH -// -// SPDX-License-Identifier: LGPL-3.0-or-later - -// stdafx.cpp : source file that includes just the standard includes -// JxrDecode.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/Src/JxrDecode/stdafx.h b/Src/JxrDecode/stdafx.h deleted file mode 100644 index 570509a3..00000000 --- a/Src/JxrDecode/stdafx.h +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-FileCopyrightText: 2017-2022 Carl Zeiss Microscopy GmbH -// -// SPDX-License-Identifier: LGPL-3.0-or-later - -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#pragma once - -#include "targetver.h" - -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers - - - -// TODO: reference additional headers your program requires here diff --git a/Src/JxrDecode/targetver.h b/Src/JxrDecode/targetver.h deleted file mode 100644 index dfd16a44..00000000 --- a/Src/JxrDecode/targetver.h +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-FileCopyrightText: 2017-2022 Carl Zeiss Microscopy GmbH -// -// SPDX-License-Identifier: LGPL-3.0-or-later - -#pragma once - -// Including SDKDDKVer.h defines the highest available Windows platform. - -// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and -// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. - -#if defined(_WIN32)||defined(_WIN64) -#include -#endif From 52ef86b8a5a73b458b1d55ca258c073f3d03451c Mon Sep 17 00:00:00 2001 From: ptahmose Date: Fri, 28 Jul 2023 13:31:57 +0200 Subject: [PATCH 06/98] use stdint --- Src/JxrDecode/CMakeLists.txt | 3 +- .../jxrlib/common/include/wmspecstring.h | 3 ++ Src/JxrDecode/jxrlib/image/encode/strenc.c | 5 +- Src/JxrDecode/jxrlib/image/sys/ansi.h | 48 +++++++++++++++++++ Src/JxrDecode/jxrlib/image/sys/strcodec.c | 8 ++-- Src/JxrDecode/jxrlib/image/sys/strcodec.h | 25 ++++++++-- .../jxrlib/image/sys/windowsmediaphoto.h | 23 ++++----- Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c | 12 ++--- Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h | 16 +++---- 9 files changed, 107 insertions(+), 36 deletions(-) create mode 100644 Src/JxrDecode/jxrlib/image/sys/ansi.h diff --git a/Src/JxrDecode/CMakeLists.txt b/Src/JxrDecode/CMakeLists.txt index ceebe7c9..48eef9a9 100644 --- a/Src/JxrDecode/CMakeLists.txt +++ b/Src/JxrDecode/CMakeLists.txt @@ -93,13 +93,14 @@ add_library(JxrDecodeStatic OBJECT "jxrlib/image/sys/image.c" "jxrlib/image/sys/adapthuff.c" "jxrlib/image/sys/strPredQuant.c" + "jxrlib/image/sys/ansi.h" "jxrlib/jxrgluelib/JXRGlue.h" "jxrlib/jxrgluelib/JXRGlue.c" "jxrlib/jxrgluelib/JXRGlueJxr.c" "jxrlib/jxrgluelib/JXRMeta.h" "jxrlib/jxrgluelib/JXRMeta.c" - "jxrlib/jxrgluelib/JXRGluePFC.c" ) + "jxrlib/jxrgluelib/JXRGluePFC.c") # prepare the configuration-file "JxrDecode_Config.h" diff --git a/Src/JxrDecode/jxrlib/common/include/wmspecstring.h b/Src/JxrDecode/jxrlib/common/include/wmspecstring.h index 9bdc98e9..1d64e816 100644 --- a/Src/JxrDecode/jxrlib/common/include/wmspecstring.h +++ b/Src/JxrDecode/jxrlib/common/include/wmspecstring.h @@ -26,6 +26,8 @@ // //*@@@---@@@@****************************************************************** + +#if false #ifndef _WMSPECSTRING_H_ #define _WMSPECSTRING_H_ @@ -340,3 +342,4 @@ void __pfx_assume(int, const char*); #endif //_WMSPECSTRING_H_ +#endif diff --git a/Src/JxrDecode/jxrlib/image/encode/strenc.c b/Src/JxrDecode/jxrlib/image/encode/strenc.c index ee556138..6dfc7883 100644 --- a/Src/JxrDecode/jxrlib/image/encode/strenc.c +++ b/Src/JxrDecode/jxrlib/image/encode/strenc.c @@ -409,7 +409,7 @@ static _FORCEINLINE PixelI forwardHalf(PixelI hHalf) //================================================================ // Color Conversion // functions to get image data from input buffer -// this inlcudes necessary color conversion and boundary padding +// this includes necessary color conversion and boundary padding //================================================================ #define _CC(r, g, b) (b -= r, r += ((b + 1) >> 1) - g, g += ((r + 0) >> 1)) #define _CC_CMYK(c, m, y, k) (y -= c, c += ((y + 1) >> 1) - m, m += (c >> 1) - k, k += ((m + 1) >> 1)) @@ -420,6 +420,7 @@ const size_t MAX_MEMORY_SIZE_IN_WORDS = 64 << 20; // 1 << 20 \approx 1 million Int StrIOEncInit(CWMImageStrCodec* pSC) { +#if false // TODO TODO TODO pSC->m_param.bIndexTable = !(pSC->WMISCP.bfBitstreamFormat == SPATIAL && pSC->WMISCP.cNumOfSliceMinus1H + pSC->WMISCP.cNumOfSliceMinus1V == 0); if (allocateBitIOInfo(pSC) != ICERR_OK) { return ICERR_ERROR; @@ -497,7 +498,7 @@ Int StrIOEncInit(CWMImageStrCodec* pSC) attachISWrite(pSC->m_ppBitIO[i], pSC->ppWStream[i]); } } - +#endif return ICERR_OK; } diff --git a/Src/JxrDecode/jxrlib/image/sys/ansi.h b/Src/JxrDecode/jxrlib/image/sys/ansi.h new file mode 100644 index 00000000..2e319497 --- /dev/null +++ b/Src/JxrDecode/jxrlib/image/sys/ansi.h @@ -0,0 +1,48 @@ +//*@@@+++@@@@****************************************************************** +// +// 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 + +//================================ +// 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 UINTPTR_T uintptr_t +//#define INTPTR_T intptr_t diff --git a/Src/JxrDecode/jxrlib/image/sys/strcodec.c b/Src/JxrDecode/jxrlib/image/sys/strcodec.c index e564b8fa..51fcf287 100644 --- a/Src/JxrDecode/jxrlib/image/sys/strcodec.c +++ b/Src/JxrDecode/jxrlib/image/sys/strcodec.c @@ -281,12 +281,12 @@ ERR CreateWS_File(struct WMPStream** ppWS, const char* szFilename, const char* s pWS->SetPos = SetPosWS_File; pWS->GetPos = GetPosWS_File; -#ifdef WIN32 - FailIf(0 != fopen_s(&pWS->state.file.pFile, szFilename, szMode), WMP_errFileIO); -#else +//#ifdef WIN32 +// FailIf(0 != fopen_s(&pWS->state.file.pFile, szFilename, szMode), WMP_errFileIO); +//#else pWS->state.file.pFile = fopen(szFilename, szMode); FailIf(NULL == pWS->state.file.pFile, WMP_errFileIO); -#endif +//#endif Cleanup: return err; diff --git a/Src/JxrDecode/jxrlib/image/sys/strcodec.h b/Src/JxrDecode/jxrlib/image/sys/strcodec.h index 92eb0001..03fabb17 100644 --- a/Src/JxrDecode/jxrlib/image/sys/strcodec.h +++ b/Src/JxrDecode/jxrlib/image/sys/strcodec.h @@ -28,6 +28,7 @@ #pragma once #include +#include #include "windowsmediaphoto.h" #include "common.h" @@ -38,6 +39,7 @@ #endif //================================================================ +/* #ifdef ENABLE_OPTIMIZATIONS #if defined(WIN32) && !defined(_WIN64) #define WMP_OPT_SSE2 @@ -53,35 +55,50 @@ #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 // UNREFERENCED_PARAMETER +/* #ifdef UNDER_CE #define PLATFORM_WCE #include "arm.h" #endif +*/ +/* #ifdef __ANSI__ #define PLATFORM_ANSI #include "ansi.h" #endif +*/ + +#include "ansi.h" + +typedef uintptr_t UINTPTR_T; +typedef intptr_t INTPTR_T; //================================================================ +typedef uint64_t U64; +#if false #ifdef PLATFORM_ANSI typedef unsigned long long U64; #else // PLATFORM_ANSI typedef unsigned __int64 U64; #endif // PLATFORM_ANSI +#endif //================================================================ #define MARKERCOUNT (PACKETLENGTH * 2) @@ -449,11 +466,11 @@ typedef struct CWMImageStrCodec { struct WMPStream** ppWStream; -#ifdef WIN32 - TCHAR** ppTempFile; -#else +//#ifdef WIN32 +// TCHAR** ppTempFile; +//#else char** ppTempFile; -#endif +//#endif // interleaved alpha support - linked structure for Alpha channel struct CWMImageStrCodec* m_pNextSC; diff --git a/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h b/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h index 5901b320..579a3eaf 100644 --- a/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h +++ b/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h @@ -34,6 +34,7 @@ #include #include #include +#include #if defined(__cplusplus) && !defined(EXTERN_C) #define EXTERN_C extern "C" @@ -48,17 +49,17 @@ 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 int8_t I8;// signed char I8; +typedef int16_t I16;// short I16; // 16 bit int +typedef int32_t I32;// int I32; +typedef int32_t Long;// long Long; +typedef uint8_t PixelC;//unsigned char PixelC; +typedef int32_t PixelI;// int PixelI; +typedef uint32_t UInt;// unsigned int UInt; +typedef uint32_t ULong;// unsigned long ULong; +typedef uint8_t U8;// unsigned char U8; // 8 bit uint +typedef uint16_t U16;// unsigned short U16; +typedef uint32_t U32;// unsigned int U32; // 32 bit uint typedef void Void; typedef void* CTXSTRCODEC; diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c index ab975ff3..fce32c00 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c @@ -667,8 +667,8 @@ ERR PutULong( ERR ReadBinaryData(__in_ecount(1) struct WMPStream* pWS, - const __in_win U32 uCount, - const __in_win U32 uValue, + const /*__in_win*/ U32 uCount, + const /*__in_win*/ U32 uValue, U8** ppbData) { ERR err = WMP_errSuccess; @@ -704,10 +704,10 @@ ERR ReadBinaryData(__in_ecount(1) struct WMPStream* pWS, 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) + 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; diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h index c7b93c0c..4262b014 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h @@ -108,10 +108,10 @@ #define WMP_valWMPhotoID WMP_valCompression -#ifdef WIN32 -#define __in_win __in -#define __out_win __out -#endif +//#ifdef WIN32 +//#define __in_win __in +//#define __out_win __out +//#endif //================================================================ @@ -230,10 +230,10 @@ EXTERN_C ERR WriteWmpDE( 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); + const /*__in_win*/ U16 uType, + const /*__in_win*/ U32 uCount, + const /*__in_win */U32 uValue, + /*__out_win */DPKPROPVARIANT* pvar); From 22abeed7a11dea81e3a949139e94ce300284f6e0 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Fri, 28 Jul 2023 13:35:12 +0200 Subject: [PATCH 07/98] remove SAL --- Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h index 4262b014..141366bb 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h @@ -197,39 +197,39 @@ typedef struct tagWmpDEMisc //================================================================ EXTERN_C ERR GetUShort( - __in_ecount(1) struct WMPStream* pWS, + /* __in_ecount(1)*/ struct WMPStream* pWS, size_t offPos, - __out_ecount(1) U16* puValue + /*__out_ecount(1)*/ U16* puValue ); EXTERN_C ERR PutUShort( - __in_ecount(1) struct WMPStream* pWS, + /*__in_ecount(1)*/ struct WMPStream* pWS, size_t offPos, U16 uValue ); EXTERN_C ERR GetULong( - __in_ecount(1) struct WMPStream* pWS, + /*__in_ecount(1)*/ struct WMPStream* pWS, size_t offPos, - __out_ecount(1) U32* puValue + /*__out_ecount(1)*/ U32* puValue ); EXTERN_C ERR PutULong( - __in_ecount(1) struct WMPStream* pWS, + /*__in_ecount(1)*/ struct WMPStream* pWS, size_t offPos, U32 uValue ); EXTERN_C ERR WriteWmpDE( - __in_ecount(1) struct WMPStream* pWS, + /*__in_ecount(1)*/ struct WMPStream* pWS, size_t* pOffPos, - const __in_ecount(1) WmpDE* pDE, + const /*__in_ecount(1)*/ WmpDE* pDE, const U8* pbData, U32* pcbDataWrittenToOffset ); -EXTERN_C ERR ReadPropvar(__in_ecount(1) struct WMPStream* pWS, +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, From f84a7aad7fda0e16298c95ea7a7af43d1ba85d4a Mon Sep 17 00:00:00 2001 From: "J. Bohl" Date: Fri, 28 Jul 2023 18:15:42 +0200 Subject: [PATCH 08/98] make build on Linux --- Src/JxrDecode/JxrDecode2.cpp | 2 +- Src/JxrDecode/JxrDecode2.h | 1 + Src/JxrDecode/jxrlib/common/include/guiddef.h | 5 +++-- Src/JxrDecode/jxrlib/image/decode/strdec.c | 16 +++++++++++---- Src/JxrDecode/jxrlib/image/sys/image.c | 14 ++++++------- Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h | 8 ++++---- Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c | 20 +++++++++---------- 7 files changed, 38 insertions(+), 28 deletions(-) diff --git a/Src/JxrDecode/JxrDecode2.cpp b/Src/JxrDecode/JxrDecode2.cpp index 7db0c08e..a67cad14 100644 --- a/Src/JxrDecode/JxrDecode2.cpp +++ b/Src/JxrDecode/JxrDecode2.cpp @@ -2,7 +2,7 @@ #include #include "jxrlib/jxrgluelib/JXRGlue.h" -#include "jxrlib/image/sys/Windowsmediaphoto.h" +#include "jxrlib/image/sys/windowsmediaphoto.h" void JxrDecode2::Decode( codecHandle h, diff --git a/Src/JxrDecode/JxrDecode2.h b/Src/JxrDecode/JxrDecode2.h index a356f3f6..9eafe7eb 100644 --- a/Src/JxrDecode/JxrDecode2.h +++ b/Src/JxrDecode/JxrDecode2.h @@ -1,6 +1,7 @@ #pragma once #include +#include class JxrDecode2 { diff --git a/Src/JxrDecode/jxrlib/common/include/guiddef.h b/Src/JxrDecode/jxrlib/common/include/guiddef.h index 3a3c5e1b..0cb4f98c 100644 --- a/Src/JxrDecode/jxrlib/common/include/guiddef.h +++ b/Src/JxrDecode/jxrlib/common/include/guiddef.h @@ -53,13 +53,14 @@ typedef struct _GUID { #endif #endif -#ifndef FAR +#define FAR +/*#ifndef FAR #if defined(_WIN32) || defined(__ANSI__) #define FAR #else #define FAR _far #endif -#endif +#endif*/ #ifndef DECLSPEC_SELECTANY #if (_MSC_VER >= 1100) diff --git a/Src/JxrDecode/jxrlib/image/decode/strdec.c b/Src/JxrDecode/jxrlib/image/decode/strdec.c index 5fb36727..bd00958d 100644 --- a/Src/JxrDecode/jxrlib/image/decode/strdec.c +++ b/Src/JxrDecode/jxrlib/image/decode/strdec.c @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright © Microsoft Corp. +// 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, +// � 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, +// � 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. // @@ -443,7 +443,15 @@ static _FORCEINLINE void inverseConvertRGBE(PixelI iFr, PixelI iFg, PixelI iFb, inverseConvert(iFg, pG, &pG_E); inverseConvert(iFb, pB, &pB_E); - *pE = max(max(pR_E, pG_E), pB_E); + if (pR_E > pG_E) + { + *pE = pR_E > pB_E ? pR_E : pB_E; + } + else + { + *pE = pG_E > pB_E ? pG_E : pB_E; + } + /**pE = max(max(pR_E, pG_E), pB_E);*/ if (*pE > pR_E) { iShift = (*pE - pR_E); diff --git a/Src/JxrDecode/jxrlib/image/sys/image.c b/Src/JxrDecode/jxrlib/image/sys/image.c index 86858a23..034df98f 100644 --- a/Src/JxrDecode/jxrlib/image/sys/image.c +++ b/Src/JxrDecode/jxrlib/image/sys/image.c @@ -38,13 +38,13 @@ #include #include -#if !(defined(__ANSI__)) -// Desktop -#include -#else -// ANSI -#include -#endif +//#if !(defined(__ANSI__)) +//// Desktop +//#include +//#else +//// ANSI +//#include +//#endif Int grgiZigzagInv4x4_lowpass[] = { 0, 1, 4, 5, 2, 8, 6, 9, diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h index d35b8d45..a94e9841 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h @@ -46,11 +46,11 @@ extern "C" { #ifndef min #define min(b,a) ((a) < (b) ? (a) : (b)) #endif -#ifdef __ANSI__ +//#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__ +//#else +//#define STRCPY_SAFE(pszDest, cbDest, pszSrc) (strcpy_s((pszDest), (cbDest), (pszSrc))) +//#endif // __ANSI__ //================================================================ typedef struct tagPKRect diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c index fce32c00..42fcc0ad 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c @@ -588,9 +588,9 @@ ERR StreamCopyIFD(struct WMPStream* pWS, U32 ofssrc, U8* pbdst, U32 cbdst, U32* //================================================================ ERR GetUShort( - __in_ecount(1) struct WMPStream* pWS, + /*__in_ecount(1)*/ struct WMPStream* pWS, size_t offPos, - __out_ecount(1) U16* puValue) + /*__out_ecount(1)*/ U16* puValue) { ERR err = WMP_errSuccess; U8 cVal; @@ -606,7 +606,7 @@ ERR GetUShort( } ERR PutUShort( - __in_ecount(1) struct WMPStream* pWS, + /*__in_ecount(1)*/ struct WMPStream* pWS, size_t offPos, U16 uValue) { @@ -623,9 +623,9 @@ ERR PutUShort( } ERR GetULong( - __in_ecount(1) struct WMPStream* pWS, + /*__in_ecount(1)*/ struct WMPStream* pWS, size_t offPos, - __out_ecount(1) U32* puValue) + /*__out_ecount(1)*/ U32* puValue) { ERR err = WMP_errSuccess; U8 cVal; @@ -645,7 +645,7 @@ ERR GetULong( } ERR PutULong( - __in_ecount(1) struct WMPStream* pWS, + /*__in_ecount(1)*/ struct WMPStream* pWS, size_t offPos, U32 uValue) { @@ -666,7 +666,7 @@ ERR PutULong( } -ERR ReadBinaryData(__in_ecount(1) struct WMPStream* pWS, +ERR ReadBinaryData(/*__in_ecount(1)*/ struct WMPStream* pWS, const /*__in_win*/ U32 uCount, const /*__in_win*/ U32 uValue, U8** ppbData) @@ -703,7 +703,7 @@ ERR ReadBinaryData(__in_ecount(1) struct WMPStream* pWS, } -ERR ReadPropvar(__in_ecount(1) struct WMPStream* pWS, +ERR ReadPropvar(/*__in_ecount(1)*/ struct WMPStream* pWS, const /*__in_win */U16 uType, const /*__in_win */U32 uCount, const /*__in_win */U32 uValue, @@ -765,9 +765,9 @@ ERR ReadPropvar(__in_ecount(1) struct WMPStream* pWS, ERR WriteWmpDE( - __in_ecount(1) struct WMPStream* pWS, + /*__in_ecount(1)*/ struct WMPStream* pWS, size_t* pOffPos, - const __in_ecount(1) WmpDE* pDE, + const/*__in_ecount(1)*/ WmpDE* pDE, const U8* pbData, U32* pcbDataWrittenToOffset) { From d8a2e880494e2971999b49f62c70f039ce3ce612 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Fri, 28 Jul 2023 19:49:34 +0200 Subject: [PATCH 09/98] cleanup --- Src/JxrDecode/CMakeLists.txt | 4 +- .../jxrlib/common/include/wmspecstring.h | 345 ------------------ .../jxrlib/common/include/wmspecstrings_adt.h | 71 ---- Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h | 68 ++-- Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h | 8 +- 5 files changed, 40 insertions(+), 456 deletions(-) delete mode 100644 Src/JxrDecode/jxrlib/common/include/wmspecstring.h delete mode 100644 Src/JxrDecode/jxrlib/common/include/wmspecstrings_adt.h diff --git a/Src/JxrDecode/CMakeLists.txt b/Src/JxrDecode/CMakeLists.txt index 48eef9a9..a15aea11 100644 --- a/Src/JxrDecode/CMakeLists.txt +++ b/Src/JxrDecode/CMakeLists.txt @@ -65,8 +65,8 @@ add_library(JxrDecodeStatic OBJECT "JxrDecode2.cpp" "jxrlib/common/include/guiddef.h" - "jxrlib/common/include/wmspecstring.h" - "jxrlib/common/include/wmspecstrings_adt.h" + #"jxrlib/common/include/wmspecstring.h" + #"jxrlib/common/include/wmspecstrings_adt.h" "jxrlib/image/decode/decode.c" "jxrlib/image/decode/decode.h" diff --git a/Src/JxrDecode/jxrlib/common/include/wmspecstring.h b/Src/JxrDecode/jxrlib/common/include/wmspecstring.h deleted file mode 100644 index 1d64e816..00000000 --- a/Src/JxrDecode/jxrlib/common/include/wmspecstring.h +++ /dev/null @@ -1,345 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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. -// -//*@@@---@@@@****************************************************************** - - -#if false -#ifndef _WMSPECSTRING_H_ -#define _WMSPECSTRING_H_ - -#if (!defined UNDER_CE && !defined NO_WINDOWS && !defined SPECSTRINGS_H) -#define SPECSTRINGS_H -/************************************************************************* -* See specstrings_strict.h for documentation of all user visible macros. -*************************************************************************/ -#if _MSC_VER -#pragma once -#endif -#include - -#ifndef __SAL_H_FULL_VER -#define __SAL_H_FULL_VER 140050727 -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - /* version specific fixes to bring sal.h upto date */ -#if __SAL_H_FULL_VER <= 140050727 - -/* Missing from RTM sal.h */ -#if !defined(__midl) && defined(_PREFAST_) && _MSC_VER >= 1000 - -#define __inexpressible_readableTo(size) __declspec("SAL_readableTo(inexpressibleCount('" SPECSTRINGIZE(size) "'))") -#define __inexpressible_writableTo(size) __declspec("SAL_writableTo(inexpressibleCount('" SPECSTRINGIZE(size) "'))") -#define __inner_bound __declspec("SAL_bound") -#define __inner_range(lb,ub) __declspec("SAL_range(" SPECSTRINGIZE(lb) "," SPECSTRINGIZE(ub) ")") -#define __inner_assume_bound_dec __inline __nothrow void __AssumeBoundInt(__post __inner_bound int i) {i;} -#define __inner_assume_bound(i) __AssumeBoundInt(i); -#define __inner_allocator __declspec("SAL_allocator") -#else -#define __inexpressible_readableTo(size) -#define __inexpressible_writableTo(size) -#define __inner_bound -#define __inner_range(lb,ub) -#define __inner_assume_bound_dec -#define __inner_assume_bound(i) -#define __inner_allocator -#endif - -#define __xcount(size) __notnull __inexpressible_writableTo(size) -#define __in_xcount(size) __in __pre __inexpressible_readableTo(size) -#define __out_xcount(size) __xcount(size) __post __valid __refparam -#define __out_xcount_part(size,length) __out_xcount(size) __post __inexpressible_readableTo(length) -#define __out_xcount_full(size) __out_xcount_part(size,size) -#define __inout_xcount(size) __out_xcount(size) __pre __valid -#define __inout_xcount_part(size,length) __out_xcount_part(size,length) __pre __valid __pre __inexpressible_readableTo(length) -#define __inout_xcount_full(size) __inout_xcount_part(size,size) -#define __xcount_opt(size) __xcount(size) __exceptthat __maybenull -#define __in_xcount_opt(size) __in_xcount(size) __exceptthat __maybenull -#define __out_xcount_opt(size) __out_xcount(size) __exceptthat __maybenull -#define __out_xcount_part_opt(size,length) __out_xcount_part(size,length) __exceptthat __maybenull -#define __out_xcount_full_opt(size) __out_xcount_full(size) __exceptthat __maybenull -#define __inout_xcount_opt(size) __inout_xcount(size) __exceptthat __maybenull -#define __inout_xcount_part_opt(size,length) __inout_xcount_part(size,length) __exceptthat __maybenull -#define __inout_xcount_full_opt(size) __inout_xcount_full(size) __exceptthat __maybenull -#define __deref_xcount(size) __ecount(1) __post __elem_readableTo(1) __post __deref __notnull __post __deref __inexpressible_writableTo(size) -#define __deref_in __in __pre __deref __deref __readonly -#define __deref_in_ecount(size) __deref_in __pre __deref __elem_readableTo(size) -#define __deref_in_bcount(size) __deref_in __pre __deref __byte_readableTo(size) -#define __deref_in_xcount(size) __deref_in __pre __deref __inexpressible_readableTo(size) -#define __deref_out_xcount(size) __deref_xcount(size) __post __deref __valid __refparam -#define __deref_out_xcount_part(size,length) __deref_out_xcount(size) __post __deref __inexpressible_readableTo(length) -#define __deref_out_xcount_full(size) __deref_out_xcount_part(size,size) -#define __deref_out_xcount(size) __deref_xcount(size) __post __deref __valid __refparam -#define __inout_xcount_opt(size) __inout_xcount(size) __exceptthat __maybenull -#define __inout_xcount_part_opt(size,length) __inout_xcount_part(size,length) __exceptthat __maybenull -#define __inout_xcount_full_opt(size) __inout_xcount_full(size) __exceptthat __maybenull -#define __deref_xcount(size) __ecount(1) __post __elem_readableTo(1) __post __deref __notnull __post __deref __inexpressible_writableTo(size) -#define __deref_in __in __pre __deref __deref __readonly -#define __deref_in_ecount(size) __deref_in __pre __deref __elem_readableTo(size) -#define __deref_in_bcount(size) __deref_in __pre __deref __byte_readableTo(size) -#define __deref_in_xcount(size) __deref_in __pre __deref __inexpressible_readableTo(size) -#define __deref_out_xcount(size) __deref_xcount(size) __post __deref __valid __refparam -#define __deref_out_xcount_part(size,length) __deref_out_xcount(size) __post __deref __inexpressible_readableTo(length) -#define __deref_out_xcount_full(size) __deref_out_xcount_part(size,size) -#define __deref_out_xcount(size) __deref_xcount(size) __post __deref __valid __refparam -#define __deref_inout_xcount(size) __deref_inout __pre __deref __inexpressible_writableTo(size) __post __deref __inexpressible_writableTo(size) -#define __deref_inout_xcount_part(size,length) __deref_inout_xcount(size) __pre __deref __inexpressible_readableTo(length) __post __deref __inexpressible_readableTo(length) -#define __deref_inout_xcount_full(size) __deref_inout_xcount_part(size,size) -#define __deref_xcount_opt(size) __deref_xcount(size) __post __deref __exceptthat __maybenull -#define __deref_in_opt __deref_in __pre __deref __exceptthat __maybenull -#define __deref_in_ecount_opt(size) __deref_in_ecount(size) __pre __deref __exceptthat __maybenull -#define __deref_in_bcount_opt(size) __deref_in_bcount(size) __pre __deref __exceptthat __maybenull -#define __deref_in_xcount_opt(size) __deref_in_xcount(size) __pre __deref __exceptthat __maybenull -#define __deref_out_xcount_opt(size) __deref_out_xcount(size) __post __deref __exceptthat __maybenull -#define __deref_out_xcount_part_opt(size,length) __deref_out_xcount_part(size,length) __post __deref __exceptthat __maybenull -#define __deref_out_xcount_full_opt(size) __deref_out_xcount_full(size) __post __deref __exceptthat __maybenull -#define __deref_inout_xcount_opt(size) __deref_inout_xcount(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull -#define __deref_inout_xcount_part_opt(size,length) __deref_inout_xcount_part(size,length) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull -#define __deref_inout_xcount_full_opt(size) __deref_inout_xcount_full(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull -#define __deref_opt_xcount(size) __deref_xcount(size) __exceptthat __maybenull -#define __deref_opt_in __deref_in __exceptthat __maybenull -#define __deref_opt_in_ecount(size) __deref_in_ecount(size) __exceptthat __maybenull -#define __deref_opt_in_bcount(size) __deref_in_bcount(size) __exceptthat __maybenull -#define __deref_opt_in_xcount(size) __deref_in_xcount(size) __exceptthat __maybenull -#define __deref_opt_out_xcount(size) __deref_out_xcount(size) __exceptthat __maybenull -#define __deref_opt_out_xcount_part(size,length) __deref_out_xcount_part(size,length) __exceptthat __maybenull -#define __deref_opt_out_xcount_full(size) __deref_out_xcount_full(size) __exceptthat __maybenull -#define __deref_opt_inout_xcount(size) __deref_inout_xcount(size) __exceptthat __maybenull -#define __deref_opt_inout_xcount_part(size,length) __deref_inout_xcount_part(size,length) __exceptthat __maybenull -#define __deref_opt_inout_xcount_full(size) __deref_inout_xcount_full(size) __exceptthat __maybenull -#define __deref_opt_xcount_opt(size) __deref_xcount_opt(size) __exceptthat __maybenull -#define __deref_opt_in_opt __deref_in_opt __exceptthat __maybenull -#define __deref_opt_in_ecount_opt(size) __deref_in_ecount_opt(size) __exceptthat __maybenull -#define __deref_opt_in_bcount_opt(size) __deref_in_bcount_opt(size) __exceptthat __maybenull -#define __deref_opt_in_xcount_opt(size) __deref_in_xcount_opt(size) __exceptthat __maybenull -#define __deref_opt_out_xcount_opt(size) __deref_out_xcount_opt(size) __exceptthat __maybenull -#define __deref_opt_out_xcount_part_opt(size,length) __deref_out_xcount_part_opt(size,length) __exceptthat __maybenull -#define __deref_opt_out_xcount_full_opt(size) __deref_out_xcount_full_opt(size) __exceptthat __maybenull -#define __deref_opt_inout_xcount_opt(size) __deref_inout_xcount_opt(size) __exceptthat __maybenull -#define __deref_opt_inout_xcount_part_opt(size,length) __deref_inout_xcount_part_opt(size,length) __exceptthat __maybenull -#define __deref_opt_inout_xcount_full_opt(size) __deref_inout_xcount_full_opt(size) __exceptthat __maybenull -/* Must protect redfinitions of macros to workaround rc.exe issues. */ -#ifndef RC_INVOKED -#undef __nullnullterminated -#define __nullnullterminated __xcount("string terminated by two nulls") -#undef __checkReturn -#define __checkReturn __post __inner_checkReturn -#endif -#endif //__SAL_H_FULL_VER <= 140050727 - -/************************************************************************ - New extensions to sal.h follow here. -*************************************************************************/ - -#if (_MSC_VER >= 1000) && !defined(__midl) && defined(_PREFAST_) -#define __file_parser(typ) __declspec("SAL_file_parser(function, " #typ ")") -#define __file_parser_class(typ) __declspec("SAL_file_parser(class, " #typ ")") -#define __file_parser_library(typ) extern int __declspec("SAL_file_parser(library, " #typ ")") __iSALFileParserLibrary##typ; -#define __source_code_content(typ) extern int __declspec("SAL_source_code_content(" #typ ")") __iSAL_Source_Code_Content##typ; -#define __class_code_content(typ) __declspec("SAL_class_code_content(" #typ ")") -#define __analysis_assert(e) __assume(e) -#define __analysis_hint(hint) __declspec("SAL_analysisHint(" #hint ")") -/* Internal defintions */ -#define __inner_data_source(src_raw) __declspec("SAL_untrusted_data_source(" src_raw ")") -#define __inner_this_data_source(src_raw) __declspec("SAL_untrusted_data_source_this(" src_raw ")") -#define __inner_out_validated(typ_raw) __declspec("SAL_post") __declspec("SAL_validated(" typ_raw ")") -#define __inner_this_out_validated(typ_raw) __declspec("SAL_validated_this(" typ_raw ")") -#define __inner_assume_validated_dec __inline __nothrow void __AssumeValidated(__inner_out_validated("BY_DESIGN") const void *p) {p;} -#define __inner_assume_validated(p) __AssumeValidated(p) -#define __inner_transfer(formal) __declspec("SAL_transfer_adt_property_from(" SPECSTRINGIZE(formal) ")") -#define __inner_encoded __declspec("SAL_encoded") - -#define __$adt_prop(adt,prop) __declspec("SAL_adt("#adt","#prop")") -#define __$adt_add_prop(adt,prop) __declspec("SAL_add_adt_property("#adt","#prop")") -#define __$adt_remove_prop(adt,prop) __declspec("SAL_remove_adt_property("#adt","#prop")") -#define __$adt_transfer_prop(arg) __declspec("SAL_transfer_adt_property_from("#arg")") -#define __$adt_type_props(typ) __declspec("SAL_post_type("#typ")") -#define __$volatile __declspec("SAL_volatile") -#define __$nonvolatile __declspec("SAL_nonvolatile") -#define __$possibly_notnulltermiated __declspec("SAL_RequiresZeroTermination(sometimes)") -#else -#define __file_parser(typ) -#define __file_parser_class(typ) -#define __file_parser_library(typ) -#define __source_code_content(typ) -#define __class_code_content(typ) -#define __analysis_assert(e) -#define __analysis_hint(hint) -/* Internal defintions */ -#define __inner_data_source(src_raw) -#define __inner_this_data_source(src_raw) -#define __inner_out_validated(typ_raw) -#define __inner_this_out_validated(typ_raw) -#define __inner_assume_validated_dec -#define __inner_assume_validated(p) -#define __inner_transfer(formal) -#define __inner_encoded -#define __$adt_prop(adt,prop) -#define __$adt_add_prop(adt,prop) -#define __$adt_remove_prop(adt,prop) -#define __$adt_transfer_prop(arg) -#define __$adt_type_props(typ) -#define __$volatile -#define __$nonvolatile -#define __$possibly_notnulltermiated -#endif // #if (_MSC_VER >= 1000) && !defined(__midl) && defined(_PREFAST_) - -#define __field_ecount(size) __notnull __elem_writableTo(size) -#define __field_bcount(size) __notnull __byte_writableTo(size) -#define __field_xcount(size) __notnull __inexpressible_writableTo(size) - -#define __field_ecount_opt(size) __maybenull __elem_writableTo(size) -#define __field_bcount_opt(size) __maybenull __byte_writableTo(size) -#define __field_xcount_opt(size) __maybenull __inexpressible_writableTo(size) - -#define __field_ecount_part(size,init) __notnull __elem_writableTo(size) __elem_readableTo(init) -#define __field_bcount_part(size,init) __notnull __byte_writableTo(size) __byte_readableTo(init) -#define __field_xcount_part(size,init) __notnull __inexpressible_writableTo(size) __inexpressible_readableTo(init) - -#define __field_ecount_part_opt(size,init) __maybenull __elem_writableTo(size) __elem_readableTo(init) -#define __field_bcount_part_opt(size,init) __maybenull __byte_writableTo(size) __byte_readableTo(init) -#define __field_xcount_part_opt(size,init) __maybenull __inexpressible_writableTo(size) __inexpressible_readableTo(init) - -#define __field_ecount_full(size) __field_ecount_part(size,size) -#define __field_bcount_full(size) __field_bcount_part(size,size) -#define __field_xcount_full(size) __field_xcount_part(size,size) - -#define __field_ecount_full_opt(size) __field_ecount_part_opt(size,size) -#define __field_bcount_full_opt(size) __field_bcount_part_opt(size,size) -#define __field_xcount_full_opt(size) __field_xcount_part_opt(size,size) - -#define __struct_bcount(size) __field_bcount(size) -#define __struct_xcount(size) __field_xcount(size) - -#if !defined(__out_awcount) -#define __out_awcount(expr,size) __pre __notnull \ - __byte_writableTo((expr) ? (size) : (size) * 2) \ - __post __valid __refparam -#endif -#if !defined(__in_awcount) -#define __in_awcount(expr,size) __pre __valid \ - __pre __deref __readonly \ - __byte_readableTo((expr) ? (size) : (size) * 2) -#endif - -/* integer related macros */ -#define __allocator __inner_allocator -#define __bound __inner_bound -#define __range(lb,ub) __inner_range(lb,ub) -#define __in_bound __pre __inner_bound -#define __out_bound __post __inner_bound -#define __deref_out_bound __post __deref __inner_bound -#define __in_range(lb,ub) __pre __inner_range(lb,ub) -#define __out_range(lb,ub) __post __inner_range(lb,ub) -#define __deref_in_range(lb,ub) __pre __deref __inner_range(lb,ub) -#define __deref_out_range(lb,ub) __post __deref __inner_range(lb,ub) -#define __field_range(lb,ub) __range(lb,ub) -#define __field_data_source(src_sym) __inner_data_source(#src_sym) - -/* Pentraion review macros */ -#define __in_data_source(src_sym) __pre __inner_data_source(#src_sym) -#define __out_data_source(src_sym) __post __inner_data_source(#src_sym) -#define __out_validated(typ_sym) __inner_out_validated(#typ_sym) -#define __this_out_data_source(src_sym) __inner_this_data_source(#src_sym) -#define __this_out_validated(typ_sym) __inner_this_out_validated(#typ_sym) -#define __transfer(formal) __post __inner_transfer(formal) -#define __rpc_entry __inner_control_entrypoint(RPC) -#define __kernel_entry __inner_control_entrypoint(UserToKernel) -#define __gdi_entry __inner_control_entrypoint(GDI) -#define __encoded_pointer __inner_encoded -#define __encoded_array __inner_encoded -#define __field_encoded_pointer __inner_encoded -#define __field_encoded_array __inner_encoded -#define __type_has_adt_prop(adt,prop) __$adt_prop(adt,prop) -#define __out_has_adt_prop(adt,prop) __post __$adt_add_prop(adt,prop) -#define __out_not_has_adt_prop(adt,prop) __post __$adt_remove_prop(adt,prop) -#define __out_transfer_adt_prop(arg) __post __$adt_transfer_prop(arg) -#define __out_has_type_adt_props(typ) __post __$adt_type_props(typ) - -/* useful PFD related macros */ -#define __possibly_notnulltermiated __post __$possibly_notnulltermiated - -#if defined(_WINDOWS_) -/* Windows Internal */ -#define __volatile __$volatile -#define __nonvolatile __$nonvolatile -#define __deref_volatile __deref __volatile -#define __deref_nonvolatile __deref __nonvolatile -#endif - -/* declare stub functions for macros */ - __inner_assume_validated_dec - __inner_assume_bound_dec - -#define __assume_validated(p) __inner_assume_validated(p) -#define __assume_bound(i) __inner_assume_bound(i) -#ifdef __cplusplus -} -#endif -#include -#ifdef _PREFIX_ -/************************************************************************** -* Defintion of __pfx_assume and __pfx_assert. Thse should be the only -* defintions of these functions. -***************************************************************************/ -#if __cplusplus -extern "C" void __pfx_assert(bool, const char*); -extern "C" void __pfx_assume(bool, const char*); -#else -void __pfx_assert(int, const char*); -void __pfx_assume(int, const char*); -#endif -/************************************************************************** -* Redefintion of __analysis_assume and __analysis_assert for PREFIX build -**************************************************************************/ -#undef __analysis_assume -#undef __analysis_assert -#define __analysis_assume(e) (__pfx_assume(e,"pfx_assume"),__assume(e)); -#define __analysis_assert(e) (__pfx_assert(e,"pfx_assert"),__assume(e)); -#endif /* ifdef _PREFIX_ */ - -/************************************************************************** -* This include should always be the last thing in this file. -* Must avoid redfinitions of macros to workaround rc.exe issues. -***************************************************************************/ -#if !(defined(RC_INVOKED) || defined(SORTPP_PASS)) -#include -#endif /* if !(defined(RC_INVOKED) || defined(SORTPP_PASS)) */ -#endif /* #ifndef SPECSTRINGS_H */ - -// Some CE versions don't have specstrings.h, some have very old version without -// __specstrings defined. So we handle CE separately in wmasalce.h -#if defined(UNDER_CE) || defined(NO_WINDOWS) -#include "wmspecstringce.h" -#endif - -#endif //_WMSPECSTRING_H_ - -#endif diff --git a/Src/JxrDecode/jxrlib/common/include/wmspecstrings_adt.h b/Src/JxrDecode/jxrlib/common/include/wmspecstrings_adt.h deleted file mode 100644 index 66d95767..00000000 --- a/Src/JxrDecode/jxrlib/common/include/wmspecstrings_adt.h +++ /dev/null @@ -1,71 +0,0 @@ -//*@@@+++@@@@****************************************************************** -// -// 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 -/************************************************************************* -* DEFINITIONS OF NEW TYPES -*************************************************************************/ -#if !defined(__midl) -#define __$compname_props \ - __type_has_adt_prop(compname,nullterminated) \ - __type_has_adt_prop(compname,valid_schars) \ - __type_has_adt_prop(compname,correct_len) \ - __nullterminated -#if defined(UNICODE) || defined(_UNICODE) -#define __$TCHAR unsigned short -#else -#define __$TCHAR char -#endif -typedef __$compname_props char* ValidCompNameA; -typedef __$compname_props unsigned short* ValidCompNameW; -typedef __$compname_props const unsigned short* ConstValidCompNameW; -typedef __$compname_props __$TCHAR* SAL_ValidCompNameT; -typedef __$compname_props const __$TCHAR* SAL_ConstValidCompNameT; -#undef __$compname_props -#undef __$TCHAR -#endif - -/************************************************************************* -* DEFINITIONS OF INLINE FUNCTIONS FOR CASTING TO THE NEW TYPES : USER -*************************************************************************/ -#if (_MSC_VER >= 1000) && !defined(__midl) && defined(_PREFAST_) -#ifdef __cplusplus -extern "C" { -#endif - void __inline __nothrow __SAL_ValidCompNameA(__out_has_type_adt_props(ValidCompNameA) const void* expr) { expr; } - void __inline __nothrow __SAL_ValidCompNameW(__out_has_type_adt_props(ValidCompNameW) const void* expr) { expr; } -#ifdef __cplusplus -} -#endif -#define __assume_ValidCompNameA(expr) __SAL_ValidCompNameA(expr) -#define __assume_ValidCompNameW(expr) __SAL_ValidCompNameW(expr) -#else -#define __assume_ValidCompNameA(expr) -#define __assume_ValidCompNameW(expr) -#endif - diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h index a94e9841..e03ad46a 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h @@ -40,12 +40,12 @@ extern "C" { #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 +//#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 @@ -298,24 +298,24 @@ extern "C" { //================================================================ -#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__ +//#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__ +//#endif // __ANSI__ //================================================================ typedef struct tagPKStream { @@ -336,9 +336,9 @@ extern "C" { ERR(*CreateStreamFromMemory)(struct WMPStream**, void*, size_t); ERR(*Release)(PKFactory**); -#ifdef __ANSI__ -#undef PKFactory -#endif // __ANSI__ +//#ifdef __ANSI__ +//#undef PKFactory +//#endif // __ANSI__ } PKFactory; //---------------------------------------------------------------- @@ -358,9 +358,9 @@ extern "C" { ERR(*CreateFormatConverter)(PKFormatConverter**); ERR(*Release)(PKCodecFactory**); -#ifdef __ANSI__ -#undef PKCodecFactory -#endif // __ANSI__ +//#ifdef __ANSI__ +//#undef PKCodecFactory +//#endif // __ANSI__ } PKCodecFactory; //---------------------------------------------------------------- @@ -465,9 +465,9 @@ extern "C" { struct WMPStream* pPATempFile; } WMP; -#ifdef __ANSI__ -#undef PKImageEncode -#endif // __ANSI__ +//#ifdef __ANSI__ +//#undef PKImageEncode +//#endif // __ANSI__ } PKImageEncode; //---------------------------------------------------------------- @@ -560,9 +560,9 @@ extern "C" { DESCRIPTIVEMETADATA sDescMetadata; } WMP; -#ifdef __ANSI__ -#undef PKImageDecode -#endif // __ANSI__ +//#ifdef __ANSI__ +//#undef PKImageDecode +//#endif // __ANSI__ } PKImageDecode; //---------------------------------------------------------------- @@ -608,9 +608,9 @@ extern "C" { PKImageDecode* pDecoder; PKPixelFormatGUID enPixelFormat; -#ifdef __ANSI__ -#undef PKFormatConverter -#endif // __ANSI__ +//#ifdef __ANSI__ +//#undef PKFormatConverter +//#endif // __ANSI__ } PKFormatConverter; //---------------------------------------------------------------- diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h index 141366bb..f02c1bd3 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h @@ -29,10 +29,10 @@ //#include #include "../image/sys/windowsmediaphoto.h" -#ifndef WIN32 -//#include -#include "../common/include/wmspecstring.h" -#endif +//#ifndef WIN32 +////#include +//#include "../common/include/wmspecstring.h" +//#endif #ifndef UNREFERENCED_PARAMETER #define UNREFERENCED_PARAMETER(P) { (P) = (P); } From 0b0538a06d274ff3fd047ac62516633857727ac7 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Fri, 28 Jul 2023 20:02:49 +0200 Subject: [PATCH 10/98] get rid of min/max --- Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c | 4 ++-- Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c index 1549dcd5..56f3d4c5 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c @@ -672,7 +672,7 @@ ERR PKImageEncode_WriteSource( || &GUID_PKPixelFormat16bppYUV422 == pPITo.pGUIDPixFmt) cbStrideTo >>= 1; - cbStride = max(cbStrideFrom, cbStrideTo); + cbStride = cbStrideFrom > cbStrideTo ? cbStrideFrom : cbStrideTo;// max(cbStrideFrom, cbStrideTo); // actual dec/enc with local buffer Call(PKAllocAligned((void**)&pb, cbStride * pRect->Height, 128)); @@ -757,7 +757,7 @@ ERR PKImageEncode_Transcode( || &GUID_PKPixelFormat16bppYUV422 == pPITo.pGUIDPixFmt) cbStrideTo >>= 1; - cbStride = max(cbStrideFrom, cbStrideTo); + cbStride = cbStrideFrom > cbStrideTo ? cbStrideFrom : cbStrideTo;// max(cbStrideFrom, cbStrideTo); if (pIE->bWMP) { cParam.cLeftX = pFC->pDecoder->WMP.wmiI.cROILeftX; diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c index 1f40a620..9dfdf02d 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c @@ -832,7 +832,7 @@ ERR PKImageEncode_EncodeContent_Encode( (pIE->WMP.wmiSCP.bYUVData && pIE->WMP.wmiSCP.cfColorFormat == YUV_420)); CWMImageBufferInfo wmiBI = { 0 }; wmiBI.pv = pbPixels + cbStride * i / (f420 ? 2 : 1); - wmiBI.cLine = min(16, cLine - i); + wmiBI.cLine = 16 < cLine - i ? 16 : cLine - i;// min(16, cLine - i); wmiBI.cbStride = cbStride; FailIf(ICERR_OK != ImageStrEncEncode(pIE->WMP.ctxSC, &wmiBI), WMP_errFail); } @@ -956,7 +956,7 @@ ERR PKImageEncode_EncodeAlpha_Encode( { CWMImageBufferInfo wmiBI = { 0 }; wmiBI.pv = pbPixels + cbStride * i; - wmiBI.cLine = min(16, cLine - i); + wmiBI.cLine = 16 < cLine - 1 ? 16 : cLine - 1;// min(16, cLine - i); wmiBI.cbStride = cbStride; FailIf(ICERR_OK != ImageStrEncEncode(pIE->WMP.ctxSC_Alpha, &wmiBI), WMP_errFail); } @@ -1337,7 +1337,7 @@ ERR PKImageEncode_WritePixelsBandedEnd_WMP(PKImageEncode* pIE) char rgbBuf[TEMPFILE_COPYBUF_SIZE]; size_t cbCopy; - cbCopy = min(sizeof(rgbBuf), cbAlpha - cbBytesCopied); + cbCopy = sizeof(rgbBuf) < cbAlpha - cbBytesCopied ? sizeof(rgbBuf) : cbAlpha - cbBytesCopied;// min(sizeof(rgbBuf), cbAlpha - cbBytesCopied); Call(pAlphaStream->Read(pAlphaStream, rgbBuf, cbCopy)); Call(pMainStream->Write(pMainStream, rgbBuf, cbCopy)); From adf00c089721d096eb8164c506136ab2f7108db7 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Fri, 28 Jul 2023 20:09:04 +0200 Subject: [PATCH 11/98] get rid of min/max --- Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c index a11fef5f..cdad6a80 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c @@ -974,9 +974,19 @@ ERR RGB96Float_RGBE(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbS for (x = 0; x < iWidth; x++) { // We clamp source RGB values at zero (don't allow negative numbers) - const float fltRed = max(pfltSrcPixel[3 * x], 0.0F); + /* const float fltRed = max(pfltSrcPixel[3 * x], 0.0F); const float fltGreen = max(pfltSrcPixel[3 * x + 1], 0.0F); - const float fltBlue = max(pfltSrcPixel[3 * x + 2], 0.0F); + const float fltBlue = max(pfltSrcPixel[3 * x + 2], 0.0F);*/ + float fltRed = pfltSrcPixel[3 * x]; + float fltGreen = pfltSrcPixel[3 * x + 1]; + float fltBlue = pfltSrcPixel[3 * x + 2]; + if (fltRed < 0) + fltRed = 0; + if (fltGreen < 0) + fltGreen = 0; + if (fltBlue < 0) + fltBlue = 0; + float fltMaxPos = fltRed; if (fltGreen > fltMaxPos) @@ -985,7 +995,7 @@ ERR RGB96Float_RGBE(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbS if (fltBlue > fltMaxPos) fltMaxPos = fltBlue; - if (fltMaxPos < 1e-32) + if (fltMaxPos < 1e-32f) { piDstPixel[4 * x] = 0; // R piDstPixel[4 * x + 1] = 0; // G From 3d9e7f5d5b94193a157125db38755996261319c7 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sat, 29 Jul 2023 01:37:27 +0200 Subject: [PATCH 12/98] load4 - make big-endian aware etc. --- Src/JxrDecode/CMakeLists.txt | 24 +++++++ Src/JxrDecode/JxrDecode_Config.h.in | 5 ++ Src/JxrDecode/jxrlib/image/decode/segdec.c | 67 ++++++++++++++++---- Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c | 1 - Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h | 43 +------------ Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c | 1 - Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c | 27 ++++---- Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h | 37 ++++------- 8 files changed, 111 insertions(+), 94 deletions(-) diff --git a/Src/JxrDecode/CMakeLists.txt b/Src/JxrDecode/CMakeLists.txt index a15aea11..f587d533 100644 --- a/Src/JxrDecode/CMakeLists.txt +++ b/Src/JxrDecode/CMakeLists.txt @@ -4,6 +4,9 @@ # build "JxrDecode" as an "object library" (cf. https://cmake.org/cmake/help/v3.0/command/add_library.html) -> we want it to be merged into the # static libCIZ-library + +include(CheckSymbolExists) + add_library(JxrDecodeStatic OBJECT JxrDecode.cpp ##stdafx.cpp @@ -114,6 +117,27 @@ if (CRASH_ON_UNALIGNED_ACCESS) else() set (jxrdecode_CrashOnUnalignedIntegers 0) endif() +# c.f. https://stackoverflow.com/questions/41770887/cross-platform-definition-of-byteswap-uint64-and-byteswap-ulong +check_symbol_exists("__builtin_bswap32" "" jxrdecode_Has_builtin_bswap32) +message("jxrdecode_Has_builtin_bswap32 = ${jxrdecode_Has_builtin_bswap32}.") +if (NOT jxrdecode_Has_builtin_bswap32) + check_symbol_exists(_byteswap_ulong "stdlib.h" jxrdecode_Has_byteswap_long_in_stdlib) + message("jxrdecode_Has_byteswap_long_in_stdlib = ${jxrdecode_Has_byteswap_long_in_stdlib}.") + if (NOT jxrdecode_Has_byteswap_long_in_stdlib) + check_symbol_exists(bswap32 "sys/endian.h" jxrdecode_Has_bswap_long_in_sys_endian) + endif() +endif() + +if (NOT jxrdecode_Has_builtin_bswap32) + set (jxrdecode_Has_builtin_bswap32 0) +endif() +if (NOT jxrdecode_Has_byteswap_long_in_stdlib) + set (jxrdecode_Has_byteswap_long_in_stdlib 0) +endif() +if (NOT jxrdecode_Has_bswap_long_in_sys_endian) + set (jxrdecode_Has_bswap_long_in_sys_endian 0) +endif() + configure_file ( "${CMAKE_CURRENT_SOURCE_DIR}/JxrDecode_Config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/JxrDecode_Config.h" diff --git a/Src/JxrDecode/JxrDecode_Config.h.in b/Src/JxrDecode/JxrDecode_Config.h.in index d3a5414f..3a101e8c 100644 --- a/Src/JxrDecode/JxrDecode_Config.h.in +++ b/Src/JxrDecode/JxrDecode_Config.h.in @@ -11,3 +11,8 @@ // is 1 it means that we cannot load an integer from an unaligned address (we'd // get a bus-error if we try), 0 means that the CPU can load from unaligned addresses #define JXRDECODE_SIGBUS_ON_UNALIGNEDINTEGERS @jxrdecode_CrashOnUnalignedIntegers@ + + +#define JXRDECODE_HAS_BUILTIN_BSWAP32 @jxrdecode_Has_builtin_bswap32@ +#define JXRDECODE_HAS_BYTESWAP_IN_STDLIB @jxrdecode_Has_byteswap_long_in_stdlib@ +#define JXRDECODE_HAS_BSWAP_LONG_IN_SYS_ENDIAN @jxrdecode_Has_bswap_long_in_sys_endian@ \ No newline at end of file diff --git a/Src/JxrDecode/jxrlib/image/decode/segdec.c b/Src/JxrDecode/jxrlib/image/decode/segdec.c index a3828394..fe358a7f 100644 --- a/Src/JxrDecode/jxrlib/image/decode/segdec.c +++ b/Src/JxrDecode/jxrlib/image/decode/segdec.c @@ -28,6 +28,7 @@ #include "../sys/strcodec.h" #include "decode.h" +#include #ifdef MEM_TRACE #define TRACE_MALLOC 1 @@ -35,6 +36,12 @@ #define TRACE_HEAP 0 #include "memtrace.h" #endif +#if JXRDECODE_HAS_BYTESWAP_IN_STDLIB + #include +#endif +#if JXRDECODE_HAS_BSWAP_LONG_IN_SYS_ENDIAN + #include +#endif extern const int dctIndex[3][16]; extern const int blkOffset[16]; @@ -54,20 +61,54 @@ static Int DecodeSignificantAbsLevel(struct CAdaptiveHuffman* pAHexpt, BitIOInfo //================================================================ static U32 _FORCEINLINE _load4(void* pv) { -#ifdef _BIG__ENDIAN_ - return (*(U32*)pv); -#else // _BIG__ENDIAN_ -#if defined(_M_IA64) || defined(_ARM_) - U32 v; - v = ((U16*)pv)[0]; - v |= ((U32)((U16*)pv)[1]) << 16; - return _byteswap_ulong(v); -#else // _M_IA64 +#if JXRDECODE_ISBIGENDIANHOST + // on a big-endian host, we have nothing to do, so just load the value + #if JXRDECODE_SIGBUS_ON_UNALIGNEDINTEGERS + U32 v; + memcpy(&v, pv, 4); + return v; + #else + return (*(U32*)pv); + #endif +#else // JXRDECODE_ISBIGENDIANHOST + // on a little endian machine, we need to swap the bytes U32 v; - memcpy(&v, pv, sizeof(U32)); - return _byteswap_ulong(v); -#endif // _M_IA64 -#endif // _BIG__ENDIAN_ + #if JXRDECODE_SIGBUS_ON_UNALIGNEDINTEGERS + memcpy(&v, pv, 4); + #else + v = (*(U32*)pv); + #endif + + // ...and use the appropriate byte-swapping function + #if JXRDECODE_HAS_BUILTIN_BSWAP32 + return __builtin_bswap32(v); + #elif JXRDECODE_HAS_BYTESWAP_IN_STDLIB + return _byteswap_ulong(v); + #elif JXRDECODE_HAS_BSWAP_LONG_IN_SYS_ENDIAN + return bswap_32(v); + #else + return (((v & 0xff000000u) >> 24) | + ((v & 0x00ff0000u) >> 8) | + ((v & 0x0000ff00u) << 8) | + ((v & 0x000000ffu) << 24)); + #endif +#endif + + +//#ifdef _BIG__ENDIAN_ +// return (*(U32*)pv); +//#else // _BIG__ENDIAN_ +//#if defined(_M_IA64) || defined(_ARM_) +// U32 v; +// v = ((U16*)pv)[0]; +// v |= ((U32)((U16*)pv)[1]) << 16; +// return _byteswap_ulong(v); +//#else // _M_IA64 +// U32 v; +// memcpy(&v, pv, sizeof(U32)); +// return _byteswap_ulong(v); +//#endif // _M_IA64 +//#endif // _BIG__ENDIAN_ } static _FORCEINLINE U32 _peekBit16(BitIOInfo* pIO, U32 cBits) diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c index 56f3d4c5..4cdc3222 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c @@ -972,4 +972,3 @@ ERR PKImageDecode_Create( Cleanup: return err; } - diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h index e03ad46a..6228bafa 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h @@ -32,7 +32,6 @@ extern "C" { #endif #include "JXRMeta.h" -//#include guiddef.h> #include "../common/include/guiddef.h" //================================================================ @@ -40,17 +39,7 @@ extern "C" { #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 @@ -298,24 +287,13 @@ extern "C" { //================================================================ -//#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__ + // forward declaration 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 { @@ -336,9 +314,6 @@ extern "C" { ERR(*CreateStreamFromMemory)(struct WMPStream**, void*, size_t); ERR(*Release)(PKFactory**); -//#ifdef __ANSI__ -//#undef PKFactory -//#endif // __ANSI__ } PKFactory; //---------------------------------------------------------------- @@ -358,9 +333,6 @@ extern "C" { ERR(*CreateFormatConverter)(PKFormatConverter**); ERR(*Release)(PKCodecFactory**); -//#ifdef __ANSI__ -//#undef PKCodecFactory -//#endif // __ANSI__ } PKCodecFactory; //---------------------------------------------------------------- @@ -464,10 +436,6 @@ extern "C" { BANDEDENCSTATE eBandedEncState; struct WMPStream* pPATempFile; } WMP; - -//#ifdef __ANSI__ -//#undef PKImageEncode -//#endif // __ANSI__ } PKImageEncode; //---------------------------------------------------------------- @@ -559,10 +527,6 @@ extern "C" { DESCRIPTIVEMETADATA sDescMetadata; } WMP; - -//#ifdef __ANSI__ -//#undef PKImageDecode -//#endif // __ANSI__ } PKImageDecode; //---------------------------------------------------------------- @@ -608,9 +572,6 @@ extern "C" { PKImageDecode* pDecoder; PKPixelFormatGUID enPixelFormat; -//#ifdef __ANSI__ -//#undef PKFormatConverter -//#endif // __ANSI__ } PKFormatConverter; //---------------------------------------------------------------- diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c index cdad6a80..1262652a 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c @@ -2345,4 +2345,3 @@ ERR PKFormatConverter_Release(PKFormatConverter** ppFC) Cleanup: return err; } - diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c index 42fcc0ad..fbdee3b2 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c @@ -588,9 +588,9 @@ ERR StreamCopyIFD(struct WMPStream* pWS, U32 ofssrc, U8* pbdst, U32 cbdst, U32* //================================================================ ERR GetUShort( - /*__in_ecount(1)*/ struct WMPStream* pWS, + struct WMPStream* pWS, size_t offPos, - /*__out_ecount(1)*/ U16* puValue) + U16* puValue) { ERR err = WMP_errSuccess; U8 cVal; @@ -606,7 +606,7 @@ ERR GetUShort( } ERR PutUShort( - /*__in_ecount(1)*/ struct WMPStream* pWS, + struct WMPStream* pWS, size_t offPos, U16 uValue) { @@ -623,9 +623,9 @@ ERR PutUShort( } ERR GetULong( - /*__in_ecount(1)*/ struct WMPStream* pWS, + struct WMPStream* pWS, size_t offPos, - /*__out_ecount(1)*/ U32* puValue) + U32* puValue) { ERR err = WMP_errSuccess; U8 cVal; @@ -645,7 +645,7 @@ ERR GetULong( } ERR PutULong( - /*__in_ecount(1)*/ struct WMPStream* pWS, + struct WMPStream* pWS, size_t offPos, U32 uValue) { @@ -666,9 +666,9 @@ ERR PutULong( } -ERR ReadBinaryData(/*__in_ecount(1)*/ struct WMPStream* pWS, - const /*__in_win*/ U32 uCount, - const /*__in_win*/ U32 uValue, +ERR ReadBinaryData(struct WMPStream* pWS, + const U32 uCount, + const U32 uValue, U8** ppbData) { ERR err = WMP_errSuccess; @@ -704,10 +704,10 @@ ERR ReadBinaryData(/*__in_ecount(1)*/ struct WMPStream* pWS, 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) + const U16 uType, + const U32 uCount, + const U32 uValue, + DPKPROPVARIANT* pvar) { ERR err = WMP_errSuccess; // U8 *pbData = NULL; @@ -902,4 +902,3 @@ ERR WriteWmpDE( *pOffPos = offPos; return err; } - diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h index f02c1bd3..f79bd3aa 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h @@ -27,12 +27,7 @@ //*@@@---@@@@****************************************************************** #pragma once -//#include #include "../image/sys/windowsmediaphoto.h" -//#ifndef WIN32 -////#include -//#include "../common/include/wmspecstring.h" -//#endif #ifndef UNREFERENCED_PARAMETER #define UNREFERENCED_PARAMETER(P) { (P) = (P); } @@ -108,12 +103,6 @@ #define WMP_valWMPhotoID WMP_valCompression -//#ifdef WIN32 -//#define __in_win __in -//#define __out_win __out -//#endif - - //================================================================ typedef enum @@ -197,43 +186,43 @@ typedef struct tagWmpDEMisc //================================================================ EXTERN_C ERR GetUShort( - /* __in_ecount(1)*/ struct WMPStream* pWS, + struct WMPStream* pWS, size_t offPos, - /*__out_ecount(1)*/ U16* puValue + U16* puValue ); EXTERN_C ERR PutUShort( - /*__in_ecount(1)*/ struct WMPStream* pWS, + struct WMPStream* pWS, size_t offPos, U16 uValue ); EXTERN_C ERR GetULong( - /*__in_ecount(1)*/ struct WMPStream* pWS, + struct WMPStream* pWS, size_t offPos, - /*__out_ecount(1)*/ U32* puValue + U32* puValue ); EXTERN_C ERR PutULong( - /*__in_ecount(1)*/ struct WMPStream* pWS, + struct WMPStream* pWS, size_t offPos, U32 uValue ); EXTERN_C ERR WriteWmpDE( - /*__in_ecount(1)*/ struct WMPStream* pWS, + struct WMPStream* pWS, size_t* pOffPos, - const /*__in_ecount(1)*/ WmpDE* pDE, + const 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); +EXTERN_C ERR ReadPropvar(struct WMPStream* pWS, + const U16 uType, + const U32 uCount, + const U32 uValue, + DPKPROPVARIANT* pvar); From 446afda2bcc7c4fc87852602c15fd86a5299a8a3 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sat, 29 Jul 2023 01:43:37 +0200 Subject: [PATCH 13/98] fix JXRDECODE_HAS_BUILTIN_BSWAP32 --- Src/JxrDecode/CMakeLists.txt | 2 +- Src/JxrDecode/jxrlib/image/decode/segdec.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Src/JxrDecode/CMakeLists.txt b/Src/JxrDecode/CMakeLists.txt index f587d533..4f37b1f0 100644 --- a/Src/JxrDecode/CMakeLists.txt +++ b/Src/JxrDecode/CMakeLists.txt @@ -118,7 +118,7 @@ else() set (jxrdecode_CrashOnUnalignedIntegers 0) endif() # c.f. https://stackoverflow.com/questions/41770887/cross-platform-definition-of-byteswap-uint64-and-byteswap-ulong -check_symbol_exists("__builtin_bswap32" "" jxrdecode_Has_builtin_bswap32) +check_symbol_exists("__builtin_bswap32" jxrdecode_Has_builtin_bswap32) message("jxrdecode_Has_builtin_bswap32 = ${jxrdecode_Has_builtin_bswap32}.") if (NOT jxrdecode_Has_builtin_bswap32) check_symbol_exists(_byteswap_ulong "stdlib.h" jxrdecode_Has_byteswap_long_in_stdlib) diff --git a/Src/JxrDecode/jxrlib/image/decode/segdec.c b/Src/JxrDecode/jxrlib/image/decode/segdec.c index fe358a7f..7f24a09f 100644 --- a/Src/JxrDecode/jxrlib/image/decode/segdec.c +++ b/Src/JxrDecode/jxrlib/image/decode/segdec.c @@ -36,6 +36,9 @@ #define TRACE_HEAP 0 #include "memtrace.h" #endif +#if JXRDECODE_HAS_BUILTIN_BSWAP32 +#include +#endif #if JXRDECODE_HAS_BYTESWAP_IN_STDLIB #include #endif From 429f5f2081e7b8384396879e4d8a366f1d874762 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sat, 29 Jul 2023 01:44:56 +0200 Subject: [PATCH 14/98] fix --- Src/JxrDecode/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/JxrDecode/CMakeLists.txt b/Src/JxrDecode/CMakeLists.txt index 4f37b1f0..8198aea7 100644 --- a/Src/JxrDecode/CMakeLists.txt +++ b/Src/JxrDecode/CMakeLists.txt @@ -118,7 +118,7 @@ else() set (jxrdecode_CrashOnUnalignedIntegers 0) endif() # c.f. https://stackoverflow.com/questions/41770887/cross-platform-definition-of-byteswap-uint64-and-byteswap-ulong -check_symbol_exists("__builtin_bswap32" jxrdecode_Has_builtin_bswap32) +check_symbol_exists(__builtin_bswap32 "byteswap.h" jxrdecode_Has_builtin_bswap32) message("jxrdecode_Has_builtin_bswap32 = ${jxrdecode_Has_builtin_bswap32}.") if (NOT jxrdecode_Has_builtin_bswap32) check_symbol_exists(_byteswap_ulong "stdlib.h" jxrdecode_Has_byteswap_long_in_stdlib) From ed60c08822e361492f7621e200dab7f41d82ada1 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sat, 29 Jul 2023 01:48:25 +0200 Subject: [PATCH 15/98] test --- Src/JxrDecode/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Src/JxrDecode/CMakeLists.txt b/Src/JxrDecode/CMakeLists.txt index 8198aea7..517d738f 100644 --- a/Src/JxrDecode/CMakeLists.txt +++ b/Src/JxrDecode/CMakeLists.txt @@ -6,6 +6,7 @@ # static libCIZ-library include(CheckSymbolExists) +include(CheckFunctionExists) add_library(JxrDecodeStatic OBJECT JxrDecode.cpp @@ -118,7 +119,7 @@ else() set (jxrdecode_CrashOnUnalignedIntegers 0) endif() # c.f. https://stackoverflow.com/questions/41770887/cross-platform-definition-of-byteswap-uint64-and-byteswap-ulong -check_symbol_exists(__builtin_bswap32 "byteswap.h" jxrdecode_Has_builtin_bswap32) +check_function_exists(__builtin_bswap32 jxrdecode_Has_builtin_bswap32) message("jxrdecode_Has_builtin_bswap32 = ${jxrdecode_Has_builtin_bswap32}.") if (NOT jxrdecode_Has_builtin_bswap32) check_symbol_exists(_byteswap_ulong "stdlib.h" jxrdecode_Has_byteswap_long_in_stdlib) From aff96208276c1f4c42ce5d0b8c56865a1a30d0b5 Mon Sep 17 00:00:00 2001 From: "J. Bohl" Date: Sat, 29 Jul 2023 10:09:31 +0200 Subject: [PATCH 16/98] detect "__builtin_bswap32" --- Src/JxrDecode/CMakeLists.txt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Src/JxrDecode/CMakeLists.txt b/Src/JxrDecode/CMakeLists.txt index 517d738f..358af1fa 100644 --- a/Src/JxrDecode/CMakeLists.txt +++ b/Src/JxrDecode/CMakeLists.txt @@ -6,7 +6,7 @@ # static libCIZ-library include(CheckSymbolExists) -include(CheckFunctionExists) +include(CheckCSourceCompiles) add_library(JxrDecodeStatic OBJECT JxrDecode.cpp @@ -119,7 +119,12 @@ else() set (jxrdecode_CrashOnUnalignedIntegers 0) endif() # c.f. https://stackoverflow.com/questions/41770887/cross-platform-definition-of-byteswap-uint64-and-byteswap-ulong -check_function_exists(__builtin_bswap32 jxrdecode_Has_builtin_bswap32) +set (CMAKE_REQUIRED_INCLUDES byteswap.h) +#check_function_exists(__builtin_bswap32 jxrdecode_Has_builtin_bswap32) +check_c_source_compiles( + "#include + int main() {__builtin_bswap32(0x12345678);}" + jxrdecode_Has_builtin_bswap32) message("jxrdecode_Has_builtin_bswap32 = ${jxrdecode_Has_builtin_bswap32}.") if (NOT jxrdecode_Has_builtin_bswap32) check_symbol_exists(_byteswap_ulong "stdlib.h" jxrdecode_Has_byteswap_long_in_stdlib) From 0642563e1c552ac2aff5573981bb81ba65559652 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sat, 29 Jul 2023 22:44:32 +0200 Subject: [PATCH 17/98] test (big-endian decoder) --- Src/JxrDecode/CMakeLists.txt | 3 +- Src/JxrDecode/jxrlib/image/sys/strcodec.c | 73 ++++++++++++++++++++++- 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/Src/JxrDecode/CMakeLists.txt b/Src/JxrDecode/CMakeLists.txt index 358af1fa..aae8548d 100644 --- a/Src/JxrDecode/CMakeLists.txt +++ b/Src/JxrDecode/CMakeLists.txt @@ -119,8 +119,7 @@ else() set (jxrdecode_CrashOnUnalignedIntegers 0) endif() # c.f. https://stackoverflow.com/questions/41770887/cross-platform-definition-of-byteswap-uint64-and-byteswap-ulong -set (CMAKE_REQUIRED_INCLUDES byteswap.h) -#check_function_exists(__builtin_bswap32 jxrdecode_Has_builtin_bswap32) +# not exactly sure why check_symbol_exists() does not work here, but it does not for me - so we do it the hard way and try to compile a test program check_c_source_compiles( "#include int main() {__builtin_bswap32(0x12345678);}" diff --git a/Src/JxrDecode/jxrlib/image/sys/strcodec.c b/Src/JxrDecode/jxrlib/image/sys/strcodec.c index 51fcf287..824dd886 100644 --- a/Src/JxrDecode/jxrlib/image/sys/strcodec.c +++ b/Src/JxrDecode/jxrlib/image/sys/strcodec.c @@ -26,7 +26,17 @@ // //*@@@---@@@@****************************************************************** #include "strcodec.h" +#include //#include "perfTimer.h" +#if JXRDECODE_HAS_BUILTIN_BSWAP32 +#include +#endif +#if JXRDECODE_HAS_BYTESWAP_IN_STDLIB +#include +#endif +#if JXRDECODE_HAS_BSWAP_LONG_IN_SYS_ENDIAN +#include +#endif #ifdef MEM_TRACE #define TRACE_MALLOC 1 @@ -664,7 +674,7 @@ ERR detach_SB(SimpleBitIO* pSB) //================================================================ // Memory access functions //================================================================ -#if (defined(WIN32) && !defined(UNDER_CE)) || (defined(UNDER_CE) && defined(_ARM_)) +/*#if (defined(WIN32) && !defined(UNDER_CE)) || (defined(UNDER_CE) && defined(_ARM_)) // WinCE ARM and Desktop x86 #else // other platform @@ -683,10 +693,30 @@ U32 _byteswap_ulong(U32 bits) } #endif // _MSC_VER #endif // _BIG__ENDIAN_ +#endif*/ +#if JXRDECODE_ISBIGENDIANHOST +#define jxr_byteswap_ulong(x) (x) +#else + U32 jxr_byteswap_ulong(U32 bits) + { + #if JXRDECODE_HAS_BUILTIN_BSWAP32 + return __builtin_bswap32(bits); + #elif JXRDECODE_HAS_BYTESWAP_IN_STDLIB + return _byteswap_ulong(bits); + #elif JXRDECODE_HAS_BSWAP_LONG_IN_SYS_ENDIAN + return bswap_32(v); + #else + return (((bits & 0xff000000u) >> 24) | + ((bits & 0x00ff0000u) >> 8) | + ((bits & 0x0000ff00u) << 8) | + ((bits & 0x000000ffu) << 24)); + #endif + } #endif U32 load4BE(void* pv) { + /* #ifdef _BIG__ENDIAN_ return (*(U32*)pv); #else // _BIG__ENDIAN_ @@ -701,15 +731,56 @@ U32 load4BE(void* pv) return _byteswap_ulong(v); #endif // _M_IA64 #endif // _BIG__ENDIAN_ + */ +#if JXRDECODE_ISBIGENDIANHOST + // on a big-endian host, we have nothing to do, so just load the value +#if JXRDECODE_SIGBUS_ON_UNALIGNEDINTEGERS + U32 v; + memcpy(&v, pv, 4); + return v; +#else + return (*(U32*)pv); +#endif +#else // JXRDECODE_ISBIGENDIANHOST + // on a little endian machine, we need to swap the bytes + U32 v; +#if JXRDECODE_SIGBUS_ON_UNALIGNEDINTEGERS + memcpy(&v, pv, 4); +#else + v = (*(U32*)pv); +#endif + + // ...and use the appropriate byte-swapping function +#if JXRDECODE_HAS_BUILTIN_BSWAP32 + return __builtin_bswap32(v); +#elif JXRDECODE_HAS_BYTESWAP_IN_STDLIB + return _byteswap_ulong(v); +#elif JXRDECODE_HAS_BSWAP_LONG_IN_SYS_ENDIAN + return bswap_32(v); +#else + return (((v & 0xff000000u) >> 24) | + ((v & 0x00ff0000u) >> 8) | + ((v & 0x0000ff00u) << 8) | + ((v & 0x000000ffu) << 24)); +#endif +#endif } #define LOAD16 load4BE +/* #ifdef _BIG__ENDIAN_ #define WRITESWAP_ENDIAN(a) ((a)>>16) #else // _BIG__ENDIAN_ #define WRITESWAP_ENDIAN(a) _byteswap_ulong(a) #endif // _BIG__ENDIAN_ +*/ +#if JXRDECODE_ISBIGENDIANHOST + #define WRITESWAP_ENDIAN(a) ((a)>>16) +#else + #define WRITESWAP_ENDIAN(a) jxr_byteswap_ulong(a) +#endif + //================================================================ // Bit I/O functions From f5dd1b91735522f323ef208b9d656f279a4a3779 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 30 Jul 2023 00:32:18 +0200 Subject: [PATCH 18/98] cosmetic --- Src/JxrDecode/jxrlib/image/decode/segdec.c | 45 ++------- Src/JxrDecode/jxrlib/image/sys/strcodec.c | 109 --------------------- Src/JxrDecode/jxrlib/image/sys/strcodec.h | 90 +---------------- 3 files changed, 7 insertions(+), 237 deletions(-) diff --git a/Src/JxrDecode/jxrlib/image/decode/segdec.c b/Src/JxrDecode/jxrlib/image/decode/segdec.c index 7f24a09f..6bfd2c64 100644 --- a/Src/JxrDecode/jxrlib/image/decode/segdec.c +++ b/Src/JxrDecode/jxrlib/image/decode/segdec.c @@ -30,12 +30,6 @@ #include "decode.h" #include -#ifdef MEM_TRACE -#define TRACE_MALLOC 1 -#define TRACE_NEW 0 -#define TRACE_HEAP 0 -#include "memtrace.h" -#endif #if JXRDECODE_HAS_BUILTIN_BSWAP32 #include #endif @@ -53,11 +47,12 @@ static Int DecodeSignificantAbsLevel(struct CAdaptiveHuffman* pAHexpt, BitIOInfo //#undef X86OPT_INLINE -#ifdef X86OPT_INLINE +//#ifdef X86OPT_INLINE +//#define _FORCEINLINE __forceinline +//#else // X86OPT_INLINE +//#define _FORCEINLINE +//#endif // X86OPT_INLINE #define _FORCEINLINE __forceinline -#else // X86OPT_INLINE -#define _FORCEINLINE -#endif // X86OPT_INLINE //================================================================ // Memory access functions @@ -96,22 +91,6 @@ static U32 _FORCEINLINE _load4(void* pv) ((v & 0x000000ffu) << 24)); #endif #endif - - -//#ifdef _BIG__ENDIAN_ -// return (*(U32*)pv); -//#else // _BIG__ENDIAN_ -//#if defined(_M_IA64) || defined(_ARM_) -// U32 v; -// v = ((U16*)pv)[0]; -// v |= ((U32)((U16*)pv)[1]) << 16; -// return _byteswap_ulong(v); -//#else // _M_IA64 -// U32 v; -// memcpy(&v, pv, sizeof(U32)); -// return _byteswap_ulong(v); -//#endif // _M_IA64 -//#endif // _BIG__ENDIAN_ } static _FORCEINLINE U32 _peekBit16(BitIOInfo* pIO, U32 cBits) @@ -153,7 +132,6 @@ Int getHuff(const short* pDecodeTable, BitIOInfo* pIO) return (iSymbolHuff); } -#if 1 static _FORCEINLINE U32 _getBool16(BitIOInfo* pIO) { U32 uiRet = pIO->uiAccumulator >> 31;//_peekBit16(pIO, 1); @@ -187,10 +165,6 @@ static _FORCEINLINE I32 _getSign(BitIOInfo* pIO) return uiRet; } -#else -#define _getBool16(x) _getBit16((x),1) -#define _getSign(x) (-_getBit16((x),1)) -#endif /** this function returns cBits if zero is read, or a signed value if first cBits are not all zero **/ static _FORCEINLINE I32 _getBit16s(BitIOInfo* pIO, U32 cBits) @@ -778,11 +752,7 @@ static _FORCEINLINE Int DecodeCoeffs(CWMImageStrCodec* pSC, CCodingContext* pCon /************************************************************************* DecodeSignificantAbsLevel *************************************************************************/ -#ifndef X86OPT_INLINE -static Int DecodeSignificantAbsLevel(struct CAdaptiveHuffman* pAHexpt, BitIOInfo* pIO) -#else static __forceinline Int DecodeSignificantAbsLevel(struct CAdaptiveHuffman* pAHexpt, BitIOInfo* pIO) -#endif { UInt iIndex; Int iFixed, iLevel; @@ -837,9 +807,8 @@ Int DecodeMacroblockLowpass(CWMImageStrCodec* pSC, CCodingContext* pContext, Int aRLCoeffs[32], iNumNonzero = 0, iIndex = 0; Int aLaplacianMean[2] = { 0, 0 }, * pLM = aLaplacianMean; Int iChannel, iCBP = 0; -#ifndef ARMOPT_BITIO // ARM opt always uses 32-bit version of getBits U32(*getBits)(BitIOInfo * pIO, U32 cBits) = _getBit16; -#endif + CWMIMBInfo* pMBInfo = &pSC->MBInfo; I32* aDC[MAX_CHANNELS]; @@ -905,11 +874,9 @@ Int DecodeMacroblockLowpass(CWMImageStrCodec* pSC, CCodingContext* pContext, iCBP |= (getBits(pIO, 1) << iChannel); } -#ifndef ARMOPT_BITIO // ARM opt always uses 32-bit version of getBits if (pContext->m_aModelLP.m_iFlcBits[0] > 14 || pContext->m_aModelLP.m_iFlcBits[1] > 14) { getBits = getBit32; } -#endif for (iChannel = 0; iChannel < iFullPlanes; iChannel++) { PixelI* pCoeffs = aDC[iChannel]; diff --git a/Src/JxrDecode/jxrlib/image/sys/strcodec.c b/Src/JxrDecode/jxrlib/image/sys/strcodec.c index 824dd886..5c43c8a3 100644 --- a/Src/JxrDecode/jxrlib/image/sys/strcodec.c +++ b/Src/JxrDecode/jxrlib/image/sys/strcodec.c @@ -674,26 +674,6 @@ ERR detach_SB(SimpleBitIO* pSB) //================================================================ // Memory access functions //================================================================ -/*#if (defined(WIN32) && !defined(UNDER_CE)) || (defined(UNDER_CE) && defined(_ARM_)) -// WinCE ARM and Desktop x86 -#else -// other platform -#ifdef _BIG__ENDIAN_ -#define _byteswap_ulong(x) (x) -#else // _BIG__ENDIAN_ -#if _MSC_VER < 1924 -U32 _byteswap_ulong(U32 bits) -{ - U32 r = (bits & 0xffu) << 24; - r |= (bits << 8) & 0xff0000u; - r |= ((bits >> 8) & 0xff00u); - r |= ((bits >> 24) & 0xffu); - - return r; -} -#endif // _MSC_VER -#endif // _BIG__ENDIAN_ -#endif*/ #if JXRDECODE_ISBIGENDIANHOST #define jxr_byteswap_ulong(x) (x) #else @@ -716,22 +696,6 @@ U32 _byteswap_ulong(U32 bits) U32 load4BE(void* pv) { - /* -#ifdef _BIG__ENDIAN_ - return (*(U32*)pv); -#else // _BIG__ENDIAN_ -#if defined(_M_IA64) || defined(_ARM_) - U32 v; - v = ((U16*)pv)[0]; - v |= ((U32)((U16*)pv)[1]) << 16; - return _byteswap_ulong(v); -#else // _M_IA64 - U32 v; - memcpy(&v, pv, sizeof(U32)); - return _byteswap_ulong(v); -#endif // _M_IA64 -#endif // _BIG__ENDIAN_ - */ #if JXRDECODE_ISBIGENDIANHOST // on a big-endian host, we have nothing to do, so just load the value #if JXRDECODE_SIGBUS_ON_UNALIGNEDINTEGERS @@ -768,13 +732,6 @@ U32 load4BE(void* pv) #define LOAD16 load4BE -/* -#ifdef _BIG__ENDIAN_ -#define WRITESWAP_ENDIAN(a) ((a)>>16) -#else // _BIG__ENDIAN_ -#define WRITESWAP_ENDIAN(a) _byteswap_ulong(a) -#endif // _BIG__ENDIAN_ -*/ #if JXRDECODE_ISBIGENDIANHOST #define WRITESWAP_ENDIAN(a) ((a)>>16) #else @@ -984,7 +941,6 @@ U8 dquantBits(U8 cQP) return (cQP < 2 ? 0 : (cQP < 4 ? 1 : (cQP < 6 ? 2 : (cQP < 10 ? 3 : 4)))); } -#ifndef ARMOPT_BITIO U32 peekBit16(BitIOInfo* pIO, U32 cBits) { PEEKBIT16(pIO, cBits); @@ -1049,7 +1005,6 @@ U32 flushToByte(BitIOInfo* pIO) { return flushBit16(pIO, (16 - pIO->cBitsUsed) & 7); } -#endif // ARMOPT_BITIO //---------------------------------------------------------------- Void putBit16z(BitIOInfo* pIO, U32 uiBits, U32 cBits) @@ -1136,7 +1091,6 @@ U32 getPosRead(BitIOInfo* pIO) //================================================================ // Block I/O functions //================================================================ -#ifndef ARMOPT_BITIO ERR attachISRead(BitIOInfo* pIO, struct WMPStream* pWS, CWMImageStrCodec* pSC) { UNREFERENCED_PARAMETER(pSC); @@ -1146,10 +1100,8 @@ ERR attachISRead(BitIOInfo* pIO, struct WMPStream* pWS, CWMImageStrCodec* pSC) pIO->pbStart = (U8*)pIO - PACKETLENGTH * 2; pIO->pbCurrent = pIO->pbStart; - //PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); pWS->SetPos(pWS, pIO->offRef); pWS->Read(pWS, pIO->pbStart, PACKETLENGTH * 2); - //PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); pIO->offRef += PACKETLENGTH * 2; pIO->uiAccumulator = load4BE(pIO->pbStart); @@ -1172,13 +1124,11 @@ ERR readIS(CWMImageStrCodec* pSC, BitIOInfo* pIO) { struct WMPStream* pWS = pIO->pWS; - //PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); //Call(0 != pIO->pWS->Read(pIO->pWS, pIO->pbStart, PACKETLENGTH)); // TODO: add error checking code pWS->SetPos(pWS, pIO->offRef); pWS->Read(pWS, pIO->pbStart, PACKETLENGTH); pIO->offRef += PACKETLENGTH; - //PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); // make shadow copy for first 4B pIO->uiShadow = *(U32*)pIO->pbStart; @@ -1211,7 +1161,6 @@ ERR detachISRead(CWMImageStrCodec* pSC, BitIOInfo* pIO) Cleanup: return err; } -#endif // ARMOPT_BITIO //---------------------------------------------------------------- ERR attachISWrite(BitIOInfo* pIO, struct WMPStream* pWS) @@ -1260,9 +1209,7 @@ ERR detachISWrite(CWMImageStrCodec* pSC, BitIOInfo* pIO) assert(0 == (pIO->cBitsUsed % 8)); Call(writeIS_L1(pSC, pIO)); - //PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); err = pIO->pWS->Write(pIO->pWS, pIO->pbStart, pIO->pbCurrent + pIO->cBitsUsed / 8 - pIO->pbStart); - //PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf); Call(err); pIO->pWS = NULL; @@ -1270,59 +1217,3 @@ ERR detachISWrite(CWMImageStrCodec* pSC, BitIOInfo* pIO) return err; } -#if false -//========================= -// Performance Measurement -//========================= -#ifndef DISABLE_PERF_MEASUREMENT - -void OutputIndivPerfTimer(struct PERFTIMERSTATE* pPerfTimer, - char* pszTimerName, - char* pszDescription, - float fltMegaPixels) -{ - //PERFTIMERRESULTS rResults; - Bool fResult; - - fResult = FALSE; - printf("%s (%s): ", pszTimerName, pszDescription); - if (pPerfTimer) - { - fResult = PerfTimerGetResults(pPerfTimer, &rResults); - if (fResult) - { - printf("%.3f milliseconds, %.6f MP/sec\n", (float)rResults.iElapsedTime / 1000000, - 1000000000 * fltMegaPixels / rResults.iElapsedTime); - if (rResults.iZeroTimeIntervals > 0) - { - printf(" *** WARNING: %d time intervals were measured as zero. " - "This perf timer has insufficient precision!\n\n", - (int)rResults.iZeroTimeIntervals); - } - } - } - if (FALSE == fResult) - printf("Results not available!\n"); -} - - -void OutputPerfTimerReport(CWMImageStrCodec* pState) -{ - float fltMegaPixels; - - assert(pState->m_fMeasurePerf); - - printf("***************************************************************************\n"); - printf("* Perf Report\n"); - printf("***************************************************************************\n\n"); - - fltMegaPixels = (float)pState->WMII.cWidth * pState->WMII.cHeight / 1000000; - printf("Image Width = %d, Height = %d, total MegaPixels = %.1f MP\n", - (int)pState->WMII.cWidth, (int)pState->WMII.cHeight, fltMegaPixels); - - OutputIndivPerfTimer(pState->m_ptEncDecPerf, "m_ptEncDecPerf", "excl I/O", fltMegaPixels); - OutputIndivPerfTimer(pState->m_ptEndToEndPerf, "m_ptEndToEndPerf", "incl I/O", fltMegaPixels); -} - -#endif // DISABLE_PERF_MEASUREMENT -#endif // false \ No newline at end of file diff --git a/Src/JxrDecode/jxrlib/image/sys/strcodec.h b/Src/JxrDecode/jxrlib/image/sys/strcodec.h index 03fabb17..f5487695 100644 --- a/Src/JxrDecode/jxrlib/image/sys/strcodec.h +++ b/Src/JxrDecode/jxrlib/image/sys/strcodec.h @@ -33,57 +33,14 @@ #include "windowsmediaphoto.h" #include "common.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 // UNREFERENCED_PARAMETER -/* -#ifdef UNDER_CE -#define PLATFORM_WCE -#include "arm.h" -#endif -*/ - -/* -#ifdef __ANSI__ -#define PLATFORM_ANSI -#include "ansi.h" -#endif -*/ - #include "ansi.h" typedef uintptr_t UINTPTR_T; @@ -92,13 +49,6 @@ typedef intptr_t INTPTR_T; //================================================================ typedef uint64_t U64; -#if false -#ifdef PLATFORM_ANSI -typedef unsigned long long U64; -#else // PLATFORM_ANSI -typedef unsigned __int64 U64; -#endif // PLATFORM_ANSI -#endif //================================================================ #define MARKERCOUNT (PACKETLENGTH * 2) @@ -184,18 +134,12 @@ typedef struct tagBitIOInfo 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, @@ -333,9 +277,6 @@ struct tagPostProcInfo { }; typedef struct CWMImageStrCodec { -#ifdef ARMOPT_COLORCONVERSION_C - CWMImageStrInvCCParam InvCCParam; -#endif size_t cbStruct; @@ -479,14 +420,6 @@ typedef struct CWMImageStrCodec { //================================ // Perf Timers //================================ -#if false -#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 -#endif - // postproc information for 2 MB rows: 0(previous row) 1(current row) struct tagPostProcInfo* pPostProcInfo[MAX_CHANNELS][2]; } CWMImageStrCodec; @@ -525,7 +458,6 @@ Void advanceOneMBRow(CWMImageStrCodec*); 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); @@ -533,7 +465,6 @@ 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); @@ -546,9 +477,7 @@ 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 @@ -661,20 +590,6 @@ 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 @@ -691,6 +606,3 @@ void flushToByte(BitIOInfo* pIO); 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); From e398516bc45f013e6ad9728d2517801e89d93c1e Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 30 Jul 2023 00:36:32 +0200 Subject: [PATCH 19/98] forceinline... --- Src/JxrDecode/jxrlib/image/decode/segdec.c | 25 ++++------------------ 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/Src/JxrDecode/jxrlib/image/decode/segdec.c b/Src/JxrDecode/jxrlib/image/decode/segdec.c index 6bfd2c64..d4b6dd64 100644 --- a/Src/JxrDecode/jxrlib/image/decode/segdec.c +++ b/Src/JxrDecode/jxrlib/image/decode/segdec.c @@ -45,14 +45,7 @@ extern const int blkOffset[16]; extern const int blkOffsetUV[4]; static Int DecodeSignificantAbsLevel(struct CAdaptiveHuffman* pAHexpt, BitIOInfo* pIO); -//#undef X86OPT_INLINE - -//#ifdef X86OPT_INLINE -//#define _FORCEINLINE __forceinline -//#else // X86OPT_INLINE -//#define _FORCEINLINE -//#endif // X86OPT_INLINE -#define _FORCEINLINE __forceinline +#define _FORCEINLINE inline //================================================================ // Memory access functions @@ -405,13 +398,8 @@ Int _FORCEINLINE DecodeSignificantRun(Int iMaxRun, struct CAdaptiveHuffman* pAHe return iRun; } -#ifndef X86OPT_INLINE -static Void DecodeFirstIndex(Int* pIndex, struct CAdaptiveHuffman* pAHexpt, - BitIOInfo* pIO) -#else -static __forceinline Void DecodeFirstIndex(Int* pIndex, struct CAdaptiveHuffman* pAHexpt, +static _FORCEINLINE Void DecodeFirstIndex(Int* pIndex, struct CAdaptiveHuffman* pAHexpt, BitIOInfo* pIO) -#endif { Int iIndex; iIndex = getHuff(pAHexpt->m_hufDecTable, pIO); @@ -420,13 +408,8 @@ static __forceinline Void DecodeFirstIndex(Int* pIndex, struct CAdaptiveHuffman* *pIndex = iIndex; } -#ifndef X86OPT_INLINE -static Void DecodeIndex(Int* pIndex, Int iLoc, struct CAdaptiveHuffman* pAHexpt, - BitIOInfo* pIO) -#else -static __forceinline Void DecodeIndex(Int* pIndex, Int iLoc, +static _FORCEINLINE Void DecodeIndex(Int* pIndex, Int iLoc, struct CAdaptiveHuffman* pAHexpt, BitIOInfo* pIO) -#endif { Int iIndex; if (iLoc < 15) { @@ -752,7 +735,7 @@ static _FORCEINLINE Int DecodeCoeffs(CWMImageStrCodec* pSC, CCodingContext* pCon /************************************************************************* DecodeSignificantAbsLevel *************************************************************************/ -static __forceinline Int DecodeSignificantAbsLevel(struct CAdaptiveHuffman* pAHexpt, BitIOInfo* pIO) +static _FORCEINLINE Int DecodeSignificantAbsLevel(struct CAdaptiveHuffman* pAHexpt, BitIOInfo* pIO) { UInt iIndex; Int iFixed, iLevel; From ff45e5e8a1ab1fe6cf6b3bdf3f56df1dcc6ee46b Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 30 Jul 2023 00:42:13 +0200 Subject: [PATCH 20/98] fix warning --- Src/JxrDecode/jxrlib/image/decode/segdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/JxrDecode/jxrlib/image/decode/segdec.c b/Src/JxrDecode/jxrlib/image/decode/segdec.c index d4b6dd64..555cf191 100644 --- a/Src/JxrDecode/jxrlib/image/decode/segdec.c +++ b/Src/JxrDecode/jxrlib/image/decode/segdec.c @@ -366,7 +366,7 @@ static Void DecodeCBP(CWMImageStrCodec* pSC, CCodingContext* pContext) pAHexpt[7-8] == condition on SRn no use *************************************************************************/ -Int _FORCEINLINE DecodeSignificantRun(Int iMaxRun, struct CAdaptiveHuffman* pAHexpt, BitIOInfo* pIO) +static Int _FORCEINLINE DecodeSignificantRun(Int iMaxRun, struct CAdaptiveHuffman* pAHexpt, BitIOInfo* pIO) { Int iIndex; static const Int aRemap[] = { 1,2,3,5,7, 1,2,3,5,7, /*1,2,3,4,6, */1,2,3,4,5 }; From aa6fb350efe39412cbe646a4ba57ee7971286604 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 30 Jul 2023 12:48:58 +0200 Subject: [PATCH 21/98] cosmetic & _rotl --- Src/JxrDecode/CMakeLists.txt | 6 ++++++ Src/libCZI/CziMetadataBuilder.cpp | 2 +- Src/libCZI_UnitTests/test_metadatabuilder.cpp | 8 ++++---- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Src/JxrDecode/CMakeLists.txt b/Src/JxrDecode/CMakeLists.txt index aae8548d..d02837ac 100644 --- a/Src/JxrDecode/CMakeLists.txt +++ b/Src/JxrDecode/CMakeLists.txt @@ -143,6 +143,12 @@ if (NOT jxrdecode_Has_bswap_long_in_sys_endian) set (jxrdecode_Has_bswap_long_in_sys_endian 0) endif() +check_symbol_exists(_rotl "stdlib.h" jxrdecode_Has_rotl) +message("jxrdecode_Has_rotl = ${jxrdecode_Has_rotl}.") +if (NOT jxrdecode_Has_rotl) + set (jxrdecode_Has_rotl 0) +endif() + configure_file ( "${CMAKE_CURRENT_SOURCE_DIR}/JxrDecode_Config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/JxrDecode_Config.h" diff --git a/Src/libCZI/CziMetadataBuilder.cpp b/Src/libCZI/CziMetadataBuilder.cpp index 1ba62063..c6009b30 100644 --- a/Src/libCZI/CziMetadataBuilder.cpp +++ b/Src/libCZI/CziMetadataBuilder.cpp @@ -983,7 +983,7 @@ static void WriteChannelDisplaySettings(const IChannelDisplaySetting* channel_di node->GetOrCreateChildNode("Low")->SetValueFlt(black_point); node->GetOrCreateChildNode("High")->SetValueFlt(white_point); - auto gradation_curve_mode = channel_display_setting->GetGradationCurveMode(); + const auto gradation_curve_mode = channel_display_setting->GetGradationCurveMode(); if (gradation_curve_mode == IDisplaySettings::GradationCurveMode::Gamma) { float gamma; diff --git a/Src/libCZI_UnitTests/test_metadatabuilder.cpp b/Src/libCZI_UnitTests/test_metadatabuilder.cpp index 92dea235..a4174042 100644 --- a/Src/libCZI_UnitTests/test_metadatabuilder.cpp +++ b/Src/libCZI_UnitTests/test_metadatabuilder.cpp @@ -521,15 +521,15 @@ TEST(MetadataBuilder, MetadataUtils11) auto mdBldr = CreateMetadataBuilder(); map ValidCA = { {"Attr1", CustomValueVariant(1234)}, {"Attr2", CustomValueVariant(string("SomeStrings"))}, {"Attr3", CustomValueVariant(true)} , {"Attr4", CustomValueVariant(12.5f)}, {"Attr5", CustomValueVariant(22.5)} }; - for (auto ValidIt = ValidCA.begin(); ValidIt != ValidCA.end(); ValidIt++) + for (auto valid_it = ValidCA.begin(); valid_it != ValidCA.end(); ++valid_it) { - auto key = ValidIt->first; - auto value = ValidIt->second; + auto key = valid_it->first; + auto value = valid_it->second; MetadataUtils::SetOrAddCustomKeyValuePair(mdBldr.get(), key, value); } - auto xml = mdBldr->GetXml(true); + const auto xml = mdBldr->GetXml(true); static const char* expectedResult = "\n" From 2194581db1ae0b76a58329577c45ed0e4cdae5cb Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 30 Jul 2023 12:53:39 +0200 Subject: [PATCH 22/98] _rotl ... --- Src/JxrDecode/CMakeLists.txt | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Src/JxrDecode/CMakeLists.txt b/Src/JxrDecode/CMakeLists.txt index d02837ac..1c0afba5 100644 --- a/Src/JxrDecode/CMakeLists.txt +++ b/Src/JxrDecode/CMakeLists.txt @@ -143,10 +143,16 @@ if (NOT jxrdecode_Has_bswap_long_in_sys_endian) set (jxrdecode_Has_bswap_long_in_sys_endian 0) endif() -check_symbol_exists(_rotl "stdlib.h" jxrdecode_Has_rotl) -message("jxrdecode_Has_rotl = ${jxrdecode_Has_rotl}.") -if (NOT jxrdecode_Has_rotl) - set (jxrdecode_Has_rotl 0) +check_symbol_exists(_rotl "stdlib.h" jxrdecode_Has_rotl_with_stdlib) +message("jxrdecode_Has_rotl_with_stdlib = ${jxrdecode_Has_rotl_with_stdlib}.") +if (NOT jxrdecode_Has_rotl_with_stdlib) + set (jxrdecode_Has_rotl_with_stdlib 0) +endif() + +check_symbol_exists(_rotl "x86intrin.h" jxrdecode_Has_rotl_with_x86intrin) +message("jxrdecode_Has_rotl_with_x86intrin= ${jxrdecode_Has_rotl_with_x86intrin}.") +if (NOT jxrdecode_Has_rotl_with_x86intrin) + set (jxrdecode_Has_rotl_with_x86intrin 0) endif() configure_file ( From d7bb1e1fe9bdbd625bc113f131e3f92bb5bbf711 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 30 Jul 2023 18:59:10 +0200 Subject: [PATCH 23/98] rotl - use if available --- Src/JxrDecode/CMakeLists.txt | 16 +++++++++----- Src/JxrDecode/JxrDecode_Config.h.in | 8 ++++++- Src/JxrDecode/jxrlib/common/include/guiddef.h | 7 ------ Src/JxrDecode/jxrlib/image/decode/segdec.c | 22 ++++++++++++++----- 4 files changed, 33 insertions(+), 20 deletions(-) diff --git a/Src/JxrDecode/CMakeLists.txt b/Src/JxrDecode/CMakeLists.txt index 1c0afba5..79ebeb1f 100644 --- a/Src/JxrDecode/CMakeLists.txt +++ b/Src/JxrDecode/CMakeLists.txt @@ -143,14 +143,18 @@ if (NOT jxrdecode_Has_bswap_long_in_sys_endian) set (jxrdecode_Has_bswap_long_in_sys_endian 0) endif() -check_symbol_exists(_rotl "stdlib.h" jxrdecode_Has_rotl_with_stdlib) -message("jxrdecode_Has_rotl_with_stdlib = ${jxrdecode_Has_rotl_with_stdlib}.") -if (NOT jxrdecode_Has_rotl_with_stdlib) - set (jxrdecode_Has_rotl_with_stdlib 0) +# Here we check for the _rotl() function - c.f. https://stackoverflow.com/questions/776508/best-practices-for-circular-shift-rotate-operations-in-c +# With MSVC, it is found in , with gcc it is expected to be found in . +check_symbol_exists(_rotl "intrin.h" jxrdecode_Has_rotl_with_intrin) +message("jxrdecode_Has_rotl_with_intrin = ${jxrdecode_Has_rotl_with_intrin}.") +if (NOT jxrdecode_Has_rotl_with_intrin) + set (jxrdecode_Has_rotl_with_intrin 0) endif() -check_symbol_exists(_rotl "x86intrin.h" jxrdecode_Has_rotl_with_x86intrin) -message("jxrdecode_Has_rotl_with_x86intrin= ${jxrdecode_Has_rotl_with_x86intrin}.") +if (NOT jxrdecode_Has_rotl_with_intrin ) + check_symbol_exists(_rotl "x86intrin.h" jxrdecode_Has_rotl_with_x86intrin) + message("jxrdecode_Has_rotl_with_x86intrin= ${jxrdecode_Has_rotl_with_x86intrin}.") +endif() if (NOT jxrdecode_Has_rotl_with_x86intrin) set (jxrdecode_Has_rotl_with_x86intrin 0) endif() diff --git a/Src/JxrDecode/JxrDecode_Config.h.in b/Src/JxrDecode/JxrDecode_Config.h.in index 3a101e8c..8d0c07e7 100644 --- a/Src/JxrDecode/JxrDecode_Config.h.in +++ b/Src/JxrDecode/JxrDecode_Config.h.in @@ -15,4 +15,10 @@ #define JXRDECODE_HAS_BUILTIN_BSWAP32 @jxrdecode_Has_builtin_bswap32@ #define JXRDECODE_HAS_BYTESWAP_IN_STDLIB @jxrdecode_Has_byteswap_long_in_stdlib@ -#define JXRDECODE_HAS_BSWAP_LONG_IN_SYS_ENDIAN @jxrdecode_Has_bswap_long_in_sys_endian@ \ No newline at end of file +#define JXRDECODE_HAS_BSWAP_LONG_IN_SYS_ENDIAN @jxrdecode_Has_bswap_long_in_sys_endian@ + +// whether the "_rotl" function is available in the respective header file - here in , which should be the case with MSVC +#define JXRDECODE_HAS_ROTL_WITH_INTRIN_H @jxrdecode_Has_rotl_with_intrin@ + +// whether the "_rotl" function is available in the respective header file - here in , which should be the case with GCC +#define JXRDECODE_HAS_ROTL_WITH_X86INTRIN_H @jxrdecode_Has_rotl_with_x86intrin@ diff --git a/Src/JxrDecode/jxrlib/common/include/guiddef.h b/Src/JxrDecode/jxrlib/common/include/guiddef.h index 0cb4f98c..14b4ab1b 100644 --- a/Src/JxrDecode/jxrlib/common/include/guiddef.h +++ b/Src/JxrDecode/jxrlib/common/include/guiddef.h @@ -54,13 +54,6 @@ typedef struct _GUID { #endif #define FAR -/*#ifndef FAR -#if defined(_WIN32) || defined(__ANSI__) -#define FAR -#else -#define FAR _far -#endif -#endif*/ #ifndef DECLSPEC_SELECTANY #if (_MSC_VER >= 1100) diff --git a/Src/JxrDecode/jxrlib/image/decode/segdec.c b/Src/JxrDecode/jxrlib/image/decode/segdec.c index 555cf191..ce4fa43d 100644 --- a/Src/JxrDecode/jxrlib/image/decode/segdec.c +++ b/Src/JxrDecode/jxrlib/image/decode/segdec.c @@ -31,7 +31,7 @@ #include #if JXRDECODE_HAS_BUILTIN_BSWAP32 -#include + #include #endif #if JXRDECODE_HAS_BYTESWAP_IN_STDLIB #include @@ -40,6 +40,16 @@ #include #endif +#if JXRDECODE_HAS_ROTL_WITH_INTRIN_H + #include + #define CAN_USE_ROTL 1 +#elif JXRDECODE_HAS_ROTL_WITH_X86INTRIN_H + #include + #define CAN_USE_ROTL 1 +#else + #define CAN_USE_ROTL 0 +#endif + extern const int dctIndex[3][16]; extern const int blkOffset[16]; extern const int blkOffsetUV[4]; @@ -940,16 +950,16 @@ Int DecodeMacroblockLowpass(CWMImageStrCodec* pSC, CCodingContext* pContext, } } else { -#ifdef WIN32 +#if CAN_USE_ROTL const Int iMask = (1 << iModelBits) - 1; -#endif // WIN32 +#endif // CAN_USE_ROTL for (k = 1; k < 16; k++) { -#ifdef WIN32 +#ifdef CAN_USE_ROTL if (pCoeffs[k]) { Int r1 = _rotl(pCoeffs[k], iModelBits); pCoeffs[k] = (r1 ^ getBits(pIO, iModelBits)) - (r1 & iMask); } -#else // WIN32 +#else // CAN_USE_ROTL if (pCoeffs[k] > 0) { pCoeffs[k] <<= iModelBits; pCoeffs[k] += getBits(pIO, iModelBits); @@ -959,7 +969,7 @@ Int DecodeMacroblockLowpass(CWMImageStrCodec* pSC, CCodingContext* pContext, pCoeffs[k] = -(-pCoeffs[k] << iModelBits); pCoeffs[k] -= getBits(pIO, iModelBits); } -#endif // WIN32 +#endif // CAN_USE_ROTL else { //pCoeffs[k] = getBits (pIO, iModelBits); //if (pCoeffs[k] && _getBool16 (pIO)) From f671e32cf9a7f43b177955632156348fda537add Mon Sep 17 00:00:00 2001 From: ptahmose Date: Mon, 31 Jul 2023 00:41:39 +0200 Subject: [PATCH 24/98] remove "special characters", fix segdec.c --- Src/JxrDecode/jxrlib/common/include/guiddef.h | 6 +++--- Src/JxrDecode/jxrlib/image/decode/JXRTranscode.c | 6 +++--- Src/JxrDecode/jxrlib/image/decode/decode.c | 6 +++--- Src/JxrDecode/jxrlib/image/decode/decode.h | 6 +++--- Src/JxrDecode/jxrlib/image/decode/postprocess.c | 6 +++--- Src/JxrDecode/jxrlib/image/decode/segdec.c | 8 ++++---- Src/JxrDecode/jxrlib/image/decode/strInvTransform.c | 6 +++--- Src/JxrDecode/jxrlib/image/decode/strPredQuantDec.c | 6 +++--- Src/JxrDecode/jxrlib/image/decode/strdec.c | 6 +++--- Src/JxrDecode/jxrlib/image/encode/encode.c | 6 +++--- Src/JxrDecode/jxrlib/image/encode/encode.h | 6 +++--- Src/JxrDecode/jxrlib/image/encode/segenc.c | 6 +++--- Src/JxrDecode/jxrlib/image/encode/strFwdTransform.c | 6 +++--- Src/JxrDecode/jxrlib/image/encode/strPredQuantEnc.c | 6 +++--- Src/JxrDecode/jxrlib/image/encode/strenc.c | 6 +++--- Src/JxrDecode/jxrlib/image/sys/adapthuff.c | 6 +++--- Src/JxrDecode/jxrlib/image/sys/ansi.h | 6 +++--- Src/JxrDecode/jxrlib/image/sys/common.h | 6 +++--- Src/JxrDecode/jxrlib/image/sys/image.c | 6 +++--- Src/JxrDecode/jxrlib/image/sys/strPredQuant.c | 6 +++--- Src/JxrDecode/jxrlib/image/sys/strTransform.c | 6 +++--- Src/JxrDecode/jxrlib/image/sys/strTransform.h | 6 +++--- Src/JxrDecode/jxrlib/image/sys/strcodec.c | 6 +++--- Src/JxrDecode/jxrlib/image/sys/strcodec.h | 6 +++--- Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h | 6 +++--- Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c | 6 +++--- Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h | 6 +++--- Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c | 6 +++--- Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c | 6 +++--- Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c | 6 +++--- Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h | 6 +++--- 31 files changed, 94 insertions(+), 94 deletions(-) diff --git a/Src/JxrDecode/jxrlib/common/include/guiddef.h b/Src/JxrDecode/jxrlib/common/include/guiddef.h index 14b4ab1b..aebc3801 100644 --- a/Src/JxrDecode/jxrlib/common/include/guiddef.h +++ b/Src/JxrDecode/jxrlib/common/include/guiddef.h @@ -1,14 +1,14 @@ //+--------------------------------------------------------------------------- // -// Copyright © Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/image/decode/JXRTranscode.c b/Src/JxrDecode/jxrlib/image/decode/JXRTranscode.c index d674d705..23dd61d5 100644 --- a/Src/JxrDecode/jxrlib/image/decode/JXRTranscode.c +++ b/Src/JxrDecode/jxrlib/image/decode/JXRTranscode.c @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright � Microsoft Corp. +// Copyright (C)) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/image/decode/decode.c b/Src/JxrDecode/jxrlib/image/decode/decode.c index 0b9400f9..d9b2916d 100644 --- a/Src/JxrDecode/jxrlib/image/decode/decode.c +++ b/Src/JxrDecode/jxrlib/image/decode/decode.c @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright © Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/image/decode/decode.h b/Src/JxrDecode/jxrlib/image/decode/decode.h index a4eacef5..1c561e95 100644 --- a/Src/JxrDecode/jxrlib/image/decode/decode.h +++ b/Src/JxrDecode/jxrlib/image/decode/decode.h @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright © Microsoft Corp. +// Copyright (C)) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/image/decode/postprocess.c b/Src/JxrDecode/jxrlib/image/decode/postprocess.c index aed51485..ee9029a7 100644 --- a/Src/JxrDecode/jxrlib/image/decode/postprocess.c +++ b/Src/JxrDecode/jxrlib/image/decode/postprocess.c @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright � Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/image/decode/segdec.c b/Src/JxrDecode/jxrlib/image/decode/segdec.c index ce4fa43d..52427ec5 100644 --- a/Src/JxrDecode/jxrlib/image/decode/segdec.c +++ b/Src/JxrDecode/jxrlib/image/decode/segdec.c @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright © Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // @@ -954,7 +954,7 @@ Int DecodeMacroblockLowpass(CWMImageStrCodec* pSC, CCodingContext* pContext, const Int iMask = (1 << iModelBits) - 1; #endif // CAN_USE_ROTL for (k = 1; k < 16; k++) { -#ifdef CAN_USE_ROTL +#if CAN_USE_ROTL if (pCoeffs[k]) { Int r1 = _rotl(pCoeffs[k], iModelBits); pCoeffs[k] = (r1 ^ getBits(pIO, iModelBits)) - (r1 & iMask); diff --git a/Src/JxrDecode/jxrlib/image/decode/strInvTransform.c b/Src/JxrDecode/jxrlib/image/decode/strInvTransform.c index d77df7d6..5250a63e 100644 --- a/Src/JxrDecode/jxrlib/image/decode/strInvTransform.c +++ b/Src/JxrDecode/jxrlib/image/decode/strInvTransform.c @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright © Microsoft Corp. +// Copyright (C)) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/image/decode/strPredQuantDec.c b/Src/JxrDecode/jxrlib/image/decode/strPredQuantDec.c index b077fad0..86d7a1d0 100644 --- a/Src/JxrDecode/jxrlib/image/decode/strPredQuantDec.c +++ b/Src/JxrDecode/jxrlib/image/decode/strPredQuantDec.c @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright © Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/image/decode/strdec.c b/Src/JxrDecode/jxrlib/image/decode/strdec.c index bd00958d..69c589dd 100644 --- a/Src/JxrDecode/jxrlib/image/decode/strdec.c +++ b/Src/JxrDecode/jxrlib/image/decode/strdec.c @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright � Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/image/encode/encode.c b/Src/JxrDecode/jxrlib/image/encode/encode.c index d6c2bbed..404a1159 100644 --- a/Src/JxrDecode/jxrlib/image/encode/encode.c +++ b/Src/JxrDecode/jxrlib/image/encode/encode.c @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright � Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/image/encode/encode.h b/Src/JxrDecode/jxrlib/image/encode/encode.h index 8b90eb8b..708466d2 100644 --- a/Src/JxrDecode/jxrlib/image/encode/encode.h +++ b/Src/JxrDecode/jxrlib/image/encode/encode.h @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright � Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/image/encode/segenc.c b/Src/JxrDecode/jxrlib/image/encode/segenc.c index b91c2668..9a703ed7 100644 --- a/Src/JxrDecode/jxrlib/image/encode/segenc.c +++ b/Src/JxrDecode/jxrlib/image/encode/segenc.c @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright � Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/image/encode/strFwdTransform.c b/Src/JxrDecode/jxrlib/image/encode/strFwdTransform.c index b4a2e5d4..f7e34f64 100644 --- a/Src/JxrDecode/jxrlib/image/encode/strFwdTransform.c +++ b/Src/JxrDecode/jxrlib/image/encode/strFwdTransform.c @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright � Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/image/encode/strPredQuantEnc.c b/Src/JxrDecode/jxrlib/image/encode/strPredQuantEnc.c index 23a05879..4161f8bb 100644 --- a/Src/JxrDecode/jxrlib/image/encode/strPredQuantEnc.c +++ b/Src/JxrDecode/jxrlib/image/encode/strPredQuantEnc.c @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright � Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/image/encode/strenc.c b/Src/JxrDecode/jxrlib/image/encode/strenc.c index 6dfc7883..eaea0283 100644 --- a/Src/JxrDecode/jxrlib/image/encode/strenc.c +++ b/Src/JxrDecode/jxrlib/image/encode/strenc.c @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright � Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/image/sys/adapthuff.c b/Src/JxrDecode/jxrlib/image/sys/adapthuff.c index b3e06586..5347cbd3 100644 --- a/Src/JxrDecode/jxrlib/image/sys/adapthuff.c +++ b/Src/JxrDecode/jxrlib/image/sys/adapthuff.c @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright � Microsoft Corp. +// Copyright (C)) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/image/sys/ansi.h b/Src/JxrDecode/jxrlib/image/sys/ansi.h index 2e319497..aeab81d8 100644 --- a/Src/JxrDecode/jxrlib/image/sys/ansi.h +++ b/Src/JxrDecode/jxrlib/image/sys/ansi.h @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright � Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/image/sys/common.h b/Src/JxrDecode/jxrlib/image/sys/common.h index 1ef5c1b3..5aa41ba4 100644 --- a/Src/JxrDecode/jxrlib/image/sys/common.h +++ b/Src/JxrDecode/jxrlib/image/sys/common.h @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright © Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/image/sys/image.c b/Src/JxrDecode/jxrlib/image/sys/image.c index 034df98f..c8b3b17a 100644 --- a/Src/JxrDecode/jxrlib/image/sys/image.c +++ b/Src/JxrDecode/jxrlib/image/sys/image.c @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright � Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/image/sys/strPredQuant.c b/Src/JxrDecode/jxrlib/image/sys/strPredQuant.c index d265f0b8..eadde88a 100644 --- a/Src/JxrDecode/jxrlib/image/sys/strPredQuant.c +++ b/Src/JxrDecode/jxrlib/image/sys/strPredQuant.c @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright � Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/image/sys/strTransform.c b/Src/JxrDecode/jxrlib/image/sys/strTransform.c index c35b0b6c..c94f2d81 100644 --- a/Src/JxrDecode/jxrlib/image/sys/strTransform.c +++ b/Src/JxrDecode/jxrlib/image/sys/strTransform.c @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright � Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/image/sys/strTransform.h b/Src/JxrDecode/jxrlib/image/sys/strTransform.h index 3ee9a64e..e83041cf 100644 --- a/Src/JxrDecode/jxrlib/image/sys/strTransform.h +++ b/Src/JxrDecode/jxrlib/image/sys/strTransform.h @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright © Microsoft Corp. +// Copyright (C)) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/image/sys/strcodec.c b/Src/JxrDecode/jxrlib/image/sys/strcodec.c index 5c43c8a3..94dd22b7 100644 --- a/Src/JxrDecode/jxrlib/image/sys/strcodec.c +++ b/Src/JxrDecode/jxrlib/image/sys/strcodec.c @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright © Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/image/sys/strcodec.h b/Src/JxrDecode/jxrlib/image/sys/strcodec.h index f5487695..c3572e04 100644 --- a/Src/JxrDecode/jxrlib/image/sys/strcodec.h +++ b/Src/JxrDecode/jxrlib/image/sys/strcodec.h @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright © Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h b/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h index 579a3eaf..830d14b6 100644 --- a/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h +++ b/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright © Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c index 4cdc3222..2e9075e9 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright © Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h index 6228bafa..6223b99e 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright © Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c index 9dfdf02d..36c35254 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c @@ -1,15 +1,15 @@ //*@@@+++@@@@****************************************************************** // -// Copyright © Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c index 1262652a..1cdc213c 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright � Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c index fbdee3b2..015ad648 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright © Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h index f79bd3aa..50fd4886 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h @@ -1,14 +1,14 @@ //*@@@+++@@@@****************************************************************** // -// Copyright © Microsoft Corp. +// Copyright (C) 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, +// * 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, +// * 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. // From aca5a1e0886e148f2869b60c358c24848728bebe Mon Sep 17 00:00:00 2001 From: ptahmose Date: Mon, 31 Jul 2023 23:18:53 +0200 Subject: [PATCH 25/98] fix problem with "aligned_malloc" (seen on MacOS) --- Src/libCZI/stdAllocator.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Src/libCZI/stdAllocator.cpp b/Src/libCZI/stdAllocator.cpp index b7825117..844574e2 100644 --- a/Src/libCZI/stdAllocator.cpp +++ b/Src/libCZI/stdAllocator.cpp @@ -18,7 +18,9 @@ void* CHeapAllocator::Allocate(std::uint64_t size) } #if LIBCZI_HAVE_ALIGNED_ALLOC - return aligned_alloc(ALLOC_ALIGNMENT, size); + // Specification requires that 'size' is an integral multiple of 'alignment' (https://en.cppreference.com/w/cpp/memory/c/aligned_alloc), + // so we round up to the next multiple of 'alignment' here. + return aligned_alloc(ALLOC_ALIGNMENT, ((size+ALLOC_ALIGNMENT-1)/ALLOC_ALIGNMENT)*ALLOC_ALIGNMENT); #elif LIBCZI_HAVE__ALIGNED_MALLOC return _aligned_malloc((size_t)size, ALLOC_ALIGNMENT); #else From 5dac7358c8445ba56676446f2b79fd6519e7c90c Mon Sep 17 00:00:00 2001 From: ptahmose Date: Fri, 4 Aug 2023 23:52:05 +0200 Subject: [PATCH 26/98] use "tagWMPStream", some steps ahead --- Src/JxrDecode/JxrDecode2.cpp | 35 +- Src/JxrDecode/JxrDecode2.h | 17 +- .../jxrlib/image/decode/JXRTranscode.c | 4 +- Src/JxrDecode/jxrlib/image/decode/strdec.c | 4 +- Src/JxrDecode/jxrlib/image/encode/strenc.c | 8 +- Src/JxrDecode/jxrlib/image/sys/strcodec.c | 58 +-- Src/JxrDecode/jxrlib/image/sys/strcodec.h | 52 +-- .../jxrlib/image/sys/windowsmediaphoto.h | 32 +- Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c | 12 +- Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h | 26 +- Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c | 36 +- Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c | 18 +- Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h | 16 +- Src/libCZI/decoder.cpp | 10 +- Src/libCZI_UnitTests/testImage.cpp | 363 +++++++++++++++++- Src/libCZI_UnitTests/testImage.h | 7 +- Src/libCZI_UnitTests/test_JxrDecode.cpp | 22 +- Src/libCZI_UnitTests/test_writer.cpp | 2 +- 18 files changed, 569 insertions(+), 153 deletions(-) diff --git a/Src/JxrDecode/JxrDecode2.cpp b/Src/JxrDecode/JxrDecode2.cpp index a67cad14..c4503689 100644 --- a/Src/JxrDecode/JxrDecode2.cpp +++ b/Src/JxrDecode/JxrDecode2.cpp @@ -4,6 +4,10 @@ #include "jxrlib/image/sys/windowsmediaphoto.h" +using namespace std; + +static JxrDecode2::PixelFormat JxrPixelFormatGuidToEnum(const GUID& guid); + void JxrDecode2::Decode( codecHandle h, // const WMPDECAPPARGS* decArgs, @@ -13,11 +17,11 @@ void JxrDecode2::Decode( std::function deliverData) { ERR err; - PKFactory* pFactory = nullptr; + /*PKFactory* pFactory = nullptr; err = PKCreateFactory(&pFactory, PK_SDK_VERSION); //if (Failed(err)) { ThrowError("PKCreateFactory failed", err); } std::unique_ptr upFactory(pFactory, [](PKFactory* p)->void {p->Release(&p); }); - + */ /*PKCodecFactory* pCodecFactory = NULL; err = PKCreateCodecFactory(&pCodecFactory, WMP_SDK_VERSION); //if (Failed(err)) { ThrowError("PKCreateCodecFactory failed", err); } @@ -31,6 +35,8 @@ void JxrDecode2::Decode( WMPStream* pStream; err = CreateWS_Memory(&pStream, const_cast(ptrData), size); + //unique_ptr upStream(pStream, [](WMPStream* p)->void {p->Close(p); p->Release(p); }); + unique_ptr upStream(pStream, [](WMPStream* p)->void {p->Close(&p); }); //err = pFactory->CreateStreamFromMemory(&pStream, const_cast(ptrData), size); PKImageDecode* pDecoder; @@ -175,10 +181,33 @@ void JxrDecode2::Decode( rc.Width = width; rc.Height = height; + JxrDecode2::PixelFormat pixel_format = JxrPixelFormatGuidToEnum(pDecoder->guidPixFormat); + void* pImage = malloc(width * height * bytes_per_pixel); upDecoder->Copy(upDecoder.get(), &rc, (U8*)pImage, width * bytes_per_pixel); - deliverData(JxrDecode2::PixelFormat::_24bppBGR, width, height, height, pImage, width * bytes_per_pixel); + deliverData(/*JxrDecode2::PixelFormat::_24bppBGR*/pixel_format, width, height, height, pImage, width * bytes_per_pixel); free(pImage); } +JxrDecode2::PixelFormat JxrPixelFormatGuidToEnum(const GUID& guid) +{ + if (IsEqualGUID(guid, GUID_PKPixelFormat8bppGray)) + { + return JxrDecode2::PixelFormat::kGray8; + } + else if (IsEqualGUID(guid, GUID_PKPixelFormat16bppGray)) + { + return JxrDecode2::PixelFormat::kGray16; + } + else if (IsEqualGUID(guid, GUID_PKPixelFormat24bppBGR)) + { + return JxrDecode2::PixelFormat::kBgr24; + } + else if (IsEqualGUID(guid, GUID_PKPixelFormat48bppRGB)) + { + return JxrDecode2::PixelFormat::kBgr48; + } + + return JxrDecode2::PixelFormat::kInvalid; +} diff --git a/Src/JxrDecode/JxrDecode2.h b/Src/JxrDecode/JxrDecode2.h index 9eafe7eb..d158d42e 100644 --- a/Src/JxrDecode/JxrDecode2.h +++ b/Src/JxrDecode/JxrDecode2.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include class JxrDecode2 @@ -8,7 +9,12 @@ class JxrDecode2 public: enum class PixelFormat { - dontCare, + kInvalid, + kBgr24, + kBgr48, + kGray8, + kGray16, + /*dontCare, _24bppBGR, _1bppBlackWhite, _8bppGray, @@ -39,9 +45,9 @@ class JxrDecode2 _80bppCMYKA, _32bppBGR, - invalid + invalid*/ }; - + typedef void* codecHandle; void Decode( @@ -52,5 +58,8 @@ class JxrDecode2 const std::function& selectDestPixFmt, std::function deliverData); - + void Decode( + const void* ptrData, + size_t size, + const std::function(PixelFormat pixFmt, std::uint32_t width, std::uint32_t height)>& get_destination_func); }; diff --git a/Src/JxrDecode/jxrlib/image/decode/JXRTranscode.c b/Src/JxrDecode/jxrlib/image/decode/JXRTranscode.c index 23dd61d5..2981f1a2 100644 --- a/Src/JxrDecode/jxrlib/image/decode/JXRTranscode.c +++ b/Src/JxrDecode/jxrlib/image/decode/JXRTranscode.c @@ -55,7 +55,7 @@ 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); +EXTERN_C Int copyTo(struct tagWMPStream*, struct tagWMPStream*, 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 }; @@ -471,7 +471,7 @@ Bool isTileExtraction(CWMImageStrCodec* pSC, CWMTranscodingParam* pParam) return FALSE; } -Int WMPhotoTranscode(struct WMPStream* pStreamIn, struct WMPStream* pStreamOut, CWMTranscodingParam* pParam) +Int WMPhotoTranscode(struct tagWMPStream* pStreamIn, struct tagWMPStream* pStreamOut, CWMTranscodingParam* pParam) { PixelI* pMBBuf, MBBufAlpha[256]; // shared buffer, decoder <=> encoder bridge PixelI* pFrameBuf = NULL, * pFrameBufAlpha = NULL; diff --git a/Src/JxrDecode/jxrlib/image/decode/strdec.c b/Src/JxrDecode/jxrlib/image/decode/strdec.c index 69c589dd..497fca0c 100644 --- a/Src/JxrDecode/jxrlib/image/decode/strdec.c +++ b/Src/JxrDecode/jxrlib/image/decode/strdec.c @@ -219,7 +219,7 @@ Int readPackets(CWMImageStrCodec* pSC) for (k = 0; k < pSC->cNumBitIO; k++) { if (pSC->ppWStream != NULL) { // new API unsigned cBands = (pSC->WMISCP.bfBitstreamFormat == SPATIAL ? 1 : pSC->cSB); - struct WMPStream** ppWS = pSC->ppWStream + (pSC->WMISCP.cNumOfSliceMinus1V + 1) * pSC->cTileRow * cBands + struct tagWMPStream** ppWS = pSC->ppWStream + (pSC->WMISCP.cNumOfSliceMinus1V + 1) * pSC->cTileRow * cBands + k / cBands * cBands + (k % cBands); if (pSC->cTileRow > 0 && pSC->m_ppBitIO[k]->pWS != NULL) // attached to the same packet of the tile on top @@ -2954,7 +2954,7 @@ Int ReadWMIHeader( U32 i; ERR err = WMP_errSuccess; Bool bTilingPresent, bInscribed, bTileStretch, bAbbreviatedHeader; - struct WMPStream* pWS = pSCP->pWStream; + struct tagWMPStream* pWS = pSCP->pWStream; SimpleBitIO SB = { 0 }; SimpleBitIO* pSB = &SB; diff --git a/Src/JxrDecode/jxrlib/image/encode/strenc.c b/Src/JxrDecode/jxrlib/image/encode/strenc.c index eaea0283..af62251f 100644 --- a/Src/JxrDecode/jxrlib/image/encode/strenc.c +++ b/Src/JxrDecode/jxrlib/image/encode/strenc.c @@ -436,9 +436,9 @@ Int StrIOEncInit(CWMImageStrCodec* pSC) #endif char* pFilename; - pSC->ppWStream = (struct WMPStream**)malloc(pSC->cNumBitIO * sizeof(struct WMPStream*)); + pSC->ppWStream = (struct tagWMPStream**)malloc(pSC->cNumBitIO * sizeof(struct WMPStream*)); if (pSC->ppWStream == NULL) return ICERR_ERROR; - memset(pSC->ppWStream, 0, pSC->cNumBitIO * sizeof(struct WMPStream*)); + memset(pSC->ppWStream, 0, pSC->cNumBitIO * sizeof(struct tagWMPStream*)); if (pSC->cmbHeight * pSC->cmbWidth * pSC->WMISCP.cChannel >= MAX_MEMORY_SIZE_IN_WORDS) { #ifdef _WINDOWS_ @@ -596,7 +596,7 @@ Int writeIndexTable(CWMImageStrCodec* pSC) return ICERR_OK; } -Int copyTo(struct WMPStream* pSrc, struct WMPStream* pDst, size_t iBytes) +Int copyTo(struct tagWMPStream* pSrc, struct tagWMPStream* pDst, size_t iBytes) { char pData[PACKETLENGTH]; @@ -669,7 +669,7 @@ Int StrIOEncTerm(CWMImageStrCodec* pSC) if (pSC->cNumBitIO > 0) { size_t i, j, k, l; - struct WMPStream* pDst = pSC->WMISCP.pWStream; + struct tagWMPStream* pDst = pSC->WMISCP.pWStream; size_t* pTable = pSC->pIndexTable; for (i = 0; i < pSC->cNumBitIO; i++) { diff --git a/Src/JxrDecode/jxrlib/image/sys/strcodec.c b/Src/JxrDecode/jxrlib/image/sys/strcodec.c index 94dd22b7..795350d7 100644 --- a/Src/JxrDecode/jxrlib/image/sys/strcodec.c +++ b/Src/JxrDecode/jxrlib/image/sys/strcodec.c @@ -273,10 +273,10 @@ ERR WMPFree(void** ppv) //================================================================ // Streaming I/O functions //================================================================ -ERR CreateWS_File(struct WMPStream** ppWS, const char* szFilename, const char* szMode) +ERR CreateWS_File(struct tagWMPStream** ppWS, const char* szFilename, const char* szMode) { ERR err = WMP_errSuccess; - struct WMPStream* pWS = NULL; + struct tagWMPStream* pWS = NULL; Call(WMPAlloc((void**)ppWS, sizeof(**ppWS))); pWS = *ppWS; @@ -302,10 +302,10 @@ ERR CreateWS_File(struct WMPStream** ppWS, const char* szFilename, const char* s return err; } -ERR CloseWS_File(struct WMPStream** ppWS) +ERR CloseWS_File(struct tagWMPStream** ppWS) { ERR err = WMP_errSuccess; - struct WMPStream* pWS = *ppWS; + struct tagWMPStream* pWS = *ppWS; fclose(pWS->state.file.pFile); Call(WMPFree((void**)ppWS)); @@ -314,19 +314,19 @@ ERR CloseWS_File(struct WMPStream** ppWS) return err; } -Bool EOSWS_File(struct WMPStream* pWS) +Bool EOSWS_File(struct tagWMPStream* pWS) { return feof(pWS->state.file.pFile); } -ERR ReadWS_File(struct WMPStream* pWS, void* pv, size_t cb) +ERR ReadWS_File(struct tagWMPStream* pWS, void* pv, size_t cb) { // ERR err = WMP_errSuccess; return (fread(pv, cb, 1, pWS->state.file.pFile) == 1) ? WMP_errSuccess : WMP_errFileIO; } -ERR WriteWS_File(struct WMPStream* pWS, const void* pv, size_t cb) +ERR WriteWS_File(struct tagWMPStream* pWS, const void* pv, size_t cb) { ERR err = WMP_errSuccess; @@ -339,7 +339,7 @@ ERR WriteWS_File(struct WMPStream* pWS, const void* pv, size_t cb) return err; } -ERR SetPosWS_File(struct WMPStream* pWS, size_t offPos) +ERR SetPosWS_File(struct tagWMPStream* pWS, size_t offPos) { ERR err = WMP_errSuccess; @@ -349,7 +349,7 @@ ERR SetPosWS_File(struct WMPStream* pWS, size_t offPos) return err; } -ERR GetPosWS_File(struct WMPStream* pWS, size_t* poffPos) +ERR GetPosWS_File(struct tagWMPStream* pWS, size_t* poffPos) { ERR err = WMP_errSuccess; long lOff = 0; @@ -362,10 +362,10 @@ ERR GetPosWS_File(struct WMPStream* pWS, size_t* poffPos) } //---------------------------------------------------------------- -ERR CreateWS_Memory(struct WMPStream** ppWS, void* pv, size_t cb) +ERR CreateWS_Memory(struct tagWMPStream** ppWS, void* pv, size_t cb) { ERR err = WMP_errSuccess; - struct WMPStream* pWS = NULL; + struct tagWMPStream* pWS = NULL; Call(WMPAlloc((void**)ppWS, sizeof(**ppWS))); pWS = *ppWS; @@ -387,7 +387,7 @@ ERR CreateWS_Memory(struct WMPStream** ppWS, void* pv, size_t cb) return err; } -ERR CloseWS_Memory(struct WMPStream** ppWS) +ERR CloseWS_Memory(struct tagWMPStream** ppWS) { ERR err = WMP_errSuccess; @@ -397,12 +397,12 @@ ERR CloseWS_Memory(struct WMPStream** ppWS) return err; } -Bool EOSWS_Memory(struct WMPStream* pWS) +Bool EOSWS_Memory(struct tagWMPStream* pWS) { return pWS->state.buf.cbBuf <= pWS->state.buf.cbCur; } -ERR ReadWS_Memory(struct WMPStream* pWS, void* pv, size_t cb) +ERR ReadWS_Memory(struct tagWMPStream* pWS, void* pv, size_t cb) { ERR err = WMP_errSuccess; @@ -423,7 +423,7 @@ ERR ReadWS_Memory(struct WMPStream* pWS, void* pv, size_t cb) return err; } -ERR WriteWS_Memory(struct WMPStream* pWS, const void* pv, size_t cb) +ERR WriteWS_Memory(struct tagWMPStream* pWS, const void* pv, size_t cb) { ERR err = WMP_errSuccess; @@ -437,7 +437,7 @@ ERR WriteWS_Memory(struct WMPStream* pWS, const void* pv, size_t cb) return err; } -ERR SetPosWS_Memory(struct WMPStream* pWS, size_t offPos) +ERR SetPosWS_Memory(struct tagWMPStream* pWS, size_t offPos) { ERR err = WMP_errSuccess; @@ -450,7 +450,7 @@ ERR SetPosWS_Memory(struct WMPStream* pWS, size_t offPos) return err; } -ERR GetPosWS_Memory(struct WMPStream* pWS, size_t* poffPos) +ERR GetPosWS_Memory(struct tagWMPStream* pWS, size_t* poffPos) { *poffPos = pWS->state.buf.cbCur; @@ -462,10 +462,10 @@ ERR GetPosWS_Memory(struct WMPStream* pWS, size_t* poffPos) // - for indefinite size, multiple stream out // - reads not supported in this mode //================================================================= -ERR CreateWS_List(struct WMPStream** ppWS) +ERR CreateWS_List(struct tagWMPStream** ppWS) { ERR err = WMP_errSuccess; - struct WMPStream* pWS = NULL; + struct tagWMPStream* pWS = NULL; Call(WMPAlloc((void**)ppWS, sizeof(**ppWS) + PACKETLENGTH + sizeof(void*))); pWS = *ppWS; @@ -492,7 +492,7 @@ ERR CreateWS_List(struct WMPStream** ppWS) return err; } -ERR CloseWS_List(struct WMPStream** ppWS) +ERR CloseWS_List(struct tagWMPStream** ppWS) { ERR err = WMP_errSuccess; @@ -513,7 +513,7 @@ ERR CloseWS_List(struct WMPStream** ppWS) return err; } -ERR ReadWS_List(struct WMPStream* pWS, void* pv, size_t cb) +ERR ReadWS_List(struct tagWMPStream* pWS, void* pv, size_t cb) { ERR err = WMP_errSuccess; @@ -544,7 +544,7 @@ ERR ReadWS_List(struct WMPStream* pWS, void* pv, size_t cb) return err; } -ERR WriteWS_List(struct WMPStream* pWS, const void* pv, size_t cb) +ERR WriteWS_List(struct tagWMPStream* pWS, const void* pv, size_t cb) { ERR err = WMP_errSuccess; @@ -578,7 +578,7 @@ ERR WriteWS_List(struct WMPStream* pWS, const void* pv, size_t cb) return err; } -ERR SetPosWS_List(struct WMPStream* pWS, size_t offPos) +ERR SetPosWS_List(struct tagWMPStream* pWS, size_t offPos) { ERR err = WMP_errSuccess; @@ -604,7 +604,7 @@ ERR SetPosWS_List(struct WMPStream* pWS, size_t offPos) return err; } -ERR GetPosWS_List(struct WMPStream* pWS, size_t* poffPos) +ERR GetPosWS_List(struct tagWMPStream* pWS, size_t* poffPos) { *poffPos = pWS->state.buf.cbCur + PACKETLENGTH * pWS->state.buf.cbBufCount; @@ -615,7 +615,7 @@ ERR GetPosWS_List(struct WMPStream* pWS, size_t* poffPos) // Simple BitIO access functions //================================================================ // init SimpleBitIO -ERR attach_SB(SimpleBitIO* pSB, struct WMPStream* pWS) +ERR attach_SB(SimpleBitIO* pSB, struct tagWMPStream* pWS) { pSB->pWS = pWS; pSB->cbRead = 0; @@ -1091,7 +1091,7 @@ U32 getPosRead(BitIOInfo* pIO) //================================================================ // Block I/O functions //================================================================ -ERR attachISRead(BitIOInfo* pIO, struct WMPStream* pWS, CWMImageStrCodec* pSC) +ERR attachISRead(BitIOInfo* pIO, struct tagWMPStream* pWS, CWMImageStrCodec* pSC) { UNREFERENCED_PARAMETER(pSC); @@ -1122,7 +1122,7 @@ ERR readIS(CWMImageStrCodec* pSC, BitIOInfo* pIO) if (PACKET1(pIO->pbStart, pIO->pbCurrent, PACKETLENGTH)) { - struct WMPStream* pWS = pIO->pWS; + struct tagWMPStream* pWS = pIO->pWS; //Call(0 != pIO->pWS->Read(pIO->pWS, pIO->pbStart, PACKETLENGTH)); // TODO: add error checking code @@ -1145,7 +1145,7 @@ ERR detachISRead(CWMImageStrCodec* pSC, BitIOInfo* pIO) { ERR err = WMP_errSuccess; - struct WMPStream* pWS = pIO->pWS; + struct tagWMPStream* pWS = pIO->pWS; size_t cbRemain = 0; // we can ONLY detach IStream at byte boundary @@ -1163,7 +1163,7 @@ ERR detachISRead(CWMImageStrCodec* pSC, BitIOInfo* pIO) } //---------------------------------------------------------------- -ERR attachISWrite(BitIOInfo* pIO, struct WMPStream* pWS) +ERR attachISWrite(BitIOInfo* pIO, struct tagWMPStream* pWS) { pWS->GetPos(pWS, &pIO->offRef); diff --git a/Src/JxrDecode/jxrlib/image/sys/strcodec.h b/Src/JxrDecode/jxrlib/image/sys/strcodec.h index c3572e04..803a8c2a 100644 --- a/Src/JxrDecode/jxrlib/image/sys/strcodec.h +++ b/Src/JxrDecode/jxrlib/image/sys/strcodec.h @@ -106,7 +106,7 @@ typedef struct tagIOContext U8* pbPacket; // packet pointer U8* pbCurrent; // current pointer - struct WMPStream* pWS; // pointer to WMPStream + struct tagWMPStream* pWS; // pointer to WMPStream long offPacket; // byte offset into stream //ULARGE_INTEGER u64Acc; @@ -141,7 +141,7 @@ typedef struct tagBitIOInfo U8* pbCurrent; // current pointer - struct WMPStream* pWS; // pointer to WMPStream + struct tagWMPStream* 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 @@ -405,7 +405,7 @@ typedef struct CWMImageStrCodec { CWMIPredInfo* PredInfoPrevRow[MAX_CHANNELS]; CWMIPredInfo* pPredInfoMemory; - struct WMPStream** ppWStream; + struct tagWMPStream** ppWStream; //#ifdef WIN32 // TCHAR** ppTempFile; @@ -482,11 +482,11 @@ U32 getBit16_S(CWMImageStrCodec* pSC, BitIOInfo* pIO, U32 cBits); //================================================================ // packet I/O //================================================================ -ERR attachISRead(BitIOInfo* pIO, struct WMPStream* pWS, CWMImageStrCodec* pSC); +ERR attachISRead(BitIOInfo* pIO, struct tagWMPStream* pWS, CWMImageStrCodec* pSC); ERR readIS(CWMImageStrCodec* pSC, BitIOInfo* pIO); ERR detachISRead(CWMImageStrCodec* pSC, BitIOInfo* pIO); -ERR attachISWrite(BitIOInfo* pIO, struct WMPStream* pWS); +ERR attachISWrite(BitIOInfo* pIO, struct tagWMPStream* pWS); ERR writeIS(CWMImageStrCodec* pSC, BitIOInfo* pIO); ERR detachISWrite(CWMImageStrCodec* pSC, BitIOInfo* pIO); @@ -506,50 +506,50 @@ Void postProcBlock(struct tagPostProcInfo* strPostProcInfo[MAX_CHANNELS][2], Pix //================================================================ typedef struct tagSimpleBitIO { - struct WMPStream* pWS; + struct tagWMPStream* pWS; U32 cbRead; U8 bAccumulator; U32 cBitLeft; } SimpleBitIO; -ERR attach_SB(SimpleBitIO* pSB, struct WMPStream* pWS); +ERR attach_SB(SimpleBitIO* pSB, struct tagWMPStream* 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 Bool EOSWS_File(struct tagWMPStream* 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 ReadWS_File(struct tagWMPStream* pWS, void* pv, size_t cb); +EXTERN_C ERR WriteWS_File(struct tagWMPStream* 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 ERR SetPosWS_File(struct tagWMPStream* pWS, size_t offPos); +EXTERN_C ERR GetPosWS_File(struct tagWMPStream* pWS, size_t* poffPos); //---------------------------------------------------------------- -EXTERN_C Bool EOSWS_Memory(struct WMPStream* pWS); +EXTERN_C Bool EOSWS_Memory(struct tagWMPStream* 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 ReadWS_Memory(struct tagWMPStream* pWS, void* pv, size_t cb); +EXTERN_C ERR WriteWS_Memory(struct tagWMPStream* pWS, const void* pv, size_t cb); +//EXTERN_C ERR GetLineWS_Memory(struct tagWMPStream* 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 SetPosWS_Memory(struct tagWMPStream* pWS, size_t offPos); +EXTERN_C ERR GetPosWS_Memory(struct tagWMPStream* pWS, size_t* poffPos); -//EXTERN_C ERR GetPtrWS_Memory(struct WMPStream* pWS, size_t align, U8** ppb); +//EXTERN_C ERR GetPtrWS_Memory(struct tagWMPStream* pWS, size_t align, U8** ppb); //---------------------------------------------------------------- -EXTERN_C Bool EOSWS_List(struct WMPStream* pWS); +EXTERN_C Bool EOSWS_List(struct tagWMPStream* 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 ReadWS_List(struct tagWMPStream* pWS, void* pv, size_t cb); +EXTERN_C ERR WriteWS_List(struct tagWMPStream* 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 SetPosWS_List(struct tagWMPStream* pWS, size_t offPos); +EXTERN_C ERR GetPosWS_List(struct tagWMPStream* pWS, size_t* poffPos); -EXTERN_C ERR CreateWS_List(struct WMPStream** ppWS); -EXTERN_C ERR CloseWS_List(struct WMPStream** ppWS); +EXTERN_C ERR CreateWS_List(struct tagWMPStream** ppWS); +EXTERN_C ERR CloseWS_List(struct tagWMPStream** ppWS); /********************************************************************/ // Stuff related to scale/spatial ordering diff --git a/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h b/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h index 830d14b6..58bffc0d 100644 --- a/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h +++ b/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h @@ -280,7 +280,7 @@ typedef long ERR; //================================================================ // WMPStream interface //================================================================ -struct WMPStream +typedef struct tagWMPStream { union { @@ -302,23 +302,23 @@ struct WMPStream Bool fMem; - ERR(*Close)(struct WMPStream** pme); + ERR(*Close)(struct tagWMPStream** pme); - Bool(*EOS)(struct WMPStream* me); + Bool(*EOS)(struct tagWMPStream* 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(*Read)(struct tagWMPStream* me, void* pv, size_t cb); + ERR(*Write)(struct tagWMPStream* me, const void* pv, size_t cb); + //ERR (*GetLine)(struct tagWMPStream* me, void* pv, size_t cb); - ERR(*SetPos)(struct WMPStream* me, size_t offPos); - ERR(*GetPos)(struct WMPStream* me, size_t* poffPos); -}; + ERR(*SetPos)(struct tagWMPStream* me, size_t offPos); + ERR(*GetPos)(struct tagWMPStream* me, size_t* poffPos); +} WMPStream; -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_File(struct tagWMPStream** ppWS, const char* szFilename, const char* szMode); +EXTERN_C ERR CloseWS_File(struct tagWMPStream** ppWS); -EXTERN_C ERR CreateWS_Memory(struct WMPStream** ppWS, void* pv, size_t cb); -EXTERN_C ERR CloseWS_Memory(struct WMPStream** ppWS); +EXTERN_C ERR CreateWS_Memory(struct tagWMPStream** ppWS, void* pv, size_t cb); +EXTERN_C ERR CloseWS_Memory(struct tagWMPStream** ppWS); //================================================================ @@ -380,7 +380,7 @@ typedef struct tagCWMIStrCodecParam { SUBBAND sbSubband; // which subbands to keep U8 uiTrimFlexBits; - struct WMPStream* pWStream; + struct tagWMPStream* pWStream; size_t cbStream; // tiling info @@ -485,8 +485,8 @@ typedef struct tagCWMTranscodingParam { } CWMTranscodingParam; EXTERN_C Int WMPhotoTranscode( - struct WMPStream* pStreamDec, // input bitstrean - struct WMPStream* pStreamEnc, // output bitstream + struct tagWMPStream* pStreamDec, // input bitstrean + struct tagWMPStream* pStreamEnc, // output bitstream CWMTranscodingParam* pParam // transcoding parameters ); diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c index 2e9075e9..1c73c44e 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c @@ -405,7 +405,7 @@ ERR PKCodecFactory_CreateDecoderFromFile(const char* szFilename, PKImageDecode** char* pExt = NULL; const PKIID* pIID = NULL; - struct WMPStream* pStream = NULL; + struct tagWMPStream* pStream = NULL; PKImageDecode* pDecoder = NULL; // get file extension @@ -437,7 +437,7 @@ ERR PKCodecFactory_CreateDecoderFromMemory(char* inBuffer, size_t size, PKImageD char* pExt = ".jxr"; const PKIID* pIID = NULL; - struct WMPStream* pStream = NULL; + struct tagWMPStream* pStream = NULL; PKImageDecode* pDecoder = NULL; // get decode PKIID @@ -458,7 +458,7 @@ ERR PKCodecFactory_CreateDecoderFromMemory(char* inBuffer, size_t size, PKImageD return err; } -ERR PKCodecFactory_CreateDecoderFromStream(struct WMPStream* pStream, PKImageDecode** ppDecoder) +ERR PKCodecFactory_CreateDecoderFromStream(struct tagWMPStream* pStream, PKImageDecode** ppDecoder) { ERR err = WMP_errSuccess; @@ -532,7 +532,7 @@ ERR PKCreateCodecFactory(PKCodecFactory** ppCFactory, U32 uVersion) //================================================================ ERR PKImageEncode_Initialize( PKImageEncode* pIE, - struct WMPStream* pStream, + struct tagWMPStream* pStream, void* pvParam, size_t cbParam) { @@ -686,7 +686,7 @@ ERR PKImageEncode_WriteSource( return err; } -ERR PKImageEncode_WritePixelsBandedBegin(PKImageEncode* pEncoder, struct WMPStream* pPATempFile) +ERR PKImageEncode_WritePixelsBandedBegin(PKImageEncode* pEncoder, struct tagWMPStream* pPATempFile) { UNREFERENCED_PARAMETER(pEncoder); UNREFERENCED_PARAMETER(pPATempFile); @@ -843,7 +843,7 @@ ERR PKImageEncode_Create(PKImageEncode** ppIE) //================================================================ ERR PKImageDecode_Initialize( PKImageDecode* pID, - struct WMPStream* pStream) + struct tagWMPStream* pStream) { ERR err = WMP_errSuccess; diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h index 6223b99e..6b5f0e00 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h @@ -310,8 +310,8 @@ extern "C" { { ERR(*CreateStream)(PKStream**); - ERR(*CreateStreamFromFilename)(struct WMPStream**, const char*, const char*); - ERR(*CreateStreamFromMemory)(struct WMPStream**, void*, size_t); + ERR(*CreateStreamFromFilename)(struct tagWMPStream**, const char*, const char*); + ERR(*CreateStreamFromMemory)(struct tagWMPStream**, void*, size_t); ERR(*Release)(PKFactory**); } PKFactory; @@ -329,7 +329,7 @@ extern "C" { ERR(*CreateCodec)(const PKIID*, void**); ERR(*CreateDecoderFromFile)(const char*, PKImageDecode**); ERR(*CreateDecoderFromMemory)(char*, size_t, PKImageDecode**); - ERR(*CreateDecoderFromStream)(struct WMPStream*, PKImageDecode**); + ERR(*CreateDecoderFromStream)(struct tagWMPStream*, PKImageDecode**); ERR(*CreateFormatConverter)(PKFormatConverter**); ERR(*Release)(PKCodecFactory**); @@ -355,7 +355,7 @@ extern "C" { typedef struct tagPKImageEncode { //ERR (*GetPixelFormat)(MILPixelFormat*)); - ERR(*Initialize)(PKImageEncode*, struct WMPStream*, void*, size_t); + ERR(*Initialize)(PKImageEncode*, struct tagWMPStream*, void*, size_t); ERR(*Terminate)(PKImageEncode*); ERR(*SetPixelFormat)(PKImageEncode*, PKPixelFormatGUID); @@ -370,7 +370,7 @@ extern "C" { ERR(*WriteSource)(PKImageEncode*, PKFormatConverter*, PKRect*); // Banded encode API - currently only implemented for WMP encoder - ERR(*WritePixelsBandedBegin)(PKImageEncode* pEncoder, struct WMPStream* pPlanarAlphaTempFile); + ERR(*WritePixelsBandedBegin)(PKImageEncode* pEncoder, struct tagWMPStream* 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 @@ -381,7 +381,7 @@ extern "C" { ERR(*Release)(PKImageEncode**); - struct WMPStream* pStream; + struct tagWMPStream* pStream; size_t offStart; PKPixelFormatGUID guidPixFormat; @@ -434,14 +434,14 @@ extern "C" { // Banded encode state variables BANDEDENCSTATE eBandedEncState; - struct WMPStream* pPATempFile; + struct tagWMPStream* pPATempFile; } WMP; } PKImageEncode; //---------------------------------------------------------------- ERR PKImageEncode_Create_WMP(PKImageEncode** ppIE); - ERR PKImageEncode_Initialize(PKImageEncode* pIE, struct WMPStream* pStream, void* pvParam, size_t cbParam); + ERR PKImageEncode_Initialize(PKImageEncode* pIE, struct tagWMPStream* 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); @@ -465,7 +465,7 @@ extern "C" { //================================================================ typedef struct tagPKImageDecode { - ERR(*Initialize)(PKImageDecode*, struct WMPStream* pStream); + ERR(*Initialize)(PKImageDecode*, struct tagWMPStream* pStream); ERR(*GetPixelFormat)(PKImageDecode*, PKPixelFormatGUID*); ERR(*GetSize)(PKImageDecode*, I32*, I32*); @@ -475,7 +475,7 @@ extern "C" { ERR(*GetDescriptiveMetadata)(PKImageDecode* pIE, DESCRIPTIVEMETADATA* pDescMetadata); - ERR(*GetRawStream)(PKImageDecode*, struct WMPStream**); + ERR(*GetRawStream)(PKImageDecode*, struct tagWMPStream**); ERR(*Copy)(PKImageDecode*, const PKRect*, U8*, U32); @@ -484,7 +484,7 @@ extern "C" { ERR(*Release)(PKImageDecode**); - struct WMPStream* pStream; + struct tagWMPStream* pStream; Bool fStreamOwner; size_t offStart; @@ -532,7 +532,7 @@ extern "C" { //---------------------------------------------------------------- ERR PKImageDecode_Create_WMP(PKImageDecode** ppID); - ERR PKImageDecode_Initialize(PKImageDecode* pID, struct WMPStream* pStream); + ERR PKImageDecode_Initialize(PKImageDecode* pID, struct tagWMPStream* 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); @@ -551,7 +551,7 @@ extern "C" { ERR PKImageDecode_Create(PKImageDecode** ppID); ERR PKCodecFactory_CreateDecoderFromFile(const char* szFilename, PKImageDecode** ppDecoder); - ERR PKCodecFactory_CreateDecoderFromStream(struct WMPStream* pStream, PKImageDecode** ppDecoder); + ERR PKCodecFactory_CreateDecoderFromStream(struct tagWMPStream* pStream, PKImageDecode** ppDecoder); //================================================================ typedef struct tagPKFormatConverter diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c index 36c35254..1bd954c3 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c @@ -211,7 +211,7 @@ ERR WriteDescMetadata(PKImageEncode* pIE, { ERR err = WMP_errSuccess; WmpDEMisc* pDEMisc = &pIE->WMP.wmiDEMisc; - struct WMPStream* pWS = pIE->pStream; + struct tagWMPStream* pWS = pIE->pStream; U32 uiMetadataOffsetSize = 0; U32 uiCount = 0; U32 uiDataWrittenToOffset = 0; @@ -281,7 +281,7 @@ ERR WriteContainerPre( { ERR err = WMP_errSuccess; const U32 OFFSET_OF_PFD = 0x20; - struct WMPStream* pWS = pIE->pStream; + struct tagWMPStream* pWS = pIE->pStream; WmpDEMisc* pDEMisc = &pIE->WMP.wmiDEMisc; PKPixelInfo PI; size_t offPos = 0; @@ -706,7 +706,7 @@ ERR WriteContainerPost( { ERR err = WMP_errSuccess; - struct WMPStream* pWS = pIE->pStream; + struct tagWMPStream* pWS = pIE->pStream; WmpDEMisc* pDEMisc = &pIE->WMP.wmiDEMisc; size_t offPos; @@ -738,7 +738,7 @@ ERR WriteContainerPost( //================================================ ERR PKImageEncode_Initialize_WMP( PKImageEncode* pIE, - struct WMPStream* pStream, + struct tagWMPStream* pStream, void* pvParam, size_t cbParam) { @@ -1217,7 +1217,7 @@ ERR PKImageEncode_WritePixels_WMP( } -ERR PKImageEncode_WritePixelsBandedBegin_WMP(PKImageEncode* pIE, struct WMPStream* pPATempFile) +ERR PKImageEncode_WritePixelsBandedBegin_WMP(PKImageEncode* pIE, struct tagWMPStream* pPATempFile) { ERR err = WMP_errSuccess; @@ -1238,7 +1238,7 @@ ERR PKImageEncode_WritePixelsBanded_WMP(PKImageEncode* pIE, U32 cLine, U8* pbPix PKPixelInfo PI = { 0 }; Bool fPI = FALSE; BANDEDENCSTATE eEncStateOrig = pIE->WMP.eBandedEncState; - struct WMPStream* pPATempFile = pIE->WMP.pPATempFile; + struct tagWMPStream* pPATempFile = pIE->WMP.pPATempFile; // Unless this is the last call, reject inputs which are not multiples of 16 FailIf(!fLastCall && 0 != cLine % 16, WMP_errMustBeMultipleOf16LinesUntilLastCall); @@ -1305,7 +1305,7 @@ ERR PKImageEncode_WritePixelsBanded_WMP(PKImageEncode* pIE, U32 cLine, U8* pbPix ERR PKImageEncode_WritePixelsBandedEnd_WMP(PKImageEncode* pIE) { ERR err = WMP_errSuccess; - struct WMPStream* pMainStream = pIE->WMP.wmiSCP.pWStream; + struct tagWMPStream* pMainStream = pIE->WMP.wmiSCP.pWStream; size_t offAlpha; assert(BANDEDENCSTATE_ENCODING == pIE->WMP.eBandedEncState); @@ -1319,7 +1319,7 @@ ERR PKImageEncode_WritePixelsBandedEnd_WMP(PKImageEncode* pIE) { size_t cbAlpha; size_t cbBytesCopied; - struct WMPStream* pAlphaStream = pIE->WMP.wmiSCP_Alpha.pWStream; + struct tagWMPStream* pAlphaStream = pIE->WMP.wmiSCP_Alpha.pWStream; assert(pAlphaStream != pMainStream); // Otherwise we didn't use a temp file @@ -1370,8 +1370,8 @@ ERR PKImageEncode_Transcode_WMP( Bool fPlanarAlpha; PKPixelInfo PI; - struct WMPStream* pWSDec = NULL; - struct WMPStream* pWSEnc = pIE->pStream; + struct tagWMPStream* pWSDec = NULL; + struct tagWMPStream* pWSEnc = pIE->pStream; // pass through metadata Call(pID->GetPixelFormat(pID, &pixGUID)); @@ -1538,7 +1538,7 @@ ERR ParsePFDEntry( ERR err = WMP_errSuccess; ERR errTmp = WMP_errSuccess; PKPixelInfo PI; - struct WMPStream* pWS = pID->pStream; + struct tagWMPStream* pWS = pID->pStream; // size_t offPos = 0; union uf { @@ -1760,7 +1760,7 @@ ERR ParsePFD( U16 cEntry) { ERR err = WMP_errSuccess; - struct WMPStream* pWS = pID->pStream; + struct tagWMPStream* pWS = pID->pStream; U16 i = 0; for (i = 0; i < cEntry; ++i) @@ -1789,7 +1789,7 @@ ERR ReadContainer( { ERR err = WMP_errSuccess; - struct WMPStream* pWS = pID->pStream; + struct tagWMPStream* pWS = pID->pStream; size_t offPos = 0; char szSig[2] = { 0 }; @@ -1834,7 +1834,7 @@ ERR ReadContainer( //================================================ ERR PKImageDecode_Initialize_WMP( PKImageDecode* pID, - struct WMPStream* pWS) + struct tagWMPStream* pWS) { ERR err = WMP_errSuccess; @@ -1900,10 +1900,10 @@ ERR PKImageDecode_GetSize_WMP( ERR PKImageDecode_GetRawStream_WMP( PKImageDecode* pID, - struct WMPStream** ppWS) + struct tagWMPStream** ppWS) { ERR err = WMP_errSuccess; - struct WMPStream* pWS = pID->pStream; + struct tagWMPStream* pWS = pID->pStream; *ppWS = NULL; Call(pWS->SetPos(pWS, pID->WMP.wmiDEMisc.uImageOffset)); @@ -1928,7 +1928,7 @@ ERR PKImageDecode_Copy_WMP( U32 i, cMBRow; U32 cMBRowStart; #endif // REENTRANT_MODE - struct WMPStream* pWS = pID->pStream; + struct tagWMPStream* pWS = pID->pStream; U8 tempAlphaMode = 0; wmiBI.pv = pb; wmiBI.cLine = pRect->Height; @@ -2153,7 +2153,7 @@ ERR PKImageDecode_GetMetadata_WMP(PKImageDecode* pID, U32 uOffset, U32 uByteCoun if (pbGot && uOffset) { - struct WMPStream* pWS = pID->pStream; + struct tagWMPStream* pWS = pID->pStream; size_t iCurrPos; FailIf(*pcbGot < uByteCount, WMP_errBufferOverflow); diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c index 015ad648..50f403f3 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c @@ -246,7 +246,7 @@ ERR BufferCalcIFDSize(const U8* pbdata, size_t cbdata, U32 ofsifd, U8 endian, U3 } -ERR StreamCalcIFDSize(struct WMPStream* pWS, U32 uIFDOfs, U32* pcbifd) +ERR StreamCalcIFDSize(struct tagWMPStream* pWS, U32 uIFDOfs, U32* pcbifd) { ERR err = WMP_errSuccess; size_t offCurPos = 0; @@ -471,7 +471,7 @@ ERR BufferCopyIFD(const U8* pbsrc, U32 cbsrc, U32 ofssrc, U8 endian, U8* pbdst, // 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 StreamCopyIFD(struct tagWMPStream* pWS, U32 ofssrc, U8* pbdst, U32 cbdst, U32* pofsdst) { ERR err = WMP_errSuccess; size_t offCurPos = 0; @@ -588,7 +588,7 @@ ERR StreamCopyIFD(struct WMPStream* pWS, U32 ofssrc, U8* pbdst, U32 cbdst, U32* //================================================================ ERR GetUShort( - struct WMPStream* pWS, + struct tagWMPStream* pWS, size_t offPos, U16* puValue) { @@ -606,7 +606,7 @@ ERR GetUShort( } ERR PutUShort( - struct WMPStream* pWS, + struct tagWMPStream* pWS, size_t offPos, U16 uValue) { @@ -623,7 +623,7 @@ ERR PutUShort( } ERR GetULong( - struct WMPStream* pWS, + struct tagWMPStream* pWS, size_t offPos, U32* puValue) { @@ -645,7 +645,7 @@ ERR GetULong( } ERR PutULong( - struct WMPStream* pWS, + struct tagWMPStream* pWS, size_t offPos, U32 uValue) { @@ -666,7 +666,7 @@ ERR PutULong( } -ERR ReadBinaryData(struct WMPStream* pWS, +ERR ReadBinaryData(struct tagWMPStream* pWS, const U32 uCount, const U32 uValue, U8** ppbData) @@ -703,7 +703,7 @@ ERR ReadBinaryData(struct WMPStream* pWS, } -ERR ReadPropvar(/*__in_ecount(1)*/ struct WMPStream* pWS, +ERR ReadPropvar(/*__in_ecount(1)*/ struct tagWMPStream* pWS, const U16 uType, const U32 uCount, const U32 uValue, @@ -765,7 +765,7 @@ ERR ReadPropvar(/*__in_ecount(1)*/ struct WMPStream* pWS, ERR WriteWmpDE( - /*__in_ecount(1)*/ struct WMPStream* pWS, + /*__in_ecount(1)*/ struct tagWMPStream* pWS, size_t* pOffPos, const/*__in_ecount(1)*/ WmpDE* pDE, const U8* pbData, diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h index 50fd4886..2335b1df 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h @@ -186,31 +186,31 @@ typedef struct tagWmpDEMisc //================================================================ EXTERN_C ERR GetUShort( - struct WMPStream* pWS, + struct tagWMPStream* pWS, size_t offPos, U16* puValue ); EXTERN_C ERR PutUShort( - struct WMPStream* pWS, + struct tagWMPStream* pWS, size_t offPos, U16 uValue ); EXTERN_C ERR GetULong( - struct WMPStream* pWS, + struct tagWMPStream* pWS, size_t offPos, U32* puValue ); EXTERN_C ERR PutULong( - struct WMPStream* pWS, + struct tagWMPStream* pWS, size_t offPos, U32 uValue ); EXTERN_C ERR WriteWmpDE( - struct WMPStream* pWS, + struct tagWMPStream* pWS, size_t* pOffPos, const WmpDE* pDE, const U8* pbData, @@ -218,7 +218,7 @@ EXTERN_C ERR WriteWmpDE( ); -EXTERN_C ERR ReadPropvar(struct WMPStream* pWS, +EXTERN_C ERR ReadPropvar(struct tagWMPStream* pWS, const U16 uType, const U32 uCount, const U32 uValue, @@ -244,6 +244,6 @@ 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 StreamCalcIFDSize(struct tagWMPStream* 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); +EXTERN_C ERR StreamCopyIFD(struct tagWMPStream* pWS, U32 ofssrc, U8* pbdest, U32 cbdest, U32* pofsdest); diff --git a/Src/libCZI/decoder.cpp b/Src/libCZI/decoder.cpp index 70b6e3df..55b3edfc 100644 --- a/Src/libCZI/decoder.cpp +++ b/Src/libCZI/decoder.cpp @@ -39,11 +39,11 @@ std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, PixelType px_type; switch (pixFmt) { - case JxrDecode2::PixelFormat::_24bppBGR: px_type = PixelType::Bgr24; break; - case JxrDecode2::PixelFormat::_8bppGray: px_type = PixelType::Gray8; break; - case JxrDecode2::PixelFormat::_48bppRGB: px_type = PixelType::Bgr48; break; - case JxrDecode2::PixelFormat::_16bppGray: px_type = PixelType::Gray16; break; - case JxrDecode2::PixelFormat::_32bppGrayFloat: px_type = PixelType::Gray32Float; break; + case JxrDecode2::PixelFormat::kBgr24: px_type = PixelType::Bgr24; break; + case JxrDecode2::PixelFormat::kGray8: px_type = PixelType::Gray8; break; + case JxrDecode2::PixelFormat::kBgr48: px_type = PixelType::Bgr48; break; + case JxrDecode2::PixelFormat::kGray16: px_type = PixelType::Gray16; break; + //case JxrDecode2::PixelFormat::_32bppGrayFloat: px_type = PixelType::Gray32Float; break; default: throw std::logic_error("need to look into these formats..."); } diff --git a/Src/libCZI_UnitTests/testImage.cpp b/Src/libCZI_UnitTests/testImage.cpp index ddec8618..b75e66e1 100644 --- a/Src/libCZI_UnitTests/testImage.cpp +++ b/Src/libCZI_UnitTests/testImage.cpp @@ -791,9 +791,9 @@ } } -/*static*/ const void* CTestImage::GetJpgXrCompressedImage(size_t* size, int* width, int* height) +/*static*/ const void* CTestImage::GetJpgXrCompressedImage_Bgr24(size_t* size, int* width, int* height) { - static unsigned char rawData[4862] = + static const unsigned char rawData[4862] = { 0x49, 0x49, 0xBC, 0x01, 0x08, 0x00, 0x00, 0x00, 0x11, 0x00, 0x0E, 0x01, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x01, 0x02, 0x00, 0x17, 0x00, 0x00, 0x00, 0xDA, 0x00, @@ -1118,3 +1118,362 @@ return rawData; } + +/*static*/ const void* CTestImage::GetJpgXrCompressedImage_Gray8(size_t* size, int* width, int* height) +{ + static const unsigned char rawData[4023] = { + 0x49, 0x49, 0xBC, 0x01, 0x20, 0x00, 0x00, 0x00, 0x24, 0xC3, 0xDD, 0x6F, + 0x03, 0x4E, 0xFE, 0x4B, 0xB1, 0x85, 0x3D, 0x77, 0x76, 0x8D, 0xC9, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0xBC, + 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0xBC, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xBC, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4E, 0x00, 0x00, 0x00, 0x81, 0xBC, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4C, 0x00, 0x00, 0x00, 0x82, 0xBC, + 0x0B, 0x00, 0x01, 0x00, 0x00, 0x00, 0x25, 0x06, 0xC0, 0x42, 0x83, 0xBC, + 0x0B, 0x00, 0x01, 0x00, 0x00, 0x00, 0x25, 0x06, 0xC0, 0x42, 0xC0, 0xBC, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0xC1, 0xBC, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x31, 0x0F, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x57, 0x4D, 0x50, 0x48, 0x4F, 0x54, 0x4F, 0x00, 0x11, 0x45, + 0xC0, 0x01, 0x00, 0x4D, 0x00, 0x4B, 0x00, 0x80, 0x20, 0x08, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x27, 0x01, 0xE8, 0x08, 0x7D, 0xFF, 0x00, 0x00, + 0x01, 0x01, 0x4E, 0x3B, 0x74, 0x00, 0x01, 0x35, 0x84, 0x04, 0x82, 0x2C, + 0x5A, 0xF9, 0x51, 0x84, 0xBD, 0x2E, 0x0A, 0x53, 0xD6, 0xC3, 0x1A, 0xDE, + 0xB8, 0x3B, 0x0E, 0xAB, 0x76, 0xE1, 0x5B, 0x30, 0x68, 0x8D, 0x9D, 0x16, + 0x00, 0x00, 0x00, 0x01, 0x02, 0xE0, 0x81, 0x88, 0x22, 0x11, 0x8E, 0x20, + 0x81, 0x88, 0x20, 0xA3, 0x18, 0x66, 0x10, 0x11, 0x0A, 0x32, 0x8C, 0xC3, + 0x87, 0xBD, 0x72, 0x65, 0x07, 0x4A, 0x5D, 0x4B, 0xAE, 0x33, 0x5D, 0x2E, + 0x40, 0x86, 0x1A, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xC2, 0x05, 0x42, 0x42, 0x40, 0x84, 0x50, 0x81, + 0x40, 0x8B, 0x60, 0x41, 0xE8, 0x2A, 0x02, 0x84, 0x1A, 0x80, 0x80, 0xA1, + 0x69, 0xBB, 0x54, 0x56, 0xAC, 0x55, 0x89, 0x1C, 0xBC, 0x6C, 0x68, 0x1E, + 0x90, 0xF3, 0x16, 0x2E, 0x21, 0x60, 0xB0, 0xCD, 0xE0, 0x21, 0x7A, 0xF9, + 0x44, 0x2C, 0x83, 0x9F, 0xC3, 0x3C, 0xF0, 0x1B, 0x7E, 0x46, 0x78, 0x92, + 0x01, 0x11, 0x86, 0x25, 0xFD, 0x1C, 0x3D, 0xE2, 0x9F, 0x07, 0x99, 0x73, + 0x9E, 0x4A, 0xB2, 0xDA, 0x91, 0xA3, 0xD4, 0x5C, 0x48, 0xA1, 0xB0, 0x6E, + 0x16, 0xC2, 0x1F, 0x89, 0x57, 0x46, 0x90, 0x18, 0x68, 0x51, 0x3C, 0xC5, + 0x54, 0x38, 0x99, 0xDB, 0xE2, 0x68, 0xA1, 0x80, 0x64, 0x03, 0x49, 0x05, + 0x96, 0xE7, 0x66, 0x16, 0xEF, 0x18, 0xDD, 0x09, 0xFE, 0x49, 0x3C, 0xF9, + 0xAC, 0x40, 0xD8, 0x1E, 0x09, 0x1C, 0xA1, 0xD4, 0xEF, 0xD2, 0x92, 0x23, + 0xFF, 0x23, 0x03, 0x88, 0x45, 0x16, 0x82, 0x35, 0x80, 0x92, 0xF4, 0x65, + 0x19, 0x12, 0x85, 0xC1, 0x2E, 0xEA, 0xF1, 0xF0, 0x3B, 0x81, 0x60, 0x36, + 0x0E, 0xCC, 0x52, 0x41, 0x20, 0x40, 0x89, 0xF7, 0x37, 0xB5, 0xBD, 0x6C, + 0xE7, 0x97, 0x04, 0x86, 0xA1, 0x60, 0x59, 0xF0, 0xAE, 0x98, 0xAC, 0x28, + 0x07, 0x06, 0xDA, 0x70, 0xC1, 0xE8, 0x1E, 0x30, 0xB3, 0x48, 0x3D, 0xFB, + 0x0E, 0xB3, 0xCF, 0x51, 0xB3, 0x93, 0xB3, 0xDF, 0x99, 0xD6, 0x05, 0xB7, + 0x9D, 0xAA, 0x87, 0xCF, 0x13, 0x28, 0x8E, 0x84, 0xAE, 0x10, 0x8B, 0xF2, + 0xB8, 0x86, 0x33, 0x47, 0xC9, 0xC6, 0xC8, 0x30, 0x8D, 0x08, 0xB4, 0x2C, + 0x00, 0x00, 0x1F, 0x40, 0x00, 0x00, 0x38, 0x00, 0x00, 0x04, 0x80, 0x00, + 0x80, 0x01, 0x03, 0x04, 0x08, 0x28, 0x20, 0x60, 0xC1, 0x03, 0x00, 0x10, + 0x30, 0x00, 0x88, 0x4E, 0xE2, 0x00, 0x60, 0x0C, 0xE4, 0xCE, 0x1C, 0x01, + 0x80, 0x1B, 0x5C, 0x4D, 0x38, 0x80, 0x40, 0x00, 0x20, 0x10, 0xC0, 0x02, + 0x18, 0x45, 0x34, 0x82, 0x12, 0x41, 0x18, 0xA0, 0x3F, 0x00, 0x1A, 0x90, + 0x82, 0x93, 0x8C, 0x7E, 0x12, 0x03, 0x08, 0xDE, 0x08, 0x8B, 0x1B, 0x08, + 0x1C, 0x0E, 0x08, 0x82, 0x07, 0x8D, 0x9E, 0x11, 0x61, 0x06, 0xF4, 0xD7, + 0x9B, 0x9B, 0xAE, 0x10, 0xA7, 0x84, 0x2F, 0x26, 0x63, 0x08, 0x44, 0xCB, + 0x18, 0x40, 0x28, 0x9A, 0x3C, 0x07, 0xB9, 0x57, 0xFA, 0x22, 0xC4, 0x20, + 0x04, 0x9F, 0x46, 0x48, 0xC4, 0x02, 0x65, 0xE1, 0x00, 0x00, 0x1C, 0xFA, + 0xCE, 0xA8, 0x62, 0x86, 0x1F, 0x9E, 0xAC, 0x66, 0x95, 0x32, 0x76, 0x20, + 0x48, 0x25, 0x65, 0x7C, 0xD8, 0x47, 0x34, 0x90, 0x08, 0x1F, 0x82, 0xCB, + 0x9F, 0xA3, 0x7A, 0xD1, 0xBB, 0x4D, 0x84, 0x8E, 0x5A, 0xA2, 0x8A, 0x43, + 0x84, 0xC4, 0xCF, 0x0A, 0x58, 0x80, 0x00, 0x00, 0x01, 0x03, 0xF1, 0xC6, + 0x20, 0x86, 0x10, 0xB0, 0x62, 0x0D, 0x1F, 0x14, 0x28, 0x45, 0x1C, 0x36, + 0x38, 0x23, 0x88, 0x31, 0x86, 0x12, 0x08, 0x45, 0x10, 0x40, 0x06, 0x30, + 0x82, 0x33, 0x11, 0x84, 0x04, 0x60, 0x86, 0x20, 0xC4, 0xE2, 0xFD, 0x06, + 0x11, 0xE0, 0xC8, 0x28, 0x40, 0x87, 0x09, 0x14, 0x46, 0xF6, 0x1C, 0x23, + 0x21, 0x04, 0xAF, 0x10, 0x40, 0x46, 0x10, 0x21, 0x04, 0xA5, 0x11, 0x08, + 0x04, 0x41, 0x20, 0xC5, 0xC6, 0x88, 0x97, 0xA3, 0x04, 0x7C, 0x36, 0x98, + 0x49, 0x0F, 0x88, 0x24, 0x16, 0x89, 0xDA, 0xE0, 0x8F, 0x86, 0xD3, 0x09, + 0x21, 0xF1, 0x04, 0x82, 0xD1, 0x3B, 0x5E, 0x12, 0x00, 0xE8, 0xC2, 0x0B, + 0x34, 0x9A, 0xE1, 0x20, 0x0E, 0x8C, 0x20, 0xB3, 0x49, 0xAE, 0x8C, 0x23, + 0x9F, 0x20, 0x0C, 0x11, 0xF7, 0x1E, 0x90, 0x49, 0xE4, 0x41, 0x25, 0xF6, + 0x00, 0x23, 0xCE, 0x8C, 0x23, 0x9F, 0x20, 0x1D, 0x11, 0xF7, 0x1E, 0x90, + 0x49, 0xE4, 0x41, 0x25, 0xE6, 0x80, 0x23, 0xCE, 0x9A, 0x51, 0x74, 0xD2, + 0x8B, 0xA6, 0x94, 0x5D, 0x35, 0xD5, 0x82, 0x1D, 0xD3, 0x08, 0x9C, 0xA0, + 0x44, 0x00, 0x36, 0x20, 0x18, 0x43, 0xFA, 0x62, 0x90, 0x03, 0x9B, 0x10, + 0x01, 0x89, 0x00, 0x30, 0x6A, 0x10, 0x6A, 0x10, 0x60, 0xC1, 0x83, 0x07, + 0x52, 0x08, 0x72, 0x61, 0x13, 0xA4, 0x11, 0x04, 0x03, 0x10, 0x05, 0x30, + 0x87, 0xCC, 0x52, 0x00, 0x31, 0x88, 0x00, 0xC4, 0x00, 0x18, 0x35, 0x08, + 0x35, 0x08, 0x30, 0x60, 0xC1, 0x83, 0xEC, 0x08, 0xFA, 0x84, 0x90, 0x7D, + 0x8C, 0x09, 0x05, 0xA9, 0xAE, 0xAF, 0xA4, 0xD6, 0xB7, 0xA8, 0x48, 0x03, + 0x08, 0x2D, 0x6A, 0x12, 0xF3, 0xA8, 0x0E, 0xAF, 0xC9, 0x56, 0xB5, 0xDF, + 0xF9, 0x2A, 0xD6, 0xBD, 0xCA, 0x03, 0xDC, 0xA0, 0x6D, 0x71, 0x81, 0xDE, + 0x30, 0x6D, 0x71, 0x81, 0xDE, 0x30, 0x3B, 0xC6, 0x07, 0x78, 0xC0, 0xEF, + 0x18, 0x1D, 0xE2, 0x07, 0x60, 0x47, 0xCE, 0x84, 0x90, 0xEC, 0x60, 0x48, + 0x25, 0xAD, 0xD8, 0x11, 0xF3, 0xA1, 0x24, 0x3C, 0x9C, 0x09, 0x04, 0xB5, + 0xBD, 0x42, 0x40, 0x23, 0x08, 0x2A, 0x90, 0x9E, 0xA1, 0x20, 0x11, 0x84, + 0x17, 0xA8, 0x49, 0x41, 0x1F, 0xE8, 0x0A, 0x12, 0x2A, 0x50, 0x7A, 0x0A, + 0x09, 0x02, 0x3A, 0xA2, 0x40, 0x54, 0x04, 0x3F, 0x04, 0x0B, 0x01, 0x0B, + 0x42, 0x01, 0x07, 0x80, 0x28, 0x3A, 0x7A, 0xAA, 0x4B, 0x4D, 0xFD, 0x6E, + 0x12, 0xCE, 0x84, 0x63, 0x49, 0x41, 0xD0, 0x81, 0xC6, 0x01, 0x81, 0x29, + 0xA3, 0x42, 0x41, 0xD2, 0x35, 0xDB, 0x58, 0x23, 0xAC, 0xA4, 0x5B, 0x28, + 0x0E, 0x26, 0x62, 0x6D, 0x71, 0x03, 0x6B, 0x88, 0x1B, 0x5C, 0x83, 0x6B, + 0xA0, 0x70, 0x94, 0x01, 0x20, 0x93, 0x13, 0x08, 0xF2, 0x18, 0x23, 0x73, + 0x96, 0x9C, 0x00, 0xA8, 0x83, 0x5C, 0x25, 0x00, 0x48, 0x24, 0xC4, 0xC2, + 0x3C, 0x86, 0x08, 0xDC, 0xEF, 0xA8, 0x01, 0xAA, 0x20, 0xDE, 0x10, 0xB2, + 0x2D, 0x8B, 0x41, 0x17, 0x10, 0x45, 0x56, 0x20, 0x86, 0x86, 0x51, 0xAB, + 0x0E, 0x62, 0x65, 0x39, 0xEC, 0x5D, 0x4D, 0x07, 0x08, 0xE1, 0xCF, 0x5A, + 0x11, 0xC4, 0x12, 0x8D, 0x33, 0x81, 0x11, 0x41, 0x68, 0x3A, 0xD6, 0xEF, + 0x66, 0x01, 0x5A, 0x12, 0x38, 0xC0, 0xE5, 0x08, 0x41, 0x1C, 0x68, 0x43, + 0x8E, 0xD7, 0x99, 0x0D, 0x82, 0x0B, 0x47, 0xB4, 0x67, 0x37, 0x9E, 0xC0, + 0x35, 0xC2, 0x20, 0xC0, 0x4C, 0xF6, 0xE2, 0xCF, 0xE2, 0x08, 0x74, 0x08, + 0xEA, 0x84, 0x63, 0x42, 0x2B, 0x31, 0x19, 0x43, 0xBA, 0x6B, 0xE0, 0x2F, + 0x1A, 0xCE, 0x12, 0xBB, 0x3C, 0x08, 0x3D, 0xD0, 0x20, 0x70, 0x20, 0x10, + 0x20, 0x14, 0x15, 0xD2, 0x87, 0xA4, 0xF1, 0x2B, 0x08, 0x7C, 0x09, 0x11, + 0x42, 0x1F, 0x02, 0x1D, 0x02, 0x0D, 0x42, 0x11, 0x40, 0x50, 0x30, 0x4A, + 0x7A, 0x5B, 0xA0, 0xBD, 0xE3, 0x41, 0x29, 0x60, 0x40, 0x69, 0xE0, 0x41, + 0x6F, 0xA1, 0x08, 0xA2, 0x46, 0x69, 0xE9, 0x6F, 0xA7, 0xF0, 0x81, 0xE3, + 0x11, 0x2E, 0xC2, 0x1B, 0xE7, 0x04, 0x0E, 0xEA, 0x71, 0x50, 0xE0, 0xC4, + 0xC2, 0x09, 0x89, 0x92, 0x1E, 0x1A, 0xF6, 0xC9, 0x09, 0x8D, 0x12, 0x75, + 0x43, 0x08, 0x4D, 0x40, 0x80, 0x3F, 0x33, 0x90, 0xE9, 0x84, 0x52, 0xC0, + 0x85, 0xEB, 0x18, 0x1F, 0x10, 0x2C, 0x03, 0x3B, 0x9D, 0x59, 0xD1, 0xA6, + 0xB4, 0x70, 0x81, 0xC3, 0xFA, 0x2D, 0x7B, 0xED, 0x66, 0x36, 0x2D, 0x04, + 0x4F, 0x04, 0x23, 0x29, 0x92, 0x44, 0xB2, 0x77, 0x51, 0xA5, 0xC7, 0x9E, + 0x7C, 0xB8, 0x76, 0xD6, 0x80, 0xE1, 0xBB, 0x13, 0x20, 0x82, 0x6B, 0x56, + 0x1B, 0xC1, 0x08, 0xDC, 0xB1, 0x75, 0x9B, 0x8C, 0x61, 0x38, 0xC6, 0xAA, + 0x49, 0x99, 0x02, 0x4B, 0x66, 0xAC, 0x70, 0x89, 0xF2, 0xAC, 0x21, 0xB8, + 0xBF, 0x85, 0x98, 0x9A, 0x29, 0x09, 0x44, 0x4A, 0xD8, 0x97, 0xA8, 0x9F, + 0xF3, 0xDA, 0xEE, 0x10, 0x78, 0x1D, 0x41, 0x7D, 0x8C, 0x9E, 0xC2, 0x01, + 0xDD, 0x0B, 0x7A, 0x5F, 0x73, 0x20, 0xF6, 0x57, 0xD1, 0x2C, 0x97, 0x96, + 0xA9, 0x61, 0xA3, 0x16, 0x61, 0xE8, 0x3F, 0x98, 0xBB, 0x77, 0x08, 0x6C, + 0x56, 0x89, 0x9C, 0xC1, 0x0D, 0x85, 0xCC, 0x47, 0xE6, 0xD9, 0x91, 0x24, + 0x70, 0x83, 0x96, 0x31, 0x0B, 0x08, 0x45, 0xC5, 0xB3, 0x16, 0xC8, 0xCA, + 0x70, 0x85, 0xC6, 0x5E, 0xDF, 0xD9, 0x6C, 0x91, 0x1D, 0x58, 0x50, 0x18, + 0xA8, 0x8C, 0xD5, 0xD8, 0x9D, 0x2E, 0xC6, 0x55, 0x01, 0x12, 0x4C, 0x01, + 0x1D, 0xE4, 0x3E, 0x58, 0x41, 0x24, 0x03, 0x1F, 0xF1, 0x92, 0xFF, 0xA2, + 0xD3, 0x25, 0xBA, 0x93, 0x0C, 0xE0, 0x61, 0x27, 0x79, 0x30, 0xF8, 0xE9, + 0x1B, 0x84, 0x4C, 0xDD, 0x41, 0xF8, 0x05, 0xF7, 0xB1, 0x1B, 0x2B, 0x49, + 0x31, 0x6D, 0xC4, 0x23, 0x31, 0x21, 0xBF, 0xB2, 0x2C, 0x42, 0xE7, 0x1B, + 0x06, 0x66, 0x99, 0x8E, 0x20, 0x88, 0x22, 0xBD, 0xA7, 0x46, 0xEF, 0x3A, + 0x36, 0xA3, 0x13, 0x9D, 0x95, 0xAA, 0x99, 0xB7, 0x2B, 0x3B, 0x14, 0x7B, + 0xFA, 0x1C, 0x20, 0x44, 0x3E, 0xF4, 0x72, 0xEB, 0x17, 0x7C, 0xF0, 0x4B, + 0x9C, 0x7A, 0x26, 0x22, 0x2C, 0x78, 0x53, 0x29, 0x16, 0x8D, 0x72, 0x4B, + 0xC7, 0x01, 0x41, 0x14, 0x01, 0xA3, 0xB2, 0x8F, 0xC7, 0xA6, 0x48, 0xBF, + 0x2C, 0x5A, 0x6A, 0xB9, 0x31, 0x8D, 0x9B, 0x37, 0x85, 0x18, 0xBE, 0x8A, + 0x7B, 0x67, 0x1F, 0xCD, 0x1D, 0x9B, 0x0B, 0x69, 0x30, 0x38, 0x81, 0xCC, + 0x70, 0x16, 0x45, 0x80, 0xE8, 0xA3, 0xFA, 0x29, 0x9C, 0x19, 0x0D, 0xFD, + 0xC7, 0x96, 0x81, 0x1A, 0xE6, 0xE3, 0x49, 0x63, 0x6A, 0x55, 0x42, 0x43, + 0x49, 0x35, 0xAA, 0xA0, 0x28, 0x59, 0x2F, 0xF8, 0xD0, 0x39, 0x88, 0x02, + 0xE8, 0xA0, 0x39, 0x88, 0x02, 0xE8, 0xA3, 0xC4, 0x70, 0x46, 0x62, 0x8C, + 0x53, 0x6D, 0x8E, 0x44, 0x3E, 0x79, 0x09, 0x40, 0x32, 0x4B, 0x53, 0x1B, + 0x92, 0x21, 0x2D, 0x4C, 0x9D, 0x88, 0x09, 0xE8, 0x88, 0x53, 0xF5, 0x6B, + 0x9A, 0x2C, 0x80, 0xA1, 0x38, 0x23, 0x96, 0x00, 0x5D, 0x61, 0x3C, 0x46, + 0xB2, 0x6E, 0x6D, 0x47, 0xAA, 0xA6, 0xC5, 0x38, 0x27, 0xB1, 0x9D, 0x02, + 0xC4, 0x5D, 0x4E, 0xCD, 0x17, 0x51, 0x25, 0x0B, 0x25, 0xCA, 0x0B, 0x11, + 0x3F, 0x4C, 0x5B, 0x08, 0x07, 0x6C, 0x8B, 0x29, 0x47, 0xA1, 0xD8, 0x69, + 0x4F, 0x44, 0x8D, 0xF5, 0xC4, 0xD9, 0x13, 0x42, 0x4F, 0x48, 0x5F, 0x95, + 0xE9, 0xC5, 0x9B, 0x16, 0x39, 0xD7, 0x92, 0x6C, 0x29, 0x00, 0x2C, 0x00, + 0x94, 0x27, 0x00, 0x6C, 0x63, 0xA5, 0x6A, 0x52, 0x8A, 0x82, 0x03, 0x95, + 0x93, 0xEC, 0x59, 0x33, 0x9B, 0xDC, 0x52, 0xEB, 0x6C, 0x25, 0x0F, 0x29, + 0xFA, 0xA6, 0x06, 0x59, 0xAD, 0xBB, 0x73, 0x7A, 0x8D, 0x82, 0xE6, 0xEE, + 0x92, 0x35, 0x5E, 0x34, 0xA1, 0x64, 0xBA, 0x12, 0x85, 0x92, 0x63, 0x5C, + 0xE9, 0x60, 0x0F, 0x01, 0x59, 0x47, 0x9B, 0xFC, 0x78, 0x0A, 0x72, 0x25, + 0xCC, 0x70, 0x14, 0xE4, 0x4B, 0x90, 0xF0, 0x14, 0x47, 0x00, 0xE8, 0x85, + 0xD1, 0x53, 0xDB, 0x2B, 0xC2, 0x01, 0x46, 0x40, 0x2E, 0x81, 0x22, 0x82, + 0xA0, 0xA8, 0x2A, 0x0A, 0x82, 0xA0, 0xA8, 0x2A, 0x0A, 0x82, 0xA0, 0x8C, + 0x80, 0xA0, 0xA8, 0x2A, 0x0A, 0x82, 0xA0, 0xBC, 0x1C, 0x23, 0x84, 0x34, + 0x37, 0x08, 0xD7, 0x60, 0x89, 0x56, 0x10, 0x45, 0xB3, 0xBA, 0xD6, 0xC2, + 0x08, 0x3B, 0x88, 0x8F, 0x52, 0x41, 0x1F, 0xC4, 0xA8, 0x68, 0x70, 0xE1, + 0xC3, 0x80, 0xB0, 0x16, 0x93, 0x08, 0xE4, 0xDC, 0x01, 0xE8, 0x8F, 0x58, + 0x60, 0x93, 0xC6, 0xC8, 0x24, 0xBD, 0x21, 0x04, 0x79, 0x84, 0x77, 0xFB, + 0x40, 0xAB, 0xB6, 0x36, 0xCA, 0x42, 0xD8, 0x25, 0x94, 0x11, 0xC6, 0x11, + 0x64, 0x12, 0x7F, 0x08, 0x82, 0x08, 0x93, 0x60, 0x91, 0x10, 0x42, 0xB0, + 0x84, 0x60, 0x23, 0xE0, 0x78, 0x16, 0x45, 0x69, 0x08, 0x3A, 0x41, 0x04, + 0x82, 0x0B, 0xD9, 0x70, 0x82, 0xA8, 0xD5, 0x96, 0x2F, 0x35, 0xB6, 0x03, + 0x09, 0x27, 0x04, 0x8D, 0x8D, 0x04, 0x17, 0x03, 0x9E, 0x36, 0x11, 0x94, + 0xE2, 0x42, 0x57, 0x3F, 0xC2, 0x1B, 0x84, 0xD7, 0xE1, 0x1B, 0xC1, 0x0A, + 0xC2, 0x26, 0x82, 0x18, 0xE6, 0x08, 0x82, 0x09, 0x17, 0x99, 0xE1, 0x04, + 0xFA, 0x3E, 0x24, 0x34, 0x22, 0xC1, 0x63, 0x2B, 0x45, 0xFD, 0xA6, 0xB9, + 0x70, 0x80, 0x61, 0x07, 0xC2, 0x09, 0x02, 0xC2, 0x1B, 0x84, 0x45, 0x04, + 0x2A, 0x26, 0x07, 0x08, 0x34, 0x58, 0x90, 0x44, 0x9C, 0x10, 0x99, 0xED, + 0x1B, 0xEA, 0x38, 0x3E, 0x34, 0xD0, 0x2F, 0x04, 0x7B, 0x04, 0x33, 0xA1, + 0xE0, 0x80, 0xF3, 0x8B, 0x00, 0xD3, 0x26, 0x7F, 0xC6, 0xEE, 0x3D, 0xBE, + 0xD1, 0x89, 0xCE, 0x3E, 0x34, 0xD0, 0x3C, 0x69, 0x68, 0x3B, 0x04, 0x43, + 0x84, 0x29, 0xED, 0x38, 0x58, 0x19, 0x8B, 0x55, 0x8F, 0x61, 0x18, 0x41, + 0x17, 0xB8, 0x65, 0xB8, 0x41, 0x30, 0x88, 0x60, 0x80, 0x51, 0xDB, 0x3B, + 0x73, 0x66, 0x2E, 0xD4, 0x20, 0xD7, 0x50, 0x81, 0xDC, 0x6E, 0xBE, 0x82, + 0x12, 0x41, 0x04, 0x76, 0x1E, 0x0E, 0x42, 0x28, 0xFE, 0x11, 0x7C, 0x0F, + 0xF3, 0x6B, 0x44, 0x59, 0x7B, 0xBF, 0xD5, 0xF2, 0x61, 0x10, 0x61, 0x13, + 0x73, 0x53, 0x50, 0x46, 0xD3, 0x43, 0xF3, 0xEA, 0xC5, 0xC0, 0xCD, 0x4E, + 0xAC, 0x76, 0x6A, 0xA6, 0x10, 0x2F, 0xA1, 0x74, 0x59, 0x41, 0x07, 0xA0, + 0x81, 0xA0, 0xC1, 0x81, 0xA0, 0x6F, 0xB0, 0x92, 0x26, 0x0A, 0x6E, 0x75, + 0x01, 0xC6, 0x46, 0xBC, 0x90, 0xC6, 0x2D, 0x47, 0x68, 0x40, 0x1A, 0xED, + 0x50, 0x41, 0xB7, 0x54, 0xC5, 0xF7, 0x2B, 0xE5, 0x57, 0x7D, 0x38, 0xB0, + 0x93, 0x27, 0x30, 0x1B, 0xB4, 0x5D, 0x90, 0x60, 0xD4, 0x10, 0x7A, 0x08, + 0x1A, 0x0C, 0x18, 0x1A, 0x06, 0xEF, 0x84, 0xA1, 0x48, 0xDA, 0x70, 0x22, + 0x75, 0x9B, 0xB0, 0x90, 0x44, 0x70, 0x44, 0x6F, 0x21, 0x6D, 0x35, 0x08, + 0xEA, 0x0D, 0x5B, 0x5B, 0xAA, 0xE1, 0x26, 0x8A, 0xE4, 0x82, 0x05, 0x6C, + 0x88, 0x75, 0x74, 0x7A, 0x94, 0x11, 0x6E, 0x83, 0x32, 0x30, 0x0E, 0xD1, + 0xD5, 0x40, 0x90, 0x45, 0xF8, 0x45, 0xB3, 0xAF, 0x3D, 0xA0, 0x87, 0xC7, + 0x43, 0xF5, 0xE9, 0x86, 0x81, 0x31, 0x69, 0x63, 0x07, 0xA5, 0xEC, 0x92, + 0xC2, 0x22, 0xD0, 0x85, 0xC2, 0x4D, 0x58, 0x0E, 0x7A, 0x10, 0x08, 0x06, + 0xAC, 0x9A, 0x50, 0x41, 0xE8, 0x20, 0x68, 0x30, 0x60, 0x68, 0x1B, 0xCF, + 0x00, 0xE8, 0xE8, 0xDD, 0x6B, 0x6C, 0x01, 0xE1, 0xF0, 0x91, 0x98, 0x43, + 0xA0, 0x1B, 0x39, 0xB1, 0x62, 0x61, 0x09, 0x5D, 0x6F, 0xBD, 0x13, 0x08, + 0x9E, 0x08, 0x97, 0x04, 0x9E, 0xC0, 0x0C, 0x20, 0x58, 0xDA, 0x7D, 0x9C, + 0x23, 0x62, 0x81, 0x12, 0x0C, 0x20, 0x50, 0x41, 0x8D, 0x61, 0x07, 0xB0, + 0x90, 0x30, 0x42, 0xB0, 0x82, 0xC0, 0xA0, 0x89, 0xF0, 0x82, 0xBC, 0x1C, + 0x02, 0x16, 0xDD, 0x7F, 0xD3, 0x04, 0x23, 0xA5, 0xC4, 0x3D, 0x26, 0x11, + 0x93, 0x5C, 0xB0, 0xFA, 0x08, 0x6C, 0x05, 0x99, 0x5A, 0x24, 0xC6, 0x6A, + 0x8E, 0x3A, 0x0E, 0x83, 0x59, 0xB2, 0x54, 0x47, 0x1A, 0x3F, 0x88, 0x8C, + 0x2E, 0x09, 0x52, 0x56, 0x66, 0xA4, 0x97, 0x4D, 0x04, 0x31, 0x40, 0x00, + 0x00, 0x01, 0x04, 0x0F, 0x05, 0x78, 0x78, 0x2B, 0xD5, 0x50, 0x01, 0x54, + 0x00, 0x3C, 0x15, 0xE1, 0xE0, 0xAF, 0x15, 0x40, 0x05, 0x50, 0x00, 0x44, + 0x00, 0x22, 0x00, 0x11, 0x00, 0x08, 0x80, 0x04, 0x40, 0x02, 0x20, 0x01, + 0x10, 0x00, 0x88, 0x00, 0xF0, 0x57, 0x87, 0x82, 0xBD, 0x55, 0x00, 0x15, + 0x40, 0x03, 0xC1, 0x5E, 0x1E, 0x0A, 0xF1, 0x54, 0x00, 0x55, 0x00, 0x04, + 0x40, 0x02, 0x20, 0x01, 0x10, 0x00, 0x88, 0x00, 0x44, 0x00, 0x22, 0x00, + 0x11, 0x00, 0x08, 0x80, 0x1D, 0x23, 0x30, 0x4C, 0x00, 0x69, 0x09, 0xAE, + 0x3D, 0x41, 0x10, 0x00, 0x88, 0x0C, 0xD2, 0x06, 0x4D, 0x70, 0x69, 0x09, + 0x9B, 0xC7, 0x58, 0x69, 0x09, 0xC7, 0xF6, 0x4F, 0xFD, 0xF4, 0x57, 0x34, + 0x20, 0xB7, 0x79, 0x14, 0x28, 0x81, 0x00, 0x05, 0x0A, 0x20, 0x40, 0x01, + 0xA7, 0x22, 0x8C, 0x52, 0x50, 0xCB, 0x45, 0xBB, 0x42, 0x88, 0x10, 0x00, + 0x50, 0xA2, 0x04, 0x00, 0x05, 0x8E, 0xAE, 0x24, 0x2B, 0xC8, 0xEA, 0x3B, + 0x2A, 0x64, 0x50, 0x70, 0x98, 0xDA, 0x36, 0x5D, 0x96, 0x76, 0x74, 0x94, + 0x2A, 0x7F, 0x6D, 0xEC, 0x19, 0x48, 0xAF, 0x1D, 0x25, 0xCF, 0xE2, 0xEE, + 0xE0, 0x13, 0x36, 0xED, 0xC9, 0x27, 0x4D, 0x82, 0xA2, 0x70, 0x55, 0x01, + 0x41, 0x00, 0x40, 0x00, 0x02, 0x80, 0xA0, 0x80, 0x20, 0x00, 0x01, 0xCE, + 0xF7, 0xC5, 0xC8, 0x9D, 0xB6, 0x06, 0x26, 0x1D, 0x99, 0xF7, 0x0C, 0xD4, + 0x05, 0x04, 0x01, 0x00, 0x00, 0x0A, 0x02, 0x82, 0x00, 0x80, 0x00, 0x03, + 0xFA, 0x44, 0x9E, 0xB6, 0x83, 0x01, 0x1F, 0x92, 0x78, 0xBF, 0xAE, 0x39, + 0x78, 0xA1, 0xFE, 0xE3, 0x22, 0xB3, 0xEC, 0x82, 0x82, 0xE9, 0xB0, 0x1D, + 0xEE, 0x96, 0xE5, 0x8E, 0x94, 0x92, 0xE0, 0x11, 0x3E, 0x24, 0x54, 0x26, + 0xA6, 0x19, 0x12, 0x97, 0x18, 0xB1, 0x9F, 0x81, 0xA4, 0xCF, 0x7E, 0x67, + 0x63, 0x85, 0x03, 0x18, 0x08, 0x80, 0x06, 0x05, 0x4D, 0x5C, 0x80, 0xA2, + 0x6D, 0x24, 0xA0, 0x28, 0x20, 0x08, 0x00, 0x00, 0x50, 0x14, 0x10, 0x04, + 0x00, 0x00, 0x1E, 0x90, 0x5C, 0x78, 0x06, 0x8E, 0x86, 0x0F, 0x62, 0x21, + 0x04, 0x3A, 0xF6, 0x55, 0x01, 0x41, 0x00, 0x40, 0x00, 0x02, 0x80, 0xA0, + 0x80, 0x20, 0x00, 0x03, 0xEE, 0x6B, 0xBB, 0x4D, 0x61, 0x46, 0xAD, 0x00, + 0xD5, 0x1C, 0x75, 0xA4, 0x11, 0x42, 0x07, 0xB9, 0xB3, 0xDC, 0x4E, 0x9C, + 0x64, 0x43, 0x39, 0x43, 0xFD, 0x3F, 0x07, 0x3E, 0xD3, 0xDC, 0x66, 0x4C, + 0x8F, 0x01, 0x60, 0x5F, 0xB7, 0x04, 0xE9, 0xA4, 0x1B, 0xEE, 0x54, 0x9C, + 0xCE, 0x83, 0x62, 0x96, 0x76, 0xBE, 0xA6, 0x9F, 0x79, 0xA6, 0xA9, 0x2F, + 0x4C, 0x59, 0x44, 0x1B, 0xBE, 0xF2, 0x80, 0x14, 0x04, 0x00, 0x20, 0x00, + 0x00, 0x02, 0x80, 0x14, 0x04, 0x00, 0x20, 0x00, 0x00, 0x03, 0x62, 0x5C, + 0xF9, 0x93, 0x09, 0xB8, 0xEA, 0x5A, 0x2F, 0x08, 0x32, 0x0A, 0xC5, 0x4A, + 0xED, 0x6C, 0xC2, 0x00, 0x02, 0x00, 0x0A, 0x00, 0x0E, 0x01, 0x81, 0xC0, + 0x52, 0x20, 0x1F, 0x06, 0x01, 0x52, 0x80, 0x7A, 0x68, 0xF9, 0xE5, 0x13, + 0xC3, 0xCC, 0xB4, 0x14, 0x47, 0x01, 0x00, 0x80, 0x60, 0x30, 0x00, 0x28, + 0x00, 0x93, 0x80, 0x2C, 0xCF, 0x87, 0x42, 0xB9, 0x5F, 0x9C, 0xE5, 0xF0, + 0xC4, 0x2B, 0x59, 0xE0, 0x5E, 0x14, 0xEA, 0x6E, 0x99, 0xAC, 0x98, 0x70, + 0x78, 0xAC, 0x71, 0xF6, 0x3A, 0x46, 0x4B, 0x1B, 0x76, 0x53, 0x88, 0x31, + 0x62, 0x01, 0x69, 0x04, 0x49, 0x10, 0x1C, 0x04, 0x02, 0x01, 0x80, 0xC0, + 0x00, 0xA0, 0x02, 0x60, 0x11, 0x24, 0x2D, 0x22, 0x08, 0xE2, 0x10, 0x8E, + 0x02, 0x01, 0x00, 0xC0, 0x60, 0x00, 0x50, 0x02, 0x80, 0x58, 0xC0, 0x5C, + 0x10, 0x04, 0x84, 0x03, 0x73, 0x88, 0x1B, 0x68, 0xCF, 0x43, 0x03, 0xAA, + 0x00, 0xA0, 0x16, 0x30, 0x17, 0x04, 0x01, 0x21, 0x00, 0xC0, 0x4C, 0x78, + 0x24, 0x7F, 0x56, 0xA3, 0x34, 0x15, 0xA0, 0xE7, 0x2E, 0xA4, 0xDA, 0x00, + 0x77, 0xB0, 0x9D, 0xAC, 0xB3, 0x44, 0xCE, 0x49, 0xD3, 0x3A, 0x45, 0xD1, + 0x8E, 0x4E, 0x0E, 0x86, 0xCD, 0x21, 0x0B, 0x84, 0x7F, 0x48, 0x84, 0x20, + 0x8A, 0x97, 0xB0, 0x50, 0x0B, 0x18, 0x0B, 0x82, 0x00, 0x90, 0x80, 0x65, + 0x00, 0x00, 0x10, 0x48, 0x80, 0x38, 0x00, 0x0A, 0x01, 0x63, 0x01, 0x70, + 0x40, 0x12, 0x10, 0x0C, 0xA0, 0x00, 0x02, 0x09, 0x10, 0x07, 0x00, 0x01, + 0x40, 0x0A, 0x02, 0x00, 0x10, 0x00, 0x00, 0x01, 0x40, 0x0A, 0x02, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x40, 0x0A, 0x02, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x40, 0x0A, 0x02, 0x00, 0x10, 0x00, 0x00, 0x02, 0xB4, 0xC1, 0x87, 0x71, + 0x35, 0x8E, 0xE3, 0x61, 0x2E, 0x12, 0x42, 0x18, 0x76, 0xD9, 0xCE, 0x93, + 0x8A, 0xC8, 0xF3, 0x2A, 0x0A, 0x50, 0xC1, 0xD1, 0xA9, 0x14, 0x0E, 0x4E, + 0x08, 0x31, 0xCF, 0x84, 0x46, 0xD0, 0x4A, 0x56, 0x31, 0x11, 0x9C, 0xD7, + 0x91, 0x26, 0x80, 0xE1, 0x1D, 0xE6, 0x7D, 0xE8, 0x29, 0x60, 0x9C, 0x90, + 0x86, 0x19, 0x46, 0x77, 0xB4, 0x67, 0x00, 0x41, 0x58, 0x21, 0xE4, 0x40, + 0x03, 0x29, 0xC6, 0x05, 0x00, 0x28, 0x08, 0x00, 0x40, 0x00, 0x00, 0x05, + 0x00, 0x28, 0x08, 0x00, 0x40, 0x00, 0x00, 0x05, 0x00, 0x28, 0x08, 0x00, + 0x40, 0x00, 0x00, 0x05, 0x00, 0x28, 0x08, 0x00, 0x40, 0x00, 0x00, 0x05, + 0x00, 0x28, 0x08, 0x00, 0x40, 0x00, 0x00, 0x05, 0x00, 0x28, 0x08, 0x00, + 0x40, 0x00, 0x00, 0x05, 0x00, 0x28, 0x08, 0x00, 0x40, 0x00, 0x00, 0x05, + 0x00, 0x28, 0x08, 0x00, 0x40, 0x00, 0x00, 0x1A, 0xBE, 0x06, 0xBB, 0xA1, + 0x23, 0x2B, 0x2A, 0x7A, 0x19, 0xE0, 0x3C, 0x13, 0x0B, 0x77, 0x94, 0xA2, + 0xDB, 0x5D, 0x64, 0x9B, 0x97, 0xE8, 0xC5, 0x35, 0x4B, 0x65, 0xA2, 0x10, + 0x9D, 0xDE, 0x77, 0xE7, 0x35, 0x5B, 0xE9, 0x00, 0x15, 0xF9, 0x3D, 0x02, + 0x71, 0x1C, 0xE5, 0xC6, 0x7D, 0x04, 0x52, 0xA1, 0xB9, 0x5F, 0xF3, 0x6F, + 0x48, 0x77, 0xBB, 0x04, 0xEA, 0x72, 0x81, 0x6C, 0x6C, 0x9B, 0xE2, 0x70, + 0x2B, 0x4A, 0x65, 0x00, 0x28, 0x08, 0x00, 0x40, 0x00, 0x00, 0x05, 0x00, + 0x28, 0x08, 0x00, 0x40, 0x00, 0x00, 0x05, 0x00, 0x28, 0x08, 0x00, 0x40, + 0x00, 0x00, 0x05, 0x00, 0x28, 0x08, 0x00, 0x40, 0x00, 0x00, 0x05, 0x00, + 0x28, 0x08, 0x00, 0x40, 0x00, 0x00, 0x05, 0x00, 0x28, 0x08, 0x00, 0x40, + 0x00, 0x00, 0x05, 0x00, 0x28, 0x08, 0x00, 0x40, 0x00, 0x00, 0x05, 0x00, + 0x28, 0x08, 0x00, 0x40, 0x00, 0x00, 0x1C, 0xA2, 0x29, 0x0E, 0x4C, 0x35, + 0xA7, 0x13, 0x99, 0x46, 0x04, 0x6A, 0xB6, 0x1D, 0x10, 0x94, 0x41, 0x23, + 0x10, 0xF9, 0xFD, 0x30, 0x9E, 0xD0, 0x39, 0xCF, 0x9E, 0xCB, 0x14, 0xA4, + 0x31, 0x41, 0xC4, 0x22, 0x0C, 0x25, 0x4F, 0xE3, 0x8F, 0x38, 0x5D, 0xD9, + 0xF4, 0x58, 0xA3, 0x55, 0xF6, 0xA5, 0xE6, 0xD8, 0xE4, 0xFC, 0x64, 0x69, + 0x0C, 0x8D, 0x4A, 0x2F, 0xF1, 0xF3, 0x91, 0x58, 0x0A, 0xD4, 0xC1, 0x8A, + 0x86, 0xE1, 0x94, 0x00, 0xA0, 0x20, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, + 0xA0, 0x20, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0xA0, 0x20, 0x01, 0x00, + 0x00, 0x00, 0x14, 0x00, 0xA0, 0x20, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, + 0xA0, 0x20, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0xA0, 0x20, 0x01, 0x00, + 0x00, 0x00, 0x14, 0x00, 0xA0, 0x20, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, + 0xA0, 0x20, 0x01, 0x00, 0x00, 0x00, 0x54, 0xB5, 0xF0, 0x3F, 0x2F, 0x16, + 0xA4, 0xDB, 0x18, 0x07, 0x18, 0x8A, 0xA0, 0xA3, 0x9D, 0x87, 0xEF, 0x7C, + 0x6B, 0x16, 0x8C, 0x83, 0x08, 0x83, 0x5A, 0xC0, 0x1C, 0x69, 0xCE, 0x56, + 0x1A, 0xE3, 0x02, 0x75, 0x65, 0x0C, 0xD6, 0xA1, 0x8F, 0x82, 0x04, 0x92, + 0x4A, 0x70, 0x14, 0x88, 0x07, 0xC1, 0x80, 0x54, 0xA0, 0x08, 0x12, 0xDB, + 0x3C, 0x25, 0x5A, 0x27, 0x9B, 0x4E, 0x70, 0x14, 0x88, 0x07, 0xC1, 0x80, + 0x54, 0xA0, 0x05, 0x00, 0x28, 0x08, 0x00, 0x40, 0x00, 0x00, 0x05, 0x00, + 0x28, 0x08, 0x00, 0x40, 0x00, 0x00, 0x05, 0x00, 0x28, 0x08, 0x00, 0x40, + 0x00, 0x00, 0x05, 0x00, 0x28, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x01, 0x40, 0x01, 0xC0, 0x30, 0x38, 0x0A, 0x44, 0x03, 0xE0, 0xC0, + 0x2A, 0x50, 0x01, 0x00, 0xC0, 0x62, 0x0C, 0x28, 0x01, 0x18, 0x0A, 0x70, + 0x15, 0x08, 0x43, 0xE0, 0xC0, 0x2A, 0x50, 0x02, 0x80, 0x58, 0xC0, 0x5C, + 0x10, 0x04, 0x84, 0x03, 0x28, 0x00, 0x00, 0x82, 0x44, 0x01, 0xC0, 0x00, + 0x50, 0x00, 0x18, 0x08, 0x04, 0x00, 0x02, 0x01, 0x94, 0x00, 0x00, 0x40, + 0x02, 0x00, 0x00, 0x00, 0x28, 0x01, 0x40, 0x40, 0x02, 0x00, 0x00, 0x00, + 0x28, 0x01, 0x40, 0x40, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x80, + 0x04, 0x00, 0x00, 0x00, 0x50, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, + 0xA0, 0x00, 0x30, 0x10, 0x08, 0x00, 0x04, 0x03, 0x28, 0x00, 0x00, 0x80, + 0x04, 0x00, 0x00, 0x00, 0x50, 0x00, 0x18, 0x08, 0x04, 0x00, 0x02, 0x01, + 0x94, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x80, + 0x04, 0x00, 0x00, 0x00, 0x50, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, + 0xA0, 0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x01, 0x40, 0x00, 0x04, 0x00, + 0x20, 0x00, 0x00, 0x05, 0x01, 0x41, 0x00, 0x40, 0x00, 0x02, 0x80, 0xA0, + 0x80, 0x20, 0x00, 0x01, 0x40, 0x50, 0x40, 0x10, 0x00, 0x00, 0xA0, 0x28, + 0x20, 0x08, 0x00, 0x00, 0x50, 0x14, 0x10, 0x04, 0x00, 0x00, 0x28, 0x0A, + 0x08, 0x02, 0x00, 0x00, 0x14, 0x05, 0x04, 0x01, 0x00, 0x00, 0x0A, 0x02, + 0x82, 0x00, 0x80, 0x00, 0x05, 0x01, 0x41, 0x00, 0x40, 0x00, 0x02, 0x80, + 0xA0, 0x80, 0x20, 0x00, 0x01, 0x40, 0x50, 0x40, 0x10, 0x00, 0x00, 0xA0, + 0x28, 0x20, 0x08, 0x00, 0x00, 0x50, 0x14, 0x10, 0x04, 0x00, 0x00, 0x28, + 0x0A, 0x08, 0x02, 0x00, 0x00, 0x14, 0x05, 0x04, 0x01, 0x00, 0x00, 0x08, + 0x61, 0x1C, 0x81, 0x18, 0x0A, 0x80, 0xE8, 0x51, 0x02, 0x00, 0x00, 0x28, + 0x81, 0x00, 0x05, 0x0A, 0x20, 0x40, 0x00, 0x05, 0x10, 0x20, 0x00, 0x02, + 0x88, 0x10, 0x00, 0x01, 0x44, 0x08, 0x00, 0x00, 0xA2, 0x04, 0x00, 0x00, + 0x51, 0x02, 0x00, 0x0A, 0x14, 0x40, 0x80, 0x00, 0x0A, 0x20, 0x40, 0x00, + 0xBE, 0x74, 0x00, 0xBE, 0x29, 0xEB, 0x49, 0x88, 0x1A, 0x40, 0x14, 0x40, + 0x80, 0x00, 0x0A, 0x20, 0x40, 0x00, 0x02, 0xBA, 0x20, 0xF0, 0x11, 0x7C, + 0xD8, 0x93, 0x9D, 0x00, 0x88, 0x00, 0x44, 0x00, 0x22, 0x00, 0x11, 0x00, + 0x08, 0x80, 0x04, 0x40, 0x02, 0x20, 0x01, 0x10, 0x00, 0x88, 0x00, 0x44, + 0x01, 0x0F, 0x80, 0x04, 0x40, 0x02, 0x20, 0x01, 0x10, 0x00, 0x88, 0x00, + 0x44, 0x00, 0x22, 0x00, 0x11, 0x00, 0x08, 0x80, 0x04, 0x40, 0x6F, 0xE1, + 0x10, 0xAC, 0xC1, 0xA0, 0x56, 0x40, 0x00, 0x08, 0x80, 0x04, 0x40, 0x02, + 0x20, 0x01, 0x10, 0x01, 0xA0, 0x56, 0x40, 0x00, 0x1A, 0x05, 0x64, 0x00, + 0x0D, 0xA5, 0x3B, 0x39, 0x94, 0xDF, 0x1F, 0xE8, 0x64, 0x14, 0xB5, 0x04, + 0x0E, 0x5E, 0x3A, 0x8D, 0x40, 0x0E, 0x90, 0x98, 0x74, 0x84, 0xC0, 0x22, + 0x00, 0x11, 0x00, 0xE9, 0x09, 0x87, 0x48, 0x4C, 0x02, 0x20, 0x01, 0x10, + 0x4A, 0x0F, 0x4D, 0x3F, 0xC3, 0xA4, 0x26, 0x1D, 0x21, 0x3E, 0x4E, 0x0A, + 0x1D, 0x32, 0x1D, 0x21, 0x30, 0xE9, 0x09, 0x87, 0x48, 0x4C, 0x3A, 0x42, + 0x60, 0x11, 0x00, 0x08, 0x80, 0x74, 0x84, 0xC3, 0xA4, 0x26, 0x01, 0x10, + 0x00, 0x88, 0x33, 0x4D, 0x97, 0x02, 0xE2, 0xAA, 0x51, 0x82, 0x76, 0xCF, + 0xBB, 0x78, 0x99, 0x09, 0x8E, 0xAB, 0xB6, 0x18, 0x74, 0x84, 0xC3, 0xA4, + 0x26, 0x01, 0x10, 0x00, 0x88, 0x07, 0x48, 0x4C, 0x3A, 0x42, 0x60, 0x11, + 0x00, 0x08, 0x84, 0x35, 0xCB, 0x5B, 0xB8, 0x5F, 0x49, 0xD5, 0xF9, 0xBA, + 0x1D, 0x42, 0xB2, 0x80, 0x03, 0xBC, 0xE6, 0x7E, 0x1B, 0x64, 0x11, 0x93, + 0x18, 0x80, 0x22, 0x00, 0x11, 0x06, 0xA6, 0xD5, 0x48, 0x84, 0x01, 0x10, + 0xFB, 0xA0, 0x30 + }; + + if (size != nullptr) + { + *size = sizeof(rawData); + } + + if (width != nullptr) + { + *width = 78; + } + + if (height != nullptr) + { + *height = 76; + } + + return rawData; +} diff --git a/Src/libCZI_UnitTests/testImage.h b/Src/libCZI_UnitTests/testImage.h index fb0d6820..88d30daf 100644 --- a/Src/libCZI_UnitTests/testImage.h +++ b/Src/libCZI_UnitTests/testImage.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2017-2022 Carl Zeiss Microscopy GmbH +// SPDX-FileCopyrightText: 2017-2022 Carl Zeis-s Microscopy GmbH // // SPDX-License-Identifier: LGPL-3.0-or-later @@ -12,8 +12,9 @@ class CTestImage static const std::uint32_t BGR24TESTIMAGE_WIDTH = 1024; static const std::uint32_t BGR24TESTIMAGE_HEIGHT = 768; static void CopyBgr24Image(void* pDest, std::uint32_t width, std::uint32_t height, int stride); - - static const void* GetJpgXrCompressedImage(size_t* size, int* width, int* height); + + static const void* GetJpgXrCompressedImage_Bgr24(size_t* size, int* width, int* height); + static const void* GetJpgXrCompressedImage_Gray8(size_t* size, int* width, int* height); static const void* GetZStd1CompressedImage(size_t* size, int* width, int* height); static const void* GetZStd1CompressedImageWithHiLoPacking(size_t* size, int* width, int* height); }; diff --git a/Src/libCZI_UnitTests/test_JxrDecode.cpp b/Src/libCZI_UnitTests/test_JxrDecode.cpp index a73dea38..306d0d47 100644 --- a/Src/libCZI_UnitTests/test_JxrDecode.cpp +++ b/Src/libCZI_UnitTests/test_JxrDecode.cpp @@ -10,11 +10,11 @@ using namespace libCZI; using namespace std; -TEST(JxrDecode, Decode1) +TEST(JxrDecode, DecodeBgr24) { auto dec = CJxrLibDecoder::Create(); size_t sizeEncoded; int expectedWidth, expectedHeight; - auto ptrEncodedData = CTestImage::GetJpgXrCompressedImage(&sizeEncoded, &expectedWidth, &expectedHeight); + auto ptrEncodedData = CTestImage::GetJpgXrCompressedImage_Bgr24(&sizeEncoded, &expectedWidth, &expectedHeight); auto bmDecoded = dec->Decode(ptrEncodedData, sizeEncoded, libCZI::PixelType::Bgr24, expectedWidth, expectedHeight); EXPECT_EQ((uint32_t)expectedWidth, bmDecoded->GetWidth()) << "Width is expected to be equal"; EXPECT_EQ((uint32_t)expectedHeight, bmDecoded->GetHeight()) << "Height is expected to be equal"; @@ -26,3 +26,21 @@ TEST(JxrDecode, Decode1) static const uint8_t expectedResult[16] = { 0x04,0x77,0x2f,0x32,0x2f,0x94,0x9b,0x07,0x0d,0x53,0xa5,0x24,0xea,0x64,0x5a,0x1a }; EXPECT_TRUE(memcmp(hash, expectedResult, 16) == 0) << "Incorrect result"; } + +TEST(JxrDecode, DecodeGray8) +{ + auto dec = CJxrLibDecoder::Create(); + size_t sizeEncoded; int expectedWidth, expectedHeight; + auto ptrEncodedData = CTestImage::GetJpgXrCompressedImage_Gray8(&sizeEncoded, &expectedWidth, &expectedHeight); + auto bmDecoded = dec->Decode(ptrEncodedData, sizeEncoded, libCZI::PixelType::Gray8, expectedWidth, expectedHeight); + EXPECT_EQ((uint32_t)expectedWidth, bmDecoded->GetWidth()) << "Width is expected to be equal"; + EXPECT_EQ((uint32_t)expectedHeight, bmDecoded->GetHeight()) << "Height is expected to be equal"; + EXPECT_EQ(bmDecoded->GetPixelType(), PixelType::Gray8) << "Not the correct pixeltype."; + + uint8_t hash[16] = { 0 }; + Utils::CalcMd5SumHash(bmDecoded.get(), hash, sizeof(hash)); + + static const uint8_t expectedResult[16] = { 0x95, 0x4c, 0x70, 0x70, 0xae, 0xfb, 0x63, 0xc6, 0xc4, 0x0a, 0xb5, 0xec, 0xef, 0x73, 0x09, 0x8d }; + EXPECT_TRUE(memcmp(hash, expectedResult, 16) == 0) << "Incorrect result"; +} + diff --git a/Src/libCZI_UnitTests/test_writer.cpp b/Src/libCZI_UnitTests/test_writer.cpp index c353db34..7e0f80e3 100644 --- a/Src/libCZI_UnitTests/test_writer.cpp +++ b/Src/libCZI_UnitTests/test_writer.cpp @@ -1269,7 +1269,7 @@ TEST(CziWriter, Writer13) size_t sizeCompressedBitmap; int widthCompressedBitmap, heightCompressedBitmap; - auto compressedBitmap = CTestImage::GetJpgXrCompressedImage(&sizeCompressedBitmap, &widthCompressedBitmap, &heightCompressedBitmap); + auto compressedBitmap = CTestImage::GetJpgXrCompressedImage_Bgr24(&sizeCompressedBitmap, &widthCompressedBitmap, &heightCompressedBitmap); AddSubBlockInfoMemPtr addSbBlkInfo; addSbBlkInfo.Clear(); From acf5359855f3ada3739f93a69b9412d085acacbd Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sat, 5 Aug 2023 11:04:33 +0200 Subject: [PATCH 27/98] ...some steps ahead --- Src/JxrDecode/JxrDecode2.cpp | 89 ++++++++++++++++++++++++++++++++++++ Src/JxrDecode/JxrDecode2.h | 8 +++- Src/libCZI/decoder.cpp | 48 +++++++++++++++++++ 3 files changed, 144 insertions(+), 1 deletion(-) diff --git a/Src/JxrDecode/JxrDecode2.cpp b/Src/JxrDecode/JxrDecode2.cpp index c4503689..cb5f1d2b 100644 --- a/Src/JxrDecode/JxrDecode2.cpp +++ b/Src/JxrDecode/JxrDecode2.cpp @@ -1,5 +1,7 @@ #include "JxrDecode2.h" #include +#include +#include #include "jxrlib/jxrgluelib/JXRGlue.h" #include "jxrlib/image/sys/windowsmediaphoto.h" @@ -7,6 +9,51 @@ using namespace std; static JxrDecode2::PixelFormat JxrPixelFormatGuidToEnum(const GUID& guid); +static void ThrowError(const char* error_message, ERR error_code); +static const char* ERR_to_string(ERR error_code); + +void JxrDecode2::Decode( + const void* ptrData, + size_t size, + const std::function(PixelFormat pixel_format, std::uint32_t width, std::uint32_t height)>& get_destination_func) +{ + WMPStream* pStream; + ERR err = CreateWS_Memory(&pStream, const_cast(ptrData), size); + if (Failed(err)) { ThrowError("CreateWS_Memory failed", err); } + unique_ptr upStream(pStream, [](WMPStream* p)->void {p->Close(&p);}); + + PKImageDecode* pDecoder; + err = PKCodecFactory_CreateDecoderFromStream(pStream, &pDecoder); + if (Failed(err)) { ThrowError("PKCodecFactory_CreateDecoderFromStream failed", err); } + std::unique_ptr upDecoder(pDecoder, [](PKImageDecode* p)->void {p->Release(&p); }); + + U32 cFrame; + err = PKImageDecode_GetFrameCount(upDecoder.get(), &cFrame); + + I32 width, height; + PKImageDecode_GetSize(upDecoder.get(), &width, &height); + + PKPixelFormatGUID pixel_format_of_decoder; + PKImageDecode_GetPixelFormat(upDecoder.get(), &pixel_format_of_decoder); + + const auto decode_info = get_destination_func( + JxrPixelFormatGuidToEnum(pixel_format_of_decoder), + width, + height); + + PKRect rc; + rc.X = 0; + rc.Y = 0; + rc.Width = width; + rc.Height = height; + err = upDecoder->Copy( + upDecoder.get(), + &rc, + static_cast(get<2>(decode_info)), + get<1>(decode_info)); + if (Failed(err)) { ThrowError("PKImageDecode_Copy failed", err); } +} + void JxrDecode2::Decode( codecHandle h, @@ -211,3 +258,45 @@ JxrDecode2::PixelFormat JxrPixelFormatGuidToEnum(const GUID& guid) return JxrDecode2::PixelFormat::kInvalid; } + +void ThrowError(const char* error_message, ERR error_code) +{ + std::stringstream ss; + if (error_message != nullptr) + { + ss << "Error in JXR-decoder -> \"" << error_message << "\" code:" << error_code << " (" << ERR_to_string(error_code) << ")"; + } + else + { + ss << "Error in JXR-decoder -> " << error_message << " (" << ERR_to_string(error_code) << ")"; + } + + throw std::runtime_error(ss.str()); +} + +const char* ERR_to_string(ERR error_code) +{ + switch (error_code) + { + case WMP_errSuccess:return "WMP_errSuccess"; + case WMP_errFail:return "WMP_errFail"; + case WMP_errNotYetImplemented:return "WMP_errNotYetImplemented"; + case WMP_errAbstractMethod:return "WMP_errAbstractMethod"; + case WMP_errOutOfMemory:return "WMP_errOutOfMemory"; + case WMP_errFileIO:return "WMP_errFileIO"; + case WMP_errBufferOverflow:return "WMP_errBufferOverflow"; + case WMP_errInvalidParameter:return "WMP_errInvalidParameter"; + case WMP_errInvalidArgument:return "WMP_errInvalidArgument"; + case WMP_errUnsupportedFormat:return "WMP_errUnsupportedFormat"; + case WMP_errIncorrectCodecVersion:return "WMP_errIncorrectCodecVersion"; + case WMP_errIndexNotFound:return "WMP_errIndexNotFound"; + case WMP_errOutOfSequence:return "WMP_errOutOfSequence"; + case WMP_errNotInitialized:return "WMP_errNotInitialized"; + case WMP_errMustBeMultipleOf16LinesUntilLastCall:return "WMP_errMustBeMultipleOf16LinesUntilLastCall"; + case WMP_errPlanarAlphaBandedEncRequiresTempFile:return "WMP_errPlanarAlphaBandedEncRequiresTempFile"; + case WMP_errAlphaModeCannotBeTranscoded:return "WMP_errAlphaModeCannotBeTranscoded"; + case WMP_errIncorrectCodecSubVersion:return "WMP_errIncorrectCodecSubVersion"; + } + + return "unknown"; +} diff --git a/Src/JxrDecode/JxrDecode2.h b/Src/JxrDecode/JxrDecode2.h index d158d42e..8eda157d 100644 --- a/Src/JxrDecode/JxrDecode2.h +++ b/Src/JxrDecode/JxrDecode2.h @@ -58,8 +58,14 @@ class JxrDecode2 const std::function& selectDestPixFmt, std::function deliverData); + /// Decodes the specified data, giving an uncompressed bitmap. + /// The specified functor 'get_destination_func' will be called + /// + /// \param ptrData Information describing the pointer. + /// \param size The size. + /// \param get_destination_func The get destination function. void Decode( const void* ptrData, size_t size, - const std::function(PixelFormat pixFmt, std::uint32_t width, std::uint32_t height)>& get_destination_func); + const std::function(PixelFormat pixel_format, std::uint32_t width, std::uint32_t height)>& get_destination_func); }; diff --git a/Src/libCZI/decoder.cpp b/Src/libCZI/decoder.cpp index 55b3edfc..3f1bee39 100644 --- a/Src/libCZI/decoder.cpp +++ b/Src/libCZI/decoder.cpp @@ -19,6 +19,53 @@ using namespace std; return make_shared(JxrDecode::Initialize()); } +std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, size_t size, libCZI::PixelType pixelType, uint32_t width, uint32_t height) +{ + std::shared_ptr bitmap; + bool bitmap_is_locked = false; + JxrDecode2 decoder2; + try + { + decoder2.Decode( + ptrData, + size, + [&](JxrDecode2::PixelFormat pixel_format, std::uint32_t width, std::uint32_t height) + ->std::tuple + { + PixelType px_type; + switch (pixel_format) + { + case JxrDecode2::PixelFormat::kBgr24: px_type = PixelType::Bgr24; break; + case JxrDecode2::PixelFormat::kGray8: px_type = PixelType::Gray8; break; + case JxrDecode2::PixelFormat::kBgr48: px_type = PixelType::Bgr48; break; + case JxrDecode2::PixelFormat::kGray16: px_type = PixelType::Gray16; break; + //case JxrDecode2::PixelFormat::_32bppGrayFloat: px_type = PixelType::Gray32Float; break; + default: throw std::logic_error("need to look into these formats..."); + } + + bitmap = GetSite()->CreateBitmap(px_type, width, height); + const auto lock_info = bitmap->Lock(); + bitmap_is_locked = true; + return make_tuple(pixel_format, lock_info.stride, lock_info.ptrDataRoi); + }); + } + catch (const std::exception& e) + { + GetSite()->Log(LOGLEVEL_ERROR, e.what()); + if (bitmap_is_locked) + { + bitmap->Unlock(); + } + + throw; + } + + bitmap->Unlock(); + + return bitmap; +} + +#if false std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, size_t size, libCZI::PixelType pixelType, uint32_t width, uint32_t height) { std::shared_ptr bm; @@ -71,6 +118,7 @@ std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, return bm; } +#endif std::shared_ptr CJxrLibDecoder::Decode2(const void* ptrData, size_t size, libCZI::PixelType pixelType, uint32_t width, uint32_t height) { From 13eb9f81e019d008f3f5885eef5db0232bc28893 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sat, 5 Aug 2023 22:34:19 +0200 Subject: [PATCH 28/98] encoding - 1st tentative steps --- Src/JxrDecode/JxrDecode2.cpp | 94 +++++++++++++++++----- Src/JxrDecode/JxrDecode2.h | 14 +++- Src/JxrDecode/jxrlib/image/encode/strenc.c | 7 +- Src/libCZI/decoder.cpp | 16 +++- Src/libCZI/decoder.h | 2 + Src/libCZI_UnitTests/test_JxrDecode.cpp | 35 ++++++++ 6 files changed, 144 insertions(+), 24 deletions(-) diff --git a/Src/JxrDecode/JxrDecode2.cpp b/Src/JxrDecode/JxrDecode2.cpp index cb5f1d2b..9eb320e7 100644 --- a/Src/JxrDecode/JxrDecode2.cpp +++ b/Src/JxrDecode/JxrDecode2.cpp @@ -17,43 +17,99 @@ void JxrDecode2::Decode( size_t size, const std::function(PixelFormat pixel_format, std::uint32_t width, std::uint32_t height)>& get_destination_func) { + if (ptrData == nullptr) { throw invalid_argument("ptrData"); } + if (size == 0) { throw invalid_argument("size"); } + if (!get_destination_func) { throw invalid_argument("get_destination_func"); } + WMPStream* pStream; ERR err = CreateWS_Memory(&pStream, const_cast(ptrData), size); - if (Failed(err)) { ThrowError("CreateWS_Memory failed", err); } - unique_ptr upStream(pStream, [](WMPStream* p)->void {p->Close(&p);}); + if (Failed(err)) { ThrowError("'CreateWS_Memory' failed", err); } + unique_ptr upStream(pStream, [](WMPStream* p)->void {p->Close(&p); }); PKImageDecode* pDecoder; err = PKCodecFactory_CreateDecoderFromStream(pStream, &pDecoder); - if (Failed(err)) { ThrowError("PKCodecFactory_CreateDecoderFromStream failed", err); } + if (Failed(err)) { ThrowError("'PKCodecFactory_CreateDecoderFromStream' failed", err); } std::unique_ptr upDecoder(pDecoder, [](PKImageDecode* p)->void {p->Release(&p); }); - U32 cFrame; - err = PKImageDecode_GetFrameCount(upDecoder.get(), &cFrame); + U32 frame_count; + err = upDecoder->GetFrameCount(upDecoder.get(), &frame_count); + if (Failed(err)) { ThrowError("'decoder::GetFrameCount' failed", err); } + if (frame_count != 1) + { + ostringstream string_stream; + string_stream << "Expecting to find a frame_count of 1, but found frame_count = ." << frame_count; + throw runtime_error(string_stream.str()); + } I32 width, height; - PKImageDecode_GetSize(upDecoder.get(), &width, &height); + upDecoder->GetSize(upDecoder.get(), &width, &height); + if (Failed(err)) { ThrowError("'decoder::GetSize' failed", err); } PKPixelFormatGUID pixel_format_of_decoder; - PKImageDecode_GetPixelFormat(upDecoder.get(), &pixel_format_of_decoder); + upDecoder->GetPixelFormat(upDecoder.get(), &pixel_format_of_decoder); + if (Failed(err)) { ThrowError("'decoder::GetPixelFormat' failed", err); } const auto decode_info = get_destination_func( - JxrPixelFormatGuidToEnum(pixel_format_of_decoder), - width, + JxrPixelFormatGuidToEnum(pixel_format_of_decoder), + width, height); - PKRect rc; - rc.X = 0; - rc.Y = 0; - rc.Width = width; - rc.Height = height; + const PKRect rc{ 0, 0, width, height }; err = upDecoder->Copy( upDecoder.get(), &rc, static_cast(get<2>(decode_info)), get<1>(decode_info)); - if (Failed(err)) { ThrowError("PKImageDecode_Copy failed", err); } + if (Failed(err)) { ThrowError("decoder::Copy failed", err); } } +void JxrDecode2::Encode( + JxrDecode2::PixelFormat pixel_format, + std::uint32_t width, + std::uint32_t height, + std::uint32_t stride, + const void* ptr_bitmap) +{ + ERR err; + PKImageEncode* pEncoder; + err = PKCodecFactory_CreateCodec(&IID_PKImageWmpEncode, (void**)&pEncoder); + + + CWMIStrCodecParam codec_parameters; + memset(&codec_parameters, 0, sizeof(codec_parameters)); + //codec_parameters.guidPixFormat = GUID_PKPixelFormat24bppBGR; + codec_parameters.bVerbose = FALSE; + codec_parameters.cfColorFormat = YUV_444; + // args->bFlagRGB_BGR = FALSE; //default BGR + codec_parameters.bdBitDepth = BD_LONG; + codec_parameters.bfBitstreamFormat = FREQUENCY; + codec_parameters.bProgressiveMode = TRUE; + codec_parameters.olOverlap = OL_ONE; + codec_parameters.cNumOfSliceMinus1H = codec_parameters.cNumOfSliceMinus1V = 0; + codec_parameters.sbSubband = SB_ALL; + codec_parameters.uAlphaMode = 0; + codec_parameters.uiDefaultQPIndex = 1; + codec_parameters.uiDefaultQPIndexAlpha = 1; + + //codec_parameters.fltImageQuality = 1.f; + //codec_parameters.bOverlapSet = 0; + //codec_parameters.bColorFormatSet = 0; + + + // { &GUID_PKPixelFormat24bppBGR, 3, CF_RGB, BD_8, 24, PK_pixfmtBGR, 2, 3, 8, 1 }, + + struct tagWMPStream* pEncodeStream = NULL; + CreateWS_File(&pEncodeStream, "C:\\temp\\test.jxr", "wb"); + + err = pEncoder->Initialize(pEncoder, pEncodeStream, &codec_parameters, sizeof(codec_parameters)); + + err = pEncoder->SetPixelFormat(pEncoder, GUID_PKPixelFormat24bppBGR); + err = pEncoder->SetSize(pEncoder, width, height); + err = pEncoder->SetResolution(pEncoder, 96.f, 96.f); + + pEncoder->WritePixels(pEncoder, height, (U8*)ptr_bitmap, stride); + pEncodeStream->Close(&pEncodeStream); +} void JxrDecode2::Decode( codecHandle h, @@ -261,17 +317,17 @@ JxrDecode2::PixelFormat JxrPixelFormatGuidToEnum(const GUID& guid) void ThrowError(const char* error_message, ERR error_code) { - std::stringstream ss; + ostringstream string_stream; if (error_message != nullptr) { - ss << "Error in JXR-decoder -> \"" << error_message << "\" code:" << error_code << " (" << ERR_to_string(error_code) << ")"; + string_stream << "Error in JXR-decoder -> \"" << error_message << "\" code:" << error_code << " (" << ERR_to_string(error_code) << ")"; } else { - ss << "Error in JXR-decoder -> " << error_message << " (" << ERR_to_string(error_code) << ")"; + string_stream << "Error in JXR-decoder -> " << error_message << " (" << ERR_to_string(error_code) << ")"; } - throw std::runtime_error(ss.str()); + throw runtime_error(string_stream.str()); } const char* ERR_to_string(ERR error_code) diff --git a/Src/JxrDecode/JxrDecode2.h b/Src/JxrDecode/JxrDecode2.h index 8eda157d..4b826f3d 100644 --- a/Src/JxrDecode/JxrDecode2.h +++ b/Src/JxrDecode/JxrDecode2.h @@ -59,7 +59,12 @@ class JxrDecode2 std::function deliverData); /// Decodes the specified data, giving an uncompressed bitmap. - /// The specified functor 'get_destination_func' will be called + /// The course of action is as follows: + /// * The decoder will be initialized with the specified compressed data. + /// * The characteristics of the compressed data will be determined - i.e the pixel type, width, height, etc. are determined. + /// * The 'get_destination_func' is called, passing in the pixel type, width, and height. + /// * The function should return a pointer to a buffer that can hold the uncompressed bitmap. + /// The tuple it returns is the pixel type, the stride and the pointer to the buffer. /// /// \param ptrData Information describing the pointer. /// \param size The size. @@ -68,4 +73,11 @@ class JxrDecode2 const void* ptrData, size_t size, const std::function(PixelFormat pixel_format, std::uint32_t width, std::uint32_t height)>& get_destination_func); + + void Encode( + JxrDecode2::PixelFormat pixel_format, + std::uint32_t width, + std::uint32_t height, + std::uint32_t stride, + const void* ptr_bitmap); }; diff --git a/Src/JxrDecode/jxrlib/image/encode/strenc.c b/Src/JxrDecode/jxrlib/image/encode/strenc.c index af62251f..a726a137 100644 --- a/Src/JxrDecode/jxrlib/image/encode/strenc.c +++ b/Src/JxrDecode/jxrlib/image/encode/strenc.c @@ -418,9 +418,12 @@ static _FORCEINLINE PixelI forwardHalf(PixelI hHalf) // BitIOInfo init/term for encoding const size_t MAX_MEMORY_SIZE_IN_WORDS = 64 << 20; // 1 << 20 \approx 1 million +#include +#define _WINDOWS_ 1 + Int StrIOEncInit(CWMImageStrCodec* pSC) { -#if false // TODO TODO TODO +//#if false // TODO TODO TODO pSC->m_param.bIndexTable = !(pSC->WMISCP.bfBitstreamFormat == SPATIAL && pSC->WMISCP.cNumOfSliceMinus1H + pSC->WMISCP.cNumOfSliceMinus1V == 0); if (allocateBitIOInfo(pSC) != ICERR_OK) { return ICERR_ERROR; @@ -498,7 +501,7 @@ Int StrIOEncInit(CWMImageStrCodec* pSC) attachISWrite(pSC->m_ppBitIO[i], pSC->ppWStream[i]); } } -#endif +//#endif return ICERR_OK; } diff --git a/Src/libCZI/decoder.cpp b/Src/libCZI/decoder.cpp index 3f1bee39..1e495985 100644 --- a/Src/libCZI/decoder.cpp +++ b/Src/libCZI/decoder.cpp @@ -19,6 +19,18 @@ using namespace std; return make_shared(JxrDecode::Initialize()); } +void CJxrLibDecoder::Encode(libCZI::PixelType pixel_type, std::uint32_t width, std::uint32_t height, std::uint32_t stride, const void* ptrData) +{ + JxrDecode2 decoder2; + decoder2.Encode( + JxrDecode2::PixelFormat::kBgr24, + width, + height, + stride, + ptrData); + +} + std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, size_t size, libCZI::PixelType pixelType, uint32_t width, uint32_t height) { std::shared_ptr bitmap; @@ -29,8 +41,8 @@ std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, decoder2.Decode( ptrData, size, - [&](JxrDecode2::PixelFormat pixel_format, std::uint32_t width, std::uint32_t height) - ->std::tuple + [&](JxrDecode2::PixelFormat pixel_format, std::uint32_t width, std::uint32_t height) + -> tuple { PixelType px_type; switch (pixel_format) diff --git a/Src/libCZI/decoder.h b/Src/libCZI/decoder.h index 9f734d38..81a8e60b 100644 --- a/Src/libCZI/decoder.h +++ b/Src/libCZI/decoder.h @@ -23,4 +23,6 @@ class CJxrLibDecoder : public libCZI::IDecoder public: std::shared_ptr Decode(const void* ptrData, size_t size, libCZI::PixelType, std::uint32_t width, std::uint32_t height) override; std::shared_ptr Decode2(const void* ptrData, size_t size, libCZI::PixelType, std::uint32_t width, std::uint32_t height); + + void Encode(libCZI::PixelType pixel_type, std::uint32_t width, std::uint32_t height, std::uint32_t stride, const void* ptrData); }; diff --git a/Src/libCZI_UnitTests/test_JxrDecode.cpp b/Src/libCZI_UnitTests/test_JxrDecode.cpp index 306d0d47..edca5901 100644 --- a/Src/libCZI_UnitTests/test_JxrDecode.cpp +++ b/Src/libCZI_UnitTests/test_JxrDecode.cpp @@ -3,6 +3,7 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include "pch.h" +#include #include "inc_libCZI.h" #include "testImage.h" #include "../libCZI/decoder.h" @@ -44,3 +45,37 @@ TEST(JxrDecode, DecodeGray8) EXPECT_TRUE(memcmp(hash, expectedResult, 16) == 0) << "Incorrect result"; } +TEST(JxrDecode, TryDecodeInvalidDataExpectException) +{ + // pass invalid data to decoder, and expect an exception + const auto dec = CJxrLibDecoder::Create(); + size_t sizeEncoded = 2345; + unique_ptr encoded_data(new uint8_t[sizeEncoded]); + for (size_t i = 0; i < sizeEncoded; i++) + { + encoded_data.get()[i] = static_cast(i); + } + + EXPECT_ANY_THROW(dec->Decode(encoded_data.get(), sizeEncoded, libCZI::PixelType::Invalid, 0, 0)); +} + +TEST(JxrDecode, TestEncoder) +{ + auto bitmap = CBitmapData::Create(PixelType::Bgr24, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); + { + ScopedBitmapLockerSP lck{ bitmap }; + CTestImage::CopyBgr24Image(lck.ptrDataRoi, bitmap->GetWidth(), bitmap->GetHeight(), lck.stride); + } + + const auto codec = CJxrLibDecoder::Create(); + + { + ScopedBitmapLockerSP lck{ bitmap }; + codec->Encode( + bitmap->GetPixelType(), + bitmap->GetWidth(), + bitmap->GetHeight(), + lck.stride, + lck.ptrDataRoi); + } +} From 238090b9864d1c73c5780fc6196db3d00862fe18 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 6 Aug 2023 00:32:54 +0200 Subject: [PATCH 29/98] adding "heap-based-stream" --- Src/JxrDecode/JxrDecode2.cpp | 3 +- Src/JxrDecode/jxrlib/image/sys/strcodec.c | 110 ++++++++++++++++++ Src/JxrDecode/jxrlib/image/sys/strcodec.h | 5 + .../jxrlib/image/sys/windowsmediaphoto.h | 12 ++ 4 files changed, 129 insertions(+), 1 deletion(-) diff --git a/Src/JxrDecode/JxrDecode2.cpp b/Src/JxrDecode/JxrDecode2.cpp index 9eb320e7..f7412b92 100644 --- a/Src/JxrDecode/JxrDecode2.cpp +++ b/Src/JxrDecode/JxrDecode2.cpp @@ -99,7 +99,8 @@ void JxrDecode2::Encode( // { &GUID_PKPixelFormat24bppBGR, 3, CF_RGB, BD_8, 24, PK_pixfmtBGR, 2, 3, 8, 1 }, struct tagWMPStream* pEncodeStream = NULL; - CreateWS_File(&pEncodeStream, "C:\\temp\\test.jxr", "wb"); + //CreateWS_File(&pEncodeStream, "C:\\temp\\test.jxr", "wb"); + CreateWS_HeapBackedWriteableStream(&pEncodeStream, 1024, 0); err = pEncoder->Initialize(pEncoder, pEncodeStream, &codec_parameters, sizeof(codec_parameters)); diff --git a/Src/JxrDecode/jxrlib/image/sys/strcodec.c b/Src/JxrDecode/jxrlib/image/sys/strcodec.c index 795350d7..b475aac6 100644 --- a/Src/JxrDecode/jxrlib/image/sys/strcodec.c +++ b/Src/JxrDecode/jxrlib/image/sys/strcodec.c @@ -457,6 +457,116 @@ ERR GetPosWS_Memory(struct tagWMPStream* pWS, size_t* poffPos) return WMP_errSuccess; } +//================================================================= +// heap-based implementation of a writeable WMPStream +// - the memory is allocated from the heao +// - the allocated memory is dynamically resized as needed +//================================================================= +ERR CreateWS_HeapBackedWriteableStream(struct tagWMPStream** ppWS, size_t cbInitial, size_t cbGrowBy) +{ + ERR err = WMP_errSuccess; + struct tagWMPStream* pWS = NULL; + + Call(WMPAlloc((void**)ppWS, sizeof(**ppWS))); + pWS = *ppWS; + + pWS->state.writeableHeapBased.cbCur = 0; + pWS->state.writeableHeapBased.cbMax = 0; + pWS->state.writeableHeapBased.cbAllocatedSize= cbInitial; + pWS->state.writeableHeapBased.cbGrowBy = cbGrowBy; + pWS->state.writeableHeapBased.pbBuf = (U8*)malloc(cbInitial); + + pWS->Close = CloseWS_HeapBackedWriteableStream; + pWS->EOS = NULL;// EOSWS_Memory; + + pWS->Read = NULL; + pWS->Write = WriteWS_HeapBackedWriteableStream; + + pWS->SetPos = SetPosWS_HeapBackedWriteableStream; + pWS->GetPos = GetPosWS_HeapBackedWriteableStream; + +Cleanup: + return err; +} + +ERR CloseWS_HeapBackedWriteableStream(struct tagWMPStream** ppWS) +{ + ERR err = WMP_errSuccess; + struct tagWMPStream* pWS = *ppWS; + + if (pWS->state.writeableHeapBased.pbBuf) + { + free(pWS->state.writeableHeapBased.pbBuf); + pWS->state.writeableHeapBased.pbBuf = NULL; + } + + Call(WMPFree((void**)ppWS)); + +Cleanup: + return err; +} + +static EnsureSize_HeapBackedWriteableStream(struct tagWMPStream* pWS, size_t size_required) +{ + ERR err = WMP_errSuccess; + + if (pWS->state.writeableHeapBased.cbAllocatedSize < size_required) + { + size_t increment = pWS->state.writeableHeapBased.cbGrowBy; + if (increment == 0) + { + increment = pWS->state.writeableHeapBased.cbAllocatedSize; + } + + size_t cbNewSize = pWS->state.writeableHeapBased.cbAllocatedSize + + ((size_required - pWS->state.writeableHeapBased.cbAllocatedSize + increment -1)/increment)*increment; + void* pvNew = realloc(pWS->state.writeableHeapBased.pbBuf, cbNewSize); + + FailIf(NULL == pvNew, WMP_errOutOfMemory); + + pWS->state.writeableHeapBased.cbAllocatedSize = cbNewSize; + pWS->state.writeableHeapBased.pbBuf = pvNew; + } + +Cleanup: + return err; +} + +ERR WriteWS_HeapBackedWriteableStream(struct tagWMPStream* pWS, const void* pv, size_t cb) +{ + ERR err = WMP_errSuccess; + + EnsureSize_HeapBackedWriteableStream(pWS, pWS->state.writeableHeapBased.cbCur + cb); + + memcpy((U8*)pWS->state.pvObj + pWS->state.writeableHeapBased.cbCur, pv, cb); + pWS->state.writeableHeapBased.cbCur += cb; + if (pWS->state.writeableHeapBased.cbCur > pWS->state.writeableHeapBased.cbMax) + { + pWS->state.writeableHeapBased.cbMax = pWS->state.writeableHeapBased.cbCur; + } + +Cleanup: + return err; +} + +ERR SetPosWS_HeapBackedWriteableStream(struct tagWMPStream* pWS, size_t offPos) +{ + EnsureSize_HeapBackedWriteableStream(pWS, offPos); + pWS->state.writeableHeapBased.cbCur = offPos; + if (pWS->state.writeableHeapBased.cbCur > pWS->state.writeableHeapBased.cbMax) + { + pWS->state.writeableHeapBased.cbMax = pWS->state.writeableHeapBased.cbCur; + } + + return WMP_errSuccess; +} + +ERR GetPosWS_HeapBackedWriteableStream(struct tagWMPStream* pWS, size_t* poffPos) +{ + *poffPos = pWS->state.writeableHeapBased.cbCur; + return WMP_errSuccess; +} + //================================================================= // Linked list based WMPStream // - for indefinite size, multiple stream out diff --git a/Src/JxrDecode/jxrlib/image/sys/strcodec.h b/Src/JxrDecode/jxrlib/image/sys/strcodec.h index 803a8c2a..eb91e290 100644 --- a/Src/JxrDecode/jxrlib/image/sys/strcodec.h +++ b/Src/JxrDecode/jxrlib/image/sys/strcodec.h @@ -538,6 +538,11 @@ EXTERN_C ERR WriteWS_Memory(struct tagWMPStream* pWS, const void* pv, size_t cb) EXTERN_C ERR SetPosWS_Memory(struct tagWMPStream* pWS, size_t offPos); EXTERN_C ERR GetPosWS_Memory(struct tagWMPStream* pWS, size_t* poffPos); +//---------------------------------------------------------------- +EXTERN_C ERR WriteWS_HeapBackedWriteableStream(struct tagWMPStream* pWS, const void* pv, size_t cb); +EXTERN_C ERR SetPosWS_HeapBackedWriteableStream(struct tagWMPStream* pWS, size_t offPos); +EXTERN_C ERR GetPosWS_HeapBackedWriteableStream(struct tagWMPStream* pWS, size_t* poffPos); + //EXTERN_C ERR GetPtrWS_Memory(struct tagWMPStream* pWS, size_t align, U8** ppb); //---------------------------------------------------------------- EXTERN_C Bool EOSWS_List(struct tagWMPStream* pWS); diff --git a/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h b/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h index 58bffc0d..92e402ff 100644 --- a/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h +++ b/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h @@ -297,6 +297,15 @@ typedef struct tagWMPStream size_t cbBufCount; } buf; + struct tagWriteableHeapBased + { + U8* pbBuf; // the buffer + size_t cbCur; // the current position + size_t cbMax; // the maximum position (i.e. similar to the file size) + size_t cbAllocatedSize; // the size of the allocated buffer + size_t cbGrowBy; // the size to grow the buffer by when needed (if 0, then thr current allocated size if used) + } writeableHeapBased; + void* pvObj; } state; @@ -320,6 +329,9 @@ EXTERN_C ERR CloseWS_File(struct tagWMPStream** ppWS); EXTERN_C ERR CreateWS_Memory(struct tagWMPStream** ppWS, void* pv, size_t cb); EXTERN_C ERR CloseWS_Memory(struct tagWMPStream** ppWS); +// create a write-only memory stream that allocates memory from the heap +EXTERN_C ERR CreateWS_HeapBackedWriteableStream(struct tagWMPStream** ppWS, size_t cbInitial, size_t cbGrowBy); +EXTERN_C ERR CloseWS_HeapBackedWriteableStream(struct tagWMPStream** ppWS); //================================================================ // Enc/Dec data structure From 831f7c1ac7be9b907100d9db2dd05154944bf63d Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 6 Aug 2023 07:42:54 +0200 Subject: [PATCH 30/98] introduce "JxrDecode2::CompressedData" --- Src/JxrDecode/JxrDecode2.cpp | 42 ++++++++++++++--- Src/JxrDecode/JxrDecode2.h | 41 ++++++++++++++++- Src/JxrDecode/jxrlib/image/sys/strcodec.c | 45 ++++++++++++++++--- Src/JxrDecode/jxrlib/image/sys/strcodec.h | 2 + .../jxrlib/image/sys/windowsmediaphoto.h | 16 ++++++- Src/libCZI/decoder.cpp | 27 +++++++++-- Src/libCZI/decoder.h | 3 +- 7 files changed, 158 insertions(+), 18 deletions(-) diff --git a/Src/JxrDecode/JxrDecode2.cpp b/Src/JxrDecode/JxrDecode2.cpp index f7412b92..bfe38373 100644 --- a/Src/JxrDecode/JxrDecode2.cpp +++ b/Src/JxrDecode/JxrDecode2.cpp @@ -63,11 +63,11 @@ void JxrDecode2::Decode( if (Failed(err)) { ThrowError("decoder::Copy failed", err); } } -void JxrDecode2::Encode( +JxrDecode2::CompressedData JxrDecode2::Encode( JxrDecode2::PixelFormat pixel_format, - std::uint32_t width, - std::uint32_t height, - std::uint32_t stride, + std::uint32_t width, + std::uint32_t height, + std::uint32_t stride, const void* ptr_bitmap) { ERR err; @@ -90,7 +90,7 @@ void JxrDecode2::Encode( codec_parameters.uAlphaMode = 0; codec_parameters.uiDefaultQPIndex = 1; codec_parameters.uiDefaultQPIndexAlpha = 1; - + //codec_parameters.fltImageQuality = 1.f; //codec_parameters.bOverlapSet = 0; //codec_parameters.bColorFormatSet = 0; @@ -109,7 +109,9 @@ void JxrDecode2::Encode( err = pEncoder->SetResolution(pEncoder, 96.f, 96.f); pEncoder->WritePixels(pEncoder, height, (U8*)ptr_bitmap, stride); - pEncodeStream->Close(&pEncodeStream); + + return CompressedData(pEncodeStream); + //pEncodeStream->Close(&pEncodeStream); } void JxrDecode2::Decode( @@ -357,3 +359,31 @@ const char* ERR_to_string(ERR error_code) return "unknown"; } + +JxrDecode2::CompressedData::~CompressedData() +{ + if (this->obj_handle_ != nullptr) + { + CloseWS_HeapBackedWriteableStream((struct tagWMPStream**)&this->obj_handle_); + } +} + +void* JxrDecode2::CompressedData::GetMemory() +{ + void* data = nullptr; + GetWS_HeapBackedWriteableStreamBuffer( + (struct tagWMPStream*)this->obj_handle_, + &data, + nullptr); + return data; +} + +size_t JxrDecode2::CompressedData::GetSize() +{ + size_t size = 0; + GetWS_HeapBackedWriteableStreamBuffer( + (struct tagWMPStream*)this->obj_handle_, + nullptr, + &size); + return size; +} diff --git a/Src/JxrDecode/JxrDecode2.h b/Src/JxrDecode/JxrDecode2.h index 4b826f3d..6b174f2c 100644 --- a/Src/JxrDecode/JxrDecode2.h +++ b/Src/JxrDecode/JxrDecode2.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -50,6 +51,39 @@ class JxrDecode2 typedef void* codecHandle; + /// This class is used to represent a blob containing the compressed data. + /// Note that it is movable but not copyable. + class CompressedData + { + private: + void* obj_handle_; + public: + CompressedData():obj_handle_(nullptr){}; + CompressedData& operator=(CompressedData&& other) + { + // "other" is soon going to be destroyed, so we let it destroy our current resource instead and we take "other"'s current resource via swapping + std::swap(this->obj_handle_, other.obj_handle_); + return *this; + } + // move constructor, takes a rvalue reference && + CompressedData(CompressedData&& other) + { + // we "steal" the resource from "other" + this->obj_handle_ = other.obj_handle_; + // "other" will soon be destroyed and its destructor will do nothing because we null out its resource here + other.obj_handle_ = nullptr; + } + CompressedData(const CompressedData&)=delete; // prevent copy constructor to be used + CompressedData& operator=(const CompressedData&)=delete; // prevent copy assignment to be used + + void* GetMemory(); + size_t GetSize(); + ~CompressedData(); + protected: + friend class JxrDecode2; + CompressedData(void* obj_handle):obj_handle_(obj_handle){}; + }; + void Decode( codecHandle h, // const WMPDECAPPARGS* decArgs, @@ -65,6 +99,11 @@ class JxrDecode2 /// * The 'get_destination_func' is called, passing in the pixel type, width, and height. /// * The function should return a pointer to a buffer that can hold the uncompressed bitmap. /// The tuple it returns is the pixel type, the stride and the pointer to the buffer. + /// Notes: + /// * The decoder will call the 'get_destination_func' function only once, and the buffer must be valid + /// until the method returns. + /// * The 'get_destination_func' function may choose to throw an exception (if the memory cannot be allocated, + /// or the reported characteristics are determined to be invalid, etc). /// /// \param ptrData Information describing the pointer. /// \param size The size. @@ -74,7 +113,7 @@ class JxrDecode2 size_t size, const std::function(PixelFormat pixel_format, std::uint32_t width, std::uint32_t height)>& get_destination_func); - void Encode( + CompressedData Encode( JxrDecode2::PixelFormat pixel_format, std::uint32_t width, std::uint32_t height, diff --git a/Src/JxrDecode/jxrlib/image/sys/strcodec.c b/Src/JxrDecode/jxrlib/image/sys/strcodec.c index b475aac6..f2465470 100644 --- a/Src/JxrDecode/jxrlib/image/sys/strcodec.c +++ b/Src/JxrDecode/jxrlib/image/sys/strcodec.c @@ -477,9 +477,9 @@ ERR CreateWS_HeapBackedWriteableStream(struct tagWMPStream** ppWS, size_t cbInit pWS->state.writeableHeapBased.pbBuf = (U8*)malloc(cbInitial); pWS->Close = CloseWS_HeapBackedWriteableStream; - pWS->EOS = NULL;// EOSWS_Memory; + pWS->EOS = EOSWS_HeapBackedWriteableStream; - pWS->Read = NULL; + pWS->Read = ReadWS_HeapBackedWriteableStream; pWS->Write = WriteWS_HeapBackedWriteableStream; pWS->SetPos = SetPosWS_HeapBackedWriteableStream; @@ -512,14 +512,22 @@ static EnsureSize_HeapBackedWriteableStream(struct tagWMPStream* pWS, size_t siz if (pWS->state.writeableHeapBased.cbAllocatedSize < size_required) { + // determine in which chunk size to grow the buffer size_t increment = pWS->state.writeableHeapBased.cbGrowBy; if (increment == 0) { + // if no increment size is specified, grow by a multiple of the current size increment = pWS->state.writeableHeapBased.cbAllocatedSize; } + // how many additional bytes do we need - note that this is guaranteed to be > 0 + size_t size_to_grow = size_required - pWS->state.writeableHeapBased.cbAllocatedSize; + + // ...and calculate the new size (where we round up to a multiple of the increment size determined above) size_t cbNewSize = pWS->state.writeableHeapBased.cbAllocatedSize + - ((size_required - pWS->state.writeableHeapBased.cbAllocatedSize + increment -1)/increment)*increment; + ((size_to_grow + increment -1) / increment) * increment; + + // note that if realloc fails, the original buffer is left untouched void* pvNew = realloc(pWS->state.writeableHeapBased.pbBuf, cbNewSize); FailIf(NULL == pvNew, WMP_errOutOfMemory); @@ -536,7 +544,7 @@ ERR WriteWS_HeapBackedWriteableStream(struct tagWMPStream* pWS, const void* pv, { ERR err = WMP_errSuccess; - EnsureSize_HeapBackedWriteableStream(pWS, pWS->state.writeableHeapBased.cbCur + cb); + Call(EnsureSize_HeapBackedWriteableStream(pWS, pWS->state.writeableHeapBased.cbCur + cb)); memcpy((U8*)pWS->state.pvObj + pWS->state.writeableHeapBased.cbCur, pv, cb); pWS->state.writeableHeapBased.cbCur += cb; @@ -551,14 +559,16 @@ ERR WriteWS_HeapBackedWriteableStream(struct tagWMPStream* pWS, const void* pv, ERR SetPosWS_HeapBackedWriteableStream(struct tagWMPStream* pWS, size_t offPos) { - EnsureSize_HeapBackedWriteableStream(pWS, offPos); + ERR err = WMP_errSuccess; + Call(EnsureSize_HeapBackedWriteableStream(pWS, offPos)); pWS->state.writeableHeapBased.cbCur = offPos; if (pWS->state.writeableHeapBased.cbCur > pWS->state.writeableHeapBased.cbMax) { pWS->state.writeableHeapBased.cbMax = pWS->state.writeableHeapBased.cbCur; } - return WMP_errSuccess; +Cleanup: + return err; } ERR GetPosWS_HeapBackedWriteableStream(struct tagWMPStream* pWS, size_t* poffPos) @@ -567,6 +577,29 @@ ERR GetPosWS_HeapBackedWriteableStream(struct tagWMPStream* pWS, size_t* poffPos return WMP_errSuccess; } +void GetWS_HeapBackedWriteableStreamBuffer(struct tagWMPStream* pWS, void** ppbBuf, size_t* pcbBuf) +{ + if (ppbBuf != NULL) + { + *ppbBuf = pWS->state.writeableHeapBased.pbBuf; + } + + if (pcbBuf != NULL) + { + *pcbBuf = pWS->state.writeableHeapBased.cbMax; + } +} + +Bool EOSWS_HeapBackedWriteableStream(struct tagWMPStream* pWS) +{ + return WMP_errAbstractMethod; +} + +ERR ReadWS_HeapBackedWriteableStream(struct tagWMPStream* pWS, void* pv, size_t cb) +{ + return WMP_errAbstractMethod; +} + //================================================================= // Linked list based WMPStream // - for indefinite size, multiple stream out diff --git a/Src/JxrDecode/jxrlib/image/sys/strcodec.h b/Src/JxrDecode/jxrlib/image/sys/strcodec.h index eb91e290..871edbbe 100644 --- a/Src/JxrDecode/jxrlib/image/sys/strcodec.h +++ b/Src/JxrDecode/jxrlib/image/sys/strcodec.h @@ -542,6 +542,8 @@ EXTERN_C ERR GetPosWS_Memory(struct tagWMPStream* pWS, size_t* poffPos); EXTERN_C ERR WriteWS_HeapBackedWriteableStream(struct tagWMPStream* pWS, const void* pv, size_t cb); EXTERN_C ERR SetPosWS_HeapBackedWriteableStream(struct tagWMPStream* pWS, size_t offPos); EXTERN_C ERR GetPosWS_HeapBackedWriteableStream(struct tagWMPStream* pWS, size_t* poffPos); +EXTERN_C Bool EOSWS_HeapBackedWriteableStream(struct tagWMPStream* pWS); +EXTERN_C ERR ReadWS_HeapBackedWriteableStream(struct tagWMPStream* pWS, void* pv, size_t cb); //EXTERN_C ERR GetPtrWS_Memory(struct tagWMPStream* pWS, size_t align, U8** ppb); //---------------------------------------------------------------- diff --git a/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h b/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h index 92e402ff..84a4c464 100644 --- a/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h +++ b/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h @@ -329,10 +329,24 @@ EXTERN_C ERR CloseWS_File(struct tagWMPStream** ppWS); EXTERN_C ERR CreateWS_Memory(struct tagWMPStream** ppWS, void* pv, size_t cb); EXTERN_C ERR CloseWS_Memory(struct tagWMPStream** ppWS); -// create a write-only memory stream that allocates memory from the heap +/// Create a write-only memory stream that allocates memory from the heap. +/// +/// \param [out] ppWS If successful, the newly constructed object is placed here. +/// \param cbInitial The initial size of the buffer in bytes. +/// \param cbGrowBy If the buffer needs to be grown, it will be grown by a multiple of this number (in bytes). +/// If 0, then the buffer will be grown by the current size of the buffer. +/// +/// \returns An error code indicating success of failure. EXTERN_C ERR CreateWS_HeapBackedWriteableStream(struct tagWMPStream** ppWS, size_t cbInitial, size_t cbGrowBy); EXTERN_C ERR CloseWS_HeapBackedWriteableStream(struct tagWMPStream** ppWS); +/// Gets (for a heap backed writeable stream buffer object) a pointer to the buffer and the size of the buffer. +/// +/// \param [in] pWS The heap backed writeable stream buffer object. +/// \param [in,out] ppbBuf If non-null, a pointer to the buffer will be placed here. +/// \param [in,out] pcbBuf If non-null, the size of the buffer (in bytes) will be placed here. +EXTERN_C void GetWS_HeapBackedWriteableStreamBuffer(struct tagWMPStream* pWS, void** ppbBuf, size_t* pcbBuf); + //================================================================ // Enc/Dec data structure //================================================================ diff --git a/Src/libCZI/decoder.cpp b/Src/libCZI/decoder.cpp index 1e495985..bb6836cc 100644 --- a/Src/libCZI/decoder.cpp +++ b/Src/libCZI/decoder.cpp @@ -14,21 +14,42 @@ using namespace libCZI; using namespace std; +class MemoryBlockOnCompressedData : public libCZI::IMemoryBlock +{ +private: + mutable JxrDecode2::CompressedData compressed_data_; +public: + MemoryBlockOnCompressedData(JxrDecode2::CompressedData&& compressed_data) + : compressed_data_(std::move(compressed_data)) + {} + + void* GetPtr() override + { + return this->compressed_data_.GetMemory(); + } + + size_t GetSizeOfData() const override + { + return this->compressed_data_.GetSize(); + } +}; + /*static*/std::shared_ptr CJxrLibDecoder::Create() { return make_shared(JxrDecode::Initialize()); } -void CJxrLibDecoder::Encode(libCZI::PixelType pixel_type, std::uint32_t width, std::uint32_t height, std::uint32_t stride, const void* ptrData) +std::shared_ptr CJxrLibDecoder::Encode(libCZI::PixelType pixel_type, std::uint32_t width, std::uint32_t height, std::uint32_t stride, const void* ptrData) { JxrDecode2 decoder2; - decoder2.Encode( + auto compressed_data = decoder2.Encode( JxrDecode2::PixelFormat::kBgr24, width, height, stride, ptrData); - + + return make_shared(std::move(compressed_data)); } std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, size_t size, libCZI::PixelType pixelType, uint32_t width, uint32_t height) diff --git a/Src/libCZI/decoder.h b/Src/libCZI/decoder.h index 81a8e60b..f1f24393 100644 --- a/Src/libCZI/decoder.h +++ b/Src/libCZI/decoder.h @@ -6,6 +6,7 @@ #include #include "libCZI_Pixels.h" +#include "libCZI_compress.h" #include "../JxrDecode/JxrDecode.h" #include "libCZI_Site.h" @@ -24,5 +25,5 @@ class CJxrLibDecoder : public libCZI::IDecoder std::shared_ptr Decode(const void* ptrData, size_t size, libCZI::PixelType, std::uint32_t width, std::uint32_t height) override; std::shared_ptr Decode2(const void* ptrData, size_t size, libCZI::PixelType, std::uint32_t width, std::uint32_t height); - void Encode(libCZI::PixelType pixel_type, std::uint32_t width, std::uint32_t height, std::uint32_t stride, const void* ptrData); + std::shared_ptr Encode(libCZI::PixelType pixel_type, std::uint32_t width, std::uint32_t height, std::uint32_t stride, const void* ptrData); }; From 3f072d22e7081e5b106149ca102f7928a637c469 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Mon, 7 Aug 2023 00:23:33 +0200 Subject: [PATCH 31/98] cosmetic --- Src/JxrDecode/jxrlib/image/decode/decode.c | 7 ------- Src/JxrDecode/jxrlib/image/decode/strdec.c | 8 -------- 2 files changed, 15 deletions(-) diff --git a/Src/JxrDecode/jxrlib/image/decode/decode.c b/Src/JxrDecode/jxrlib/image/decode/decode.c index d9b2916d..e0940b0c 100644 --- a/Src/JxrDecode/jxrlib/image/decode/decode.c +++ b/Src/JxrDecode/jxrlib/image/decode/decode.c @@ -40,13 +40,6 @@ Revision History: #include "../sys/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 ******************************************************************/ diff --git a/Src/JxrDecode/jxrlib/image/decode/strdec.c b/Src/JxrDecode/jxrlib/image/decode/strdec.c index 497fca0c..4388021e 100644 --- a/Src/JxrDecode/jxrlib/image/decode/strdec.c +++ b/Src/JxrDecode/jxrlib/image/decode/strdec.c @@ -29,14 +29,6 @@ #include "decode.h" #include "../sys/strTransform.h" #include -//#include "perfTimer.h" - -#ifdef MEM_TRACE -#define TRACE_MALLOC 1 -#define TRACE_NEW 0 -#define TRACE_HEAP 0 -#include "memtrace.h" -#endif #ifdef X86OPT_INLINE #define _FORCEINLINE __forceinline From 2ad18efd6e69f25db3b10f4483788721483fc68b Mon Sep 17 00:00:00 2001 From: ptahmose Date: Fri, 18 Aug 2023 00:31:32 +0200 Subject: [PATCH 32/98] get rid of "atlbase" --- Src/libCZI/decoder_wic.cpp | 57 ++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/Src/libCZI/decoder_wic.cpp b/Src/libCZI/decoder_wic.cpp index d2808e93..bfe57d87 100644 --- a/Src/libCZI/decoder_wic.cpp +++ b/Src/libCZI/decoder_wic.cpp @@ -8,7 +8,7 @@ #include "BitmapOperations.h" #include -#include +//#include #include "Site.h" #pragma comment(lib, "Windowscodecs.lib") @@ -16,6 +16,18 @@ using namespace std; using namespace libCZI; +struct COMDeleter +{ + template + void operator()(T* ptr) + { + if (ptr) + { + ptr->Release(); + } + } +}; + static void ThrowIfFailed(const char* function, HRESULT hr) { if (FAILED(hr)) @@ -28,19 +40,20 @@ static void ThrowIfFailed(const char* function, HRESULT hr) /*static*/std::shared_ptr CWicJpgxrDecoder::Create() { - CComPtr cpWicImagingFactor; - HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&cpWicImagingFactor); + //CComPtr cpWicImagingFactor; + IWICImagingFactory* wicImagingFactor; + HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&wicImagingFactor); if (hr == CO_E_NOTINITIALIZED) { // that's for sure a bit controversial (that we call this COM-initialization here, you better make sure // that the current thread is already initialized by the caller CoInitializeEx(NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE); - hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&cpWicImagingFactor); + hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&wicImagingFactor); } ThrowIfFailed("Creating WICImageFactory", hr); - return make_shared(cpWicImagingFactor); + return make_shared(wicImagingFactor); } CWicJpgxrDecoder::CWicJpgxrDecoder(IWICImagingFactory* pFactory) @@ -218,31 +231,37 @@ static bool DeterminePixelType(const WICPixelFormatGUID& wicPxlFmt, GUID* destPi GetSite()->Log(LOGLEVEL_CHATTYINFORMATION, ss.str()); } - CComPtr cpWicStream; - HRESULT hr = this->pFactory->CreateStream(&cpWicStream); + IWICStream* wicStream; + HRESULT hr = this->pFactory->CreateStream(&wicStream/*cpWicStream*/); ThrowIfFailed("pFactory->CreateStream", hr); + //CComPtr cpWicStream; + unique_ptr up_wicStream(wicStream); // Initialize the stream with the memory pointer and size. - hr = cpWicStream->InitializeFromMemory((BYTE*)(ptrData), (DWORD)size); + hr = up_wicStream->InitializeFromMemory(static_cast(const_cast(ptrData)), static_cast(size)); ThrowIfFailed("wicStream->InitializeFromMemory", hr); - CComPtr cpWicBitmapDecoder; + //CComPtr cpWicBitmapDecoder; + IWICBitmapDecoder* wicBitmapDecoder; hr = this->pFactory->CreateDecoderFromStream( - cpWicStream, + up_wicStream.get(), NULL,/*decoder vendor*/ WICDecodeMetadataCacheOnDemand, - &cpWicBitmapDecoder); + &wicBitmapDecoder); ThrowIfFailed("pFactory->CreateDecoderFromStream", hr); + unique_ptr< IWICBitmapDecoder, COMDeleter> up_wicBitmapDecoder(wicBitmapDecoder); - CComPtr cpWicBitmapFrameDecode; - hr = cpWicBitmapDecoder->GetFrame(0, &cpWicBitmapFrameDecode); + //CComPtr cpWicBitmapFrameDecode; + IWICBitmapFrameDecode* wicBitmapFrameDecode; + hr = up_wicBitmapDecoder->GetFrame(0, /*&cpWicBitmapFrameDecode*/&wicBitmapFrameDecode); ThrowIfFailed("wicBitmapDecoder->GetFrame", hr); + unique_ptr up_wicBitmapFrameDecode(wicBitmapFrameDecode); IntSize sizeBitmap; WICPixelFormatGUID wicPxlFmt; WICPixelFormatGUID wicDestPxlFmt; PixelType px_type; - hr = cpWicBitmapFrameDecode->GetPixelFormat(&wicPxlFmt); + hr = up_wicBitmapFrameDecode->GetPixelFormat(&wicPxlFmt); ThrowIfFailed("wicBitmapFrameDecode->GetPixelFormat", hr); if (GetSite()->IsEnabled(LOGLEVEL_CHATTYINFORMATION)) @@ -262,7 +281,7 @@ static bool DeterminePixelType(const WICPixelFormatGUID& wicPxlFmt, GUID* destPi throw std::logic_error("pixel type validation failed..."); } - hr = cpWicBitmapFrameDecode->GetSize(&sizeBitmap.w, &sizeBitmap.h); + hr = up_wicBitmapFrameDecode->GetSize(&sizeBitmap.w, &sizeBitmap.h); ThrowIfFailed("wicBitmapFrameDecode->GetSize", hr); if (sizeBitmap.h != height || sizeBitmap.w != width) { @@ -281,22 +300,24 @@ static bool DeterminePixelType(const WICPixelFormatGUID& wicPxlFmt, GUID* destPi if (wicPxlFmt == wicDestPxlFmt) { // in this case we do not need to create a converter - hr = cpWicBitmapFrameDecode->CopyPixels(NULL, bmLckInfo.stride, bmLckInfo.stride * sizeBitmap.h, (BYTE*)bmLckInfo.ptrDataRoi); + hr = up_wicBitmapFrameDecode->CopyPixels(NULL, bmLckInfo.stride, bmLckInfo.stride * sizeBitmap.h, (BYTE*)bmLckInfo.ptrDataRoi); ThrowIfFailed("wicBitmapFrameDecode->CopyPixels", hr); } else { - CComPtr pFormatConverter; + //CComPtr pFormatConverter; + IWICFormatConverter* pFormatConverter; hr = this->pFactory->CreateFormatConverter(&pFormatConverter); ThrowIfFailed("pFactory->CreateFormatConverter", hr); hr = pFormatConverter->Initialize( - cpWicBitmapFrameDecode, // Input bitmap to convert + up_wicBitmapFrameDecode.get(), // Input bitmap to convert wicDestPxlFmt, // Destination pixel format WICBitmapDitherTypeNone, // Specified dither pattern nullptr, // Specify a particular palette 0, // Alpha threshold WICBitmapPaletteTypeCustom); // Palette translation type ThrowIfFailed("pFormatConverter->Initialize", hr); + unique_ptr up_formatConverter(pFormatConverter); hr = pFormatConverter->CopyPixels(NULL, bmLckInfo.stride, bmLckInfo.stride * sizeBitmap.h, (BYTE*)bmLckInfo.ptrDataRoi); ThrowIfFailed("pFormatConverter->CopyPixels", hr); } From a55182951e1c0b6c008273bdcb53bcda9b0391f8 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Fri, 18 Aug 2023 00:35:17 +0200 Subject: [PATCH 33/98] some cleanup --- Src/libCZI/decoder_wic.cpp | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/Src/libCZI/decoder_wic.cpp b/Src/libCZI/decoder_wic.cpp index bfe57d87..dc48894a 100644 --- a/Src/libCZI/decoder_wic.cpp +++ b/Src/libCZI/decoder_wic.cpp @@ -8,7 +8,6 @@ #include "BitmapOperations.h" #include -//#include #include "Site.h" #pragma comment(lib, "Windowscodecs.lib") @@ -40,19 +39,17 @@ static void ThrowIfFailed(const char* function, HRESULT hr) /*static*/std::shared_ptr CWicJpgxrDecoder::Create() { - //CComPtr cpWicImagingFactor; IWICImagingFactory* wicImagingFactor; - HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&wicImagingFactor); + HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, reinterpret_cast(&wicImagingFactor)); if (hr == CO_E_NOTINITIALIZED) { // that's for sure a bit controversial (that we call this COM-initialization here, you better make sure // that the current thread is already initialized by the caller CoInitializeEx(NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE); - hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&wicImagingFactor); + hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, reinterpret_cast(&wicImagingFactor)); } ThrowIfFailed("Creating WICImageFactory", hr); - return make_shared(wicImagingFactor); } @@ -234,14 +231,12 @@ static bool DeterminePixelType(const WICPixelFormatGUID& wicPxlFmt, GUID* destPi IWICStream* wicStream; HRESULT hr = this->pFactory->CreateStream(&wicStream/*cpWicStream*/); ThrowIfFailed("pFactory->CreateStream", hr); - //CComPtr cpWicStream; unique_ptr up_wicStream(wicStream); // Initialize the stream with the memory pointer and size. hr = up_wicStream->InitializeFromMemory(static_cast(const_cast(ptrData)), static_cast(size)); ThrowIfFailed("wicStream->InitializeFromMemory", hr); - //CComPtr cpWicBitmapDecoder; IWICBitmapDecoder* wicBitmapDecoder; hr = this->pFactory->CreateDecoderFromStream( up_wicStream.get(), @@ -251,9 +246,8 @@ static bool DeterminePixelType(const WICPixelFormatGUID& wicPxlFmt, GUID* destPi ThrowIfFailed("pFactory->CreateDecoderFromStream", hr); unique_ptr< IWICBitmapDecoder, COMDeleter> up_wicBitmapDecoder(wicBitmapDecoder); - //CComPtr cpWicBitmapFrameDecode; IWICBitmapFrameDecode* wicBitmapFrameDecode; - hr = up_wicBitmapDecoder->GetFrame(0, /*&cpWicBitmapFrameDecode*/&wicBitmapFrameDecode); + hr = up_wicBitmapDecoder->GetFrame(0, &wicBitmapFrameDecode); ThrowIfFailed("wicBitmapDecoder->GetFrame", hr); unique_ptr up_wicBitmapFrameDecode(wicBitmapFrameDecode); @@ -305,7 +299,6 @@ static bool DeterminePixelType(const WICPixelFormatGUID& wicPxlFmt, GUID* destPi } else { - //CComPtr pFormatConverter; IWICFormatConverter* pFormatConverter; hr = this->pFactory->CreateFormatConverter(&pFormatConverter); ThrowIfFailed("pFactory->CreateFormatConverter", hr); @@ -318,7 +311,7 @@ static bool DeterminePixelType(const WICPixelFormatGUID& wicPxlFmt, GUID* destPi WICBitmapPaletteTypeCustom); // Palette translation type ThrowIfFailed("pFormatConverter->Initialize", hr); unique_ptr up_formatConverter(pFormatConverter); - hr = pFormatConverter->CopyPixels(NULL, bmLckInfo.stride, bmLckInfo.stride * sizeBitmap.h, (BYTE*)bmLckInfo.ptrDataRoi); + hr = pFormatConverter->CopyPixels(NULL, bmLckInfo.stride, bmLckInfo.stride * sizeBitmap.h, static_cast(bmLckInfo.ptrDataRoi)); ThrowIfFailed("pFormatConverter->CopyPixels", hr); } From 622a6923e7c9ff8fea050f73c38d58c740b6faca Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sat, 19 Aug 2023 00:43:37 +0200 Subject: [PATCH 34/98] get rid of ATL-dependency --- Src/CZICmd/SaveBitmap.cpp | 45 ++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/Src/CZICmd/SaveBitmap.cpp b/Src/CZICmd/SaveBitmap.cpp index c90e5947..5be0f549 100644 --- a/Src/CZICmd/SaveBitmap.cpp +++ b/Src/CZICmd/SaveBitmap.cpp @@ -12,20 +12,39 @@ //----------------------------------------------------------------------------- #if CZICMD_USE_WIC == 1 -#include +//#include +#include #include #pragma comment(lib, "Windowscodecs.lib") +using namespace std; + +struct COMDeleter +{ + template + void operator()(T* ptr) + { + if (ptr) + { + ptr->Release(); + } + } +}; + class CWicSaveBitmap :public ISaveBitmap { private: - CComPtr cpWicImagingFactory; + //CComPtr cpWicImagingFactory; + unique_ptr cpWicImagingFactory; public: CWicSaveBitmap() { - HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&this->cpWicImagingFactory); + IWICImagingFactory* pWicImagingFactory; + HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&pWicImagingFactory); + //HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&this->cpWicImagingFactory); ThrowIfFailed("Creating WICImageFactory", hr); + this->cpWicImagingFactory = unique_ptr(pWicImagingFactory); } virtual void Save(const wchar_t* fileName, SaveDataFormat dataFormat, libCZI::IBitmapData* bitmap) @@ -59,18 +78,20 @@ class CWicSaveBitmap :public ISaveBitmap private: void SaveWithWIC(const wchar_t* filename, const GUID encoder, const WICPixelFormatGUID& wicPixelFmt, libCZI::IBitmapData* bitmap) { - CComPtr stream; + //CComPtr stream; + IWICStream* stream; // Create a stream for the encoder HRESULT hr = this->cpWicImagingFactory->CreateStream(&stream); ThrowIfFailed("IWICImagingFactory::CreateStream", hr); + unique_ptr up_stream(stream); // Initialize the stream using the output file path - hr = stream->InitializeFromFilename(filename, GENERIC_WRITE); + hr = up_stream->InitializeFromFilename(filename, GENERIC_WRITE); ThrowIfFailed("IWICStream::InitializeFromFilename", hr); - this->SaveWithWIC(stream, encoder, wicPixelFmt, bitmap); + this->SaveWithWIC(up_stream.get(), encoder, wicPixelFmt, bitmap); - hr = stream->Commit(STGC_DEFAULT); + hr = up_stream->Commit(STGC_DEFAULT); ThrowIfFailed("IWICStream::Commit", hr, [](HRESULT ec) {return SUCCEEDED(ec) || ec == E_NOTIMPL; }); } @@ -78,20 +99,24 @@ class CWicSaveBitmap :public ISaveBitmap { // cf. http://msdn.microsoft.com/en-us/library/windows/desktop/ee719797(v=vs.85).aspx - CComPtr wicBitmapEncoder; + //CComPtr wicBitmapEncoder; + IWICBitmapEncoder* wicBitmapEncoder; HRESULT hr = this->cpWicImagingFactory->CreateEncoder( encoder, nullptr, // No preferred codec vendor. &wicBitmapEncoder); ThrowIfFailed("Creating IWICImagingFactory::CreateEncoder", hr); + unique_ptr up_wicBitmapEncoder(wicBitmapEncoder); // Create encoder to write to image file hr = wicBitmapEncoder->Initialize(destStream, WICBitmapEncoderNoCache); ThrowIfFailed("IWICBitmapEncoder::Initialize", hr); - CComPtr frameEncode; + //CComPtr frameEncode; + IWICBitmapFrameEncode* frameEncode; hr = wicBitmapEncoder->CreateNewFrame(&frameEncode, nullptr); ThrowIfFailed("IWICBitmapEncoder::CreateNewFrame", hr); + unique_ptr up_frameEncode(frameEncode); hr = frameEncode->Initialize(nullptr); ThrowIfFailed("IWICBitmapFrameEncode::CreateNewFrame", hr); @@ -113,7 +138,7 @@ class CWicSaveBitmap :public ISaveBitmap } auto bitmapData = spBitmap->Lock(); - hr = frameEncode->WritePixels(spBitmap->GetHeight(), bitmapData.stride, spBitmap->GetHeight() * bitmapData.stride, (BYTE*)bitmapData.ptrDataRoi); + hr = frameEncode->WritePixels(spBitmap->GetHeight(), bitmapData.stride, spBitmap->GetHeight() * bitmapData.stride, static_cast(bitmapData.ptrDataRoi)); spBitmap->Unlock(); ThrowIfFailed("IWICBitmapFrameEncode::WritePixels", hr); From f075f21b8c9693f608fc3abf7e964bd002ea3dbf Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sat, 19 Aug 2023 00:47:10 +0200 Subject: [PATCH 35/98] cleanup --- Src/CZICmd/SaveBitmap.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/Src/CZICmd/SaveBitmap.cpp b/Src/CZICmd/SaveBitmap.cpp index 5be0f549..adc8b941 100644 --- a/Src/CZICmd/SaveBitmap.cpp +++ b/Src/CZICmd/SaveBitmap.cpp @@ -35,14 +35,12 @@ struct COMDeleter class CWicSaveBitmap :public ISaveBitmap { private: - //CComPtr cpWicImagingFactory; unique_ptr cpWicImagingFactory; public: CWicSaveBitmap() { IWICImagingFactory* pWicImagingFactory; - HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&pWicImagingFactory); - //HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&this->cpWicImagingFactory); + const HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, reinterpret_cast(&pWicImagingFactory)); ThrowIfFailed("Creating WICImageFactory", hr); this->cpWicImagingFactory = unique_ptr(pWicImagingFactory); } @@ -78,12 +76,11 @@ class CWicSaveBitmap :public ISaveBitmap private: void SaveWithWIC(const wchar_t* filename, const GUID encoder, const WICPixelFormatGUID& wicPixelFmt, libCZI::IBitmapData* bitmap) { - //CComPtr stream; IWICStream* stream; // Create a stream for the encoder HRESULT hr = this->cpWicImagingFactory->CreateStream(&stream); ThrowIfFailed("IWICImagingFactory::CreateStream", hr); - unique_ptr up_stream(stream); + const unique_ptr up_stream(stream); // Initialize the stream using the output file path hr = up_stream->InitializeFromFilename(filename, GENERIC_WRITE); @@ -99,7 +96,6 @@ class CWicSaveBitmap :public ISaveBitmap { // cf. http://msdn.microsoft.com/en-us/library/windows/desktop/ee719797(v=vs.85).aspx - //CComPtr wicBitmapEncoder; IWICBitmapEncoder* wicBitmapEncoder; HRESULT hr = this->cpWicImagingFactory->CreateEncoder( encoder, @@ -112,7 +108,6 @@ class CWicSaveBitmap :public ISaveBitmap hr = wicBitmapEncoder->Initialize(destStream, WICBitmapEncoderNoCache); ThrowIfFailed("IWICBitmapEncoder::Initialize", hr); - //CComPtr frameEncode; IWICBitmapFrameEncode* frameEncode; hr = wicBitmapEncoder->CreateNewFrame(&frameEncode, nullptr); ThrowIfFailed("IWICBitmapEncoder::CreateNewFrame", hr); @@ -137,7 +132,7 @@ class CWicSaveBitmap :public ISaveBitmap // TODO } - auto bitmapData = spBitmap->Lock(); + const auto bitmapData = spBitmap->Lock(); hr = frameEncode->WritePixels(spBitmap->GetHeight(), bitmapData.stride, spBitmap->GetHeight() * bitmapData.stride, static_cast(bitmapData.ptrDataRoi)); spBitmap->Unlock(); ThrowIfFailed("IWICBitmapFrameEncode::WritePixels", hr); From 1a82b6218d72e526e9e90b9fe7c9c1e69bc07cf7 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sat, 19 Aug 2023 23:18:05 +0200 Subject: [PATCH 36/98] cosmetic & make compile with Mingw --- Src/CZICmd/SaveBitmap.cpp | 1 - Src/JxrDecode/jxrlib/image/sys/strcodec.c | 2 +- Src/libCZI/StreamImpl.cpp | 6 +++--- Src/libCZI/decoder_wic.cpp | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Src/CZICmd/SaveBitmap.cpp b/Src/CZICmd/SaveBitmap.cpp index adc8b941..60099e3c 100644 --- a/Src/CZICmd/SaveBitmap.cpp +++ b/Src/CZICmd/SaveBitmap.cpp @@ -12,7 +12,6 @@ //----------------------------------------------------------------------------- #if CZICMD_USE_WIC == 1 -//#include #include #include diff --git a/Src/JxrDecode/jxrlib/image/sys/strcodec.c b/Src/JxrDecode/jxrlib/image/sys/strcodec.c index f2465470..a0f356de 100644 --- a/Src/JxrDecode/jxrlib/image/sys/strcodec.c +++ b/Src/JxrDecode/jxrlib/image/sys/strcodec.c @@ -506,7 +506,7 @@ ERR CloseWS_HeapBackedWriteableStream(struct tagWMPStream** ppWS) return err; } -static EnsureSize_HeapBackedWriteableStream(struct tagWMPStream* pWS, size_t size_required) +static ERR EnsureSize_HeapBackedWriteableStream(struct tagWMPStream* pWS, size_t size_required) { ERR err = WMP_errSuccess; diff --git a/Src/libCZI/StreamImpl.cpp b/Src/libCZI/StreamImpl.cpp index 96df6e7e..b642aaa5 100644 --- a/Src/libCZI/StreamImpl.cpp +++ b/Src/libCZI/StreamImpl.cpp @@ -39,7 +39,7 @@ CSimpleStreamImpl::CSimpleStreamImpl(const wchar_t* filename) std::stringstream ss; #if (_WIN32) char errMsg[100]; - strerror_s(errMsg, err); + strerror_s(errMsg, sizeof(errMsg), err); ss << "Error opening the file \"" << Utilities::convertWchar_tToUtf8(filename) << "\" -> errno=" << err << " (" << errMsg << ")"; #else ss << "Error opening the file \"" << filename_utf8 << "\" -> errno=" << err << " (" << strerror(err) << ")"; @@ -381,7 +381,7 @@ CSimpleOutputStreamStreams::CSimpleOutputStreamStreams(const wchar_t* filename, std::stringstream ss; #if (_WIN32) char errMsg[100]; - strerror_s(errMsg, err); + strerror_s(errMsg, sizeof(char), err); ss << "Error opening the file \"" << Utilities::convertWchar_tToUtf8(filename) << "\" -> errno=" << err << " (" << errMsg << ")"; #else ss << "Error opening the file \"" << filename_utf8 << "\" -> errno=" << err << " (" << strerror(err) << ")"; @@ -573,7 +573,7 @@ CSimpleInputOutputStreamImpl::CSimpleInputOutputStreamImpl(const wchar_t* filena std::stringstream ss; #if (_WIN32) char errMsg[100]; - strerror_s(errMsg, err); + strerror_s(errMsg, sizeof(errMsg), err); ss << "Error opening the file \"" << Utilities::convertWchar_tToUtf8(filename) << "\" -> errno=" << err << " (" << errMsg << ")"; #else ss << "Error opening the file \"" << filename_utf8 << "\" -> errno=" << err << " (" << strerror(err) << ")"; diff --git a/Src/libCZI/decoder_wic.cpp b/Src/libCZI/decoder_wic.cpp index dc48894a..fed567bd 100644 --- a/Src/libCZI/decoder_wic.cpp +++ b/Src/libCZI/decoder_wic.cpp @@ -234,7 +234,7 @@ static bool DeterminePixelType(const WICPixelFormatGUID& wicPxlFmt, GUID* destPi unique_ptr up_wicStream(wicStream); // Initialize the stream with the memory pointer and size. - hr = up_wicStream->InitializeFromMemory(static_cast(const_cast(ptrData)), static_cast(size)); + hr = up_wicStream->InitializeFromMemory(static_cast(const_cast(ptrData)), static_cast(size)); ThrowIfFailed("wicStream->InitializeFromMemory", hr); IWICBitmapDecoder* wicBitmapDecoder; From c81d82be0d86071787a54f655626ff8d2f0cd564 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 20 Aug 2023 23:40:32 +0200 Subject: [PATCH 37/98] refactor "google-test"-integration (works now with mingw, but still WIP) --- Src/libCZI_UnitTests/CMakeLists.txt | 47 +++++++------------------- Src/libCZI_UnitTests/CMakeLists.txt.in | 2 +- Src/libCZI_UnitTests/inc_libCZI.h | 4 --- Src/libCZI_UnitTests/main.cpp | 4 +-- Src/libCZI_UnitTests/testImageHiLo.cpp | 1 - 5 files changed, 15 insertions(+), 43 deletions(-) diff --git a/Src/libCZI_UnitTests/CMakeLists.txt b/Src/libCZI_UnitTests/CMakeLists.txt index b02b3b0d..8203625c 100644 --- a/Src/libCZI_UnitTests/CMakeLists.txt +++ b/Src/libCZI_UnitTests/CMakeLists.txt @@ -2,34 +2,19 @@ # # SPDX-License-Identifier: LGPL-3.0-or-later -# downlad and build googletest -> https://github.com/google/googletest/tree/main/googletest , https://crascit.com/2015/07/25/cmake-gtest/ +include(FetchContent) -# Download and unpack googletest at configure time -configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt) - -# Prevent overriding the parent project's compiler/linker -# settings on Windows (cf. https://github.com/google/googletest/blob/master/googletest/README.md) -set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) set(INSTALL_GTEST OFF CACHE BOOL "" FORCE) +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) -execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . RESULT_VARIABLE result WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/googletest-download" ) - -if(result) - message(FATAL_ERROR "CMake step for googletest failed: ${result}") -endif() - -execute_process(COMMAND ${CMAKE_COMMAND} --build . RESULT_VARIABLE result WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download ) - -if(result) - message(FATAL_ERROR "Build step for googletest failed: ${result}") -endif() +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip + DOWNLOAD_EXTRACT_TIMESTAMP TRUE) +FetchContent_MakeAvailable(googletest) -# Add googletest directly to our build. This defines -# the gtest and gtest_main targets. -add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src - ${CMAKE_CURRENT_BINARY_DIR}/googletest-build - EXCLUDE_FROM_ALL) ADD_EXECUTABLE(libCZI_UnitTests inc_libCZI.h @@ -64,22 +49,14 @@ ADD_EXECUTABLE(libCZI_UnitTests testImage1.cpp test_multichannelcomposite.cpp utils.cpp - pch.cpp + # pch.cpp testImage.cpp test_reader.cpp utils.h test_Accessors.cpp) -# Now simply link against gtest or gtest_main as needed. Eg -TARGET_LINK_LIBRARIES(libCZI_UnitTests - libCZIStatic - gtest - gmock -) - -set_target_properties(libCZI_UnitTests PROPERTIES INCLUDE_DIRECTORIES "${gtest_SOURCE_DIR}/include") - -set_target_properties(libCZI_UnitTests PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED YES) +TARGET_LINK_LIBRARIES(libCZI_UnitTests PRIVATE libCZIStatic GTest::gtest GTest::gmock) -add_test(NAME libCZI_UnitTests COMMAND libCZI_UnitTests) +target_compile_definitions(libCZI_UnitTests PRIVATE _LIBCZISTATICLIB) +add_test(NAME libCZI_UnitTests COMMAND libCZI_UnitTests) \ No newline at end of file diff --git a/Src/libCZI_UnitTests/CMakeLists.txt.in b/Src/libCZI_UnitTests/CMakeLists.txt.in index 445b65d1..dcaf0cfc 100644 --- a/Src/libCZI_UnitTests/CMakeLists.txt.in +++ b/Src/libCZI_UnitTests/CMakeLists.txt.in @@ -9,7 +9,7 @@ project(googletest-download NONE) include(ExternalProject) ExternalProject_Add(googletest GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG release-1.12.1 + GIT_TAG v1.14.0 SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src" BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build" CONFIGURE_COMMAND "" diff --git a/Src/libCZI_UnitTests/inc_libCZI.h b/Src/libCZI_UnitTests/inc_libCZI.h index a36711ac..65898893 100644 --- a/Src/libCZI_UnitTests/inc_libCZI.h +++ b/Src/libCZI_UnitTests/inc_libCZI.h @@ -4,14 +4,10 @@ #pragma once -#define _LIBCZISTATICLIB - #include "../libCZI/libCZI.h" #include "../libCZI/splines.h" - #include "../libCZI/bitmapData.h" #include "../libCZI/stdAllocator.h" #include "../libCZI/BitmapOperations.h" - #include "../libCZI/CziSubBlockDirectory.h" diff --git a/Src/libCZI_UnitTests/main.cpp b/Src/libCZI_UnitTests/main.cpp index b9609086..c8db71e9 100644 --- a/Src/libCZI_UnitTests/main.cpp +++ b/Src/libCZI_UnitTests/main.cpp @@ -2,11 +2,11 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - int ret = RUN_ALL_TESTS(); + const int ret = RUN_ALL_TESTS(); return ret; } diff --git a/Src/libCZI_UnitTests/testImageHiLo.cpp b/Src/libCZI_UnitTests/testImageHiLo.cpp index 16f07e86..bc177306 100644 --- a/Src/libCZI_UnitTests/testImageHiLo.cpp +++ b/Src/libCZI_UnitTests/testImageHiLo.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" #include "testImage.h" /*static*/ const void* CTestImage::GetZStd1CompressedImageWithHiLoPacking(size_t* size, int* width, int* height) From eb134005a5a97ef44450c4d422a38297e7db08fd Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 20 Aug 2023 23:44:48 +0200 Subject: [PATCH 38/98] refactor googletest integration --- Src/libCZI_UnitTests/CMakeLists.txt | 7 +++---- Src/libCZI_UnitTests/CMakeLists.txt.in | 19 ------------------- Src/libCZI_UnitTests/MemInputOutputStream.cpp | 2 +- Src/libCZI_UnitTests/MemOutputStream.cpp | 2 +- Src/libCZI_UnitTests/MockMetadataSegment.cpp | 2 +- Src/libCZI_UnitTests/SegmentWalker.cpp | 2 +- .../{pch.h => include_gtest.h} | 0 Src/libCZI_UnitTests/pch.cpp | 5 ----- Src/libCZI_UnitTests/testImage1.cpp | 2 +- Src/libCZI_UnitTests/test_Accessors.cpp | 2 +- .../test_CziSubBlockDirectory.cpp | 2 +- Src/libCZI_UnitTests/test_DimCoordinate.cpp | 2 +- Src/libCZI_UnitTests/test_DisplaySettings.cpp | 2 +- Src/libCZI_UnitTests/test_IndexSet.cpp | 2 +- Src/libCZI_UnitTests/test_JxrDecode.cpp | 2 +- Src/libCZI_UnitTests/test_LUT.cpp | 2 +- .../test_StreamImplementations.cpp | 2 +- Src/libCZI_UnitTests/test_Utilities.cpp | 2 +- Src/libCZI_UnitTests/test_ZstdCompress.cpp | 2 +- Src/libCZI_UnitTests/test_ZstdDecode.cpp | 2 +- .../test_bitmapOperations.cpp | 2 +- Src/libCZI_UnitTests/test_metadatabuilder.cpp | 2 +- Src/libCZI_UnitTests/test_metadatareading.cpp | 2 +- .../test_multichannelcomposite.cpp | 2 +- Src/libCZI_UnitTests/test_reader.cpp | 2 +- Src/libCZI_UnitTests/test_readerwriter.cpp | 2 +- Src/libCZI_UnitTests/test_splines.cpp | 2 +- Src/libCZI_UnitTests/test_writer.cpp | 2 +- 28 files changed, 27 insertions(+), 52 deletions(-) delete mode 100644 Src/libCZI_UnitTests/CMakeLists.txt.in rename Src/libCZI_UnitTests/{pch.h => include_gtest.h} (100%) delete mode 100644 Src/libCZI_UnitTests/pch.cpp diff --git a/Src/libCZI_UnitTests/CMakeLists.txt b/Src/libCZI_UnitTests/CMakeLists.txt index 8203625c..cbb0188f 100644 --- a/Src/libCZI_UnitTests/CMakeLists.txt +++ b/Src/libCZI_UnitTests/CMakeLists.txt @@ -17,8 +17,8 @@ FetchContent_MakeAvailable(googletest) ADD_EXECUTABLE(libCZI_UnitTests - inc_libCZI.h - pch.h + inc_libCZI.h + include_gtest.h testImage.h test_readerwriter.cpp main.cpp @@ -49,8 +49,7 @@ ADD_EXECUTABLE(libCZI_UnitTests testImage1.cpp test_multichannelcomposite.cpp utils.cpp - # pch.cpp - testImage.cpp + testImage.cpp test_reader.cpp utils.h test_Accessors.cpp) diff --git a/Src/libCZI_UnitTests/CMakeLists.txt.in b/Src/libCZI_UnitTests/CMakeLists.txt.in deleted file mode 100644 index dcaf0cfc..00000000 --- a/Src/libCZI_UnitTests/CMakeLists.txt.in +++ /dev/null @@ -1,19 +0,0 @@ -# SPDX-FileCopyrightText: 2017-2022 Carl Zeiss Microscopy GmbH -# -# SPDX-License-Identifier: LGPL-3.0-or-later - -cmake_minimum_required(VERSION 2.8.2) - -project(googletest-download NONE) - -include(ExternalProject) -ExternalProject_Add(googletest - GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG v1.14.0 - SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src" - BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build" - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - TEST_COMMAND "" -) \ No newline at end of file diff --git a/Src/libCZI_UnitTests/MemInputOutputStream.cpp b/Src/libCZI_UnitTests/MemInputOutputStream.cpp index b817d26e..d948543d 100644 --- a/Src/libCZI_UnitTests/MemInputOutputStream.cpp +++ b/Src/libCZI_UnitTests/MemInputOutputStream.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include "MemInputOutputStream.h" CMemInputOutputStream::CMemInputOutputStream(size_t initialSize) :ptr(nullptr), allocatedSize(initialSize), usedSize(0) diff --git a/Src/libCZI_UnitTests/MemOutputStream.cpp b/Src/libCZI_UnitTests/MemOutputStream.cpp index 612001ad..c10f3918 100644 --- a/Src/libCZI_UnitTests/MemOutputStream.cpp +++ b/Src/libCZI_UnitTests/MemOutputStream.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include "MemOutputStream.h" #include diff --git a/Src/libCZI_UnitTests/MockMetadataSegment.cpp b/Src/libCZI_UnitTests/MockMetadataSegment.cpp index eda02a27..f3777853 100644 --- a/Src/libCZI_UnitTests/MockMetadataSegment.cpp +++ b/Src/libCZI_UnitTests/MockMetadataSegment.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include "MockMetadataSegment.h" using namespace libCZI; diff --git a/Src/libCZI_UnitTests/SegmentWalker.cpp b/Src/libCZI_UnitTests/SegmentWalker.cpp index 1e2bbdd0..29434722 100644 --- a/Src/libCZI_UnitTests/SegmentWalker.cpp +++ b/Src/libCZI_UnitTests/SegmentWalker.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include "SegmentWalker.h" #if !defined(__GNUC__) diff --git a/Src/libCZI_UnitTests/pch.h b/Src/libCZI_UnitTests/include_gtest.h similarity index 100% rename from Src/libCZI_UnitTests/pch.h rename to Src/libCZI_UnitTests/include_gtest.h diff --git a/Src/libCZI_UnitTests/pch.cpp b/Src/libCZI_UnitTests/pch.cpp deleted file mode 100644 index 53affeb1..00000000 --- a/Src/libCZI_UnitTests/pch.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// SPDX-FileCopyrightText: 2017-2022 Carl Zeiss Microscopy GmbH -// -// SPDX-License-Identifier: LGPL-3.0-or-later - -#include "pch.h" diff --git a/Src/libCZI_UnitTests/testImage1.cpp b/Src/libCZI_UnitTests/testImage1.cpp index 4da43cf1..ea8cdf24 100644 --- a/Src/libCZI_UnitTests/testImage1.cpp +++ b/Src/libCZI_UnitTests/testImage1.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include "testImage.h" /*static*/ const void* CTestImage::GetZStd1CompressedImage(size_t* size, int* width, int* height) diff --git a/Src/libCZI_UnitTests/test_Accessors.cpp b/Src/libCZI_UnitTests/test_Accessors.cpp index ab18dd9f..7bc8073a 100644 --- a/Src/libCZI_UnitTests/test_Accessors.cpp +++ b/Src/libCZI_UnitTests/test_Accessors.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include #include #include diff --git a/Src/libCZI_UnitTests/test_CziSubBlockDirectory.cpp b/Src/libCZI_UnitTests/test_CziSubBlockDirectory.cpp index 9e8f604f..5181a893 100644 --- a/Src/libCZI_UnitTests/test_CziSubBlockDirectory.cpp +++ b/Src/libCZI_UnitTests/test_CziSubBlockDirectory.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include "testImage.h" #include "inc_libCZI.h" diff --git a/Src/libCZI_UnitTests/test_DimCoordinate.cpp b/Src/libCZI_UnitTests/test_DimCoordinate.cpp index 3f0a0544..c38c0f5b 100644 --- a/Src/libCZI_UnitTests/test_DimCoordinate.cpp +++ b/Src/libCZI_UnitTests/test_DimCoordinate.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include "inc_libCZI.h" using namespace libCZI; diff --git a/Src/libCZI_UnitTests/test_DisplaySettings.cpp b/Src/libCZI_UnitTests/test_DisplaySettings.cpp index 1f9c6c9e..8306cd7b 100644 --- a/Src/libCZI_UnitTests/test_DisplaySettings.cpp +++ b/Src/libCZI_UnitTests/test_DisplaySettings.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include "inc_libCZI.h" #include "MockMetadataSegment.h" #include "utils.h" diff --git a/Src/libCZI_UnitTests/test_IndexSet.cpp b/Src/libCZI_UnitTests/test_IndexSet.cpp index 15d1dc3e..4291e12a 100644 --- a/Src/libCZI_UnitTests/test_IndexSet.cpp +++ b/Src/libCZI_UnitTests/test_IndexSet.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include "inc_libCZI.h" using namespace libCZI; diff --git a/Src/libCZI_UnitTests/test_JxrDecode.cpp b/Src/libCZI_UnitTests/test_JxrDecode.cpp index edca5901..afb8813b 100644 --- a/Src/libCZI_UnitTests/test_JxrDecode.cpp +++ b/Src/libCZI_UnitTests/test_JxrDecode.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include #include "inc_libCZI.h" #include "testImage.h" diff --git a/Src/libCZI_UnitTests/test_LUT.cpp b/Src/libCZI_UnitTests/test_LUT.cpp index 0ee5ceb1..dc691aa0 100644 --- a/Src/libCZI_UnitTests/test_LUT.cpp +++ b/Src/libCZI_UnitTests/test_LUT.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include "inc_libCZI.h" using namespace libCZI; diff --git a/Src/libCZI_UnitTests/test_StreamImplementations.cpp b/Src/libCZI_UnitTests/test_StreamImplementations.cpp index eb4578e9..d4946fcf 100644 --- a/Src/libCZI_UnitTests/test_StreamImplementations.cpp +++ b/Src/libCZI_UnitTests/test_StreamImplementations.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include "inc_libCZI.h" using namespace libCZI; diff --git a/Src/libCZI_UnitTests/test_Utilities.cpp b/Src/libCZI_UnitTests/test_Utilities.cpp index 8a0edbe4..deded59e 100644 --- a/Src/libCZI_UnitTests/test_Utilities.cpp +++ b/Src/libCZI_UnitTests/test_Utilities.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include "inc_libCZI.h" #include "../libCZI/CziParse.h" diff --git a/Src/libCZI_UnitTests/test_ZstdCompress.cpp b/Src/libCZI_UnitTests/test_ZstdCompress.cpp index b7351ac7..9ccfb591 100644 --- a/Src/libCZI_UnitTests/test_ZstdCompress.cpp +++ b/Src/libCZI_UnitTests/test_ZstdCompress.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include "inc_libCZI.h" #include "utils.h" #include "../libCZI/decoder_zstd.h" diff --git a/Src/libCZI_UnitTests/test_ZstdDecode.cpp b/Src/libCZI_UnitTests/test_ZstdDecode.cpp index a7043373..a2fdd2e5 100644 --- a/Src/libCZI_UnitTests/test_ZstdDecode.cpp +++ b/Src/libCZI_UnitTests/test_ZstdDecode.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include "inc_libCZI.h" #include "testImage.h" #include "../libCZI/decoder_zstd.h" diff --git a/Src/libCZI_UnitTests/test_bitmapOperations.cpp b/Src/libCZI_UnitTests/test_bitmapOperations.cpp index 5d58b9f5..19cf6e07 100644 --- a/Src/libCZI_UnitTests/test_bitmapOperations.cpp +++ b/Src/libCZI_UnitTests/test_bitmapOperations.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include "testImage.h" #include "inc_libCZI.h" #include "utils.h" diff --git a/Src/libCZI_UnitTests/test_metadatabuilder.cpp b/Src/libCZI_UnitTests/test_metadatabuilder.cpp index a4174042..5c79a006 100644 --- a/Src/libCZI_UnitTests/test_metadatabuilder.cpp +++ b/Src/libCZI_UnitTests/test_metadatabuilder.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include "inc_libCZI.h" using namespace libCZI; diff --git a/Src/libCZI_UnitTests/test_metadatareading.cpp b/Src/libCZI_UnitTests/test_metadatareading.cpp index 7676dd50..2e50a024 100644 --- a/Src/libCZI_UnitTests/test_metadatareading.cpp +++ b/Src/libCZI_UnitTests/test_metadatareading.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include "inc_libCZI.h" #include "MockMetadataSegment.h" #include "utils.h" diff --git a/Src/libCZI_UnitTests/test_multichannelcomposite.cpp b/Src/libCZI_UnitTests/test_multichannelcomposite.cpp index 1673ba82..95534013 100644 --- a/Src/libCZI_UnitTests/test_multichannelcomposite.cpp +++ b/Src/libCZI_UnitTests/test_multichannelcomposite.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include "inc_libCZI.h" using namespace libCZI; diff --git a/Src/libCZI_UnitTests/test_reader.cpp b/Src/libCZI_UnitTests/test_reader.cpp index e267a21f..074214d0 100644 --- a/Src/libCZI_UnitTests/test_reader.cpp +++ b/Src/libCZI_UnitTests/test_reader.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include "inc_libCZI.h" using namespace libCZI; diff --git a/Src/libCZI_UnitTests/test_readerwriter.cpp b/Src/libCZI_UnitTests/test_readerwriter.cpp index b5c3f0f7..9bf343ea 100644 --- a/Src/libCZI_UnitTests/test_readerwriter.cpp +++ b/Src/libCZI_UnitTests/test_readerwriter.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include "inc_libCZI.h" #include "MemOutputStream.h" #include "utils.h" diff --git a/Src/libCZI_UnitTests/test_splines.cpp b/Src/libCZI_UnitTests/test_splines.cpp index 7331647c..71290fb1 100644 --- a/Src/libCZI_UnitTests/test_splines.cpp +++ b/Src/libCZI_UnitTests/test_splines.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include "inc_libCZI.h" using namespace libCZI; diff --git a/Src/libCZI_UnitTests/test_writer.cpp b/Src/libCZI_UnitTests/test_writer.cpp index 7e0f80e3..ff6b8e2e 100644 --- a/Src/libCZI_UnitTests/test_writer.cpp +++ b/Src/libCZI_UnitTests/test_writer.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include "inc_libCZI.h" #include "MemOutputStream.h" #include "SegmentWalker.h" From e2e466037d6b0eaaf654bb9507acfb59c408b38a Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 20 Aug 2023 23:54:57 +0200 Subject: [PATCH 39/98] fix build errors --- .gitignore | 7 ++----- Src/libCZI_UnitTests/testImage.cpp | 3 ++- Src/libCZI_UnitTests/utils.cpp | 1 - 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index bd0c6aaf..aaf2d0d0 100644 --- a/.gitignore +++ b/.gitignore @@ -296,14 +296,11 @@ __pycache__/ # BEGIN additions to the stock .gitignore-file -# exclude "cmake-directory" -cmake-build-debug/ - - +# exclude "cmake-build-directory" +/cmake-build-*/ /build /Src/Build/VS -/cmake-build-debug---wsl /out/Src/Build/Doxygen/ /out/ /Src/.vscode diff --git a/Src/libCZI_UnitTests/testImage.cpp b/Src/libCZI_UnitTests/testImage.cpp index b75e66e1..16054f74 100644 --- a/Src/libCZI_UnitTests/testImage.cpp +++ b/Src/libCZI_UnitTests/testImage.cpp @@ -2,8 +2,9 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" #include "testImage.h" +#include +#include /*static*/void CTestImage::CopyBgr24Image(void* pDest, std::uint32_t width, std::uint32_t height, int stride) { diff --git a/Src/libCZI_UnitTests/utils.cpp b/Src/libCZI_UnitTests/utils.cpp index 336b3add..621e0fb5 100644 --- a/Src/libCZI_UnitTests/utils.cpp +++ b/Src/libCZI_UnitTests/utils.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" #include "utils.h" #include "../libCZI/bitmapData.h" From 1a1477d97b0049b3454e5ae058593eacb3521347 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Mon, 21 Aug 2023 00:07:56 +0200 Subject: [PATCH 40/98] cosmetic --- Src/JxrDecode/JxrDecode_Config.h.in | 6 +++++- Src/libCZI_UnitTests/include_gtest.h | 5 ----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Src/JxrDecode/JxrDecode_Config.h.in b/Src/JxrDecode/JxrDecode_Config.h.in index 8d0c07e7..ad984d91 100644 --- a/Src/JxrDecode/JxrDecode_Config.h.in +++ b/Src/JxrDecode/JxrDecode_Config.h.in @@ -12,9 +12,13 @@ // get a bus-error if we try), 0 means that the CPU can load from unaligned addresses #define JXRDECODE_SIGBUS_ON_UNALIGNEDINTEGERS @jxrdecode_CrashOnUnalignedIntegers@ - +// whether the intrinsic "__builtin_bswap32" is available (in the header-file byteswap.h) #define JXRDECODE_HAS_BUILTIN_BSWAP32 @jxrdecode_Has_builtin_bswap32@ + +// whether the function ""_byteswap_ulong" is available (in the header-file stdlib.h) #define JXRDECODE_HAS_BYTESWAP_IN_STDLIB @jxrdecode_Has_byteswap_long_in_stdlib@ + +// whether the function "bswap32" is available (in the header-file sys/endian.h) #define JXRDECODE_HAS_BSWAP_LONG_IN_SYS_ENDIAN @jxrdecode_Has_bswap_long_in_sys_endian@ // whether the "_rotl" function is available in the respective header file - here in , which should be the case with MSVC diff --git a/Src/libCZI_UnitTests/include_gtest.h b/Src/libCZI_UnitTests/include_gtest.h index 625e9750..b7d58786 100644 --- a/Src/libCZI_UnitTests/include_gtest.h +++ b/Src/libCZI_UnitTests/include_gtest.h @@ -2,11 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -// -// pch.h -// Header for standard system include files. -// - #pragma once #include From 49a37a18f484a22e43ec88e7d771e6c21ef07727 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Mon, 21 Aug 2023 00:50:29 +0200 Subject: [PATCH 41/98] finish JPGXR-encode-decode-unittest --- Src/JxrDecode/JxrDecode2.cpp | 7 ++--- Src/JxrDecode/JxrDecode2.h | 6 +++-- Src/libCZI_UnitTests/test_JxrDecode.cpp | 35 ++++++++++++++++++------- Src/libCZI_UnitTests/utils.cpp | 6 ++--- 4 files changed, 35 insertions(+), 19 deletions(-) diff --git a/Src/JxrDecode/JxrDecode2.cpp b/Src/JxrDecode/JxrDecode2.cpp index bfe38373..ee6bfdb5 100644 --- a/Src/JxrDecode/JxrDecode2.cpp +++ b/Src/JxrDecode/JxrDecode2.cpp @@ -70,13 +70,10 @@ JxrDecode2::CompressedData JxrDecode2::Encode( std::uint32_t stride, const void* ptr_bitmap) { - ERR err; PKImageEncode* pEncoder; - err = PKCodecFactory_CreateCodec(&IID_PKImageWmpEncode, (void**)&pEncoder); - + ERR err = PKCodecFactory_CreateCodec(&IID_PKImageWmpEncode, (void**)&pEncoder); - CWMIStrCodecParam codec_parameters; - memset(&codec_parameters, 0, sizeof(codec_parameters)); + CWMIStrCodecParam codec_parameters = {}; //codec_parameters.guidPixFormat = GUID_PKPixelFormat24bppBGR; codec_parameters.bVerbose = FALSE; codec_parameters.cfColorFormat = YUV_444; diff --git a/Src/JxrDecode/JxrDecode2.h b/Src/JxrDecode/JxrDecode2.h index 6b174f2c..b1a532da 100644 --- a/Src/JxrDecode/JxrDecode2.h +++ b/Src/JxrDecode/JxrDecode2.h @@ -59,20 +59,22 @@ class JxrDecode2 void* obj_handle_; public: CompressedData():obj_handle_(nullptr){}; - CompressedData& operator=(CompressedData&& other) + CompressedData& operator=(CompressedData&& other) noexcept { // "other" is soon going to be destroyed, so we let it destroy our current resource instead and we take "other"'s current resource via swapping std::swap(this->obj_handle_, other.obj_handle_); return *this; } + // move constructor, takes a rvalue reference && - CompressedData(CompressedData&& other) + CompressedData(CompressedData&& other) noexcept { // we "steal" the resource from "other" this->obj_handle_ = other.obj_handle_; // "other" will soon be destroyed and its destructor will do nothing because we null out its resource here other.obj_handle_ = nullptr; } + CompressedData(const CompressedData&)=delete; // prevent copy constructor to be used CompressedData& operator=(const CompressedData&)=delete; // prevent copy assignment to be used diff --git a/Src/libCZI_UnitTests/test_JxrDecode.cpp b/Src/libCZI_UnitTests/test_JxrDecode.cpp index afb8813b..a0b1a561 100644 --- a/Src/libCZI_UnitTests/test_JxrDecode.cpp +++ b/Src/libCZI_UnitTests/test_JxrDecode.cpp @@ -6,6 +6,7 @@ #include #include "inc_libCZI.h" #include "testImage.h" +#include "utils.h" #include "../libCZI/decoder.h" using namespace libCZI; @@ -59,23 +60,39 @@ TEST(JxrDecode, TryDecodeInvalidDataExpectException) EXPECT_ANY_THROW(dec->Decode(encoded_data.get(), sizeEncoded, libCZI::PixelType::Invalid, 0, 0)); } -TEST(JxrDecode, TestEncoder) +TEST(JxrDecode, CompressAndDecompressCheckForSameContent) { - auto bitmap = CBitmapData::Create(PixelType::Bgr24, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); + const auto bitmap = CBitmapData::Create(PixelType::Bgr24, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); { - ScopedBitmapLockerSP lck{ bitmap }; + const ScopedBitmapLockerSP lck{ bitmap }; CTestImage::CopyBgr24Image(lck.ptrDataRoi, bitmap->GetWidth(), bitmap->GetHeight(), lck.stride); } const auto codec = CJxrLibDecoder::Create(); + shared_ptr encodedData; { - ScopedBitmapLockerSP lck{ bitmap }; - codec->Encode( - bitmap->GetPixelType(), - bitmap->GetWidth(), - bitmap->GetHeight(), - lck.stride, + const ScopedBitmapLockerSP lck{ bitmap }; + encodedData = codec->Encode( + bitmap->GetPixelType(), + bitmap->GetWidth(), + bitmap->GetHeight(), + lck.stride, lck.ptrDataRoi); } + + void* encoded_data_ptr = encodedData->GetPtr(); + ASSERT_NE(encoded_data_ptr, nullptr) << "Encoded data is null."; + const size_t size_of_encoded_data = encodedData->GetSizeOfData(); + ASSERT_LT(size_of_encoded_data, static_cast(Utils::GetBytesPerPixel(bitmap->GetPixelType()) * bitmap->GetWidth() * bitmap->GetHeight())) << + "Encoded data is too large (larger than the original data), which is unexpected."; + + const auto bitmap_decoded = codec->Decode( + encodedData->GetPtr(), + encodedData->GetSizeOfData(), + libCZI::PixelType::Bgr24, + bitmap->GetWidth(), + bitmap->GetHeight()); + const bool are_equal = AreBitmapDataEqual(bitmap, bitmap_decoded); + EXPECT_TRUE(are_equal) << "Original bitmap and encoded-decoded one are not identical."; } diff --git a/Src/libCZI_UnitTests/utils.cpp b/Src/libCZI_UnitTests/utils.cpp index 621e0fb5..b2250335 100644 --- a/Src/libCZI_UnitTests/utils.cpp +++ b/Src/libCZI_UnitTests/utils.cpp @@ -439,10 +439,10 @@ bool AreBitmapDataEqual(const std::shared_ptr& bmp1, const const uint8_t* bufBmp1 = reinterpret_cast(lockBmp1.ptrDataRoi); const uint8_t* bufBmp2 = reinterpret_cast(lockBmp2.ptrDataRoi); - uint32_t height = bmp1->GetHeight(); + const uint32_t height = bmp1->GetHeight(); size_t line = bmp1->GetWidth() * static_cast(Utils::GetBytesPerPixel(bmp1->GetPixelType())); - uint32_t stride1 = lockBmp1.stride; - uint32_t stride2 = lockBmp2.stride; + const uint32_t stride1 = lockBmp1.stride; + const uint32_t stride2 = lockBmp2.stride; for (uint32_t i = 0; i < height; ++i) { From cf7afcc9ca8ab53e8274437aef34cd9fdc1a9ede Mon Sep 17 00:00:00 2001 From: ptahmose Date: Mon, 21 Aug 2023 00:56:20 +0200 Subject: [PATCH 42/98] tinkering... --- Src/JxrDecode/jxrlib/image/encode/strenc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Src/JxrDecode/jxrlib/image/encode/strenc.c b/Src/JxrDecode/jxrlib/image/encode/strenc.c index a726a137..ab28a4ff 100644 --- a/Src/JxrDecode/jxrlib/image/encode/strenc.c +++ b/Src/JxrDecode/jxrlib/image/encode/strenc.c @@ -418,12 +418,12 @@ static _FORCEINLINE PixelI forwardHalf(PixelI hHalf) // BitIOInfo init/term for encoding const size_t MAX_MEMORY_SIZE_IN_WORDS = 64 << 20; // 1 << 20 \approx 1 million -#include -#define _WINDOWS_ 1 +//#include +//#define _WINDOWS_ 1 Int StrIOEncInit(CWMImageStrCodec* pSC) { -//#if false // TODO TODO TODO +#if false // TODO TODO TODO pSC->m_param.bIndexTable = !(pSC->WMISCP.bfBitstreamFormat == SPATIAL && pSC->WMISCP.cNumOfSliceMinus1H + pSC->WMISCP.cNumOfSliceMinus1V == 0); if (allocateBitIOInfo(pSC) != ICERR_OK) { return ICERR_ERROR; @@ -501,7 +501,7 @@ Int StrIOEncInit(CWMImageStrCodec* pSC) attachISWrite(pSC->m_ppBitIO[i], pSC->ppWStream[i]); } } -//#endif +#endif return ICERR_OK; } From 9527164b8f766d68cd340ce5e70b9339137d74b1 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Mon, 21 Aug 2023 01:00:22 +0200 Subject: [PATCH 43/98] fix --- Src/libCZI_UnitTests/testImage.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Src/libCZI_UnitTests/testImage.h b/Src/libCZI_UnitTests/testImage.h index 88d30daf..863f7481 100644 --- a/Src/libCZI_UnitTests/testImage.h +++ b/Src/libCZI_UnitTests/testImage.h @@ -5,6 +5,7 @@ #pragma once #include +#include class CTestImage { From ab81c74158259b716c3ef1bac0130570f6b0723f Mon Sep 17 00:00:00 2001 From: ptahmose Date: Mon, 21 Aug 2023 21:47:06 +0200 Subject: [PATCH 44/98] tentative - get rid of "temp-file-stuff" --- Src/JxrDecode/jxrlib/image/encode/strenc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Src/JxrDecode/jxrlib/image/encode/strenc.c b/Src/JxrDecode/jxrlib/image/encode/strenc.c index ab28a4ff..5a7e34bc 100644 --- a/Src/JxrDecode/jxrlib/image/encode/strenc.c +++ b/Src/JxrDecode/jxrlib/image/encode/strenc.c @@ -423,7 +423,7 @@ const size_t MAX_MEMORY_SIZE_IN_WORDS = 64 << 20; // 1 << 20 \approx 1 million Int StrIOEncInit(CWMImageStrCodec* pSC) { -#if false // TODO TODO TODO +//#if false // TODO TODO TODO pSC->m_param.bIndexTable = !(pSC->WMISCP.bfBitstreamFormat == SPATIAL && pSC->WMISCP.cNumOfSliceMinus1H + pSC->WMISCP.cNumOfSliceMinus1V == 0); if (allocateBitIOInfo(pSC) != ICERR_OK) { return ICERR_ERROR; @@ -443,7 +443,7 @@ Int StrIOEncInit(CWMImageStrCodec* pSC) if (pSC->ppWStream == NULL) return ICERR_ERROR; memset(pSC->ppWStream, 0, pSC->cNumBitIO * sizeof(struct tagWMPStream*)); - if (pSC->cmbHeight * pSC->cmbWidth * pSC->WMISCP.cChannel >= MAX_MEMORY_SIZE_IN_WORDS) { +/* if (pSC->cmbHeight * pSC->cmbWidth * pSC->WMISCP.cChannel >= MAX_MEMORY_SIZE_IN_WORDS) { #ifdef _WINDOWS_ pSC->ppTempFile = (TCHAR**)malloc(pSC->cNumBitIO * sizeof(TCHAR*)); if (pSC->ppTempFile == NULL) return ICERR_ERROR; @@ -453,10 +453,10 @@ Int StrIOEncInit(CWMImageStrCodec* pSC) if (pSC->ppTempFile == NULL) return ICERR_ERROR; memset(pSC->ppTempFile, 0, pSC->cNumBitIO * sizeof(char*)); #endif - } + }*/ for (i = 0; i < pSC->cNumBitIO; i++) { - if (pSC->cmbHeight * pSC->cmbWidth * pSC->WMISCP.cChannel >= MAX_MEMORY_SIZE_IN_WORDS) { + /* if (pSC->cmbHeight * pSC->cmbWidth * pSC->WMISCP.cChannel >= MAX_MEMORY_SIZE_IN_WORDS) { #if defined(_WINDOWS_) || defined(UNDER_CE) // tmpnam does not exist in VS2005 WinCE CRT Bool bUnicode = sizeof(TCHAR) == 2; pSC->ppTempFile[i] = (TCHAR*)malloc(MAX_PATH * sizeof(TCHAR)); @@ -495,13 +495,13 @@ Int StrIOEncInit(CWMImageStrCodec* pSC) if (CreateWS_File(pSC->ppWStream + i, pFilename, "w+b") != ICERR_OK) return ICERR_ERROR; } - else { + else */{ if (CreateWS_List(pSC->ppWStream + i) != ICERR_OK) return ICERR_ERROR; } attachISWrite(pSC->m_ppBitIO[i], pSC->ppWStream[i]); } } -#endif +//#endif return ICERR_OK; } From a9d5c6b6ca521d398bff0ff8ce8e0d0961208b79 Mon Sep 17 00:00:00 2001 From: "J. Bohl" Date: Mon, 21 Aug 2023 22:31:09 +0200 Subject: [PATCH 45/98] fix issue with CMake < 3.24 --- Src/libCZI_UnitTests/CMakeLists.txt | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Src/libCZI_UnitTests/CMakeLists.txt b/Src/libCZI_UnitTests/CMakeLists.txt index cbb0188f..c5302854 100644 --- a/Src/libCZI_UnitTests/CMakeLists.txt +++ b/Src/libCZI_UnitTests/CMakeLists.txt @@ -8,14 +8,19 @@ set(INSTALL_GTEST OFF CACHE BOOL "" FORCE) # For Windows: Prevent overriding the parent project's compiler/linker settings set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) -FetchContent_Declare( - googletest - URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip - DOWNLOAD_EXTRACT_TIMESTAMP TRUE) +if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.24.0") + FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip + DOWNLOAD_EXTRACT_TIMESTAMP TRUE) +else () + FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip) +endif() FetchContent_MakeAvailable(googletest) - ADD_EXECUTABLE(libCZI_UnitTests inc_libCZI.h include_gtest.h From c1911ca91adc095f2edf5c2d6c3d674ce977d24a Mon Sep 17 00:00:00 2001 From: ptahmose Date: Mon, 21 Aug 2023 22:49:49 +0200 Subject: [PATCH 46/98] no more "temp files for encoding" --- Src/JxrDecode/jxrlib/image/encode/strenc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Src/JxrDecode/jxrlib/image/encode/strenc.c b/Src/JxrDecode/jxrlib/image/encode/strenc.c index 5a7e34bc..43b95f6f 100644 --- a/Src/JxrDecode/jxrlib/image/encode/strenc.c +++ b/Src/JxrDecode/jxrlib/image/encode/strenc.c @@ -416,7 +416,7 @@ static _FORCEINLINE PixelI forwardHalf(PixelI hHalf) //================================================================ // BitIOInfo init/term for encoding -const size_t MAX_MEMORY_SIZE_IN_WORDS = 64 << 20; // 1 << 20 \approx 1 million +//const size_t MAX_MEMORY_SIZE_IN_WORDS = 64 << 20; // 1 << 20 \approx 1 million //#include //#define _WINDOWS_ 1 @@ -433,11 +433,11 @@ Int StrIOEncInit(CWMImageStrCodec* pSC) if (pSC->cNumBitIO > 0) { size_t i; -#if defined(_WINDOWS_) || defined(UNDER_CE) // tmpnam does not exist in VS2005 WinCE CRT +/*#if defined(_WINDOWS_) || defined(UNDER_CE) // tmpnam does not exist in VS2005 WinCE CRT TCHAR szPath[MAX_PATH]; DWORD cSize, j, k; #endif - char* pFilename; + char* pFilename;*/ pSC->ppWStream = (struct tagWMPStream**)malloc(pSC->cNumBitIO * sizeof(struct WMPStream*)); if (pSC->ppWStream == NULL) return ICERR_ERROR; @@ -706,7 +706,7 @@ Int StrIOEncTerm(CWMImageStrCodec* pSC) } } - if (pSC->cmbHeight * pSC->cmbWidth * pSC->WMISCP.cChannel >= MAX_MEMORY_SIZE_IN_WORDS) { + /*if (pSC->cmbHeight * pSC->cmbWidth * pSC->WMISCP.cChannel >= MAX_MEMORY_SIZE_IN_WORDS) { for (i = 0; i < pSC->cNumBitIO; i++) { if (pSC->ppWStream && pSC->ppWStream[i]) { if ((*(pSC->ppWStream + i))->state.file.pFile) { @@ -732,7 +732,7 @@ Int StrIOEncTerm(CWMImageStrCodec* pSC) if (pSC->ppTempFile) free(pSC->ppTempFile); } - else { + else*/ { for (i = 0; i < pSC->cNumBitIO; i++) { if (pSC->ppWStream && pSC->ppWStream[i]) pSC->ppWStream[i]->Close(pSC->ppWStream + i); From d9424bb889f5de14108098e3c641b68ec9ad60a2 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Thu, 24 Aug 2023 01:33:56 +0200 Subject: [PATCH 47/98] starting with "quality" and some more (WIP) --- Src/JxrDecode/JxrDecode2.cpp | 203 +++++++++++++++- Src/JxrDecode/JxrDecode2.h | 4 +- Src/libCZI/decoder.cpp | 295 +++++++++++++----------- Src/libCZI/decoder.h | 2 +- Src/libCZI_UnitTests/test_JxrDecode.cpp | 92 +++++++- 5 files changed, 455 insertions(+), 141 deletions(-) diff --git a/Src/JxrDecode/JxrDecode2.cpp b/Src/JxrDecode/JxrDecode2.cpp index ee6bfdb5..c3ed80af 100644 --- a/Src/JxrDecode/JxrDecode2.cpp +++ b/Src/JxrDecode/JxrDecode2.cpp @@ -8,6 +8,7 @@ using namespace std; +static void ApplyQuality(float quality, JxrDecode2::PixelFormat pixel_format, std::uint32_t width, PKImageEncode* pEncoder); static JxrDecode2::PixelFormat JxrPixelFormatGuidToEnum(const GUID& guid); static void ThrowError(const char* error_message, ERR error_code); static const char* ERR_to_string(ERR error_code); @@ -68,7 +69,8 @@ JxrDecode2::CompressedData JxrDecode2::Encode( std::uint32_t width, std::uint32_t height, std::uint32_t stride, - const void* ptr_bitmap) + const void* ptr_bitmap, + float quality/*=1.f*/) { PKImageEncode* pEncoder; ERR err = PKCodecFactory_CreateCodec(&IID_PKImageWmpEncode, (void**)&pEncoder); @@ -86,6 +88,7 @@ JxrDecode2::CompressedData JxrDecode2::Encode( codec_parameters.sbSubband = SB_ALL; codec_parameters.uAlphaMode = 0; codec_parameters.uiDefaultQPIndex = 1; + codec_parameters.uiDefaultQPIndexAlpha = 1; //codec_parameters.fltImageQuality = 1.f; @@ -101,7 +104,27 @@ JxrDecode2::CompressedData JxrDecode2::Encode( err = pEncoder->Initialize(pEncoder, pEncodeStream, &codec_parameters, sizeof(codec_parameters)); - err = pEncoder->SetPixelFormat(pEncoder, GUID_PKPixelFormat24bppBGR); + if (quality < 1.f) + { + ApplyQuality(quality, pixel_format, width, pEncoder); + } + + switch (pixel_format) + { + case PixelFormat::kBgr24: + err = pEncoder->SetPixelFormat(pEncoder, GUID_PKPixelFormat24bppBGR); + break; + case PixelFormat::kGray8: + err = pEncoder->SetPixelFormat(pEncoder, GUID_PKPixelFormat8bppGray); + break; + case PixelFormat::kBgr48: + err = pEncoder->SetPixelFormat(pEncoder, GUID_PKPixelFormat48bppRGB); + break; + case PixelFormat::kGray16: + err = pEncoder->SetPixelFormat(pEncoder, GUID_PKPixelFormat16bppGray); + break; + } + //err = pEncoder->SetPixelFormat(pEncoder, GUID_PKPixelFormat24bppBGR); err = pEncoder->SetSize(pEncoder, width, height); err = pEncoder->SetResolution(pEncoder, 96.f, 96.f); @@ -384,3 +407,179 @@ size_t JxrDecode2::CompressedData::GetSize() &size); return size; } + +/*static*/void ApplyQuality(float quality, JxrDecode2::PixelFormat pixel_format, uint32_t width, PKImageEncode* pEncoder) +{ + // this is resembling the code from https://github.com/ptahmose/jxrlib/blob/f7521879862b9085318e814c6157490dd9dbbdb4/jxrencoderdecoder/JxrEncApp.c#L677C1-L738C10 +#if 1 + // optimized for PSNR + static const int DPK_QPS_420[11][6] = { // for 8 bit only + { 66, 65, 70, 72, 72, 77 }, + { 59, 58, 63, 64, 63, 68 }, + { 52, 51, 57, 56, 56, 61 }, + { 48, 48, 54, 51, 50, 55 }, + { 43, 44, 48, 46, 46, 49 }, + { 37, 37, 42, 38, 38, 43 }, + { 26, 28, 31, 27, 28, 31 }, + { 16, 17, 22, 16, 17, 21 }, + { 10, 11, 13, 10, 10, 13 }, + { 5, 5, 6, 5, 5, 6 }, + { 2, 2, 3, 2, 2, 2 } + }; + + static const int DPK_QPS_8[12][6] = { + { 67, 79, 86, 72, 90, 98 }, + { 59, 74, 80, 64, 83, 89 }, + { 53, 68, 75, 57, 76, 83 }, + { 49, 64, 71, 53, 70, 77 }, + { 45, 60, 67, 48, 67, 74 }, + { 40, 56, 62, 42, 59, 66 }, + { 33, 49, 55, 35, 51, 58 }, + { 27, 44, 49, 28, 45, 50 }, + { 20, 36, 42, 20, 38, 44 }, + { 13, 27, 34, 13, 28, 34 }, + { 7, 17, 21, 8, 17, 21 }, // Photoshop 100% + { 2, 5, 6, 2, 5, 6 } + }; +#else + // optimized for SSIM + static const int DPK_QPS_420[11][6] = { // for 8 bit only + { 67, 77, 80, 75, 82, 86 }, + { 58, 67, 71, 63, 74, 78 }, + { 50, 60, 64, 54, 66, 69 }, + { 46, 55, 59, 49, 60, 63 }, + { 41, 48, 53, 43, 52, 56 }, + { 35, 43, 48, 36, 44, 49 }, + { 29, 37, 41, 30, 38, 41 }, + { 22, 29, 33, 22, 29, 33 }, + { 15, 20, 26, 14, 20, 25 }, + { 9, 14, 18, 8, 14, 17 }, + { 4, 6, 7, 3, 5, 5 } + }; + + static const int DPK_QPS_8[12][6] = { + { 67, 93, 98, 71, 98, 104 }, + { 59, 83, 88, 61, 89, 95 }, + { 50, 76, 81, 53, 85, 90 }, + { 46, 71, 77, 47, 79, 85 }, + { 41, 67, 71, 42, 75, 78 }, + { 34, 59, 65, 35, 66, 72 }, + { 30, 54, 60, 29, 60, 66 }, + { 24, 48, 53, 22, 53, 58 }, + { 18, 39, 45, 17, 43, 48 }, + { 13, 34, 38, 11, 35, 38 }, + { 8, 20, 24, 7, 22, 25 }, // Photoshop 100% + { 2, 5, 6, 2, 5, 6 } + }; +#endif + + static const int DPK_QPS_16[11][6] = { + { 197, 203, 210, 202, 207, 213 }, + { 174, 188, 193, 180, 189, 196 }, + { 152, 167, 173, 156, 169, 174 }, + { 135, 152, 157, 137, 153, 158 }, + { 119, 137, 141, 119, 138, 142 }, + { 102, 120, 125, 100, 120, 124 }, + { 82, 98, 104, 79, 98, 103 }, + { 60, 76, 81, 58, 76, 81 }, + { 39, 52, 58, 36, 52, 58 }, + { 16, 27, 33, 14, 27, 33 }, + { 5, 8, 9, 4, 7, 8 } + }; + + static const int DPK_QPS_16f[11][6] = { + { 148, 177, 171, 165, 187, 191 }, + { 133, 155, 153, 147, 172, 181 }, + { 114, 133, 138, 130, 157, 167 }, + { 97, 118, 120, 109, 137, 144 }, + { 76, 98, 103, 85, 115, 121 }, + { 63, 86, 91, 62, 96, 99 }, + { 46, 68, 71, 43, 73, 75 }, + { 29, 48, 52, 27, 48, 51 }, + { 16, 30, 35, 14, 29, 34 }, + { 8, 14, 17, 7, 13, 17 }, + { 3, 5, 7, 3, 5, 6 } + }; + + static const int DPK_QPS_32f[11][6] = { + { 194, 206, 209, 204, 211, 217 }, + { 175, 187, 196, 186, 193, 205 }, + { 157, 170, 177, 167, 180, 190 }, + { 133, 152, 156, 144, 163, 168 }, + { 116, 138, 142, 117, 143, 148 }, + { 98, 120, 123, 96, 123, 126 }, + { 80, 99, 102, 78, 99, 102 }, + { 65, 79, 84, 63, 79, 84 }, + { 48, 61, 67, 45, 60, 66 }, + { 27, 41, 46, 24, 40, 45 }, + { 3, 22, 24, 2, 21, 22 } + }; + + //if (!args.bOverlapSet) + //{ + // Image width must be at least 2 MB wide for subsampled chroma and two levels of overlap! + if (quality >= 0.5F || /*rect.Width*/width < 2 * MB_WIDTH_PIXEL) + pEncoder->WMP.wmiSCP.olOverlap = OL_ONE; + else + pEncoder->WMP.wmiSCP.olOverlap = OL_TWO; + //} + + //if (!args.bColorFormatSet) + //{ + if (quality >= 0.5F || /*PI.uBitsPerSample > 8*/(pixel_format == JxrDecode2::PixelFormat::kBgr48 || pixel_format == JxrDecode2::PixelFormat::kGray16)) + pEncoder->WMP.wmiSCP.cfColorFormat = YUV_444; + else + pEncoder->WMP.wmiSCP.cfColorFormat = YUV_420; + //} + + //if (PI.bdBitDepth == BD_1) + //{ + // pEncoder->WMP.wmiSCP.uiDefaultQPIndex = (U8)(8 - 5.0F * + // quality/*args.fltImageQuality*/ + 0.5F); + //} + //else + { + // remap [0.8, 0.866, 0.933, 1.0] to [0.8, 0.9, 1.0, 1.1] + // to use 8-bit DPK QP table (0.933 == Photoshop JPEG 100) + int qi; + float qf; + const int* pQPs; + if (/*args.fltImageQuality*/quality > 0.8f && /*PI.bdBitDepth == BD_8*/ + (pixel_format == JxrDecode2::PixelFormat::kBgr24 || pixel_format == JxrDecode2::PixelFormat::kGray8) && + pEncoder->WMP.wmiSCP.cfColorFormat != YUV_420 && + pEncoder->WMP.wmiSCP.cfColorFormat != YUV_422) + quality/*args.fltImageQuality*/ = 0.8f + (quality/*args.fltImageQuality*/ - 0.8f) * 1.5f; + + qi = (int)(10.f * quality/*args.fltImageQuality*/); + qf = 10.f * quality/*args.fltImageQuality*/ - (float)qi; + + /*pQPs = + (pEncoder->WMP.wmiSCP.cfColorFormat == YUV_420 || + pEncoder->WMP.wmiSCP.cfColorFormat == YUV_422) ? + DPK_QPS_420[qi] : + (PI.bdBitDepth == BD_8 ? DPK_QPS_8[qi] : + (PI.bdBitDepth == BD_16 ? DPK_QPS_16[qi] : + (PI.bdBitDepth == BD_16F ? DPK_QPS_16f[qi] : + DPK_QPS_32f[qi])));*/ + pQPs = + (pEncoder->WMP.wmiSCP.cfColorFormat == YUV_420 || + pEncoder->WMP.wmiSCP.cfColorFormat == YUV_422) ? + DPK_QPS_420[qi] : + (pixel_format == JxrDecode2::PixelFormat::kBgr24 || pixel_format == JxrDecode2::PixelFormat::kGray8) ? DPK_QPS_8[qi] : + ((pixel_format == JxrDecode2::PixelFormat::kBgr48 || pixel_format == JxrDecode2::PixelFormat::kGray16) ? DPK_QPS_16[qi] : + (DPK_QPS_32f[qi])); + + pEncoder->WMP.wmiSCP.uiDefaultQPIndex = (U8)(0.5f + + (float)pQPs[0] * (1.f - qf) + (float)(pQPs + 6)[0] * qf); + pEncoder->WMP.wmiSCP.uiDefaultQPIndexU = (U8)(0.5f + + (float)pQPs[1] * (1.f - qf) + (float)(pQPs + 6)[1] * qf); + pEncoder->WMP.wmiSCP.uiDefaultQPIndexV = (U8)(0.5f + + (float)pQPs[2] * (1.f - qf) + (float)(pQPs + 6)[2] * qf); + pEncoder->WMP.wmiSCP.uiDefaultQPIndexYHP = (U8)(0.5f + + (float)pQPs[3] * (1.f - qf) + (float)(pQPs + 6)[3] * qf); + pEncoder->WMP.wmiSCP.uiDefaultQPIndexUHP = (U8)(0.5f + + (float)pQPs[4] * (1.f - qf) + (float)(pQPs + 6)[4] * qf); + pEncoder->WMP.wmiSCP.uiDefaultQPIndexVHP = (U8)(0.5f + + (float)pQPs[5] * (1.f - qf) + (float)(pQPs + 6)[5] * qf); + } +} diff --git a/Src/JxrDecode/JxrDecode2.h b/Src/JxrDecode/JxrDecode2.h index b1a532da..22b8f54f 100644 --- a/Src/JxrDecode/JxrDecode2.h +++ b/Src/JxrDecode/JxrDecode2.h @@ -15,6 +15,7 @@ class JxrDecode2 kBgr48, kGray8, kGray16, + _32bppGrayFloat, /*dontCare, _24bppBGR, _1bppBlackWhite, @@ -120,5 +121,6 @@ class JxrDecode2 std::uint32_t width, std::uint32_t height, std::uint32_t stride, - const void* ptr_bitmap); + const void* ptr_bitmap, + float quality = 1.f); }; diff --git a/Src/libCZI/decoder.cpp b/Src/libCZI/decoder.cpp index bb6836cc..68022c7c 100644 --- a/Src/libCZI/decoder.cpp +++ b/Src/libCZI/decoder.cpp @@ -39,15 +39,38 @@ class MemoryBlockOnCompressedData : public libCZI::IMemoryBlock return make_shared(JxrDecode::Initialize()); } -std::shared_ptr CJxrLibDecoder::Encode(libCZI::PixelType pixel_type, std::uint32_t width, std::uint32_t height, std::uint32_t stride, const void* ptrData) +std::shared_ptr CJxrLibDecoder::Encode(libCZI::PixelType pixel_type, std::uint32_t width, std::uint32_t height, std::uint32_t stride, const void* ptrData, float quality) { + JxrDecode2::PixelFormat jxrdecode_pixel_format; + switch (pixel_type) + { + case PixelType::Bgr24: + jxrdecode_pixel_format = JxrDecode2::PixelFormat::kBgr24; + break; + case PixelType::Bgr48: + jxrdecode_pixel_format = JxrDecode2::PixelFormat::kBgr48; + break; + case PixelType::Gray8: + jxrdecode_pixel_format = JxrDecode2::PixelFormat::kGray8; + break; + case PixelType::Gray16: + jxrdecode_pixel_format = JxrDecode2::PixelFormat::kGray16; + break; + case PixelType::Gray32Float: + jxrdecode_pixel_format = JxrDecode2::PixelFormat::_32bppGrayFloat; + break; + default: + throw std::logic_error("unsupported pixel type"); + } + JxrDecode2 decoder2; auto compressed_data = decoder2.Encode( - JxrDecode2::PixelFormat::kBgr24, + jxrdecode_pixel_format, width, height, stride, - ptrData); + ptrData, + quality); return make_shared(std::move(compressed_data)); } @@ -65,21 +88,21 @@ std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, [&](JxrDecode2::PixelFormat pixel_format, std::uint32_t width, std::uint32_t height) -> tuple { - PixelType px_type; - switch (pixel_format) - { - case JxrDecode2::PixelFormat::kBgr24: px_type = PixelType::Bgr24; break; - case JxrDecode2::PixelFormat::kGray8: px_type = PixelType::Gray8; break; - case JxrDecode2::PixelFormat::kBgr48: px_type = PixelType::Bgr48; break; - case JxrDecode2::PixelFormat::kGray16: px_type = PixelType::Gray16; break; - //case JxrDecode2::PixelFormat::_32bppGrayFloat: px_type = PixelType::Gray32Float; break; - default: throw std::logic_error("need to look into these formats..."); - } + PixelType px_type; + switch (pixel_format) + { + case JxrDecode2::PixelFormat::kBgr24: px_type = PixelType::Bgr24; break; + case JxrDecode2::PixelFormat::kGray8: px_type = PixelType::Gray8; break; + case JxrDecode2::PixelFormat::kBgr48: px_type = PixelType::Bgr48; break; + case JxrDecode2::PixelFormat::kGray16: px_type = PixelType::Gray16; break; + //case JxrDecode2::PixelFormat::_32bppGrayFloat: px_type = PixelType::Gray32Float; break; + default: throw std::logic_error("need to look into these formats..."); + } - bitmap = GetSite()->CreateBitmap(px_type, width, height); - const auto lock_info = bitmap->Lock(); - bitmap_is_locked = true; - return make_tuple(pixel_format, lock_info.stride, lock_info.ptrDataRoi); + bitmap = GetSite()->CreateBitmap(px_type, width, height); + const auto lock_info = bitmap->Lock(); + bitmap_is_locked = true; + return make_tuple(pixel_format, lock_info.stride, lock_info.ptrDataRoi); }); } catch (const std::exception& e) @@ -109,13 +132,13 @@ std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, nullptr, [&](JxrDecode2::PixelFormat pixFmt, std::uint32_t width, std::uint32_t height, std::uint32_t linesCount, const void* ptrData, std::uint32_t stride)->void { - /* if (GetSite()->IsEnabled(LOGLEVEL_CHATTYINFORMATION)) - { - stringstream ss; ss << "JxrDecode: decode done - pixelfmt=" << JxrDecode::PixelFormatAsInformalString(pixFmt) << " width=" << width << " height=" << height << " linesCount=" << linesCount << " stride=" << stride; - GetSite()->Log(LOGLEVEL_CHATTYINFORMATION, ss.str()); - }*/ + /* if (GetSite()->IsEnabled(LOGLEVEL_CHATTYINFORMATION)) + { + stringstream ss; ss << "JxrDecode: decode done - pixelfmt=" << JxrDecode::PixelFormatAsInformalString(pixFmt) << " width=" << width << " height=" << height << " linesCount=" << linesCount << " stride=" << stride; + GetSite()->Log(LOGLEVEL_CHATTYINFORMATION, ss.str()); + }*/ - // TODO: it seems feasible to directly decode to the buffer (saving us the copy) + // TODO: it seems feasible to directly decode to the buffer (saving us the copy) PixelType px_type; switch (pixFmt) { @@ -123,7 +146,7 @@ std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, case JxrDecode2::PixelFormat::kGray8: px_type = PixelType::Gray8; break; case JxrDecode2::PixelFormat::kBgr48: px_type = PixelType::Bgr48; break; case JxrDecode2::PixelFormat::kGray16: px_type = PixelType::Gray16; break; - //case JxrDecode2::PixelFormat::_32bppGrayFloat: px_type = PixelType::Gray32Float; break; + //case JxrDecode2::PixelFormat::_32bppGrayFloat: px_type = PixelType::Gray32Float; break; default: throw std::logic_error("need to look into these formats..."); } @@ -146,8 +169,8 @@ std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, { CBitmapOperations::RGB48ToBGR48(width, height, (uint16_t*)bmLckInfo.ptrDataRoi, bmLckInfo.stride); } - } - ); +} + ); return bm; } @@ -175,93 +198,93 @@ std::shared_ptr CJxrLibDecoder::Decode2(const void* ptrData // which pixelformat we want to get from the decoder. // ...one problem is that not all format-conversions are possible - we choose the "closest" JxrDecode::PixelFormat destFmt; - switch (decPixFmt) - { - case JxrDecode::PixelFormat::_24bppBGR: - case JxrDecode::PixelFormat::_32bppRGBE: - case JxrDecode::PixelFormat::_32bppCMYK: - case JxrDecode::PixelFormat::_32bppBGR: - case JxrDecode::PixelFormat::_16bppBGR555: - case JxrDecode::PixelFormat::_16bppBGR565: - case JxrDecode::PixelFormat::_32bppBGR101010: - case JxrDecode::PixelFormat::_24bppRGB: - case JxrDecode::PixelFormat::_32bppBGRA: - destFmt = JxrDecode::PixelFormat::_24bppBGR; - if (pixelType != libCZI::PixelType::Bgr24) - { - throw std::runtime_error("pixel type validation failed..."); - } - - break; - case JxrDecode::PixelFormat::_1bppBlackWhite: - case JxrDecode::PixelFormat::_8bppGray: - destFmt = JxrDecode::PixelFormat::_8bppGray; - if (pixelType != libCZI::PixelType::Gray8) - { - throw std::runtime_error("pixel type validation failed..."); - } - - break; - case JxrDecode::PixelFormat::_16bppGray: - case JxrDecode::PixelFormat::_16bppGrayFixedPoint: - case JxrDecode::PixelFormat::_16bppGrayHalf: - destFmt = JxrDecode::PixelFormat::_16bppGray; - if (pixelType != libCZI::PixelType::Gray16) - { - throw std::runtime_error("pixel type validation failed..."); - } - - break; - case JxrDecode::PixelFormat::_32bppGrayFixedPoint: - case JxrDecode::PixelFormat::_32bppGrayFloat: - destFmt = JxrDecode::PixelFormat::_32bppGrayFloat; - if (pixelType != libCZI::PixelType::Bgra32) - { - throw std::runtime_error("pixel type validation failed..."); - } + switch (decPixFmt) + { + case JxrDecode::PixelFormat::_24bppBGR: + case JxrDecode::PixelFormat::_32bppRGBE: + case JxrDecode::PixelFormat::_32bppCMYK: + case JxrDecode::PixelFormat::_32bppBGR: + case JxrDecode::PixelFormat::_16bppBGR555: + case JxrDecode::PixelFormat::_16bppBGR565: + case JxrDecode::PixelFormat::_32bppBGR101010: + case JxrDecode::PixelFormat::_24bppRGB: + case JxrDecode::PixelFormat::_32bppBGRA: + destFmt = JxrDecode::PixelFormat::_24bppBGR; + if (pixelType != libCZI::PixelType::Bgr24) + { + throw std::runtime_error("pixel type validation failed..."); + } - break; - case JxrDecode::PixelFormat::_48bppRGB: - destFmt = JxrDecode::PixelFormat::_48bppRGB; - if (pixelType != libCZI::PixelType::Bgr48) - { - throw std::runtime_error("pixel type validation failed..."); - } - - break; - case JxrDecode::PixelFormat::_48bppRGBFixedPoint: - case JxrDecode::PixelFormat::_48bppRGBHalf: - case JxrDecode::PixelFormat::_96bppRGBFixedPoint: - case JxrDecode::PixelFormat::_128bppRGBFloat: - case JxrDecode::PixelFormat::_64bppCMYK: - case JxrDecode::PixelFormat::_64bppRGBA: - case JxrDecode::PixelFormat::_64bppRGBAFixedPoint: - case JxrDecode::PixelFormat::_64bppRGBAHalf: - case JxrDecode::PixelFormat::_128bppRGBAFixedPoint: - case JxrDecode::PixelFormat::_128bppRGBAFloat: - case JxrDecode::PixelFormat::_40bppCMYKA: - case JxrDecode::PixelFormat::_80bppCMYKA: - default: - throw std::logic_error("need to look into these formats..."); - } + break; + case JxrDecode::PixelFormat::_1bppBlackWhite: + case JxrDecode::PixelFormat::_8bppGray: + destFmt = JxrDecode::PixelFormat::_8bppGray; + if (pixelType != libCZI::PixelType::Gray8) + { + throw std::runtime_error("pixel type validation failed..."); + } - if (width != decodedWidth || height != decodedHeight) - { - throw std::runtime_error("width and/or height validation failed..."); - } + break; + case JxrDecode::PixelFormat::_16bppGray: + case JxrDecode::PixelFormat::_16bppGrayFixedPoint: + case JxrDecode::PixelFormat::_16bppGrayHalf: + destFmt = JxrDecode::PixelFormat::_16bppGray; + if (pixelType != libCZI::PixelType::Gray16) + { + throw std::runtime_error("pixel type validation failed..."); + } - if (GetSite()->IsEnabled(LOGLEVEL_CHATTYINFORMATION)) - { - stringstream ss; ss << "JxrDecode: original pixelfmt: " << JxrDecode::PixelFormatAsInformalString(decPixFmt) << ", requested pixelfmt: " << JxrDecode::PixelFormatAsInformalString(destFmt); - GetSite()->Log(LOGLEVEL_CHATTYINFORMATION, ss.str()); - } + break; + case JxrDecode::PixelFormat::_32bppGrayFixedPoint: + case JxrDecode::PixelFormat::_32bppGrayFloat: + destFmt = JxrDecode::PixelFormat::_32bppGrayFloat; + if (pixelType != libCZI::PixelType::Bgra32) + { + throw std::runtime_error("pixel type validation failed..."); + } - if (destFmt == JxrDecode::PixelFormat::invalid) - { - throw std::logic_error("need to look into these formats..."); - } + break; + case JxrDecode::PixelFormat::_48bppRGB: + destFmt = JxrDecode::PixelFormat::_48bppRGB; + if (pixelType != libCZI::PixelType::Bgr48) + { + throw std::runtime_error("pixel type validation failed..."); + } + + break; + case JxrDecode::PixelFormat::_48bppRGBFixedPoint: + case JxrDecode::PixelFormat::_48bppRGBHalf: + case JxrDecode::PixelFormat::_96bppRGBFixedPoint: + case JxrDecode::PixelFormat::_128bppRGBFloat: + case JxrDecode::PixelFormat::_64bppCMYK: + case JxrDecode::PixelFormat::_64bppRGBA: + case JxrDecode::PixelFormat::_64bppRGBAFixedPoint: + case JxrDecode::PixelFormat::_64bppRGBAHalf: + case JxrDecode::PixelFormat::_128bppRGBAFixedPoint: + case JxrDecode::PixelFormat::_128bppRGBAFloat: + case JxrDecode::PixelFormat::_40bppCMYKA: + case JxrDecode::PixelFormat::_80bppCMYKA: + default: + throw std::logic_error("need to look into these formats..."); + } - return destFmt; + if (width != decodedWidth || height != decodedHeight) + { + throw std::runtime_error("width and/or height validation failed..."); + } + + if (GetSite()->IsEnabled(LOGLEVEL_CHATTYINFORMATION)) + { + stringstream ss; ss << "JxrDecode: original pixelfmt: " << JxrDecode::PixelFormatAsInformalString(decPixFmt) << ", requested pixelfmt: " << JxrDecode::PixelFormatAsInformalString(destFmt); + GetSite()->Log(LOGLEVEL_CHATTYINFORMATION, ss.str()); + } + + if (destFmt == JxrDecode::PixelFormat::invalid) + { + throw std::logic_error("need to look into these formats..."); + } + + return destFmt; }, [&](JxrDecode::PixelFormat pixFmt, std::uint32_t width, std::uint32_t height, std::uint32_t linesCount, const void* ptrData, std::uint32_t stride)->void { @@ -271,37 +294,37 @@ std::shared_ptr CJxrLibDecoder::Decode2(const void* ptrData GetSite()->Log(LOGLEVEL_CHATTYINFORMATION, ss.str()); } - // TODO: it seems feasible to directly decode to the buffer (saving us the copy) - PixelType px_type; - switch (pixFmt) - { - case JxrDecode::PixelFormat::_24bppBGR: px_type = PixelType::Bgr24; break; - case JxrDecode::PixelFormat::_8bppGray: px_type = PixelType::Gray8; break; - case JxrDecode::PixelFormat::_48bppRGB: px_type = PixelType::Bgr48; break; - case JxrDecode::PixelFormat::_16bppGray: px_type = PixelType::Gray16; break; - case JxrDecode::PixelFormat::_32bppGrayFloat: px_type = PixelType::Gray32Float; break; - default: throw std::logic_error("need to look into these formats..."); - } - - bm = GetSite()->CreateBitmap(px_type, width, height); - auto bmLckInfo = ScopedBitmapLockerSP(bm); - if (bmLckInfo.stride != stride) - { - for (uint32_t i = 0; i < linesCount; ++i) + // TODO: it seems feasible to directly decode to the buffer (saving us the copy) + PixelType px_type; + switch (pixFmt) + { + case JxrDecode::PixelFormat::_24bppBGR: px_type = PixelType::Bgr24; break; + case JxrDecode::PixelFormat::_8bppGray: px_type = PixelType::Gray8; break; + case JxrDecode::PixelFormat::_48bppRGB: px_type = PixelType::Bgr48; break; + case JxrDecode::PixelFormat::_16bppGray: px_type = PixelType::Gray16; break; + case JxrDecode::PixelFormat::_32bppGrayFloat: px_type = PixelType::Gray32Float; break; + default: throw std::logic_error("need to look into these formats..."); + } + + bm = GetSite()->CreateBitmap(px_type, width, height); + auto bmLckInfo = ScopedBitmapLockerSP(bm); + if (bmLckInfo.stride != stride) { - memcpy(static_cast(bmLckInfo.ptrDataRoi) + i * bmLckInfo.stride, static_cast(ptrData) + i * stride, stride); + for (uint32_t i = 0; i < linesCount; ++i) + { + memcpy(static_cast(bmLckInfo.ptrDataRoi) + i * bmLckInfo.stride, static_cast(ptrData) + i * stride, stride); + } + } + else + { + memcpy(bmLckInfo.ptrDataRoi, ptrData, static_cast(stride) * linesCount); } - } - else - { - memcpy(bmLckInfo.ptrDataRoi, ptrData, static_cast(stride) * linesCount); - } - // since BGR48 is not available as output, we need to convert (#36) - if (px_type == PixelType::Bgr48) - { - CBitmapOperations::RGB48ToBGR48(width, height, (uint16_t*)bmLckInfo.ptrDataRoi, bmLckInfo.stride); - } + // since BGR48 is not available as output, we need to convert (#36) + if (px_type == PixelType::Bgr48) + { + CBitmapOperations::RGB48ToBGR48(width, height, (uint16_t*)bmLckInfo.ptrDataRoi, bmLckInfo.stride); + } }); } catch (std::runtime_error& err) diff --git a/Src/libCZI/decoder.h b/Src/libCZI/decoder.h index f1f24393..f52ee7d0 100644 --- a/Src/libCZI/decoder.h +++ b/Src/libCZI/decoder.h @@ -25,5 +25,5 @@ class CJxrLibDecoder : public libCZI::IDecoder std::shared_ptr Decode(const void* ptrData, size_t size, libCZI::PixelType, std::uint32_t width, std::uint32_t height) override; std::shared_ptr Decode2(const void* ptrData, size_t size, libCZI::PixelType, std::uint32_t width, std::uint32_t height); - std::shared_ptr Encode(libCZI::PixelType pixel_type, std::uint32_t width, std::uint32_t height, std::uint32_t stride, const void* ptrData); + std::shared_ptr Encode(libCZI::PixelType pixel_type, std::uint32_t width, std::uint32_t height, std::uint32_t stride, const void* ptrData, float quality = 1.f); }; diff --git a/Src/libCZI_UnitTests/test_JxrDecode.cpp b/Src/libCZI_UnitTests/test_JxrDecode.cpp index a0b1a561..30e58511 100644 --- a/Src/libCZI_UnitTests/test_JxrDecode.cpp +++ b/Src/libCZI_UnitTests/test_JxrDecode.cpp @@ -60,7 +60,7 @@ TEST(JxrDecode, TryDecodeInvalidDataExpectException) EXPECT_ANY_THROW(dec->Decode(encoded_data.get(), sizeEncoded, libCZI::PixelType::Invalid, 0, 0)); } -TEST(JxrDecode, CompressAndDecompressCheckForSameContent) +TEST(JxrDecode, CompressAndDecompressCheckForSameContent_Bgr24) { const auto bitmap = CBitmapData::Create(PixelType::Bgr24, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); { @@ -96,3 +96,93 @@ TEST(JxrDecode, CompressAndDecompressCheckForSameContent) const bool are_equal = AreBitmapDataEqual(bitmap, bitmap_decoded); EXPECT_TRUE(are_equal) << "Original bitmap and encoded-decoded one are not identical."; } + +TEST(JxrDecode, CompressAndDecompressCheckForSameContent_Gray8) +{ + const auto bitmap = CBitmapData::Create(PixelType::Gray8, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); + { + const auto bitmap_bgr24 = CBitmapData::Create(PixelType::Bgr24, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); + const ScopedBitmapLockerSP locked_bgr24{ bitmap_bgr24 }; + const ScopedBitmapLockerSP locked_gray8{ bitmap }; + CTestImage::CopyBgr24Image(locked_bgr24.ptrDataRoi, bitmap_bgr24->GetWidth(), bitmap_bgr24->GetHeight(), locked_bgr24.stride); + for (size_t y = 0;yGetHeight();++y) + { + for (size_t x = 0;xGetWidth();++x) + { + const auto bgr24_pixel = reinterpret_cast(locked_bgr24.ptrDataRoi)[y * locked_bgr24.stride + x * 3]; + auto gray8_pixel = reinterpret_cast(locked_gray8.ptrDataRoi)[y * locked_gray8.stride + x]; + gray8_pixel = static_cast(bgr24_pixel * 0.299 + bgr24_pixel * 0.587 + bgr24_pixel * 0.114); + } + } + } + + const auto codec = CJxrLibDecoder::Create(); + shared_ptr encodedData; + + { + const ScopedBitmapLockerSP lck{ bitmap }; + encodedData = codec->Encode( + bitmap->GetPixelType(), + bitmap->GetWidth(), + bitmap->GetHeight(), + lck.stride, + lck.ptrDataRoi); + } + + void* encoded_data_ptr = encodedData->GetPtr(); + ASSERT_NE(encoded_data_ptr, nullptr) << "Encoded data is null."; + const size_t size_of_encoded_data = encodedData->GetSizeOfData(); + ASSERT_LT(size_of_encoded_data, static_cast(Utils::GetBytesPerPixel(bitmap->GetPixelType()) * bitmap->GetWidth() * bitmap->GetHeight())) << + "Encoded data is too large (larger than the original data), which is unexpected."; + + const auto bitmap_decoded = codec->Decode( + encodedData->GetPtr(), + encodedData->GetSizeOfData(), + libCZI::PixelType::Gray8, + bitmap->GetWidth(), + bitmap->GetHeight()); + const bool are_equal = AreBitmapDataEqual(bitmap, bitmap_decoded); + EXPECT_TRUE(are_equal) << "Original bitmap and encoded-decoded one are not identical."; +} + +TEST(JxrDecode, CompressAndDecompressCheckForSameContentQuality) +{ + const auto bitmap = CBitmapData::Create(PixelType::Bgr24, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); + { + const ScopedBitmapLockerSP lck{ bitmap }; + CTestImage::CopyBgr24Image(lck.ptrDataRoi, bitmap->GetWidth(), bitmap->GetHeight(), lck.stride); + } + + const auto codec = CJxrLibDecoder::Create(); + shared_ptr encodedData; + + { + const ScopedBitmapLockerSP lck{ bitmap }; + encodedData = codec->Encode( + bitmap->GetPixelType(), + bitmap->GetWidth(), + bitmap->GetHeight(), + lck.stride, + lck.ptrDataRoi, + 1.f); + } + + void* encoded_data_ptr = encodedData->GetPtr(); + ASSERT_NE(encoded_data_ptr, nullptr) << "Encoded data is null."; + const size_t size_of_encoded_data = encodedData->GetSizeOfData(); + ASSERT_LT(size_of_encoded_data, static_cast(Utils::GetBytesPerPixel(bitmap->GetPixelType()) * bitmap->GetWidth() * bitmap->GetHeight())) << + "Encoded data is too large (larger than the original data), which is unexpected."; + + FILE* fp = fopen("N:\\test.jxr", "wb"); + fwrite(encoded_data_ptr, size_of_encoded_data, 1, fp); + fclose(fp); + + const auto bitmap_decoded = codec->Decode( + encodedData->GetPtr(), + encodedData->GetSizeOfData(), + libCZI::PixelType::Bgr24, + bitmap->GetWidth(), + bitmap->GetHeight()); + const bool are_equal = AreBitmapDataEqual(bitmap, bitmap_decoded); + EXPECT_TRUE(are_equal) << "Original bitmap and encoded-decoded one are not identical."; +} From e6537851a15e391088d1fe4c918f8f03b81fdc13 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 27 Aug 2023 00:47:02 +0200 Subject: [PATCH 48/98] add some tests for JPGXR, cosmetic --- Src/libCZI/decoder.cpp | 48 ++++++-- Src/libCZI_UnitTests/test_JxrDecode.cpp | 155 +++++++++++++++++++++--- Src/libCZI_UnitTests/utils.cpp | 43 +++++++ Src/libCZI_UnitTests/utils.h | 4 + 4 files changed, 223 insertions(+), 27 deletions(-) diff --git a/Src/libCZI/decoder.cpp b/Src/libCZI/decoder.cpp index 68022c7c..4eef6df5 100644 --- a/Src/libCZI/decoder.cpp +++ b/Src/libCZI/decoder.cpp @@ -34,6 +34,23 @@ class MemoryBlockOnCompressedData : public libCZI::IMemoryBlock } }; +static libCZI::PixelType PixelTypeFromJxrPixelFormat(JxrDecode2::PixelFormat pixel_format) +{ + switch (pixel_format) + { + case JxrDecode2::PixelFormat::kBgr24: + return PixelType::Bgr24; + case JxrDecode2::PixelFormat::kGray8: + return PixelType::Gray8; + case JxrDecode2::PixelFormat::kBgr48: + return PixelType::Bgr48; + case JxrDecode2::PixelFormat::kGray16: + return PixelType::Gray16; + default: + return PixelType::Invalid; + } +} + /*static*/std::shared_ptr CJxrLibDecoder::Create() { return make_shared(JxrDecode::Initialize()); @@ -88,18 +105,31 @@ std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, [&](JxrDecode2::PixelFormat pixel_format, std::uint32_t width, std::uint32_t height) -> tuple { - PixelType px_type; - switch (pixel_format) + const auto pixel_type_from_compressed_data = PixelTypeFromJxrPixelFormat(pixel_format); + if (pixel_type_from_compressed_data == PixelType::Invalid) { - case JxrDecode2::PixelFormat::kBgr24: px_type = PixelType::Bgr24; break; - case JxrDecode2::PixelFormat::kGray8: px_type = PixelType::Gray8; break; - case JxrDecode2::PixelFormat::kBgr48: px_type = PixelType::Bgr48; break; - case JxrDecode2::PixelFormat::kGray16: px_type = PixelType::Gray16; break; - //case JxrDecode2::PixelFormat::_32bppGrayFloat: px_type = PixelType::Gray32Float; break; - default: throw std::logic_error("need to look into these formats..."); + throw std::logic_error("unsupported pixel type"); + } + + if (pixel_type_from_compressed_data != pixelType) + { + ostringstream ss; + ss << "pixel type mismatch: expected \"" << Utils::PixelTypeToInformalString(pixelType) << "\", but got \"" << Utils::PixelTypeToInformalString(pixel_type_from_compressed_data) << "\""; + throw std::logic_error(ss.str()); } - bitmap = GetSite()->CreateBitmap(px_type, width, height); + //PixelType px_type; + //switch (pixel_format) + //{ + //case JxrDecode2::PixelFormat::kBgr24: px_type = PixelType::Bgr24; break; + //case JxrDecode2::PixelFormat::kGray8: px_type = PixelType::Gray8; break; + //case JxrDecode2::PixelFormat::kBgr48: px_type = PixelType::Bgr48; break; + //case JxrDecode2::PixelFormat::kGray16: px_type = PixelType::Gray16; break; + // //case JxrDecode2::PixelFormat::_32bppGrayFloat: px_type = PixelType::Gray32Float; break; + //default: throw std::logic_error("need to look into these formats..."); + //} + + bitmap = GetSite()->CreateBitmap(pixel_type_from_compressed_data , width, height); const auto lock_info = bitmap->Lock(); bitmap_is_locked = true; return make_tuple(pixel_format, lock_info.stride, lock_info.ptrDataRoi); diff --git a/Src/libCZI_UnitTests/test_JxrDecode.cpp b/Src/libCZI_UnitTests/test_JxrDecode.cpp index 30e58511..caee4e61 100644 --- a/Src/libCZI_UnitTests/test_JxrDecode.cpp +++ b/Src/libCZI_UnitTests/test_JxrDecode.cpp @@ -4,6 +4,8 @@ #include "include_gtest.h" #include +#include +#include #include "inc_libCZI.h" #include "testImage.h" #include "utils.h" @@ -60,7 +62,7 @@ TEST(JxrDecode, TryDecodeInvalidDataExpectException) EXPECT_ANY_THROW(dec->Decode(encoded_data.get(), sizeEncoded, libCZI::PixelType::Invalid, 0, 0)); } -TEST(JxrDecode, CompressAndDecompressCheckForSameContent_Bgr24) +TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Bgr24) { const auto bitmap = CBitmapData::Create(PixelType::Bgr24, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); { @@ -97,7 +99,7 @@ TEST(JxrDecode, CompressAndDecompressCheckForSameContent_Bgr24) EXPECT_TRUE(are_equal) << "Original bitmap and encoded-decoded one are not identical."; } -TEST(JxrDecode, CompressAndDecompressCheckForSameContent_Gray8) +TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Gray8) { const auto bitmap = CBitmapData::Create(PixelType::Gray8, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); { @@ -105,13 +107,13 @@ TEST(JxrDecode, CompressAndDecompressCheckForSameContent_Gray8) const ScopedBitmapLockerSP locked_bgr24{ bitmap_bgr24 }; const ScopedBitmapLockerSP locked_gray8{ bitmap }; CTestImage::CopyBgr24Image(locked_bgr24.ptrDataRoi, bitmap_bgr24->GetWidth(), bitmap_bgr24->GetHeight(), locked_bgr24.stride); - for (size_t y = 0;yGetHeight();++y) + for (size_t y = 0; y < bitmap_bgr24->GetHeight(); ++y) { - for (size_t x = 0;xGetWidth();++x) + for (size_t x = 0; x < bitmap_bgr24->GetWidth(); ++x) { - const auto bgr24_pixel = reinterpret_cast(locked_bgr24.ptrDataRoi)[y * locked_bgr24.stride + x * 3]; - auto gray8_pixel = reinterpret_cast(locked_gray8.ptrDataRoi)[y * locked_gray8.stride + x]; - gray8_pixel = static_cast(bgr24_pixel * 0.299 + bgr24_pixel * 0.587 + bgr24_pixel * 0.114); + const auto bgr24_pixel = &static_cast(locked_bgr24.ptrDataRoi)[y * locked_bgr24.stride + x * 3]; + const auto gray8_pixel = &static_cast(locked_gray8.ptrDataRoi)[y * locked_gray8.stride + x]; + *gray8_pixel = static_cast(bgr24_pixel[0] * 0.299 + bgr24_pixel[1] * 0.587 + bgr24_pixel[2] * 0.114); } } } @@ -145,12 +147,129 @@ TEST(JxrDecode, CompressAndDecompressCheckForSameContent_Gray8) EXPECT_TRUE(are_equal) << "Original bitmap and encoded-decoded one are not identical."; } -TEST(JxrDecode, CompressAndDecompressCheckForSameContentQuality) +TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Gray16) { - const auto bitmap = CBitmapData::Create(PixelType::Bgr24, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); + const auto bitmap_gray16 = CBitmapData::Create(PixelType::Gray16, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); { - const ScopedBitmapLockerSP lck{ bitmap }; - CTestImage::CopyBgr24Image(lck.ptrDataRoi, bitmap->GetWidth(), bitmap->GetHeight(), lck.stride); + const auto bitmap_bgr24 = CBitmapData::Create(PixelType::Bgr24, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); + const ScopedBitmapLockerSP locked_bgr24{ bitmap_bgr24 }; + const ScopedBitmapLockerSP locked_gray16{ bitmap_gray16 }; + CTestImage::CopyBgr24Image(locked_bgr24.ptrDataRoi, bitmap_bgr24->GetWidth(), bitmap_bgr24->GetHeight(), locked_bgr24.stride); + for (size_t y = 0; y < bitmap_bgr24->GetHeight(); ++y) + { + for (size_t x = 0; x < bitmap_bgr24->GetWidth(); ++x) + { + const auto bgr24_pixel = &static_cast(locked_bgr24.ptrDataRoi)[y * locked_bgr24.stride + x * 3]; + const auto gray16_pixel = reinterpret_cast(&static_cast(locked_gray16.ptrDataRoi)[y * locked_gray16.stride + 2 * x]); + *gray16_pixel = static_cast( + (static_cast(bgr24_pixel[0]) << 8) * 0.299 + + (static_cast(bgr24_pixel[1]) << 8) * 0.587 + + (static_cast(bgr24_pixel[2]) << 8) * 0.114); + } + } + } + + const auto codec = CJxrLibDecoder::Create(); + shared_ptr encodedData; + + { + const ScopedBitmapLockerSP lck{ bitmap_gray16 }; + encodedData = codec->Encode( + bitmap_gray16->GetPixelType(), + bitmap_gray16->GetWidth(), + bitmap_gray16->GetHeight(), + lck.stride, + lck.ptrDataRoi); + } + + void* encoded_data_ptr = encodedData->GetPtr(); + ASSERT_NE(encoded_data_ptr, nullptr) << "Encoded data is null."; + const size_t size_of_encoded_data = encodedData->GetSizeOfData(); + ASSERT_LT(size_of_encoded_data, static_cast(Utils::GetBytesPerPixel(bitmap_gray16->GetPixelType()) * bitmap_gray16->GetWidth() * bitmap_gray16->GetHeight())) << + "Encoded data is too large (larger than the original data), which is unexpected."; + + const auto bitmap_decoded = codec->Decode( + encodedData->GetPtr(), + encodedData->GetSizeOfData(), + libCZI::PixelType::Gray16, + bitmap_gray16->GetWidth(), + bitmap_gray16->GetHeight()); + const bool are_equal = AreBitmapDataEqual(bitmap_gray16, bitmap_decoded); + EXPECT_TRUE(are_equal) << "Original bitmap and encoded-decoded one are not identical."; +} + +TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Bgr48) +{ + const auto bitmap_bgr48 = CBitmapData::Create(PixelType::Bgr48, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); + { + const auto bitmap_bgr24 = CBitmapData::Create(PixelType::Bgr24, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); + const ScopedBitmapLockerSP locked_bgr24{ bitmap_bgr24 }; + const ScopedBitmapLockerSP locked_bgr48{ bitmap_bgr48 }; + CTestImage::CopyBgr24Image(locked_bgr24.ptrDataRoi, bitmap_bgr24->GetWidth(), bitmap_bgr24->GetHeight(), locked_bgr24.stride); + + const mt19937 rng_engine{ static_cast(time(nullptr)) }; + independent_bits_engine random_bytes_engine(rng_engine); + for (size_t y = 0; y < bitmap_bgr48->GetHeight(); ++y) + { + for (size_t x = 0; x < bitmap_bgr48->GetWidth(); ++x) + { + const auto bgr24_pixel = &static_cast(locked_bgr24.ptrDataRoi)[y * locked_bgr24.stride + x * 3]; + const auto bgr48_pixel = reinterpret_cast(&static_cast(locked_bgr48.ptrDataRoi)[y * locked_bgr48.stride + 6 * x]); + + // we fill the lower 8 bits with a random byte + bgr48_pixel[0] = static_cast((static_cast(bgr24_pixel[0]) << 8) | static_cast(random_bytes_engine())); + bgr48_pixel[1] = static_cast((static_cast(bgr24_pixel[1]) << 8) | static_cast(random_bytes_engine())); + bgr48_pixel[2] = static_cast((static_cast(bgr24_pixel[2]) << 8) | static_cast(random_bytes_engine())); + } + } + } + + const auto codec = CJxrLibDecoder::Create(); + shared_ptr encodedData; + + { + const ScopedBitmapLockerSP lck{ bitmap_bgr48 }; + encodedData = codec->Encode( + bitmap_bgr48->GetPixelType(), + bitmap_bgr48->GetWidth(), + bitmap_bgr48->GetHeight(), + lck.stride, + lck.ptrDataRoi); + } + + void* encoded_data_ptr = encodedData->GetPtr(); + ASSERT_NE(encoded_data_ptr, nullptr) << "Encoded data is null."; + const size_t size_of_encoded_data = encodedData->GetSizeOfData(); + ASSERT_LT(size_of_encoded_data, static_cast(Utils::GetBytesPerPixel(bitmap_bgr48->GetPixelType()) * bitmap_bgr48->GetWidth() * bitmap_bgr48->GetHeight())) << + "Encoded data is too large (larger than the original data), which is unexpected."; + + const auto bitmap_decoded = codec->Decode( + encodedData->GetPtr(), + encodedData->GetSizeOfData(), + libCZI::PixelType::Bgr48, + bitmap_bgr48->GetWidth(), + bitmap_bgr48->GetHeight()); + const bool are_equal = AreBitmapDataEqual(bitmap_bgr48, bitmap_decoded); + EXPECT_TRUE(are_equal) << "Original bitmap and encoded-decoded one are not identical."; +} + +TEST(JxrDecode, CompressLossyAndDecompressCheckForSimilarity_Gray8) +{ + const auto bitmap = CBitmapData::Create(PixelType::Gray8, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); + { + const auto bitmap_bgr24 = CBitmapData::Create(PixelType::Bgr24, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); + const ScopedBitmapLockerSP locked_bgr24{ bitmap_bgr24 }; + const ScopedBitmapLockerSP locked_gray8{ bitmap }; + CTestImage::CopyBgr24Image(locked_bgr24.ptrDataRoi, bitmap_bgr24->GetWidth(), bitmap_bgr24->GetHeight(), locked_bgr24.stride); + for (size_t y = 0; y < bitmap_bgr24->GetHeight(); ++y) + { + for (size_t x = 0; x < bitmap_bgr24->GetWidth(); ++x) + { + const auto bgr24_pixel = &static_cast(locked_bgr24.ptrDataRoi)[y * locked_bgr24.stride + x * 3]; + const auto gray8_pixel = &static_cast(locked_gray8.ptrDataRoi)[y * locked_gray8.stride + x]; + *gray8_pixel = static_cast(bgr24_pixel[0] * 0.299 + bgr24_pixel[1] * 0.587 + bgr24_pixel[2] * 0.114); + } + } } const auto codec = CJxrLibDecoder::Create(); @@ -164,7 +283,7 @@ TEST(JxrDecode, CompressAndDecompressCheckForSameContentQuality) bitmap->GetHeight(), lck.stride, lck.ptrDataRoi, - 1.f); + 0.9f); } void* encoded_data_ptr = encodedData->GetPtr(); @@ -173,16 +292,16 @@ TEST(JxrDecode, CompressAndDecompressCheckForSameContentQuality) ASSERT_LT(size_of_encoded_data, static_cast(Utils::GetBytesPerPixel(bitmap->GetPixelType()) * bitmap->GetWidth() * bitmap->GetHeight())) << "Encoded data is too large (larger than the original data), which is unexpected."; - FILE* fp = fopen("N:\\test.jxr", "wb"); - fwrite(encoded_data_ptr, size_of_encoded_data, 1, fp); - fclose(fp); + /*FILE* fp = fopen("N:\\test.jxr", "wb"); + fwrite(encoded_data_ptr, size_of_encoded_data, 1, fp); + fclose(fp);*/ const auto bitmap_decoded = codec->Decode( encodedData->GetPtr(), encodedData->GetSizeOfData(), - libCZI::PixelType::Bgr24, + libCZI::PixelType::Gray8, bitmap->GetWidth(), bitmap->GetHeight()); - const bool are_equal = AreBitmapDataEqual(bitmap, bitmap_decoded); - EXPECT_TRUE(are_equal) << "Original bitmap and encoded-decoded one are not identical."; + const auto max_difference_mean_difference = CalculateMaxDifferenceMeanDifference(bitmap, bitmap_decoded); + EXPECT_TRUE(get<0>(max_difference_mean_difference) <= 5 && get<1>(max_difference_mean_difference) < 1) << "Original bitmap and encoded-decoded one are not identical."; } diff --git a/Src/libCZI_UnitTests/utils.cpp b/Src/libCZI_UnitTests/utils.cpp index b2250335..0d5b44d9 100644 --- a/Src/libCZI_UnitTests/utils.cpp +++ b/Src/libCZI_UnitTests/utils.cpp @@ -469,6 +469,49 @@ bool AreBitmapDataEqual(const std::shared_ptr& bmp1, const return result; } +std::tuple CalculateMaxDifferenceMeanDifference(const std::shared_ptr& bmp1, const std::shared_ptr& bmp2) +{ + float sumDifference = 0.0f; + float maxDifference = 0.0f; + + if (bmp1->GetHeight() != bmp2->GetHeight() || + bmp1->GetWidth() != bmp2->GetWidth() || + bmp1->GetPixelType() != bmp2->GetPixelType()) + { + throw invalid_argument("Bitmaps must have the same size and pixel type"); + } + + if (bmp1->GetPixelType() != PixelType::Gray8) + { + throw invalid_argument("Bitmaps must be of type Gray8"); + } + + ScopedBitmapLockerSP lockBmp1{ bmp1 }; + ScopedBitmapLockerSP lockBmp2{ bmp2 }; + + const uint8_t* bufBmp1 = reinterpret_cast(lockBmp1.ptrDataRoi); + const uint8_t* bufBmp2 = reinterpret_cast(lockBmp2.ptrDataRoi); + + const uint32_t stride1 = lockBmp1.stride; + const uint32_t stride2 = lockBmp2.stride; + + for (uint32_t y = 0; y < bmp1->GetHeight(); ++y) + { + const uint8_t* bufBmp1 = reinterpret_cast(lockBmp1.ptrDataRoi) + y * lockBmp1.stride; + const uint8_t* bufBmp2 = reinterpret_cast(lockBmp2.ptrDataRoi) + y * lockBmp2.stride; + + for (uint32_t x = 0; x < bmp1->GetWidth(); ++x) + { + const float difference = fabs(static_cast(bufBmp1[x]) - static_cast(bufBmp2[x])); + sumDifference += difference; + maxDifference = max(maxDifference, difference); + } + } + + const float meanDifference = sumDifference / (static_cast(bmp1->GetWidth()) * bmp1->GetHeight()); + return std::make_tuple(maxDifference, meanDifference); +} + const bool WRITEOUT_CZI = false; //const bool WRITEOUT_CZI = true; diff --git a/Src/libCZI_UnitTests/utils.h b/Src/libCZI_UnitTests/utils.h index f83e60e5..85176134 100644 --- a/Src/libCZI_UnitTests/utils.h +++ b/Src/libCZI_UnitTests/utils.h @@ -6,6 +6,8 @@ #include "inc_libCZI.h" #include "MemInputOutputStream.h" +#include +#include /** * \brief Creates a testing bitmap with the given width, height and the pixel type. @@ -52,6 +54,8 @@ std::shared_ptr GetZeissLogoBitmap(void); */ bool AreBitmapDataEqual(const std::shared_ptr& bmp1, const std::shared_ptr& bmp2); +std::tuple CalculateMaxDifferenceMeanDifference(const std::shared_ptr& bmp1, const std::shared_ptr& bmp2); + void WriteOutTestCzi(const char* testcaseName, const char* testname, const void* ptr, size_t size); void WriteOutTestCzi(const char* testcaseName, const char* testname, const std::shared_ptr& str); From 9d2711bc3ebc376fa3466a554f960f11c2a8513b Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 27 Aug 2023 01:01:23 +0200 Subject: [PATCH 49/98] use good-old rand() --- Src/libCZI_UnitTests/test_JxrDecode.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Src/libCZI_UnitTests/test_JxrDecode.cpp b/Src/libCZI_UnitTests/test_JxrDecode.cpp index caee4e61..bb93a49d 100644 --- a/Src/libCZI_UnitTests/test_JxrDecode.cpp +++ b/Src/libCZI_UnitTests/test_JxrDecode.cpp @@ -4,7 +4,7 @@ #include "include_gtest.h" #include -#include +#include #include #include "inc_libCZI.h" #include "testImage.h" @@ -207,8 +207,6 @@ TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Bgr48) const ScopedBitmapLockerSP locked_bgr48{ bitmap_bgr48 }; CTestImage::CopyBgr24Image(locked_bgr24.ptrDataRoi, bitmap_bgr24->GetWidth(), bitmap_bgr24->GetHeight(), locked_bgr24.stride); - const mt19937 rng_engine{ static_cast(time(nullptr)) }; - independent_bits_engine random_bytes_engine(rng_engine); for (size_t y = 0; y < bitmap_bgr48->GetHeight(); ++y) { for (size_t x = 0; x < bitmap_bgr48->GetWidth(); ++x) @@ -217,9 +215,9 @@ TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Bgr48) const auto bgr48_pixel = reinterpret_cast(&static_cast(locked_bgr48.ptrDataRoi)[y * locked_bgr48.stride + 6 * x]); // we fill the lower 8 bits with a random byte - bgr48_pixel[0] = static_cast((static_cast(bgr24_pixel[0]) << 8) | static_cast(random_bytes_engine())); - bgr48_pixel[1] = static_cast((static_cast(bgr24_pixel[1]) << 8) | static_cast(random_bytes_engine())); - bgr48_pixel[2] = static_cast((static_cast(bgr24_pixel[2]) << 8) | static_cast(random_bytes_engine())); + bgr48_pixel[0] = static_cast((static_cast(bgr24_pixel[0]) << 8) | static_cast(rand() & 0xff)); + bgr48_pixel[1] = static_cast((static_cast(bgr24_pixel[1]) << 8) | static_cast(rand() & 0xff)); + bgr48_pixel[2] = static_cast((static_cast(bgr24_pixel[2]) << 8) | static_cast(rand() & 0xff)); } } } From 0096cba0606f4245158712591b5c460e55ec3547 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 27 Aug 2023 11:31:30 +0200 Subject: [PATCH 50/98] update --- Src/JxrDecode/JxrDecode.cpp | 2 ++ Src/JxrDecode/JxrDecode.h | 2 ++ Src/JxrDecode/JxrDecode2.h | 10 +++++----- Src/libCZI/decoder.cpp | 24 ++++++++---------------- Src/libCZI/decoder.h | 8 ++++---- Src/libCZI_UnitTests/test_JxrDecode.cpp | 16 ++++++++-------- Src/libCZI_UnitTests/utils.cpp | 6 ------ Src/libCZI_UnitTests/utils.h | 7 +++++++ 8 files changed, 36 insertions(+), 39 deletions(-) diff --git a/Src/JxrDecode/JxrDecode.cpp b/Src/JxrDecode/JxrDecode.cpp index f7703338..0cf46af9 100644 --- a/Src/JxrDecode/JxrDecode.cpp +++ b/Src/JxrDecode/JxrDecode.cpp @@ -2,6 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later +#if false #include #include #include @@ -421,3 +422,4 @@ const char* JxrDecode::PixelFormatAsInformalString(PixelFormat pfmt) default:return "unknwon"; } } +#endif diff --git a/Src/JxrDecode/JxrDecode.h b/Src/JxrDecode/JxrDecode.h index 73c312bf..41b1c081 100644 --- a/Src/JxrDecode/JxrDecode.h +++ b/Src/JxrDecode/JxrDecode.h @@ -4,6 +4,7 @@ #pragma once +#if false #include #include #include @@ -135,3 +136,4 @@ namespace JxrDecode void Destroy(codecHandle h); } +#endif diff --git a/Src/JxrDecode/JxrDecode2.h b/Src/JxrDecode/JxrDecode2.h index 22b8f54f..1bdb9682 100644 --- a/Src/JxrDecode/JxrDecode2.h +++ b/Src/JxrDecode/JxrDecode2.h @@ -49,7 +49,7 @@ class JxrDecode2 invalid*/ }; - + typedef void* codecHandle; /// This class is used to represent a blob containing the compressed data. @@ -59,7 +59,7 @@ class JxrDecode2 private: void* obj_handle_; public: - CompressedData():obj_handle_(nullptr){}; + CompressedData() :obj_handle_(nullptr) {} // default constructor CompressedData& operator=(CompressedData&& other) noexcept { // "other" is soon going to be destroyed, so we let it destroy our current resource instead and we take "other"'s current resource via swapping @@ -76,15 +76,15 @@ class JxrDecode2 other.obj_handle_ = nullptr; } - CompressedData(const CompressedData&)=delete; // prevent copy constructor to be used - CompressedData& operator=(const CompressedData&)=delete; // prevent copy assignment to be used + CompressedData(const CompressedData&) = delete; // prevent copy constructor to be used + CompressedData& operator=(const CompressedData&) = delete; // prevent copy assignment to be used void* GetMemory(); size_t GetSize(); ~CompressedData(); protected: friend class JxrDecode2; - CompressedData(void* obj_handle):obj_handle_(obj_handle){}; + CompressedData(void* obj_handle) :obj_handle_(obj_handle) {} }; void Decode( diff --git a/Src/libCZI/decoder.cpp b/Src/libCZI/decoder.cpp index 4eef6df5..9e853768 100644 --- a/Src/libCZI/decoder.cpp +++ b/Src/libCZI/decoder.cpp @@ -53,7 +53,8 @@ static libCZI::PixelType PixelTypeFromJxrPixelFormat(JxrDecode2::PixelFormat pix /*static*/std::shared_ptr CJxrLibDecoder::Create() { - return make_shared(JxrDecode::Initialize()); + //return make_shared(JxrDecode::Initialize()); + return make_shared(); } std::shared_ptr CJxrLibDecoder::Encode(libCZI::PixelType pixel_type, std::uint32_t width, std::uint32_t height, std::uint32_t stride, const void* ptrData, float quality) @@ -102,10 +103,10 @@ std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, decoder2.Decode( ptrData, size, - [&](JxrDecode2::PixelFormat pixel_format, std::uint32_t width, std::uint32_t height) + [&](JxrDecode2::PixelFormat actual_pixel_format, std::uint32_t actual_width, std::uint32_t actual_height) -> tuple { - const auto pixel_type_from_compressed_data = PixelTypeFromJxrPixelFormat(pixel_format); + const auto pixel_type_from_compressed_data = PixelTypeFromJxrPixelFormat(actual_pixel_format); if (pixel_type_from_compressed_data == PixelType::Invalid) { throw std::logic_error("unsupported pixel type"); @@ -118,21 +119,10 @@ std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, throw std::logic_error(ss.str()); } - //PixelType px_type; - //switch (pixel_format) - //{ - //case JxrDecode2::PixelFormat::kBgr24: px_type = PixelType::Bgr24; break; - //case JxrDecode2::PixelFormat::kGray8: px_type = PixelType::Gray8; break; - //case JxrDecode2::PixelFormat::kBgr48: px_type = PixelType::Bgr48; break; - //case JxrDecode2::PixelFormat::kGray16: px_type = PixelType::Gray16; break; - // //case JxrDecode2::PixelFormat::_32bppGrayFloat: px_type = PixelType::Gray32Float; break; - //default: throw std::logic_error("need to look into these formats..."); - //} - - bitmap = GetSite()->CreateBitmap(pixel_type_from_compressed_data , width, height); + bitmap = GetSite()->CreateBitmap(pixel_type_from_compressed_data , actual_width, actual_height); const auto lock_info = bitmap->Lock(); bitmap_is_locked = true; - return make_tuple(pixel_format, lock_info.stride, lock_info.ptrDataRoi); + return make_tuple(actual_pixel_format, lock_info.stride, lock_info.ptrDataRoi); }); } catch (const std::exception& e) @@ -206,6 +196,7 @@ std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, } #endif +#if false std::shared_ptr CJxrLibDecoder::Decode2(const void* ptrData, size_t size, libCZI::PixelType pixelType, uint32_t width, uint32_t height) { std::shared_ptr bm; @@ -384,3 +375,4 @@ std::shared_ptr CJxrLibDecoder::Decode2(const void* ptrData return bm; } +#endif diff --git a/Src/libCZI/decoder.h b/Src/libCZI/decoder.h index f52ee7d0..4165cac1 100644 --- a/Src/libCZI/decoder.h +++ b/Src/libCZI/decoder.h @@ -13,17 +13,17 @@ class CJxrLibDecoder : public libCZI::IDecoder { private: - JxrDecode::codecHandle handle; +// JxrDecode::codecHandle handle; public: static std::shared_ptr Create(); - explicit CJxrLibDecoder(JxrDecode::codecHandle handle) + /* explicit CJxrLibDecoder(JxrDecode::codecHandle handle) : handle(handle) - {} + {}*/ public: std::shared_ptr Decode(const void* ptrData, size_t size, libCZI::PixelType, std::uint32_t width, std::uint32_t height) override; - std::shared_ptr Decode2(const void* ptrData, size_t size, libCZI::PixelType, std::uint32_t width, std::uint32_t height); + //std::shared_ptr Decode2(const void* ptrData, size_t size, libCZI::PixelType, std::uint32_t width, std::uint32_t height); std::shared_ptr Encode(libCZI::PixelType pixel_type, std::uint32_t width, std::uint32_t height, std::uint32_t stride, const void* ptrData, float quality = 1.f); }; diff --git a/Src/libCZI_UnitTests/test_JxrDecode.cpp b/Src/libCZI_UnitTests/test_JxrDecode.cpp index bb93a49d..c7aa53a9 100644 --- a/Src/libCZI_UnitTests/test_JxrDecode.cpp +++ b/Src/libCZI_UnitTests/test_JxrDecode.cpp @@ -16,10 +16,10 @@ using namespace std; TEST(JxrDecode, DecodeBgr24) { - auto dec = CJxrLibDecoder::Create(); + const auto dec = CJxrLibDecoder::Create(); size_t sizeEncoded; int expectedWidth, expectedHeight; - auto ptrEncodedData = CTestImage::GetJpgXrCompressedImage_Bgr24(&sizeEncoded, &expectedWidth, &expectedHeight); - auto bmDecoded = dec->Decode(ptrEncodedData, sizeEncoded, libCZI::PixelType::Bgr24, expectedWidth, expectedHeight); + const auto ptrEncodedData = CTestImage::GetJpgXrCompressedImage_Bgr24(&sizeEncoded, &expectedWidth, &expectedHeight); + const auto bmDecoded = dec->Decode(ptrEncodedData, sizeEncoded, libCZI::PixelType::Bgr24, expectedWidth, expectedHeight); EXPECT_EQ((uint32_t)expectedWidth, bmDecoded->GetWidth()) << "Width is expected to be equal"; EXPECT_EQ((uint32_t)expectedHeight, bmDecoded->GetHeight()) << "Height is expected to be equal"; EXPECT_EQ(bmDecoded->GetPixelType(), PixelType::Bgr24) << "Not the correct pixeltype."; @@ -33,10 +33,10 @@ TEST(JxrDecode, DecodeBgr24) TEST(JxrDecode, DecodeGray8) { - auto dec = CJxrLibDecoder::Create(); + const auto dec = CJxrLibDecoder::Create(); size_t sizeEncoded; int expectedWidth, expectedHeight; - auto ptrEncodedData = CTestImage::GetJpgXrCompressedImage_Gray8(&sizeEncoded, &expectedWidth, &expectedHeight); - auto bmDecoded = dec->Decode(ptrEncodedData, sizeEncoded, libCZI::PixelType::Gray8, expectedWidth, expectedHeight); + const auto ptrEncodedData = CTestImage::GetJpgXrCompressedImage_Gray8(&sizeEncoded, &expectedWidth, &expectedHeight); + const auto bmDecoded = dec->Decode(ptrEncodedData, sizeEncoded, libCZI::PixelType::Gray8, expectedWidth, expectedHeight); EXPECT_EQ((uint32_t)expectedWidth, bmDecoded->GetWidth()) << "Width is expected to be equal"; EXPECT_EQ((uint32_t)expectedHeight, bmDecoded->GetHeight()) << "Height is expected to be equal"; EXPECT_EQ(bmDecoded->GetPixelType(), PixelType::Gray8) << "Not the correct pixeltype."; @@ -52,8 +52,8 @@ TEST(JxrDecode, TryDecodeInvalidDataExpectException) { // pass invalid data to decoder, and expect an exception const auto dec = CJxrLibDecoder::Create(); - size_t sizeEncoded = 2345; - unique_ptr encoded_data(new uint8_t[sizeEncoded]); + constexpr size_t sizeEncoded = 2345; + const unique_ptr encoded_data(new uint8_t[sizeEncoded]); for (size_t i = 0; i < sizeEncoded; i++) { encoded_data.get()[i] = static_cast(i); diff --git a/Src/libCZI_UnitTests/utils.cpp b/Src/libCZI_UnitTests/utils.cpp index 0d5b44d9..88ebb26e 100644 --- a/Src/libCZI_UnitTests/utils.cpp +++ b/Src/libCZI_UnitTests/utils.cpp @@ -489,12 +489,6 @@ std::tuple CalculateMaxDifferenceMeanDifference(const std::shared_ ScopedBitmapLockerSP lockBmp1{ bmp1 }; ScopedBitmapLockerSP lockBmp2{ bmp2 }; - const uint8_t* bufBmp1 = reinterpret_cast(lockBmp1.ptrDataRoi); - const uint8_t* bufBmp2 = reinterpret_cast(lockBmp2.ptrDataRoi); - - const uint32_t stride1 = lockBmp1.stride; - const uint32_t stride2 = lockBmp2.stride; - for (uint32_t y = 0; y < bmp1->GetHeight(); ++y) { const uint8_t* bufBmp1 = reinterpret_cast(lockBmp1.ptrDataRoi) + y * lockBmp1.stride; diff --git a/Src/libCZI_UnitTests/utils.h b/Src/libCZI_UnitTests/utils.h index 85176134..ae58f926 100644 --- a/Src/libCZI_UnitTests/utils.h +++ b/Src/libCZI_UnitTests/utils.h @@ -54,6 +54,13 @@ std::shared_ptr GetZeissLogoBitmap(void); */ bool AreBitmapDataEqual(const std::shared_ptr& bmp1, const std::shared_ptr& bmp2); +/// Calculates the maximum difference and the mean difference of the pixel values of the two bitmaps. +/// The two bitmaps must have the same size and pixel type, otherwise an exception is thrown. +/// +/// \param bmp1 The first bitmap. +/// \param bmp2 The second bitmap. +/// +/// \returns The maximum difference and the mean difference of the pixel values of the two bitmaps. std::tuple CalculateMaxDifferenceMeanDifference(const std::shared_ptr& bmp1, const std::shared_ptr& bmp2); void WriteOutTestCzi(const char* testcaseName, const char* testname, const void* ptr, size_t size); From 1f30eaf8f5aa0eff2eb070cbed0e9e0d2e6b6832 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 27 Aug 2023 14:56:17 +0200 Subject: [PATCH 51/98] fix some clang-warnings --- .../jxrlib/image/decode/strPredQuantDec.c | 12 ++++++---- Src/JxrDecode/jxrlib/image/encode/strenc.c | 4 ++-- Src/JxrDecode/jxrlib/image/sys/strcodec.c | 24 ++++++++++++------- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/Src/JxrDecode/jxrlib/image/decode/strPredQuantDec.c b/Src/JxrDecode/jxrlib/image/decode/strPredQuantDec.c index 86d7a1d0..a1b74c1f 100644 --- a/Src/JxrDecode/jxrlib/image/decode/strPredQuantDec.c +++ b/Src/JxrDecode/jxrlib/image/decode/strPredQuantDec.c @@ -70,13 +70,17 @@ Int dequantizeMacroblock(CWMImageStrCodec* pSC) 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)) + 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) + } + else if (cf == YUV_422) { dequantizeBlock4x2(pSC->p1MBbuffer[i], pMBInfo->iBlockDC[i], pTile->pQuantizerLP[i][pMBInfo->iQIndexLP].iQP); - else // 420 + } + else {// 420 dequantizeBlock2x2(pSC->p1MBbuffer[i], pMBInfo->iBlockDC[i], pTile->pQuantizerLP[i][pMBInfo->iQIndexLP].iQP); + } + } } return ICERR_OK; diff --git a/Src/JxrDecode/jxrlib/image/encode/strenc.c b/Src/JxrDecode/jxrlib/image/encode/strenc.c index 43b95f6f..9024f6ba 100644 --- a/Src/JxrDecode/jxrlib/image/encode/strenc.c +++ b/Src/JxrDecode/jxrlib/image/encode/strenc.c @@ -1320,8 +1320,8 @@ static Void InitializeStrEnc(CWMImageStrCodec* pSC, // set nExpBias if (pSC->WMISCP.nExpBias == 0) - pSC->WMISCP.nExpBias = 4 + 128;//default - pSC->WMISCP.nExpBias += 128; // rollover arithmetic + pSC->WMISCP.nExpBias = -124; // 4 + 128 -> default + pSC->WMISCP.nExpBias *= -1; // rollover arithmetic, flip sign pSC->cRow = 0; pSC->cColumn = 0; diff --git a/Src/JxrDecode/jxrlib/image/sys/strcodec.c b/Src/JxrDecode/jxrlib/image/sys/strcodec.c index a0f356de..d410c476 100644 --- a/Src/JxrDecode/jxrlib/image/sys/strcodec.c +++ b/Src/JxrDecode/jxrlib/image/sys/strcodec.c @@ -987,25 +987,33 @@ Void freeTileInfo(CWMImageStrCodec* pSC) { size_t iTile; - if ((pSC->m_param.uQPMode & 1) != 0) // not DC uniform + if ((pSC->m_param.uQPMode & 1) != 0) {// not DC uniform for (iTile = 0; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile++) freeQuantizer(pSC->pTile[iTile].pQuantizerDC); - else + } + else { freeQuantizer(pSC->pTile[0].pQuantizerDC); + } - if (pSC->WMISCP.sbSubband != SB_DC_ONLY) - if ((pSC->m_param.uQPMode & 2) != 0) // not LP uniform + if (pSC->WMISCP.sbSubband != SB_DC_ONLY) { + if ((pSC->m_param.uQPMode & 2) != 0) {// not LP uniform for (iTile = 0; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile++) freeQuantizer(pSC->pTile[iTile].pQuantizerLP); - else + } + else { freeQuantizer(pSC->pTile[0].pQuantizerLP); + } + } - if (pSC->WMISCP.sbSubband != SB_DC_ONLY && pSC->WMISCP.sbSubband != SB_NO_HIGHPASS) - if ((pSC->m_param.uQPMode & 4) != 0) // not HP uniform + if (pSC->WMISCP.sbSubband != SB_DC_ONLY && pSC->WMISCP.sbSubband != SB_NO_HIGHPASS) { + if ((pSC->m_param.uQPMode & 4) != 0) {// not HP uniform for (iTile = 0; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile++) freeQuantizer(pSC->pTile[iTile].pQuantizerHP); - else + } + else { freeQuantizer(pSC->pTile[0].pQuantizerHP); + } + } if (pSC->pTile != NULL) free(pSC->pTile); From 49e5e8b6890784567a8bc861733f5cb5befb5a00 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 27 Aug 2023 15:04:12 +0200 Subject: [PATCH 52/98] fix clang warning --- Src/JxrDecode/jxrlib/image/sys/strcodec.c | 57 ++++++++++++----------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/Src/JxrDecode/jxrlib/image/sys/strcodec.c b/Src/JxrDecode/jxrlib/image/sys/strcodec.c index d410c476..29c93592 100644 --- a/Src/JxrDecode/jxrlib/image/sys/strcodec.c +++ b/Src/JxrDecode/jxrlib/image/sys/strcodec.c @@ -291,12 +291,12 @@ ERR CreateWS_File(struct tagWMPStream** ppWS, const char* szFilename, const char pWS->SetPos = SetPosWS_File; pWS->GetPos = GetPosWS_File; -//#ifdef WIN32 -// FailIf(0 != fopen_s(&pWS->state.file.pFile, szFilename, szMode), WMP_errFileIO); -//#else + //#ifdef WIN32 + // FailIf(0 != fopen_s(&pWS->state.file.pFile, szFilename, szMode), WMP_errFileIO); + //#else pWS->state.file.pFile = fopen(szFilename, szMode); FailIf(NULL == pWS->state.file.pFile, WMP_errFileIO); -//#endif + //#endif Cleanup: return err; @@ -472,7 +472,7 @@ ERR CreateWS_HeapBackedWriteableStream(struct tagWMPStream** ppWS, size_t cbInit pWS->state.writeableHeapBased.cbCur = 0; pWS->state.writeableHeapBased.cbMax = 0; - pWS->state.writeableHeapBased.cbAllocatedSize= cbInitial; + pWS->state.writeableHeapBased.cbAllocatedSize = cbInitial; pWS->state.writeableHeapBased.cbGrowBy = cbGrowBy; pWS->state.writeableHeapBased.pbBuf = (U8*)malloc(cbInitial); @@ -524,8 +524,8 @@ static ERR EnsureSize_HeapBackedWriteableStream(struct tagWMPStream* pWS, size_t size_t size_to_grow = size_required - pWS->state.writeableHeapBased.cbAllocatedSize; // ...and calculate the new size (where we round up to a multiple of the increment size determined above) - size_t cbNewSize = pWS->state.writeableHeapBased.cbAllocatedSize + - ((size_to_grow + increment -1) / increment) * increment; + size_t cbNewSize = pWS->state.writeableHeapBased.cbAllocatedSize + + ((size_to_grow + increment - 1) / increment) * increment; // note that if realloc fails, the original buffer is left untouched void* pvNew = realloc(pWS->state.writeableHeapBased.pbBuf, cbNewSize); @@ -820,21 +820,21 @@ ERR detach_SB(SimpleBitIO* pSB) #if JXRDECODE_ISBIGENDIANHOST #define jxr_byteswap_ulong(x) (x) #else - U32 jxr_byteswap_ulong(U32 bits) - { - #if JXRDECODE_HAS_BUILTIN_BSWAP32 - return __builtin_bswap32(bits); - #elif JXRDECODE_HAS_BYTESWAP_IN_STDLIB - return _byteswap_ulong(bits); - #elif JXRDECODE_HAS_BSWAP_LONG_IN_SYS_ENDIAN - return bswap_32(v); - #else - return (((bits & 0xff000000u) >> 24) | - ((bits & 0x00ff0000u) >> 8) | - ((bits & 0x0000ff00u) << 8) | - ((bits & 0x000000ffu) << 24)); - #endif - } +U32 jxr_byteswap_ulong(U32 bits) +{ +#if JXRDECODE_HAS_BUILTIN_BSWAP32 + return __builtin_bswap32(bits); +#elif JXRDECODE_HAS_BYTESWAP_IN_STDLIB + return _byteswap_ulong(bits); +#elif JXRDECODE_HAS_BSWAP_LONG_IN_SYS_ENDIAN + return bswap_32(v); +#else + return (((bits & 0xff000000u) >> 24) | + ((bits & 0x00ff0000u) >> 8) | + ((bits & 0x0000ff00u) << 8) | + ((bits & 0x000000ffu) << 24)); +#endif +} #endif U32 load4BE(void* pv) @@ -876,9 +876,9 @@ U32 load4BE(void* pv) #define LOAD16 load4BE #if JXRDECODE_ISBIGENDIANHOST - #define WRITESWAP_ENDIAN(a) ((a)>>16) +#define WRITESWAP_ENDIAN(a) ((a)>>16) #else - #define WRITESWAP_ENDIAN(a) jxr_byteswap_ulong(a) +#define WRITESWAP_ENDIAN(a) jxr_byteswap_ulong(a) #endif @@ -1047,11 +1047,14 @@ Void formatQuantizer(CWMIQuantizer* pQuantizer[MAX_CHANNELS], U8 cChMode, size_t size_t iCh; for (iCh = 0; iCh < cCh; iCh++) { - if (iCh > 0) - if (cChMode == 0) // uniform + if (iCh > 0) { + if (cChMode == 0) {// uniform pQuantizer[iCh][iPos] = pQuantizer[0][iPos]; - else if (cChMode == 1) // mixed + } + else if (cChMode == 1) {// mixed pQuantizer[iCh][iPos] = pQuantizer[1][iPos]; + } + } remapQP(pQuantizer[iCh] + iPos, (iCh > 0 && bShiftedUV == TRUE) ? SHIFTZERO - 1 : SHIFTZERO, bScaledArith); } } From 0adef4919f43610fc9b0786536537dc55dafda92 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 27 Aug 2023 15:16:54 +0200 Subject: [PATCH 53/98] clang warning --- Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c index 1bd954c3..91f95ac2 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c @@ -373,8 +373,9 @@ ERR WriteContainerPre( //================ // PFD assert(offPos <= OFFSET_OF_PFD); // otherwise stuff is overwritten - if (offPos < OFFSET_OF_PFD) + if (offPos < OFFSET_OF_PFD) { Call(pWS->Write(pWS, Zero, OFFSET_OF_PFD - offPos)); + } offPos = (size_t)OFFSET_OF_PFD; if (!pIE->WMP.bHasAlpha || pIE->WMP.wmiSCP.uAlphaMode != 2) //no planar alpha From e8a99948fd468f77e9a1ff40a754e2e8a09ca2d4 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 27 Aug 2023 15:21:00 +0200 Subject: [PATCH 54/98] fix some clang warnings --- Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c | 4 ++-- Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c index 1cdc213c..40f2564b 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGluePFC.c @@ -56,9 +56,9 @@ static U32 Convert_Half_To_Float(U16 u16) { return s << 31; } - else if (~(~0 << 5) == e) // inf, snan, qnan + else if (~(~0u << 5) == e) // inf, snan, qnan { - return (s << 31) | ~(~0 << 8) << 23 | (m << 13); + return (s << 31) | ~(~0u << 8) << 23 | (m << 13); } return (s << 31) | ((e - 15 + 127) << 23) | (m << 13); // norm diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c index 50f403f3..b0bf5a45 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.c @@ -308,8 +308,9 @@ ERR StreamCalcIFDSize(struct tagWMPStream* pWS, U32 uIFDOfs, U32* pcbifd) *pcbifd = cbifd; Cleanup: - if (GetPosOK) + if (GetPosOK) { Call(pWS->SetPos(pWS, offCurPos)); + } return (err); } @@ -579,8 +580,9 @@ ERR StreamCopyIFD(struct tagWMPStream* pWS, U32 ofssrc, U8* pbdst, U32 cbdst, U3 *pofsdst = ofsdstnextdata; Cleanup: - if (GetPosOK) + if (GetPosOK) { Call(pWS->SetPos(pWS, offCurPos)); + } return err; } From bd9b6d6b58ae27bdfe80a04154b8f986f998939e Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 27 Aug 2023 20:07:33 +0200 Subject: [PATCH 55/98] get rid of "GUID" --- Src/libCZI/CMakeLists.txt | 6 +-- Src/libCZI/CziAttachmentsDirectory.cpp | 10 ++-- Src/libCZI/CziAttachmentsDirectory.h | 3 +- Src/libCZI/CziReaderWriter.cpp | 6 +-- Src/libCZI/CziReaderWriter.h | 2 +- Src/libCZI/CziStructs.h | 9 ++-- Src/libCZI/CziWriter.h | 6 +-- Src/libCZI/FileHeaderSegmentData.h | 4 +- Src/libCZI/MD5Sum.h | 2 + Src/libCZI/StreamImpl.h | 3 ++ Src/libCZI/libCZI.h | 4 +- Src/libCZI/priv_guiddef.h | 69 +++++++++++++++++++++++++- Src/libCZI/stdAllocator.cpp | 1 + Src/libCZI/stdafx.h | 2 + Src/libCZI/utilities.cpp | 20 ++++++-- Src/libCZI/utilities.h | 7 +-- 16 files changed, 122 insertions(+), 32 deletions(-) diff --git a/Src/libCZI/CMakeLists.txt b/Src/libCZI/CMakeLists.txt index c8629824..509fa045 100644 --- a/Src/libCZI/CMakeLists.txt +++ b/Src/libCZI/CMakeLists.txt @@ -43,7 +43,7 @@ set(LIBCZISRCFILES SingleChannelTileAccessor.cpp SingleChannelTileCompositor.cpp splines.cpp - stdafx.cpp + #stdafx.cpp stdAllocator.cpp StreamImpl.cpp utilities.cpp @@ -98,10 +98,10 @@ set(LIBCZISRCFILES SingleChannelTileCompositor.h Site.h splines.h - stdafx.h + #stdafx.h stdAllocator.h StreamImpl.h - targetver.h + #targetver.h utilities.h XmlNodeWrapper.h BitmapOperations.hpp diff --git a/Src/libCZI/CziAttachmentsDirectory.cpp b/Src/libCZI/CziAttachmentsDirectory.cpp index 04dc89c6..cba4b8f3 100644 --- a/Src/libCZI/CziAttachmentsDirectory.cpp +++ b/Src/libCZI/CziAttachmentsDirectory.cpp @@ -7,13 +7,14 @@ /*static*/bool CCziAttachmentsDirectoryBase::CompareForEquality_Id(const AttachmentEntry& a, const AttachmentEntry& b) { - int r = memcmp(&a.ContentGuid, &b.ContentGuid, sizeof(GUID)); - if (r != 0) + //int r = memcmp(&a.ContentGuid, &b.ContentGuid, sizeof(GUID)); + //if (r != 0) + if (a.ContentGuid != b.ContentGuid) { return false; } - r = strncmp(a.Name, b.Name, sizeof(a.Name)); + int r = strncmp(a.Name, b.Name, sizeof(a.Name)); if (r != 0) { return false; @@ -89,7 +90,8 @@ int CWriterCziAttachmentsDirectory::GetAttachmentCount() const bool CWriterCziAttachmentsDirectory::AttachmentEntriesCompare::operator()(const AttachmentEntry& a, const AttachmentEntry& b) const { // we shall return true if a is considered to go before b in the strict weak ordering the function defines - int r = memcmp(&a.ContentGuid, &b.ContentGuid, sizeof(GUID)); + int r = a.ContentGuid.compare(b.ContentGuid); + // int r = memcmp(&a.ContentGuid, &b.ContentGuid, sizeof(GUID)); if (r < 0) { return true; diff --git a/Src/libCZI/CziAttachmentsDirectory.h b/Src/libCZI/CziAttachmentsDirectory.h index 3b713c66..2bc5819a 100644 --- a/Src/libCZI/CziAttachmentsDirectory.h +++ b/Src/libCZI/CziAttachmentsDirectory.h @@ -3,6 +3,7 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #pragma once +#include "priv_guiddef.h" #include #include #include @@ -14,7 +15,7 @@ class CCziAttachmentsDirectoryBase struct AttachmentEntry { std::int64_t FilePosition; - GUID ContentGuid; + libCZI::GUID ContentGuid; char ContentFileType[8]; char Name[80]; }; diff --git a/Src/libCZI/CziReaderWriter.cpp b/Src/libCZI/CziReaderWriter.cpp index f0bbc5c3..cfe9d63e 100644 --- a/Src/libCZI/CziReaderWriter.cpp +++ b/Src/libCZI/CziReaderWriter.cpp @@ -435,7 +435,7 @@ void CCziReaderWriter::ReadCziStructure() fhs.data.Major = 1; fhs.data.Minor = 0; - GUID fileGuid = this->info->GetFileGuid(); + libCZI::GUID fileGuid = this->info->GetFileGuid(); if (Utilities::IsGuidNull(fileGuid)) { fileGuid = Utilities::GenerateNewGuid(); @@ -456,9 +456,9 @@ void CCziReaderWriter::ReadCziStructure() this->DetermineNextSubBlockOffset(); } -GUID CCziReaderWriter::UpdateFileHeaderGuid() +libCZI::GUID CCziReaderWriter::UpdateFileHeaderGuid() { - GUID fileGuid = this->info->GetFileGuid(); + libCZI::GUID fileGuid = this->info->GetFileGuid(); if (Utilities::IsGuidNull(fileGuid)) { fileGuid = Utilities::GenerateNewGuid(); diff --git a/Src/libCZI/CziReaderWriter.h b/Src/libCZI/CziReaderWriter.h index 2b11f2d2..fc3f8f97 100644 --- a/Src/libCZI/CziReaderWriter.h +++ b/Src/libCZI/CziReaderWriter.h @@ -57,7 +57,7 @@ class CCziReaderWriter : public libCZI::ICziReaderWriter void Finish(); void ReadCziStructure(); - GUID UpdateFileHeaderGuid(); + libCZI::GUID UpdateFileHeaderGuid(); void DetermineNextSubBlockOffset(); std::tuple ReplaceSubBlock(const libCZI::AddSubBlockInfo& addSubBlockInfo, const CCziSubBlockDirectoryBase::SubBlkEntry& subBlkEntry); diff --git a/Src/libCZI/CziStructs.h b/Src/libCZI/CziStructs.h index 286e32c4..8d9bc176 100644 --- a/Src/libCZI/CziStructs.h +++ b/Src/libCZI/CziStructs.h @@ -4,6 +4,7 @@ #pragma once +#include "priv_guiddef.h" // TODO: we need a platform-independent replacement for GUID #if !defined(__GNUC__) @@ -50,7 +51,7 @@ typedef struct PACKED AttachmentInfo std::int64_t AllocatedSize; std::int64_t DataSize; std::int32_t FilePart; - GUID ContentGuid; + libCZI::GUID ContentGuid; char ContentFileType[8]; char Name[80]; //HANDLE FileHandle; @@ -120,8 +121,8 @@ struct PACKED FileHeaderSegmentData std::int32_t Minor; std::int32_t _Reserved1; std::int32_t _Reserved2; - GUID PrimaryFileGuid; - GUID FileGuid; + libCZI::GUID PrimaryFileGuid; + libCZI::GUID FileGuid; std::int32_t FilePart; std::int64_t SubBlockDirectoryPosition; std::int64_t MetadataPosition; @@ -202,7 +203,7 @@ struct PACKED AttachmentEntryA1 unsigned char _spare[10]; std::int64_t FilePosition; std::int32_t FilePart; - GUID ContentGuid; + libCZI::GUID ContentGuid; unsigned char ContentFileType[8]; unsigned char Name[80]; }; diff --git a/Src/libCZI/CziWriter.h b/Src/libCZI/CziWriter.h index 3d725f0f..5cc92160 100644 --- a/Src/libCZI/CziWriter.h +++ b/Src/libCZI/CziWriter.h @@ -234,12 +234,12 @@ class CCziWriter : public libCZI::ICziWriter { private: std::shared_ptr writerInfo; - GUID fileGuid; + libCZI::GUID fileGuid; public: explicit CziWriterInfoWrapper(std::shared_ptr writerInfo); const libCZI::IDimBounds* GetDimBounds() const override { return this->writerInfo->GetDimBounds(); } - const GUID& GetFileGuid() const override { return this->fileGuid; } + const libCZI::GUID& GetFileGuid() const override { return this->fileGuid; } bool TryGetMIndexMinMax(int* min, int* max) const override { return this->writerInfo->TryGetMIndexMinMax(min, max); } bool TryGetReservedSizeForAttachmentDirectory(size_t* size) const override { return this->writerInfo->TryGetReservedSizeForAttachmentDirectory(size); } bool TryGetReservedSizeForSubBlockDirectory(size_t* size) const override { return this->writerInfo->TryGetReservedSizeForSubBlockDirectory(size); } @@ -288,7 +288,7 @@ class CCziWriter : public libCZI::ICziWriter private: struct FileHeaderData { - GUID primaryFileGuid; + libCZI::GUID primaryFileGuid; std::uint64_t subBlockDirectoryPosition; std::uint64_t metadataPosition; std::uint64_t attachmentDirectoryPosition; diff --git a/Src/libCZI/FileHeaderSegmentData.h b/Src/libCZI/FileHeaderSegmentData.h index 3cf0417c..704a1f2a 100644 --- a/Src/libCZI/FileHeaderSegmentData.h +++ b/Src/libCZI/FileHeaderSegmentData.h @@ -11,7 +11,7 @@ class CFileHeaderSegmentData { private: int verMajor, verMinor; - GUID fileGuid; + libCZI::GUID fileGuid; std::uint64_t subBlockDirectoryPosition; std::uint64_t attachmentDirectoryPosition; std::uint64_t metadataPosition; @@ -45,7 +45,7 @@ class CFileHeaderSegmentData std::uint64_t GetSubBlockDirectoryPosition() const { return this->subBlockDirectoryPosition; } std::uint64_t GetAttachmentDirectoryPosition() const { return this->attachmentDirectoryPosition; } std::uint64_t GetMetadataPosition() const { return this->metadataPosition; } - GUID GetFileGuid()const { return this->fileGuid; } + libCZI::GUID GetFileGuid()const { return this->fileGuid; } bool GetIsSubBlockDirectoryPositionValid()const { diff --git a/Src/libCZI/MD5Sum.h b/Src/libCZI/MD5Sum.h index 1f15f69a..4ff8d72c 100644 --- a/Src/libCZI/MD5Sum.h +++ b/Src/libCZI/MD5Sum.h @@ -1,7 +1,9 @@ // SPDX-FileCopyrightText: 1991-2 RSA Data Security, Inc. // // SPDX-License-Identifier: RSA-MD + #pragma once +#include /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved. diff --git a/Src/libCZI/StreamImpl.h b/Src/libCZI/StreamImpl.h index f05f9459..ca530eef 100644 --- a/Src/libCZI/StreamImpl.h +++ b/Src/libCZI/StreamImpl.h @@ -8,6 +8,9 @@ #include "libCZI.h" #include "inc_libCZI_Config.h" #include +#if defined(_WIN32) + #include +#endif /// A simplistic stream implementation (based on C-runtime fopen). Note that this implementation is NOT thread-safe. class CSimpleStreamImpl : public libCZI::IStream diff --git a/Src/libCZI/libCZI.h b/Src/libCZI/libCZI.h index 4f75c2a9..d3c42a8a 100644 --- a/Src/libCZI/libCZI.h +++ b/Src/libCZI/libCZI.h @@ -327,7 +327,7 @@ namespace libCZI /// Information about an attachment. struct AttachmentInfo { - GUID contentGuid; ///< A Guid identifying the content of the attachment. + libCZI::GUID contentGuid; ///< A Guid identifying the content of the attachment. char contentFileType[9]; ///< A null-terminated character array identifying the content of the attachment. std::string name; ///< A string identifying the content of the attachment. }; @@ -612,7 +612,7 @@ namespace libCZI { ///< The file-GUID of the CZI. Note: CZI defines two GUIDs, this is the "FileGuid". Multi-file containers /// (for which the other GUID "PrimaryFileGuid" is used) are not supported by libCZI currently. - GUID fileGuid; + libCZI::GUID fileGuid; int majorVersion; ///< The major version. int minorVersion; ///< The minor version. }; diff --git a/Src/libCZI/priv_guiddef.h b/Src/libCZI/priv_guiddef.h index f5bdba50..57f542f7 100644 --- a/Src/libCZI/priv_guiddef.h +++ b/Src/libCZI/priv_guiddef.h @@ -1,3 +1,69 @@ +#pragma once + + +#include + +namespace libCZI +{ + struct GUID + { + std::uint32_t Data1; + std::uint16_t Data2; + std::uint16_t Data3; + std::uint8_t Data4[8]; + + bool operator==(const GUID& other) const + { + return this->Data1 == other.Data1 && + this->Data2 == other.Data2 && + this->Data3 == other.Data3 && + this->Data4[0] == other.Data4[0] && + this->Data4[1] == other.Data4[1] && + this->Data4[2] == other.Data4[2] && + this->Data4[3] == other.Data4[3] && + this->Data4[4] == other.Data4[4] && + this->Data4[5] == other.Data4[5] && + this->Data4[6] == other.Data4[6] && + this->Data4[7] == other.Data4[7]; + } + + bool operator!=(const GUID& other) const + { + return !(*this == other); + } + + int compare(const GUID& other) const + { + if (this->Data1 != other.Data1) + { + return this->Data1 < other.Data1 ? -1 : 1; + } + + if (this->Data2 != other.Data2) + { + return this->Data2 < other.Data2 ? -1 : 1; + } + + if (this->Data3 != other.Data3) + { + return this->Data3 < other.Data3 ? -1 : 1; + } + + for (int i = 0; i < 8; ++i) + { + if (this->Data4[i] != other.Data4[i]) + { + return this->Data4[i] < other.Data4[i] ? -1 : 1; + } + } + + return 0; + } + }; +} + + +#if false // SPDX-FileCopyrightText: Microsoft Corp. // // SPDX-License-Identifier: BSD-3-Clause @@ -94,7 +160,7 @@ typedef struct _GUID { EXTERN_C const GUID FAR name #endif // INITGUID -#define DEFINE_OLEGUID(name, l, w1, w2) DEFINE_GUID(name, l, w1, w2, 0xC0,0,0,0,0,0,0,0x46) +//#define DEFINE_OLEGUID(name, l, w1, w2) DEFINE_GUID(name, l, w1, w2, 0xC0,0,0,0,0,0,0,0x46) #ifndef _GUIDDEF_H_ #define _GUIDDEF_H_ @@ -233,3 +299,4 @@ __inline int operator!=(REFGUID guidOne, REFGUID guidOther) #endif // __midl #endif // _GUIDDEF_H_ +#endif diff --git a/Src/libCZI/stdAllocator.cpp b/Src/libCZI/stdAllocator.cpp index 844574e2..90a44e03 100644 --- a/Src/libCZI/stdAllocator.cpp +++ b/Src/libCZI/stdAllocator.cpp @@ -6,6 +6,7 @@ #include "stdAllocator.h" #include #include +#include #include "libCZI_Config.h" constexpr int ALLOC_ALIGNMENT = 32; diff --git a/Src/libCZI/stdafx.h b/Src/libCZI/stdafx.h index ac08adb3..de990293 100644 --- a/Src/libCZI/stdafx.h +++ b/Src/libCZI/stdafx.h @@ -9,6 +9,7 @@ #pragma once +/* #include "targetver.h" #if defined(_WIN32)||defined(_WIN64) @@ -29,3 +30,4 @@ #include #include #include +*/ diff --git a/Src/libCZI/utilities.cpp b/Src/libCZI/utilities.cpp index 08f39bc6..d0d4d4f4 100644 --- a/Src/libCZI/utilities.cpp +++ b/Src/libCZI/utilities.cpp @@ -6,9 +6,13 @@ #include "utilities.h" #include #include +#include #if !defined(_WIN32) #include #endif +#if defined(_WIN32) +#include +#endif #include "inc_libCZI_Config.h" #if LIBCZI_HAVE_ENDIAN_H #include "endian.h" @@ -119,12 +123,18 @@ tString trimImpl(const tString& str, const tString& whitespace) } } -/*static*/GUID Utilities::GenerateNewGuid() +/*static*/libCZI::GUID Utilities::GenerateNewGuid() { #if defined(_WIN32) - GUID guid; + ::GUID guid; CoCreateGuid(&guid); - return guid; + libCZI::GUID guid_value + { + guid.Data1, + guid.Data2, + guid.Data3, + { guid.Data4[0],guid.Data4[1],guid.Data4[2],guid.Data4[3],guid.Data4[4],guid.Data4[5],guid.Data4[6],guid.Data4[7] }}; + return guid_value; #else std::mt19937 rng; rng.seed(std::random_device()()); @@ -203,7 +213,7 @@ tString trimImpl(const tString& str, const tString& whitespace) return false; } -/*static*/bool Utilities::IsGuidNull(const GUID& g) +/*static*/bool Utilities::IsGuidNull(const libCZI::GUID& g) { return g.Data1 == 0 && g.Data2 == 0 && g.Data3 == 0 && g.Data4[0] == 0 && g.Data4[1] == 0 && g.Data4[2] == 0 && g.Data4[3] == 0 && @@ -306,7 +316,7 @@ tString trimImpl(const tString& str, const tString& whitespace) #endif } -/*static*/void Utilities::ConvertGuidToHostByteOrder(GUID* p) +/*static*/void Utilities::ConvertGuidToHostByteOrder(libCZI::GUID* p) { #if LIBCZI_ISBIGENDIANHOST Utilities::ConvertInt32ToHostByteOrder((int32_t*)&(p->Data1)); diff --git a/Src/libCZI/utilities.h b/Src/libCZI/utilities.h index 4a3e2695..9bd8bd69 100644 --- a/Src/libCZI/utilities.h +++ b/Src/libCZI/utilities.h @@ -10,6 +10,7 @@ #include #include #include "libCZI_Pixels.h" +#include "priv_guiddef.h" class Utilities { @@ -119,14 +120,14 @@ class Utilities static void Tokenize(const std::wstring& str, std::vector& tokens, const std::wstring& delimiters = L" "); - static GUID GenerateNewGuid(); + static libCZI::GUID GenerateNewGuid(); - static bool IsGuidNull(const GUID& g); + static bool IsGuidNull(const libCZI::GUID& g); static void ConvertInt16ToHostByteOrder(std::int16_t* p); static void ConvertInt32ToHostByteOrder(std::int32_t* p); static void ConvertInt64ToHostByteOrder(std::int64_t* p); - static void ConvertGuidToHostByteOrder(GUID* p); + static void ConvertGuidToHostByteOrder(libCZI::GUID* p); static bool TryGetRgb8ColorFromString(const std::wstring& strXml, libCZI::Rgb8Color& color); static std::string Rgb8ColorToString(const libCZI::Rgb8Color& color); From e8be68a23008c6f9f2087b371956d26696248960 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 27 Aug 2023 20:10:54 +0200 Subject: [PATCH 56/98] fix --- Src/libCZI/utilities.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/libCZI/utilities.cpp b/Src/libCZI/utilities.cpp index d0d4d4f4..fbcbd032 100644 --- a/Src/libCZI/utilities.cpp +++ b/Src/libCZI/utilities.cpp @@ -139,7 +139,7 @@ tString trimImpl(const tString& str, const tString& whitespace) std::mt19937 rng; rng.seed(std::random_device()()); uniform_int_distribution distu32; - GUID g; + libCZI::GUID g; g.Data1 = distu32(rng); auto r = distu32(rng); g.Data2 = (uint16_t)r; From 2ef3cb6cdd72d9b187e629369732df3d820ac697 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 27 Aug 2023 20:51:38 +0200 Subject: [PATCH 57/98] remove stdafx --- Src/libCZI/CMakeLists.txt | 6 +- Src/libCZI/CziAttachmentsDirectory.h | 2 +- Src/libCZI/CziStructs.h | 3 +- Src/libCZI/libCZI.h | 1 - Src/libCZI/libCZI_Utilities.h | 74 +++++++ Src/libCZI/priv_guiddef.h | 302 --------------------------- Src/libCZI/stdafx.cpp | 12 -- Src/libCZI/stdafx.h | 33 --- Src/libCZI/targetver.h | 14 -- Src/libCZI/utilities.h | 2 +- 10 files changed, 79 insertions(+), 370 deletions(-) delete mode 100644 Src/libCZI/priv_guiddef.h delete mode 100644 Src/libCZI/stdafx.cpp delete mode 100644 Src/libCZI/stdafx.h delete mode 100644 Src/libCZI/targetver.h diff --git a/Src/libCZI/CMakeLists.txt b/Src/libCZI/CMakeLists.txt index 509fa045..ffd313e8 100644 --- a/Src/libCZI/CMakeLists.txt +++ b/Src/libCZI/CMakeLists.txt @@ -43,7 +43,6 @@ set(LIBCZISRCFILES SingleChannelTileAccessor.cpp SingleChannelTileCompositor.cpp splines.cpp - #stdafx.cpp stdAllocator.cpp StreamImpl.cpp utilities.cpp @@ -90,7 +89,6 @@ set(LIBCZISRCFILES libCZI_Write.h MD5Sum.h MultiChannelCompositor.h - priv_guiddef.h SingleChannelAccessorBase.h SingleChannelPyramidLevelTileAccessor.h SingleChannelScalingTileAccessor.h @@ -98,10 +96,8 @@ set(LIBCZISRCFILES SingleChannelTileCompositor.h Site.h splines.h - #stdafx.h stdAllocator.h StreamImpl.h - #targetver.h utilities.h XmlNodeWrapper.h BitmapOperations.hpp @@ -240,7 +236,7 @@ configure_file ( # Define headers for this library. PUBLIC headers are used for compiling the library, and will be added to consumers' build paths. set(libCZIPublicHeaders "ImportExport.h" "libCZI.h" "libCZI_Compositor.h" "libCZI_DimCoordinate.h" "libCZI_exceptions.h" "libCZI_Helpers.h" "libCZI_Metadata.h" "libCZI_Metadata2.h" "libCZI_Pixels.h" "libCZI_ReadWrite.h" - "libCZI_Site.h" "libCZI_Utilities.h" "libCZI_Write.h" "libCZI_compress.h" "priv_guiddef.h") + "libCZI_Site.h" "libCZI_Utilities.h" "libCZI_Write.h" "libCZI_compress.h") # #define the shared libCZI - library diff --git a/Src/libCZI/CziAttachmentsDirectory.h b/Src/libCZI/CziAttachmentsDirectory.h index 2bc5819a..e8de9ad7 100644 --- a/Src/libCZI/CziAttachmentsDirectory.h +++ b/Src/libCZI/CziAttachmentsDirectory.h @@ -3,7 +3,7 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #pragma once -#include "priv_guiddef.h" +#include "libCZI_Utilities.h" #include #include #include diff --git a/Src/libCZI/CziStructs.h b/Src/libCZI/CziStructs.h index 8d9bc176..47ebcf9c 100644 --- a/Src/libCZI/CziStructs.h +++ b/Src/libCZI/CziStructs.h @@ -4,8 +4,9 @@ #pragma once -#include "priv_guiddef.h" +//#include "priv_guiddef.h" // TODO: we need a platform-independent replacement for GUID +#include "libCZI_Utilities.h" #if !defined(__GNUC__) #include diff --git a/Src/libCZI/libCZI.h b/Src/libCZI/libCZI.h index d3c42a8a..bc7c1c5a 100644 --- a/Src/libCZI/libCZI.h +++ b/Src/libCZI/libCZI.h @@ -13,7 +13,6 @@ #include "ImportExport.h" -#include "priv_guiddef.h" #include "libCZI_exceptions.h" #include "libCZI_DimCoordinate.h" #include "libCZI_Pixels.h" diff --git a/Src/libCZI/libCZI_Utilities.h b/Src/libCZI/libCZI_Utilities.h index 8f224737..0f5f926e 100644 --- a/Src/libCZI/libCZI_Utilities.h +++ b/Src/libCZI/libCZI_Utilities.h @@ -10,11 +10,85 @@ #include #include #include +#include #include "libCZI_Metadata.h" #include "libCZI_Pixels.h" namespace libCZI { + /// \brief Represents a globally unique identifier (GUID) consisting of four unsigned 32-bit integers. + /// + /// The GUID is represented as a struct with 4 Data fields of different sizes, allowing it to be packed + /// more tightly than a 16-byte array. This implementation is compatible with the Microsoft GUID + /// definition, but it is not necessarily byte-swappable with it. + struct LIBCZI_API GUID + { + std::uint32_t Data1; ///< The first component of the GUID. + std::uint16_t Data2; ///< The second component of the GUID. + std::uint16_t Data3; ///< The third component of the GUID. + std::uint8_t Data4[8]; ///< The fourth component of the GUID, represented as an array of 8 bytes. + + /// \brief Provide an equality comparison operator between GUID objects. + /// + /// \param other The GUID object to compare with. + /// \return True if the GUID objects are equal, otherwise false. + bool operator==(const GUID& other) const + { + return this->Data1 == other.Data1 && + this->Data2 == other.Data2 && + this->Data3 == other.Data3 && + this->Data4[0] == other.Data4[0] && + this->Data4[1] == other.Data4[1] && + this->Data4[2] == other.Data4[2] && + this->Data4[3] == other.Data4[3] && + this->Data4[4] == other.Data4[4] && + this->Data4[5] == other.Data4[5] && + this->Data4[6] == other.Data4[6] && + this->Data4[7] == other.Data4[7]; + } + + /// \brief Provide an inequality comparison operator between GUID objects. + /// + /// \param other The GUID object to compare with. + /// \return True if the GUID objects are different, otherwise false. + bool operator!=(const GUID& other) const + { + return !(*this == other); + } + + /// \brief Provide a method to lexically compare two GUID objects. + /// + /// \param other The GUID object to compare with. + /// \return An integer less than, equal to, or greater than 0 if this GUID is less than, equal to, or greater than the other GUID. + int compare(const GUID& other) const + { + if (this->Data1 != other.Data1) + { + return this->Data1 < other.Data1 ? -1 : 1; + } + + if (this->Data2 != other.Data2) + { + return this->Data2 < other.Data2 ? -1 : 1; + } + + if (this->Data3 != other.Data3) + { + return this->Data3 < other.Data3 ? -1 : 1; + } + + for (int i = 0; i < 8; ++i) + { + if (this->Data4[i] != other.Data4[i]) + { + return this->Data4[i] < other.Data4[i] ? -1 : 1; + } + } + + return 0; + } + }; + class ISubBlockRepository; class IDisplaySettings; class ICompressParameters; diff --git a/Src/libCZI/priv_guiddef.h b/Src/libCZI/priv_guiddef.h deleted file mode 100644 index 57f542f7..00000000 --- a/Src/libCZI/priv_guiddef.h +++ /dev/null @@ -1,302 +0,0 @@ -#pragma once - - -#include - -namespace libCZI -{ - struct GUID - { - std::uint32_t Data1; - std::uint16_t Data2; - std::uint16_t Data3; - std::uint8_t Data4[8]; - - bool operator==(const GUID& other) const - { - return this->Data1 == other.Data1 && - this->Data2 == other.Data2 && - this->Data3 == other.Data3 && - this->Data4[0] == other.Data4[0] && - this->Data4[1] == other.Data4[1] && - this->Data4[2] == other.Data4[2] && - this->Data4[3] == other.Data4[3] && - this->Data4[4] == other.Data4[4] && - this->Data4[5] == other.Data4[5] && - this->Data4[6] == other.Data4[6] && - this->Data4[7] == other.Data4[7]; - } - - bool operator!=(const GUID& other) const - { - return !(*this == other); - } - - int compare(const GUID& other) const - { - if (this->Data1 != other.Data1) - { - return this->Data1 < other.Data1 ? -1 : 1; - } - - if (this->Data2 != other.Data2) - { - return this->Data2 < other.Data2 ? -1 : 1; - } - - if (this->Data3 != other.Data3) - { - return this->Data3 < other.Data3 ? -1 : 1; - } - - for (int i = 0; i < 8; ++i) - { - if (this->Data4[i] != other.Data4[i]) - { - return this->Data4[i] < other.Data4[i] ? -1 : 1; - } - } - - return 0; - } - }; -} - - -#if false -// SPDX-FileCopyrightText: Microsoft Corp. -// -// SPDX-License-Identifier: BSD-3-Clause -//+--------------------------------------------------------------------------- -// -// 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. -// -// File: guiddef.h -// -// Contents: GUID definition -// -//---------------------------------------------------------------------------- - -#ifndef GUID_DEFINED -#define GUID_DEFINED -#if defined(__midl) -typedef struct { - unsigned long Data1; - unsigned short Data2; - unsigned short Data3; - byte Data4[8]; -} GUID; -#else -typedef struct _GUID { -#if defined(_WINDOWS_) || !__LP64__ - unsigned long Data1; -#else - unsigned int Data1; -#endif - unsigned short Data2; - unsigned short Data3; - unsigned char Data4[8]; -} GUID; -#endif -#endif - -#ifndef FAR -#if defined(_WIN32) || defined(__ANSI__) -#define FAR -#else -//#define FAR _far -#define FAR -#endif -#endif - -#ifndef DECLSPEC_SELECTANY -#if (_MSC_VER >= 1100) -#define DECLSPEC_SELECTANY __declspec(selectany) -#else -#define DECLSPEC_SELECTANY -#endif -#endif - -#ifndef EXTERN_C -#ifdef __cplusplus -#define EXTERN_C extern "C" -#else -#define EXTERN_C extern -#endif -#endif - -#ifdef DEFINE_GUID -#undef DEFINE_GUID -#endif - -#ifdef INITGUID -#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - const GUID DECLSPEC_SELECTANY name \ - = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } -#else -#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - EXTERN_C const GUID FAR name -#endif // INITGUID - -//#define DEFINE_OLEGUID(name, l, w1, w2) DEFINE_GUID(name, l, w1, w2, 0xC0,0,0,0,0,0,0,0x46) - -#ifndef _GUIDDEF_H_ -#define _GUIDDEF_H_ - -#ifndef __LPGUID_DEFINED__ -#define __LPGUID_DEFINED__ -typedef GUID* LPGUID; -#endif - -#ifndef __LPCGUID_DEFINED__ -#define __LPCGUID_DEFINED__ -typedef const GUID* LPCGUID; -#endif - -#ifndef __IID_DEFINED__ -#define __IID_DEFINED__ - -typedef GUID IID; -typedef IID* LPIID; -#define IID_NULL GUID_NULL -#define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2) -typedef GUID CLSID; -typedef CLSID* LPCLSID; -#define CLSID_NULL GUID_NULL -#define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2) -typedef GUID FMTID; -typedef FMTID* LPFMTID; -#define FMTID_NULL GUID_NULL -#define IsEqualFMTID(rfmtid1, rfmtid2) IsEqualGUID(rfmtid1, rfmtid2) - -#ifdef __midl_proxy -#define __MIDL_CONST -#else -#define __MIDL_CONST const -#endif - -#ifndef _REFGUID_DEFINED -#define _REFGUID_DEFINED -#ifdef __cplusplus -#define REFGUID const GUID & -#else -#define REFGUID const GUID * __MIDL_CONST -#endif -#endif - -#ifndef _REFIID_DEFINED -#define _REFIID_DEFINED -#ifdef __cplusplus -#define REFIID const IID & -#else -#define REFIID const IID * __MIDL_CONST -#endif -#endif - -#ifndef _REFCLSID_DEFINED -#define _REFCLSID_DEFINED -#ifdef __cplusplus -#define REFCLSID const IID & -#else -#define REFCLSID const IID * __MIDL_CONST -#endif -#endif - -#ifndef _REFFMTID_DEFINED -#define _REFFMTID_DEFINED -#ifdef __cplusplus -#define REFFMTID const IID & -#else -#define REFFMTID const IID * __MIDL_CONST -#endif -#endif - -#endif // !__IID_DEFINED__ - -#if !defined (__midl) -#if !defined (_SYS_GUID_OPERATORS_) -#define _SYS_GUID_OPERATORS_ -#include - -// Faster (but makes code fatter) inline version...use sparingly -#ifdef __cplusplus -__inline int InlineIsEqualGUID(REFGUID rguid1, REFGUID rguid2) -{ - return ( - ((unsigned long*)&rguid1)[0] == ((unsigned long*)&rguid2)[0] && - ((unsigned long*)&rguid1)[1] == ((unsigned long*)&rguid2)[1] && - ((unsigned long*)&rguid1)[2] == ((unsigned long*)&rguid2)[2] && - ((unsigned long*)&rguid1)[3] == ((unsigned long*)&rguid2)[3]); -} - -__inline int IsEqualGUID(REFGUID rguid1, REFGUID rguid2) -{ - return !memcmp(&rguid1, &rguid2, sizeof(GUID)); -} - -#else // ! __cplusplus - -#define InlineIsEqualGUID(rguid1, rguid2) \ - (((unsigned long *) rguid1)[0] == ((unsigned long *) rguid2)[0] && \ - ((unsigned long *) rguid1)[1] == ((unsigned long *) rguid2)[1] && \ - ((unsigned long *) rguid1)[2] == ((unsigned long *) rguid2)[2] && \ - ((unsigned long *) rguid1)[3] == ((unsigned long *) rguid2)[3]) - -#define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID))) - -#endif // __cplusplus - -#ifdef __INLINE_ISEQUAL_GUID -#undef IsEqualGUID -#define IsEqualGUID(rguid1, rguid2) InlineIsEqualGUID(rguid1, rguid2) -#endif - -// Same type, different name - -#define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2) -#define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2) - - -#if !defined _SYS_GUID_OPERATOR_EQ_ && !defined _NO_SYS_GUID_OPERATOR_EQ_ -#define _SYS_GUID_OPERATOR_EQ_ -// A couple of C++ helpers - -#ifdef __cplusplus -__inline int operator==(REFGUID guidOne, REFGUID guidOther) -{ - return IsEqualGUID(guidOne, guidOther); -} - -__inline int operator!=(REFGUID guidOne, REFGUID guidOther) -{ - return !(guidOne == guidOther); -} -#endif -#endif // _SYS_GUID_OPERATOR_EQ_ -#endif // _SYS_GUID_OPERATORS_ -#endif // __midl -#endif // _GUIDDEF_H_ - -#endif diff --git a/Src/libCZI/stdafx.cpp b/Src/libCZI/stdafx.cpp deleted file mode 100644 index 2916d482..00000000 --- a/Src/libCZI/stdafx.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-FileCopyrightText: 2017-2022 Carl Zeiss Microscopy GmbH -// -// SPDX-License-Identifier: LGPL-3.0-or-later - -// stdafx.cpp : source file that includes just the standard includes -// libCZI.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/Src/libCZI/stdafx.h b/Src/libCZI/stdafx.h deleted file mode 100644 index de990293..00000000 --- a/Src/libCZI/stdafx.h +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-FileCopyrightText: 2017-2022 Carl Zeiss Microscopy GmbH -// -// SPDX-License-Identifier: LGPL-3.0-or-later - -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#pragma once - -/* -#include "targetver.h" - -#if defined(_WIN32)||defined(_WIN64) -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -// Windows Header Files: -#include -#include -#else -#include "priv_guiddef.h" -#endif - - - -// TODO: reference additional headers your program requires here - -#include -#include -#include -#include -#include -*/ diff --git a/Src/libCZI/targetver.h b/Src/libCZI/targetver.h deleted file mode 100644 index dfd16a44..00000000 --- a/Src/libCZI/targetver.h +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-FileCopyrightText: 2017-2022 Carl Zeiss Microscopy GmbH -// -// SPDX-License-Identifier: LGPL-3.0-or-later - -#pragma once - -// Including SDKDDKVer.h defines the highest available Windows platform. - -// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and -// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. - -#if defined(_WIN32)||defined(_WIN64) -#include -#endif diff --git a/Src/libCZI/utilities.h b/Src/libCZI/utilities.h index 9bd8bd69..b99b241c 100644 --- a/Src/libCZI/utilities.h +++ b/Src/libCZI/utilities.h @@ -10,7 +10,7 @@ #include #include #include "libCZI_Pixels.h" -#include "priv_guiddef.h" +#include "libCZI_Utilities.h" class Utilities { From c0255d33d6545660972cafd016501f70a5b3ef06 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 27 Aug 2023 20:59:00 +0200 Subject: [PATCH 58/98] remove includes of stdafx.h --- Src/libCZI/BitmapOperations.cpp | 1 - Src/libCZI/CZIReader.cpp | 1 - Src/libCZI/CreateBitmap.cpp | 1 - Src/libCZI/CziAttachment.cpp | 1 - Src/libCZI/CziAttachmentsDirectory.cpp | 1 - Src/libCZI/CziDimensionInfo.cpp | 1 - Src/libCZI/CziDisplaySettings.cpp | 1 - Src/libCZI/CziMetadata.cpp | 1 - Src/libCZI/CziMetadataBuilder.cpp | 1 - Src/libCZI/CziMetadataDocumentInfo.cpp | 1 - Src/libCZI/CziMetadataDocumentInfo2.cpp | 1 - Src/libCZI/CziMetadataSegment.cpp | 1 - Src/libCZI/CziParse.cpp | 1 - Src/libCZI/CziReaderWriter.cpp | 1 - Src/libCZI/CziStructs.cpp | 1 - Src/libCZI/CziSubBlock.cpp | 1 - Src/libCZI/CziSubBlockDirectory.cpp | 1 - Src/libCZI/CziUtils.cpp | 1 - Src/libCZI/CziWriter.cpp | 1 - Src/libCZI/DimCoordinate.cpp | 1 - Src/libCZI/IndexSet.cpp | 1 - Src/libCZI/MD5Sum.cpp | 1 - Src/libCZI/MultiChannelCompositor.cpp | 2 -- Src/libCZI/SingleChannelAccessorBase.cpp | 1 - Src/libCZI/SingleChannelPyramidLevelTileAccessor.cpp | 1 - Src/libCZI/SingleChannelScalingTileAccessor.cpp | 1 - Src/libCZI/SingleChannelTileAccessor.cpp | 1 - Src/libCZI/SingleChannelTileCompositor.cpp | 1 - Src/libCZI/StreamImpl.cpp | 1 - Src/libCZI/decoder.cpp | 1 - Src/libCZI/decoder_wic.cpp | 1 - Src/libCZI/decoder_zstd.cpp | 1 - Src/libCZI/libCZI_Lib.cpp | 1 - Src/libCZI/libCZI_Site.cpp | 1 - Src/libCZI/libCZI_Utilities.cpp | 2 -- Src/libCZI/splines.cpp | 1 - Src/libCZI/stdAllocator.cpp | 1 - Src/libCZI/utilities.cpp | 1 - Src/libCZI/utilities_simd.cpp | 1 - Src/libCZI/zstdCompress.cpp | 2 -- 40 files changed, 43 deletions(-) diff --git a/Src/libCZI/BitmapOperations.cpp b/Src/libCZI/BitmapOperations.cpp index b1e92d32..dd0138d1 100644 --- a/Src/libCZI/BitmapOperations.cpp +++ b/Src/libCZI/BitmapOperations.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include #include "BitmapOperations.h" #include "MD5Sum.h" diff --git a/Src/libCZI/CZIReader.cpp b/Src/libCZI/CZIReader.cpp index 6fc25959..0d254af0 100644 --- a/Src/libCZI/CZIReader.cpp +++ b/Src/libCZI/CZIReader.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include #include "CZIReader.h" #include "CziParse.h" diff --git a/Src/libCZI/CreateBitmap.cpp b/Src/libCZI/CreateBitmap.cpp index ae433edc..9254312a 100644 --- a/Src/libCZI/CreateBitmap.cpp +++ b/Src/libCZI/CreateBitmap.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "bitmapData.h" #include "Site.h" #include "libCZI.h" diff --git a/Src/libCZI/CziAttachment.cpp b/Src/libCZI/CziAttachment.cpp index 66ec5905..1291f78f 100644 --- a/Src/libCZI/CziAttachment.cpp +++ b/Src/libCZI/CziAttachment.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include #include "CziAttachment.h" #include "CziUtils.h" diff --git a/Src/libCZI/CziAttachmentsDirectory.cpp b/Src/libCZI/CziAttachmentsDirectory.cpp index cba4b8f3..8da6ef2f 100644 --- a/Src/libCZI/CziAttachmentsDirectory.cpp +++ b/Src/libCZI/CziAttachmentsDirectory.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "CziAttachmentsDirectory.h" /*static*/bool CCziAttachmentsDirectoryBase::CompareForEquality_Id(const AttachmentEntry& a, const AttachmentEntry& b) diff --git a/Src/libCZI/CziDimensionInfo.cpp b/Src/libCZI/CziDimensionInfo.cpp index 3f6b321a..79f9a27b 100644 --- a/Src/libCZI/CziDimensionInfo.cpp +++ b/Src/libCZI/CziDimensionInfo.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "CziDimensionInfo.h" /*virtual*/ libCZI::DimensionIndex CCziDimensionInfo::GetDimension() const diff --git a/Src/libCZI/CziDisplaySettings.cpp b/Src/libCZI/CziDisplaySettings.cpp index 31a59095..bdd570aa 100644 --- a/Src/libCZI/CziDisplaySettings.cpp +++ b/Src/libCZI/CziDisplaySettings.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include #include "CziDisplaySettings.h" #include "splines.h" diff --git a/Src/libCZI/CziMetadata.cpp b/Src/libCZI/CziMetadata.cpp index 728807ea..ee1eab16 100644 --- a/Src/libCZI/CziMetadata.cpp +++ b/Src/libCZI/CziMetadata.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "CziMetadata.h" #include "CziMetadataDocumentInfo.h" diff --git a/Src/libCZI/CziMetadataBuilder.cpp b/Src/libCZI/CziMetadataBuilder.cpp index c6009b30..edda3946 100644 --- a/Src/libCZI/CziMetadataBuilder.cpp +++ b/Src/libCZI/CziMetadataBuilder.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "CziMetadataBuilder.h" #include "utilities.h" #include diff --git a/Src/libCZI/CziMetadataDocumentInfo.cpp b/Src/libCZI/CziMetadataDocumentInfo.cpp index 9c684ed3..a75e6fd1 100644 --- a/Src/libCZI/CziMetadataDocumentInfo.cpp +++ b/Src/libCZI/CziMetadataDocumentInfo.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "CziMetadataDocumentInfo.h" #include "CziDimensionInfo.h" #include "CziDisplaySettings.h" diff --git a/Src/libCZI/CziMetadataDocumentInfo2.cpp b/Src/libCZI/CziMetadataDocumentInfo2.cpp index 9e1c913a..9983ac24 100644 --- a/Src/libCZI/CziMetadataDocumentInfo2.cpp +++ b/Src/libCZI/CziMetadataDocumentInfo2.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include #include "CziMetadataDocumentInfo.h" #include "CziMetadataDocumentInfo2.h" diff --git a/Src/libCZI/CziMetadataSegment.cpp b/Src/libCZI/CziMetadataSegment.cpp index f11e4624..c2fc9e70 100644 --- a/Src/libCZI/CziMetadataSegment.cpp +++ b/Src/libCZI/CziMetadataSegment.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "CziMetadataSegment.h" #include "CziUtils.h" diff --git a/Src/libCZI/CziParse.cpp b/Src/libCZI/CziParse.cpp index 93c8a9ba..2c1584f2 100644 --- a/Src/libCZI/CziParse.cpp +++ b/Src/libCZI/CziParse.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "libCZI.h" #include "CziParse.h" #include "CziStructs.h" diff --git a/Src/libCZI/CziReaderWriter.cpp b/Src/libCZI/CziReaderWriter.cpp index cfe9d63e..dc77dd3e 100644 --- a/Src/libCZI/CziReaderWriter.cpp +++ b/Src/libCZI/CziReaderWriter.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "CziReaderWriter.h" #include "CziMetadataSegment.h" #include "libCZI_Utilities.h" diff --git a/Src/libCZI/CziStructs.cpp b/Src/libCZI/CziStructs.cpp index a876d99a..5c405184 100644 --- a/Src/libCZI/CziStructs.cpp +++ b/Src/libCZI/CziStructs.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "CziStructs.h" #include "utilities.h" #include "inc_libCZI_Config.h" diff --git a/Src/libCZI/CziSubBlock.cpp b/Src/libCZI/CziSubBlock.cpp index fefea48c..8e2c2c91 100644 --- a/Src/libCZI/CziSubBlock.cpp +++ b/Src/libCZI/CziSubBlock.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "CziSubBlock.h" #include "CziUtils.h" diff --git a/Src/libCZI/CziSubBlockDirectory.cpp b/Src/libCZI/CziSubBlockDirectory.cpp index f2f2f3b8..123b343b 100644 --- a/Src/libCZI/CziSubBlockDirectory.cpp +++ b/Src/libCZI/CziSubBlockDirectory.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "CziSubBlockDirectory.h" #include "CziUtils.h" diff --git a/Src/libCZI/CziUtils.cpp b/Src/libCZI/CziUtils.cpp index 48806749..1aa8c8d8 100644 --- a/Src/libCZI/CziUtils.cpp +++ b/Src/libCZI/CziUtils.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include #include "CziUtils.h" diff --git a/Src/libCZI/CziWriter.cpp b/Src/libCZI/CziWriter.cpp index 779f8a08..60c7a237 100644 --- a/Src/libCZI/CziWriter.cpp +++ b/Src/libCZI/CziWriter.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "CziWriter.h" #include "CziMetadataSegment.h" #include "libCZI_Utilities.h" diff --git a/Src/libCZI/DimCoordinate.cpp b/Src/libCZI/DimCoordinate.cpp index 799513dd..cb7e9b64 100644 --- a/Src/libCZI/DimCoordinate.cpp +++ b/Src/libCZI/DimCoordinate.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "libCZI.h" #include #include diff --git a/Src/libCZI/IndexSet.cpp b/Src/libCZI/IndexSet.cpp index 890bb6e8..92b4be1e 100644 --- a/Src/libCZI/IndexSet.cpp +++ b/Src/libCZI/IndexSet.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "IndexSet.h" #include "utilities.h" diff --git a/Src/libCZI/MD5Sum.cpp b/Src/libCZI/MD5Sum.cpp index 8f4be46b..d2387e6f 100644 --- a/Src/libCZI/MD5Sum.cpp +++ b/Src/libCZI/MD5Sum.cpp @@ -23,7 +23,6 @@ These notices must be retained in any copies of any part of this documentation and/or software. */ -#include "stdafx.h" #include #include "MD5Sum.h" diff --git a/Src/libCZI/MultiChannelCompositor.cpp b/Src/libCZI/MultiChannelCompositor.cpp index e95b053b..4e5a2972 100644 --- a/Src/libCZI/MultiChannelCompositor.cpp +++ b/Src/libCZI/MultiChannelCompositor.cpp @@ -2,8 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" - #include "MultiChannelCompositor.h" #include "libCZI_Utilities.h" #include diff --git a/Src/libCZI/SingleChannelAccessorBase.cpp b/Src/libCZI/SingleChannelAccessorBase.cpp index de6e2ab7..91252188 100644 --- a/Src/libCZI/SingleChannelAccessorBase.cpp +++ b/Src/libCZI/SingleChannelAccessorBase.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "SingleChannelAccessorBase.h" #include "BitmapOperations.h" diff --git a/Src/libCZI/SingleChannelPyramidLevelTileAccessor.cpp b/Src/libCZI/SingleChannelPyramidLevelTileAccessor.cpp index 0c03aa15..e162e3a7 100644 --- a/Src/libCZI/SingleChannelPyramidLevelTileAccessor.cpp +++ b/Src/libCZI/SingleChannelPyramidLevelTileAccessor.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include #include "SingleChannelPyramidLevelTileAccessor.h" #include "utilities.h" diff --git a/Src/libCZI/SingleChannelScalingTileAccessor.cpp b/Src/libCZI/SingleChannelScalingTileAccessor.cpp index 3a32971b..881e9026 100644 --- a/Src/libCZI/SingleChannelScalingTileAccessor.cpp +++ b/Src/libCZI/SingleChannelScalingTileAccessor.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "SingleChannelScalingTileAccessor.h" #include "utilities.h" #include "BitmapOperations.h" diff --git a/Src/libCZI/SingleChannelTileAccessor.cpp b/Src/libCZI/SingleChannelTileAccessor.cpp index 07259a3f..d58452d2 100644 --- a/Src/libCZI/SingleChannelTileAccessor.cpp +++ b/Src/libCZI/SingleChannelTileAccessor.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "SingleChannelTileAccessor.h" #include "CziUtils.h" #include "utilities.h" diff --git a/Src/libCZI/SingleChannelTileCompositor.cpp b/Src/libCZI/SingleChannelTileCompositor.cpp index a093d892..514dfde3 100644 --- a/Src/libCZI/SingleChannelTileCompositor.cpp +++ b/Src/libCZI/SingleChannelTileCompositor.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "libCZI.h" #include "SingleChannelTileCompositor.h" #include "BitmapOperations.h" diff --git a/Src/libCZI/StreamImpl.cpp b/Src/libCZI/StreamImpl.cpp index b642aaa5..59923e2f 100644 --- a/Src/libCZI/StreamImpl.cpp +++ b/Src/libCZI/StreamImpl.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "StreamImpl.h" #include #include diff --git a/Src/libCZI/decoder.cpp b/Src/libCZI/decoder.cpp index 9e853768..1284be3b 100644 --- a/Src/libCZI/decoder.cpp +++ b/Src/libCZI/decoder.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "decoder.h" #include "../JxrDecode/JxrDecode.h" #include "../JxrDecode/JxrDecode2.h" diff --git a/Src/libCZI/decoder_wic.cpp b/Src/libCZI/decoder_wic.cpp index fed567bd..720343de 100644 --- a/Src/libCZI/decoder_wic.cpp +++ b/Src/libCZI/decoder_wic.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #if defined(_WIN32) #include "decoder_wic.h" #include "BitmapOperations.h" diff --git a/Src/libCZI/decoder_zstd.cpp b/Src/libCZI/decoder_zstd.cpp index ea040171..633e801c 100644 --- a/Src/libCZI/decoder_zstd.cpp +++ b/Src/libCZI/decoder_zstd.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "decoder_zstd.h" #include #if (ZSTD_VERSION_MAJOR >= 1 && ZSTD_VERSION_MINOR >= 5) diff --git a/Src/libCZI/libCZI_Lib.cpp b/Src/libCZI/libCZI_Lib.cpp index 12af5cb4..b5ae5978 100644 --- a/Src/libCZI/libCZI_Lib.cpp +++ b/Src/libCZI/libCZI_Lib.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "libCZI.h" #include "CZIReader.h" #include "CziMetadata.h" diff --git a/Src/libCZI/libCZI_Site.cpp b/Src/libCZI/libCZI_Site.cpp index bed37ff8..5aa84264 100644 --- a/Src/libCZI/libCZI_Site.cpp +++ b/Src/libCZI/libCZI_Site.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "libCZI.h" #include "decoder.h" #include "decoder_zstd.h" diff --git a/Src/libCZI/libCZI_Utilities.cpp b/Src/libCZI/libCZI_Utilities.cpp index 455b612e..5363ea99 100644 --- a/Src/libCZI/libCZI_Utilities.cpp +++ b/Src/libCZI/libCZI_Utilities.cpp @@ -2,8 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" - #include "libCZI.h" #include "Site.h" #include "BitmapOperations.h" diff --git a/Src/libCZI/splines.cpp b/Src/libCZI/splines.cpp index 82e9f216..c1b8c483 100644 --- a/Src/libCZI/splines.cpp +++ b/Src/libCZI/splines.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "splines.h" #include #include diff --git a/Src/libCZI/stdAllocator.cpp b/Src/libCZI/stdAllocator.cpp index 90a44e03..0ba99859 100644 --- a/Src/libCZI/stdAllocator.cpp +++ b/Src/libCZI/stdAllocator.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "stdAllocator.h" #include #include diff --git a/Src/libCZI/utilities.cpp b/Src/libCZI/utilities.cpp index fbcbd032..6fd626ea 100644 --- a/Src/libCZI/utilities.cpp +++ b/Src/libCZI/utilities.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include "utilities.h" #include #include diff --git a/Src/libCZI/utilities_simd.cpp b/Src/libCZI/utilities_simd.cpp index a66fb6d4..33cbe0fd 100644 --- a/Src/libCZI/utilities_simd.cpp +++ b/Src/libCZI/utilities_simd.cpp @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" #include #include #include "inc_libCZI_Config.h" diff --git a/Src/libCZI/zstdCompress.cpp b/Src/libCZI/zstdCompress.cpp index 1a6a4c9c..f2fe815c 100644 --- a/Src/libCZI/zstdCompress.cpp +++ b/Src/libCZI/zstdCompress.cpp @@ -2,8 +2,6 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "stdafx.h" - #include #include #include From 1b91ac01942434cc376e6f7b27b49a3a2b00b929 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 27 Aug 2023 22:59:20 +0200 Subject: [PATCH 59/98] cosmetic --- Src/libCZI/CziAttachmentsDirectory.cpp | 3 --- Src/libCZI/CziStructs.h | 2 -- Src/libCZI/StreamImpl.h | 2 +- Src/libCZI/libCZI.h | 6 +++--- Src/libCZI/libCZI_Helpers.h | 4 ++-- 5 files changed, 6 insertions(+), 11 deletions(-) diff --git a/Src/libCZI/CziAttachmentsDirectory.cpp b/Src/libCZI/CziAttachmentsDirectory.cpp index 8da6ef2f..a3988a44 100644 --- a/Src/libCZI/CziAttachmentsDirectory.cpp +++ b/Src/libCZI/CziAttachmentsDirectory.cpp @@ -6,8 +6,6 @@ /*static*/bool CCziAttachmentsDirectoryBase::CompareForEquality_Id(const AttachmentEntry& a, const AttachmentEntry& b) { - //int r = memcmp(&a.ContentGuid, &b.ContentGuid, sizeof(GUID)); - //if (r != 0) if (a.ContentGuid != b.ContentGuid) { return false; @@ -90,7 +88,6 @@ bool CWriterCziAttachmentsDirectory::AttachmentEntriesCompare::operator()(const { // we shall return true if a is considered to go before b in the strict weak ordering the function defines int r = a.ContentGuid.compare(b.ContentGuid); - // int r = memcmp(&a.ContentGuid, &b.ContentGuid, sizeof(GUID)); if (r < 0) { return true; diff --git a/Src/libCZI/CziStructs.h b/Src/libCZI/CziStructs.h index 47ebcf9c..9c192b73 100644 --- a/Src/libCZI/CziStructs.h +++ b/Src/libCZI/CziStructs.h @@ -4,8 +4,6 @@ #pragma once -//#include "priv_guiddef.h" -// TODO: we need a platform-independent replacement for GUID #include "libCZI_Utilities.h" #if !defined(__GNUC__) diff --git a/Src/libCZI/StreamImpl.h b/Src/libCZI/StreamImpl.h index ca530eef..c5f2810c 100644 --- a/Src/libCZI/StreamImpl.h +++ b/Src/libCZI/StreamImpl.h @@ -9,7 +9,7 @@ #include "inc_libCZI_Config.h" #include #if defined(_WIN32) - #include + #include #endif /// A simplistic stream implementation (based on C-runtime fopen). Note that this implementation is NOT thread-safe. diff --git a/Src/libCZI/libCZI.h b/Src/libCZI/libCZI.h index bc7c1c5a..0ad89265 100644 --- a/Src/libCZI/libCZI.h +++ b/Src/libCZI/libCZI.h @@ -326,9 +326,9 @@ namespace libCZI /// Information about an attachment. struct AttachmentInfo { - libCZI::GUID contentGuid; ///< A Guid identifying the content of the attachment. - char contentFileType[9]; ///< A null-terminated character array identifying the content of the attachment. - std::string name; ///< A string identifying the content of the attachment. + libCZI::GUID contentGuid; ///< A Guid identifying the content of the attachment. + char contentFileType[9]; ///< A null-terminated character array identifying the content of the attachment. + std::string name; ///< A string identifying the content of the attachment. }; /// Representation of an attachment. An attachment is a binary blob, its inner structure is opaque. diff --git a/Src/libCZI/libCZI_Helpers.h b/Src/libCZI/libCZI_Helpers.h index 0b9a383c..da6b9ee3 100644 --- a/Src/libCZI/libCZI_Helpers.h +++ b/Src/libCZI/libCZI_Helpers.h @@ -141,7 +141,7 @@ namespace libCZI this->lutStore.clear(); } - void AddChannelSetting(int chIdx, const libCZI::IChannelDisplaySetting* chDsplSetting, std::function getPixelTypeForChannelIndex) + void AddChannelSetting(int chIdx, const libCZI::IChannelDisplaySetting* chDsplSetting, const std::function& getPixelTypeForChannelIndex) { // Note that we only add this channel IF IT IS ENABLED. If not, we DO NOT and MUST NOT call the // "getPixelTypeForChannelIndex"-callback! @@ -190,7 +190,7 @@ namespace libCZI this->activeChannels.push_back(chIdx); } - static int GetSizeForLUT(int chIdx, std::function getPixelTypeForChannelIndex) + static int GetSizeForLUT(int chIdx, const std::function& getPixelTypeForChannelIndex) { libCZI::PixelType pxlType = getPixelTypeForChannelIndex(chIdx); switch (pxlType) From 5635d54614af7e755437bbc6625cb1156a058e89 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 27 Aug 2023 23:05:53 +0200 Subject: [PATCH 60/98] fix --- Src/libCZI/BitmapOperations.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Src/libCZI/BitmapOperations.hpp b/Src/libCZI/BitmapOperations.hpp index 8380a456..d066b9d5 100644 --- a/Src/libCZI/BitmapOperations.hpp +++ b/Src/libCZI/BitmapOperations.hpp @@ -8,6 +8,7 @@ #include "CziUtils.h" #include +#include #if defined(_DEBUG) #include #endif From a90f32b6134dd6b0540462426d43ae26b6c3f0bb Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 27 Aug 2023 23:07:54 +0200 Subject: [PATCH 61/98] fix --- Src/libCZI/CziAttachmentsDirectory.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Src/libCZI/CziAttachmentsDirectory.cpp b/Src/libCZI/CziAttachmentsDirectory.cpp index a3988a44..ac759e43 100644 --- a/Src/libCZI/CziAttachmentsDirectory.cpp +++ b/Src/libCZI/CziAttachmentsDirectory.cpp @@ -3,6 +3,7 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include "CziAttachmentsDirectory.h" +#include /*static*/bool CCziAttachmentsDirectoryBase::CompareForEquality_Id(const AttachmentEntry& a, const AttachmentEntry& b) { From 683bb1909bf345f92af7b851d78942edfcd273f2 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Mon, 28 Aug 2023 23:45:31 +0200 Subject: [PATCH 62/98] remove "printf's" --- Src/JxrDecode/CMakeLists.txt | 4 +- Src/JxrDecode/jxrlib/common/include/log.h | 22 +++++++++ Src/JxrDecode/jxrlib/common/src/log.c | 42 +++++++++++++++++ Src/JxrDecode/jxrlib/image/decode/decode.c | 3 +- .../jxrlib/image/decode/postprocess.c | 4 +- Src/JxrDecode/jxrlib/image/decode/strdec.c | 23 +++++----- Src/JxrDecode/jxrlib/image/encode/encode.c | 8 ---- Src/JxrDecode/jxrlib/image/encode/segenc.c | 8 ---- Src/JxrDecode/jxrlib/image/encode/strenc.c | 45 ++++++++----------- Src/JxrDecode/jxrlib/image/sys/image.c | 7 --- Src/JxrDecode/jxrlib/image/sys/strcodec.c | 7 --- .../jxrlib/image/sys/windowsmediaphoto.h | 6 +-- Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c | 2 +- 13 files changed, 106 insertions(+), 75 deletions(-) create mode 100644 Src/JxrDecode/jxrlib/common/include/log.h create mode 100644 Src/JxrDecode/jxrlib/common/src/log.c diff --git a/Src/JxrDecode/CMakeLists.txt b/Src/JxrDecode/CMakeLists.txt index 79ebeb1f..23b40e1e 100644 --- a/Src/JxrDecode/CMakeLists.txt +++ b/Src/JxrDecode/CMakeLists.txt @@ -69,6 +69,8 @@ add_library(JxrDecodeStatic OBJECT "JxrDecode2.cpp" "jxrlib/common/include/guiddef.h" + "jxrlib/common/include/log.h" + "jxrlib/common/src/log.c" #"jxrlib/common/include/wmspecstring.h" #"jxrlib/common/include/wmspecstrings_adt.h" @@ -104,7 +106,7 @@ add_library(JxrDecodeStatic OBJECT "jxrlib/jxrgluelib/JXRGlueJxr.c" "jxrlib/jxrgluelib/JXRMeta.h" "jxrlib/jxrgluelib/JXRMeta.c" - "jxrlib/jxrgluelib/JXRGluePFC.c") + "jxrlib/jxrgluelib/JXRGluePFC.c" "jxrlib/common/include/log.h" "jxrlib/common/src/log.c") # prepare the configuration-file "JxrDecode_Config.h" diff --git a/Src/JxrDecode/jxrlib/common/include/log.h b/Src/JxrDecode/jxrlib/common/include/log.h new file mode 100644 index 00000000..b333175f --- /dev/null +++ b/Src/JxrDecode/jxrlib/common/include/log.h @@ -0,0 +1,22 @@ +#ifndef JXRLIB_COMMON_INCLUDE_LOG_H_ +#define JXRLIB_COMMON_INCLUDE_LOG_H_ + +#if __cplusplus +extern "C" { +#endif + + typedef enum { + JXR_LOG_LEVEL_INFO, + JXR_LOG_LEVEL_WARNING, + JXR_LOG_LEVEL_ERROR + } JxrLogLevel; + + void JxrLibLog(JxrLogLevel log_level, const char* format, ...); + + void SetJxrLogFunction(void (*log_func)(JxrLogLevel log_level, const char* log_text)); + +#if __cplusplus +} // extern "C" +#endif + +#endif // JXRLIB_COMMON_INCLUDE_LOG_H_ diff --git a/Src/JxrDecode/jxrlib/common/src/log.c b/Src/JxrDecode/jxrlib/common/src/log.c new file mode 100644 index 00000000..6c4474bd --- /dev/null +++ b/Src/JxrDecode/jxrlib/common/src/log.c @@ -0,0 +1,42 @@ +#include "../include/log.h" + +#include +#include +#include + +static void (*g_pfn_log_func)(JxrLogLevel, const char*) = NULL; + +void JxrLibLog(JxrLogLevel log_level, const char* format, ...) +{ + void (*log_func)(JxrLogLevel, const char*) = g_pfn_log_func; + if (log_func == NULL) + { + return; + } + + va_list args; + va_start(args, format); + char string_on_stack[1024]; + int length = vsnprintf(string_on_stack,sizeof(string_on_stack), format, args); + if (length + 1 > sizeof(string_on_stack)) + { + char* string_on_heap = (char*)malloc(length + 1); + if (string_on_heap != NULL) + { + vsnprintf(string_on_heap, length + 1, format, args); + log_func(log_level, string_on_heap); + free(string_on_heap); + } + } + else + { + log_func(log_level, string_on_stack); + } + + va_end(args); +} + +void SetJxrLogFunction(void (*log_func)(JxrLogLevel log_level, const char* log_text)) +{ + g_pfn_log_func = log_func; +} \ No newline at end of file diff --git a/Src/JxrDecode/jxrlib/image/decode/decode.c b/Src/JxrDecode/jxrlib/image/decode/decode.c index e0940b0c..c6ff690d 100644 --- a/Src/JxrDecode/jxrlib/image/decode/decode.c +++ b/Src/JxrDecode/jxrlib/image/decode/decode.c @@ -39,6 +39,7 @@ Revision History: *******************************************************************************/ #include "../sys/strcodec.h" #include "decode.h" +#include "../../common/include/log.h" /****************************************************************** Free Adaptive Huffman Table @@ -94,7 +95,7 @@ static Int InitializeAH(CAdaptiveHuffman** ppAdHuff, Int iSym) } *ppAdHuff = NULL; if (-1 == iMemStatus) { - printf("Insufficient memory to init decoder.\n"); + JxrLibLog(JXR_LOG_LEVEL_ERROR, "Insufficient memory to init decoder.\n"); } return ICERR_ERROR; } diff --git a/Src/JxrDecode/jxrlib/image/decode/postprocess.c b/Src/JxrDecode/jxrlib/image/decode/postprocess.c index ee9029a7..3c8f5854 100644 --- a/Src/JxrDecode/jxrlib/image/decode/postprocess.c +++ b/Src/JxrDecode/jxrlib/image/decode/postprocess.c @@ -58,7 +58,7 @@ Int initPostProc(struct tagPostProcInfo* strPostProcInfo[MAX_CHANNELS][2], size_ 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 (b32bit) // integer overflow/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)); @@ -274,7 +274,7 @@ Void postProcBlock(struct tagPostProcInfo* strPostProcInfo[MAX_CHANNELS][2], Pix } } - // two horizontally adjacent blocks have same texture and similiar DCs + // two horizontally adjacent blocks have same texture and similar 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; diff --git a/Src/JxrDecode/jxrlib/image/decode/strdec.c b/Src/JxrDecode/jxrlib/image/decode/strdec.c index 4388021e..81b5babe 100644 --- a/Src/JxrDecode/jxrlib/image/decode/strdec.c +++ b/Src/JxrDecode/jxrlib/image/decode/strdec.c @@ -28,6 +28,7 @@ #include "../sys/strcodec.h" #include "decode.h" #include "../sys/strTransform.h" +#include "../../common/include/log.h" #include #ifdef X86OPT_INLINE @@ -2501,35 +2502,35 @@ Int StrIODecInit(CWMImageStrCodec* pSC) if (pSC->WMISCP.bVerbose) { U32 i, j; - printf("\n%d horizontal tiles:\n", pSC->WMISCP.cNumOfSliceMinus1H + 1); + JxrLibLog(JXR_LOG_LEVEL_INFO, "\n%d horizontal tiles:\n", pSC->WMISCP.cNumOfSliceMinus1H + 1); for (i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1H; i++) { - printf(" offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileY[i]); + JxrLibLog(JXR_LOG_LEVEL_INFO, " offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileY[i]); } - printf("\n%d vertical tiles:\n", pSC->WMISCP.cNumOfSliceMinus1V + 1); + JxrLibLog(JXR_LOG_LEVEL_INFO, "\n%d vertical tiles:\n", pSC->WMISCP.cNumOfSliceMinus1V + 1); for (i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i++) { - printf(" offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileX[i]); + JxrLibLog(JXR_LOG_LEVEL_INFO, " offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileX[i]); } if (pSC->WMISCP.bfBitstreamFormat == SPATIAL) { - printf("\nSpatial order bitstream\n"); + JxrLibLog(JXR_LOG_LEVEL_INFO, "\nSpatial order bitstream\n"); } else { - printf("\nFrequency order bitstream\n"); + JxrLibLog(JXR_LOG_LEVEL_INFO, "\nFrequency order bitstream\n"); } if (!pSC->m_param.bIndexTable) { - printf("\nstreaming mode, no index table.\n"); + JxrLibLog(JXR_LOG_LEVEL_INFO, "\nstreaming mode, no index table.\n"); } else if (pSC->WMISCP.bfBitstreamFormat == SPATIAL) { for (j = 0; j <= pSC->WMISCP.cNumOfSliceMinus1H; j++) { for (i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i++) { size_t* p = &pSC->pIndexTable[j * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + i]; if (i + j != pSC->WMISCP.cNumOfSliceMinus1H + pSC->WMISCP.cNumOfSliceMinus1V) { - printf("bitstream size for tile (%d, %d): %d.\n", j, i, (int)(p[1] - p[0])); + JxrLibLog(JXR_LOG_LEVEL_INFO, "bitstream size for tile (%d, %d): %d.\n", j, i, (int)(p[1] - p[0])); } else { - printf("bitstream size for tile (%d, %d): unknown.\n", j, i); + JxrLibLog(JXR_LOG_LEVEL_INFO, "bitstream size for tile (%d, %d): unknown.\n", j, i); } } } @@ -2539,11 +2540,11 @@ Int StrIODecInit(CWMImageStrCodec* pSC) for (i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i++) { size_t* p = &pSC->pIndexTable[(j * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + i) * 4]; if (i + j != pSC->WMISCP.cNumOfSliceMinus1H + pSC->WMISCP.cNumOfSliceMinus1V) { - printf("bitstream size of (DC, LP, AC, FL) for tile (%d, %d): %d %d %d %d.\n", j, i, + JxrLibLog(JXR_LOG_LEVEL_INFO, "bitstream size of (DC, LP, AC, FL) for tile (%d, %d): %d %d %d %d.\n", j, i, (int)(p[1] - p[0]), (int)(p[2] - p[1]), (int)(p[3] - p[2]), (int)(p[4] - p[3])); } else { - printf("bitstream size of (DC, LP, AC, FL) for tile (%d, %d): %d %d %d unknown.\n", j, i, + JxrLibLog(JXR_LOG_LEVEL_INFO, "bitstream size of (DC, LP, AC, FL) for tile (%d, %d): %d %d %d unknown.\n", j, i, (int)(p[1] - p[0]), (int)(p[2] - p[1]), (int)(p[3] - p[2])); } } diff --git a/Src/JxrDecode/jxrlib/image/encode/encode.c b/Src/JxrDecode/jxrlib/image/encode/encode.c index 404a1159..abfd49c2 100644 --- a/Src/JxrDecode/jxrlib/image/encode/encode.c +++ b/Src/JxrDecode/jxrlib/image/encode/encode.c @@ -26,19 +26,11 @@ // //*@@@---@@@@****************************************************************** -#include #include #include "encode.h" #include "../sys/strcodec.h" #include "../sys/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 diff --git a/Src/JxrDecode/jxrlib/image/encode/segenc.c b/Src/JxrDecode/jxrlib/image/encode/segenc.c index 9a703ed7..ec826151 100644 --- a/Src/JxrDecode/jxrlib/image/encode/segenc.c +++ b/Src/JxrDecode/jxrlib/image/encode/segenc.c @@ -26,18 +26,10 @@ // //*@@@---@@@@****************************************************************** -#include #include #include "../sys/strcodec.h" #include "encode.h" -#ifdef MEM_TRACE -#define TRACE_MALLOC 1 -#define TRACE_NEW 0 -#define TRACE_HEAP 0 -#include "memtrace.h" -#endif - /** local function definitions **/ #ifdef X86OPT_INLINE __forceinline diff --git a/Src/JxrDecode/jxrlib/image/encode/strenc.c b/Src/JxrDecode/jxrlib/image/encode/strenc.c index 9024f6ba..c11b0456 100644 --- a/Src/JxrDecode/jxrlib/image/encode/strenc.c +++ b/Src/JxrDecode/jxrlib/image/encode/strenc.c @@ -28,15 +28,8 @@ #include "../sys/strcodec.h" #include "encode.h" #include "../sys/strTransform.h" +#include "../../common/include/log.h" #include -//#include "perfTimer.h" - -#ifdef MEM_TRACE -#define TRACE_MALLOC 1 -#define TRACE_NEW 0 -#define TRACE_HEAP 0 -#include "memtrace.h" -#endif #ifdef ADI_SYS_OPT extern char L1WW[]; @@ -628,30 +621,30 @@ Int StrIOEncTerm(CWMImageStrCodec* pSC) if (pSC->WMISCP.bVerbose) { U32 i, j; - printf("\n%d horizontal tiles:\n", pSC->WMISCP.cNumOfSliceMinus1H + 1); + JxrLibLog(JXR_LOG_LEVEL_INFO, "\n%d horizontal tiles:\n", pSC->WMISCP.cNumOfSliceMinus1H + 1); for (i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1H; i++) { - printf(" offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileY[i]); + JxrLibLog(JXR_LOG_LEVEL_INFO, " offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileY[i]); } - printf("\n%d vertical tiles:\n", pSC->WMISCP.cNumOfSliceMinus1V + 1); + JxrLibLog(JXR_LOG_LEVEL_INFO, "\n%d vertical tiles:\n", pSC->WMISCP.cNumOfSliceMinus1V + 1); for (i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i++) { - printf(" offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileX[i]); + JxrLibLog(JXR_LOG_LEVEL_INFO, " offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileX[i]); } if (pSC->WMISCP.bfBitstreamFormat == SPATIAL) { - printf("\nSpatial order bitstream\n"); + JxrLibLog(JXR_LOG_LEVEL_INFO, "\nSpatial order bitstream\n"); } else { - printf("\nFrequency order bitstream\n"); + JxrLibLog(JXR_LOG_LEVEL_INFO, "\nFrequency order bitstream\n"); } if (!pSC->m_param.bIndexTable) { - printf("\nstreaming mode, no index table.\n"); + JxrLibLog(JXR_LOG_LEVEL_INFO, "\nstreaming mode, no index table.\n"); } else if (pSC->WMISCP.bfBitstreamFormat == SPATIAL) { for (j = 0; j <= pSC->WMISCP.cNumOfSliceMinus1H; j++) { for (i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i++) { - printf("bitstream size for tile (%d, %d): %d.\n", j, i, (int)pSC->pIndexTable[j * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + i]); + JxrLibLog(JXR_LOG_LEVEL_INFO, "bitstream size for tile (%d, %d): %d.\n", j, i, (int)pSC->pIndexTable[j * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + i]); } } } @@ -659,7 +652,7 @@ Int StrIOEncTerm(CWMImageStrCodec* pSC) for (j = 0; j <= pSC->WMISCP.cNumOfSliceMinus1H; j++) { for (i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i++) { size_t* p = &pSC->pIndexTable[(j * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + i) * 4]; - printf("bitstream size of (DC, LP, AC, FL) for tile (%d, %d): %d %d %d %d.\n", j, i, + JxrLibLog(JXR_LOG_LEVEL_INFO, "bitstream size of (DC, LP, AC, FL) for tile (%d, %d): %d %d %d %d.\n", j, i, (int)p[0], (int)p[1], (int)p[2], (int)p[3]); } } @@ -1190,12 +1183,12 @@ Int ValidateArgs(CWMImageInfo* pII, CWMIStrCodecParam* pSCP) Bool bTooNarrowTile = FALSE; if (pII->cWidth > (1 << 28) || pII->cHeight > (1 << 28) || pII->cWidth == 0 || pII->cHeight == 0) { - printf("Unsurpported image size!\n"); + JxrLibLog(JXR_LOG_LEVEL_INFO, "Unsurpported image size!\n"); return ICERR_ERROR; // unsurpported image size } if (((pSCP->cfColorFormat == YUV_420) || (pSCP->cfColorFormat == YUV_422)) && (pSCP->olOverlap == OL_TWO) && ((Int)(((U32)pII->cWidth + 15) >> 4) < 2)) { - printf("Image width must be at least 2 MB wide for subsampled chroma and two levels of overlap!\n"); + JxrLibLog(JXR_LOG_LEVEL_INFO, "Image width must be at least 2 MB wide for subsampled chroma and two levels of overlap!\n"); return ICERR_ERROR; } @@ -1203,15 +1196,15 @@ Int ValidateArgs(CWMImageInfo* pII, CWMIStrCodecParam* pSCP) pSCP->sbSubband = SB_ALL; if (pII->bdBitDepth == BD_5 && (pII->cfColorFormat != CF_RGB || pII->cBitsPerUnit != 16 || pII->cLeadingPadding != 0)) { - printf("Unsupported BD_5 image format!\n"); + JxrLibLog(JXR_LOG_LEVEL_INFO, "Unsupported BD_5 image format!\n"); return ICERR_ERROR; // BD_5 must be compact RGB! } if (pII->bdBitDepth == BD_565 && (pII->cfColorFormat != CF_RGB || pII->cBitsPerUnit != 16 || pII->cLeadingPadding != 0)) { - printf("Unsupported BD_565 image format!\n"); + JxrLibLog(JXR_LOG_LEVEL_INFO, "Unsupported BD_565 image format!\n"); return ICERR_ERROR; // BD_5 must be compact RGB! } if (pII->bdBitDepth == BD_10 && (pII->cfColorFormat != CF_RGB || pII->cBitsPerUnit != 32 || pII->cLeadingPadding != 0)) { - printf("Unsupported BD_10 image format!\n"); + JxrLibLog(JXR_LOG_LEVEL_INFO, "Unsupported BD_10 image format!\n"); return ICERR_ERROR; // BD_10 must be compact RGB! } @@ -1221,7 +1214,7 @@ Int ValidateArgs(CWMImageInfo* pII, CWMIStrCodecParam* pSCP) if (BD_1 == pII->bdBitDepth) { // binary image if (pII->cfColorFormat != Y_ONLY) { - printf("BD_1 image must be black-and white!\n"); + JxrLibLog(JXR_LOG_LEVEL_INFO, "BD_1 image must be black-and white!\n"); return ICERR_ERROR; } pSCP->cfColorFormat = Y_ONLY; // can only be black white @@ -1234,13 +1227,13 @@ Int ValidateArgs(CWMImageInfo* pII, CWMIStrCodecParam* pSCP) || pII->bdBitDepth == BD_5 || pII->bdBitDepth == BD_10 || pII->bdBitDepth == BD_1)) { - printf("Alpha is not supported for this pixel format!\n"); + JxrLibLog(JXR_LOG_LEVEL_INFO, "Alpha is not supported for this pixel format!\n"); return ICERR_ERROR; } if ((pSCP->cfColorFormat == YUV_420 || pSCP->cfColorFormat == YUV_422) && (pII->bdBitDepth == BD_16F || pII->bdBitDepth == BD_32F || pII->cfColorFormat == CF_RGBE)) { - printf("Float or RGBE images must be encoded with YUV 444!\n"); + JxrLibLog(JXR_LOG_LEVEL_INFO, "Float or RGBE images must be encoded with YUV 444!\n"); return ICERR_ERROR; } @@ -1259,7 +1252,7 @@ Int ValidateArgs(CWMImageInfo* pII, CWMIStrCodecParam* pSCP) bTooNarrowTile = TRUE; } if (bTooNarrowTile) { - printf("Tile width must be at least 2 MB wide for hard tiles, subsampled chroma, and two levels of overlap!\n"); + JxrLibLog(JXR_LOG_LEVEL_INFO, "Tile width must be at least 2 MB wide for hard tiles, subsampled chroma, and two levels of overlap!\n"); return ICERR_ERROR; } diff --git a/Src/JxrDecode/jxrlib/image/sys/image.c b/Src/JxrDecode/jxrlib/image/sys/image.c index c8b3b17a..123a1c56 100644 --- a/Src/JxrDecode/jxrlib/image/sys/image.c +++ b/Src/JxrDecode/jxrlib/image/sys/image.c @@ -28,13 +28,6 @@ #include "strcodec.h" -#ifdef MEM_TRACE -#define TRACE_MALLOC 1 -#define TRACE_NEW 0 -#define TRACE_HEAP 0 -#include "memtrace.h" -#endif - #include #include diff --git a/Src/JxrDecode/jxrlib/image/sys/strcodec.c b/Src/JxrDecode/jxrlib/image/sys/strcodec.c index 29c93592..b1c676ae 100644 --- a/Src/JxrDecode/jxrlib/image/sys/strcodec.c +++ b/Src/JxrDecode/jxrlib/image/sys/strcodec.c @@ -38,13 +38,6 @@ #include #endif -#ifdef MEM_TRACE -#define TRACE_MALLOC 1 -#define TRACE_NEW 0 -#define TRACE_HEAP 0 -#include "memtrace.h" -#endif - //================================================================ // Quantization index tables //================================================================ diff --git a/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h b/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h index 84a4c464..88a904eb 100644 --- a/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h +++ b/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h @@ -35,6 +35,7 @@ #include #include #include +#include "../../common/include/log.h" #if defined(__cplusplus) && !defined(EXTERN_C) #define EXTERN_C extern "C" @@ -251,8 +252,8 @@ typedef long ERR; #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)); \ + JxrLibLog(JXR_LOG_LEVEL_ERROR, "FAILED: %ld=%s" CRLF, (err), (szExp)); \ + JxrLibLog(JXR_LOG_LEVEL_ERROR, " %s:%ld" CRLF, (szFile), (nLine)); \ #else #define Report(err, szExp, szFile, lLine) err = err @@ -539,4 +540,3 @@ EXTERN_C Int WMPhotoDetile( ); #endif // WMI_WINDOWSMEDIAPHOTO_H - diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c index 91f95ac2..8747a4eb 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c @@ -1746,7 +1746,7 @@ ERR ParsePFDEntry( break; default: - fprintf(stderr, "Unrecognized WMPTag: %d(%#x), %d, %d, %#x" CRLF, + JxrLibLog(JXR_LOG_LEVEL_WARNING, "Unrecognized WMPTag: %d(%#x), %d, %d, %#x" CRLF, (int)uTag, (int)uTag, (int)uType, (int)uCount, (int)uValue); break; } From 1e0949c8a90207e72a0370151bdece0a71948c94 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Tue, 29 Aug 2023 20:23:50 +0200 Subject: [PATCH 63/98] make gray32float work with jpxr --- Src/JxrDecode/JxrDecode2.cpp | 7 ++++ Src/JxrDecode/JxrDecode2.h | 2 +- Src/libCZI/decoder.cpp | 4 +- Src/libCZI_UnitTests/test_JxrDecode.cpp | 51 +++++++++++++++++++++++++ Src/libCZI_UnitTests/utils.cpp | 28 +++++++++++++- Src/libCZI_UnitTests/utils.h | 9 +++++ 6 files changed, 98 insertions(+), 3 deletions(-) diff --git a/Src/JxrDecode/JxrDecode2.cpp b/Src/JxrDecode/JxrDecode2.cpp index c3ed80af..d85a9a9e 100644 --- a/Src/JxrDecode/JxrDecode2.cpp +++ b/Src/JxrDecode/JxrDecode2.cpp @@ -123,6 +123,9 @@ JxrDecode2::CompressedData JxrDecode2::Encode( case PixelFormat::kGray16: err = pEncoder->SetPixelFormat(pEncoder, GUID_PKPixelFormat16bppGray); break; + case PixelFormat::kGray32Float: + err = pEncoder->SetPixelFormat(pEncoder, GUID_PKPixelFormat32bppGrayFloat); + break; } //err = pEncoder->SetPixelFormat(pEncoder, GUID_PKPixelFormat24bppBGR); err = pEncoder->SetSize(pEncoder, width, height); @@ -334,6 +337,10 @@ JxrDecode2::PixelFormat JxrPixelFormatGuidToEnum(const GUID& guid) { return JxrDecode2::PixelFormat::kBgr48; } + else if (IsEqualGUID(guid, GUID_PKPixelFormat32bppGrayFloat)) + { + return JxrDecode2::PixelFormat::kGray32Float; + } return JxrDecode2::PixelFormat::kInvalid; } diff --git a/Src/JxrDecode/JxrDecode2.h b/Src/JxrDecode/JxrDecode2.h index 1bdb9682..c3dc14a2 100644 --- a/Src/JxrDecode/JxrDecode2.h +++ b/Src/JxrDecode/JxrDecode2.h @@ -15,7 +15,7 @@ class JxrDecode2 kBgr48, kGray8, kGray16, - _32bppGrayFloat, + kGray32Float, /*dontCare, _24bppBGR, _1bppBlackWhite, diff --git a/Src/libCZI/decoder.cpp b/Src/libCZI/decoder.cpp index 1284be3b..9ef7e422 100644 --- a/Src/libCZI/decoder.cpp +++ b/Src/libCZI/decoder.cpp @@ -45,6 +45,8 @@ static libCZI::PixelType PixelTypeFromJxrPixelFormat(JxrDecode2::PixelFormat pix return PixelType::Bgr48; case JxrDecode2::PixelFormat::kGray16: return PixelType::Gray16; + case JxrDecode2::PixelFormat::kGray32Float: + return PixelType::Gray32Float; default: return PixelType::Invalid; } @@ -74,7 +76,7 @@ std::shared_ptr CJxrLibDecoder::Encode(libCZI::PixelType p jxrdecode_pixel_format = JxrDecode2::PixelFormat::kGray16; break; case PixelType::Gray32Float: - jxrdecode_pixel_format = JxrDecode2::PixelFormat::_32bppGrayFloat; + jxrdecode_pixel_format = JxrDecode2::PixelFormat::kGray32Float; break; default: throw std::logic_error("unsupported pixel type"); diff --git a/Src/libCZI_UnitTests/test_JxrDecode.cpp b/Src/libCZI_UnitTests/test_JxrDecode.cpp index c7aa53a9..9ce6f88a 100644 --- a/Src/libCZI_UnitTests/test_JxrDecode.cpp +++ b/Src/libCZI_UnitTests/test_JxrDecode.cpp @@ -198,6 +198,57 @@ TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Gray16) EXPECT_TRUE(are_equal) << "Original bitmap and encoded-decoded one are not identical."; } +TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Gray32Float) +{ + const auto bitmap_gray32float = CBitmapData::Create(PixelType::Gray32Float, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); + { + const auto bitmap_bgr24 = CBitmapData::Create(PixelType::Bgr24, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); + const ScopedBitmapLockerSP locked_bgr24{ bitmap_bgr24 }; + const ScopedBitmapLockerSP locked_gray16{ bitmap_gray32float }; + CTestImage::CopyBgr24Image(locked_bgr24.ptrDataRoi, bitmap_bgr24->GetWidth(), bitmap_bgr24->GetHeight(), locked_bgr24.stride); + for (size_t y = 0; y < bitmap_bgr24->GetHeight(); ++y) + { + for (size_t x = 0; x < bitmap_bgr24->GetWidth(); ++x) + { + const auto bgr24_pixel = &static_cast(locked_bgr24.ptrDataRoi)[y * locked_bgr24.stride + x * 3]; + const auto gray32float_pixel = reinterpret_cast(&static_cast(locked_gray16.ptrDataRoi)[y * locked_gray16.stride + 4 * x]); + *gray32float_pixel = + bgr24_pixel[0] * 0.299f + + bgr24_pixel[1] * 0.587f + + bgr24_pixel[2] * 0.114f; + } + } + } + + const auto codec = CJxrLibDecoder::Create(); + shared_ptr encodedData; + + { + const ScopedBitmapLockerSP lck{ bitmap_gray32float }; + encodedData = codec->Encode( + bitmap_gray32float->GetPixelType(), + bitmap_gray32float->GetWidth(), + bitmap_gray32float->GetHeight(), + lck.stride, + lck.ptrDataRoi); + } + + void* encoded_data_ptr = encodedData->GetPtr(); + ASSERT_NE(encoded_data_ptr, nullptr) << "Encoded data is null."; + const size_t size_of_encoded_data = encodedData->GetSizeOfData(); + ASSERT_LT(size_of_encoded_data, static_cast(Utils::GetBytesPerPixel(bitmap_gray32float->GetPixelType()) * bitmap_gray32float->GetWidth() * bitmap_gray32float->GetHeight())) << + "Encoded data is too large (larger than the original data), which is unexpected."; + + const auto bitmap_decoded = codec->Decode( + encodedData->GetPtr(), + encodedData->GetSizeOfData(), + libCZI::PixelType::Gray32Float, + bitmap_gray32float->GetWidth(), + bitmap_gray32float->GetHeight()); + const bool are_equal = CompareGrayFloat32Bitmaps(bitmap_gray32float, bitmap_decoded, 0.01f); + EXPECT_TRUE(are_equal) << "Original bitmap and encoded-decoded one are not identical."; +} + TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Bgr48) { const auto bitmap_bgr48 = CBitmapData::Create(PixelType::Bgr48, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); diff --git a/Src/libCZI_UnitTests/utils.cpp b/Src/libCZI_UnitTests/utils.cpp index 88ebb26e..99eaf81d 100644 --- a/Src/libCZI_UnitTests/utils.cpp +++ b/Src/libCZI_UnitTests/utils.cpp @@ -427,7 +427,7 @@ bool AreBitmapDataEqual(const std::shared_ptr& bmp1, const { bool result = true; - if ((bmp1 != nullptr) && (bmp2 != nullptr)) + if (bmp1 && bmp2) { if ((bmp1->GetHeight() == bmp2->GetHeight()) && (bmp1->GetWidth() == bmp2->GetWidth()) && @@ -469,6 +469,32 @@ bool AreBitmapDataEqual(const std::shared_ptr& bmp1, const return result; } +bool CompareGrayFloat32Bitmaps(const std::shared_ptr& bmp1, const std::shared_ptr& bmp2, float max_difference) +{ + if (!bmp1 || !bmp2 || bmp1->GetWidth() != bmp2->GetWidth() || bmp1->GetHeight() != bmp2->GetHeight() || bmp1->GetPixelType() != bmp2->GetPixelType() || bmp1->GetPixelType() != PixelType::Gray32Float) + { + throw invalid_argument("Bitmaps must have the same size and pixel type, and must have pixeltype gray32float"); + } + + ScopedBitmapLockerSP lockBmp1{ bmp1 }; + ScopedBitmapLockerSP lockBmp2{ bmp2 }; + + for (uint32_t y = 0; y < bmp1->GetHeight(); y++) + { + const float* bitmap_a = reinterpret_cast(static_cast(lockBmp1.ptrDataRoi) + static_cast(y) * lockBmp1.stride); + const float* bitmap_b = reinterpret_cast(static_cast(lockBmp2.ptrDataRoi) + static_cast(y) * lockBmp2.stride); + for (uint32_t x = 0; x < bmp1->GetWidth(); x++) + { + if (abs(bitmap_a[x] - bitmap_b[x]) > max_difference) + { + return false; + } + } + } + + return true; +} + std::tuple CalculateMaxDifferenceMeanDifference(const std::shared_ptr& bmp1, const std::shared_ptr& bmp2) { float sumDifference = 0.0f; diff --git a/Src/libCZI_UnitTests/utils.h b/Src/libCZI_UnitTests/utils.h index ae58f926..af4defc8 100644 --- a/Src/libCZI_UnitTests/utils.h +++ b/Src/libCZI_UnitTests/utils.h @@ -54,6 +54,15 @@ std::shared_ptr GetZeissLogoBitmap(void); */ bool AreBitmapDataEqual(const std::shared_ptr& bmp1, const std::shared_ptr& bmp2); +/// Compare two bitmaps which must both be of pixel-type gray-float-32. The maximum allowed difference (per pixel) is given as a parameter. +/// +/// \param bmp1 The first bitmap. +/// \param bmp2 The second bitmap. +/// \param max_difference The maximum difference. +/// +/// \returns True if both bitmaps are equal (i.e. the difference for all pixels is less than the specified value); false otherwise. +bool CompareGrayFloat32Bitmaps(const std::shared_ptr& bmp1, const std::shared_ptr& bmp2, float max_difference); + /// Calculates the maximum difference and the mean difference of the pixel values of the two bitmaps. /// The two bitmaps must have the same size and pixel type, otherwise an exception is thrown. /// From 9a7d9b259618fee6736a15c3da44b296d91aecac Mon Sep 17 00:00:00 2001 From: ptahmose Date: Tue, 29 Aug 2023 23:27:40 +0200 Subject: [PATCH 64/98] add include / fix build error --- Src/libCZI/utilities.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Src/libCZI/utilities.cpp b/Src/libCZI/utilities.cpp index 6fd626ea..8b9930d5 100644 --- a/Src/libCZI/utilities.cpp +++ b/Src/libCZI/utilities.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #if !defined(_WIN32) #include #endif From 2853d5c618d0269e49c097844843548089656ca2 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Wed, 30 Aug 2023 01:23:57 +0200 Subject: [PATCH 65/98] cleanup & cosmetic --- Src/JxrDecode/JxrDecode2.cpp | 255 +++++++++++++------ Src/JxrDecode/JxrDecode2.h | 66 ++--- Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c | 11 +- Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c | 5 +- Src/libCZI/decoder.cpp | 19 +- Src/libCZI_UnitTests/test_JxrDecode.cpp | 69 ++++- 6 files changed, 293 insertions(+), 132 deletions(-) diff --git a/Src/JxrDecode/JxrDecode2.cpp b/Src/JxrDecode/JxrDecode2.cpp index d85a9a9e..95309179 100644 --- a/Src/JxrDecode/JxrDecode2.cpp +++ b/Src/JxrDecode/JxrDecode2.cpp @@ -11,12 +11,87 @@ using namespace std; static void ApplyQuality(float quality, JxrDecode2::PixelFormat pixel_format, std::uint32_t width, PKImageEncode* pEncoder); static JxrDecode2::PixelFormat JxrPixelFormatGuidToEnum(const GUID& guid); static void ThrowError(const char* error_message, ERR error_code); -static const char* ERR_to_string(ERR error_code); + +static const char* ERR_to_string(ERR error_code) +{ + switch (error_code) + { + case WMP_errSuccess:return "WMP_errSuccess"; + case WMP_errFail:return "WMP_errFail"; + case WMP_errNotYetImplemented:return "WMP_errNotYetImplemented"; + case WMP_errAbstractMethod:return "WMP_errAbstractMethod"; + case WMP_errOutOfMemory:return "WMP_errOutOfMemory"; + case WMP_errFileIO:return "WMP_errFileIO"; + case WMP_errBufferOverflow:return "WMP_errBufferOverflow"; + case WMP_errInvalidParameter:return "WMP_errInvalidParameter"; + case WMP_errInvalidArgument:return "WMP_errInvalidArgument"; + case WMP_errUnsupportedFormat:return "WMP_errUnsupportedFormat"; + case WMP_errIncorrectCodecVersion:return "WMP_errIncorrectCodecVersion"; + case WMP_errIndexNotFound:return "WMP_errIndexNotFound"; + case WMP_errOutOfSequence:return "WMP_errOutOfSequence"; + case WMP_errNotInitialized:return "WMP_errNotInitialized"; + case WMP_errMustBeMultipleOf16LinesUntilLastCall:return "WMP_errMustBeMultipleOf16LinesUntilLastCall"; + case WMP_errPlanarAlphaBandedEncRequiresTempFile:return "WMP_errPlanarAlphaBandedEncRequiresTempFile"; + case WMP_errAlphaModeCannotBeTranscoded:return "WMP_errAlphaModeCannotBeTranscoded"; + case WMP_errIncorrectCodecSubVersion:return "WMP_errIncorrectCodecSubVersion"; + } + + return nullptr; +} + +static JxrDecode2::PixelFormat JxrPixelFormatGuidToEnum(const GUID& guid) +{ + if (IsEqualGUID(guid, GUID_PKPixelFormat8bppGray)) + { + return JxrDecode2::PixelFormat::kGray8; + } + else if (IsEqualGUID(guid, GUID_PKPixelFormat16bppGray)) + { + return JxrDecode2::PixelFormat::kGray16; + } + else if (IsEqualGUID(guid, GUID_PKPixelFormat24bppBGR)) + { + return JxrDecode2::PixelFormat::kBgr24; + } + else if (IsEqualGUID(guid, GUID_PKPixelFormat48bppRGB)) + { + return JxrDecode2::PixelFormat::kBgr48; + } + else if (IsEqualGUID(guid, GUID_PKPixelFormat32bppGrayFloat)) + { + return JxrDecode2::PixelFormat::kGray32Float; + } + + return JxrDecode2::PixelFormat::kInvalid; +} + +static void WriteGuidToStream(ostringstream& string_stream, const GUID& guid) +{ + string_stream << std::uppercase; + string_stream.width(8); + string_stream << std::hex << guid.Data1 << '-'; + string_stream.width(4); + string_stream << std::hex << guid.Data2 << '-'; + string_stream.width(4); + string_stream << std::hex << guid.Data3 << '-'; + string_stream.width(2); + string_stream << std::hex + << static_cast(guid.Data4[0]) + << static_cast(guid.Data4[1]) + << '-' + << static_cast(guid.Data4[2]) + << static_cast(guid.Data4[3]) + << static_cast(guid.Data4[4]) + << static_cast(guid.Data4[5]) + << static_cast(guid.Data4[6]) + << static_cast(guid.Data4[7]); + string_stream << std::nouppercase; +} void JxrDecode2::Decode( const void* ptrData, size_t size, - const std::function(PixelFormat pixel_format, std::uint32_t width, std::uint32_t height)>& get_destination_func) + const std::function(PixelFormat pixel_format, std::uint32_t width, std::uint32_t height)>& get_destination_func) { if (ptrData == nullptr) { throw invalid_argument("ptrData"); } if (size == 0) { throw invalid_argument("size"); } @@ -24,17 +99,17 @@ void JxrDecode2::Decode( WMPStream* pStream; ERR err = CreateWS_Memory(&pStream, const_cast(ptrData), size); - if (Failed(err)) { ThrowError("'CreateWS_Memory' failed", err); } + if (Failed(err)) { ThrowJxrlibError("'CreateWS_Memory' failed", err); } unique_ptr upStream(pStream, [](WMPStream* p)->void {p->Close(&p); }); PKImageDecode* pDecoder; err = PKCodecFactory_CreateDecoderFromStream(pStream, &pDecoder); - if (Failed(err)) { ThrowError("'PKCodecFactory_CreateDecoderFromStream' failed", err); } + if (Failed(err)) { ThrowJxrlibError("'PKCodecFactory_CreateDecoderFromStream' failed", err); } std::unique_ptr upDecoder(pDecoder, [](PKImageDecode* p)->void {p->Release(&p); }); U32 frame_count; err = upDecoder->GetFrameCount(upDecoder.get(), &frame_count); - if (Failed(err)) { ThrowError("'decoder::GetFrameCount' failed", err); } + if (Failed(err)) { ThrowJxrlibError("'decoder::GetFrameCount' failed", err); } if (frame_count != 1) { ostringstream string_stream; @@ -44,14 +119,24 @@ void JxrDecode2::Decode( I32 width, height; upDecoder->GetSize(upDecoder.get(), &width, &height); - if (Failed(err)) { ThrowError("'decoder::GetSize' failed", err); } + if (Failed(err)) { ThrowJxrlibError("'decoder::GetSize' failed", err); } PKPixelFormatGUID pixel_format_of_decoder; upDecoder->GetPixelFormat(upDecoder.get(), &pixel_format_of_decoder); - if (Failed(err)) { ThrowError("'decoder::GetPixelFormat' failed", err); } + if (Failed(err)) { ThrowJxrlibError("'decoder::GetPixelFormat' failed", err); } + + const auto jxrpixel_format = JxrPixelFormatGuidToEnum(pixel_format_of_decoder); + if (jxrpixel_format == JxrDecode2::PixelFormat::kInvalid) + { + ostringstream string_stream; + string_stream << "Unsupported pixel format: {"; + WriteGuidToStream(string_stream, pixel_format_of_decoder); + string_stream << "}"; + throw runtime_error(string_stream.str()); + } const auto decode_info = get_destination_func( - JxrPixelFormatGuidToEnum(pixel_format_of_decoder), + jxrpixel_format, width, height); @@ -59,12 +144,12 @@ void JxrDecode2::Decode( err = upDecoder->Copy( upDecoder.get(), &rc, - static_cast(get<2>(decode_info)), + static_cast(get<0>(decode_info)), get<1>(decode_info)); - if (Failed(err)) { ThrowError("decoder::Copy failed", err); } + if (Failed(err)) { ThrowJxrlibError("decoder::Copy failed", err); } } -JxrDecode2::CompressedData JxrDecode2::Encode( +/*static*/JxrDecode2::CompressedData JxrDecode2::Encode( JxrDecode2::PixelFormat pixel_format, std::uint32_t width, std::uint32_t height, @@ -72,8 +157,29 @@ JxrDecode2::CompressedData JxrDecode2::Encode( const void* ptr_bitmap, float quality/*=1.f*/) { - PKImageEncode* pEncoder; - ERR err = PKCodecFactory_CreateCodec(&IID_PKImageWmpEncode, (void**)&pEncoder); + if (ptr_bitmap == nullptr) + { + throw invalid_argument("ptr_bitmap"); + } + + PKImageEncode* pImageEncoder; + ERR err = PKCodecFactory_CreateCodec(&IID_PKImageWmpEncode, reinterpret_cast(&pImageEncoder)); + if (Failed(err)) + { + ThrowJxrlibError("'PKCodecFactory_CreateCodec' failed", err); + } + + unique_ptr upImageEncoder( + pImageEncoder, + [](PKImageEncode* p)->void + { + // If we get here, we need to 'disassociate' the stream from the encoder, + // because this image-encode-object would otherwise try to destroy the stream-object. + // However, we want to keep the stream-object around, so we can return it to the caller + // (and, in case of leaving with an exception, the stream-object will be destroyed by the unique_ptr below). + p->pStream = nullptr; + p->Release(&p); + }); CWMIStrCodecParam codec_parameters = {}; //codec_parameters.guidPixFormat = GUID_PKPixelFormat24bppBGR; @@ -100,43 +206,80 @@ JxrDecode2::CompressedData JxrDecode2::Encode( struct tagWMPStream* pEncodeStream = NULL; //CreateWS_File(&pEncodeStream, "C:\\temp\\test.jxr", "wb"); - CreateWS_HeapBackedWriteableStream(&pEncodeStream, 1024, 0); + err = CreateWS_HeapBackedWriteableStream(&pEncodeStream, 1024, 0); + if (Failed(err)) + { + ThrowJxrlibError("'CreateWS_HeapBackedWriteableStream' failed", err); + } - err = pEncoder->Initialize(pEncoder, pEncodeStream, &codec_parameters, sizeof(codec_parameters)); + unique_ptr upEncodeStream(pEncodeStream, [](WMPStream* p)->void {p->Close(&p); }); + + err = upImageEncoder->Initialize(upImageEncoder.get(), pEncodeStream, &codec_parameters, sizeof(codec_parameters)); + if (Failed(err)) + { + ThrowJxrlibError("'encoder::Initialize' failed", err); + } if (quality < 1.f) { - ApplyQuality(quality, pixel_format, width, pEncoder); + ApplyQuality(quality, pixel_format, width, upImageEncoder.get()); } switch (pixel_format) { case PixelFormat::kBgr24: - err = pEncoder->SetPixelFormat(pEncoder, GUID_PKPixelFormat24bppBGR); + err = upImageEncoder->SetPixelFormat(upImageEncoder.get(), GUID_PKPixelFormat24bppBGR); break; case PixelFormat::kGray8: - err = pEncoder->SetPixelFormat(pEncoder, GUID_PKPixelFormat8bppGray); + err = upImageEncoder->SetPixelFormat(upImageEncoder.get(), GUID_PKPixelFormat8bppGray); break; case PixelFormat::kBgr48: - err = pEncoder->SetPixelFormat(pEncoder, GUID_PKPixelFormat48bppRGB); + err = upImageEncoder->SetPixelFormat(upImageEncoder.get(), GUID_PKPixelFormat48bppRGB); break; case PixelFormat::kGray16: - err = pEncoder->SetPixelFormat(pEncoder, GUID_PKPixelFormat16bppGray); + err = upImageEncoder->SetPixelFormat(upImageEncoder.get(), GUID_PKPixelFormat16bppGray); break; case PixelFormat::kGray32Float: - err = pEncoder->SetPixelFormat(pEncoder, GUID_PKPixelFormat32bppGrayFloat); + err = upImageEncoder->SetPixelFormat(upImageEncoder.get(), GUID_PKPixelFormat32bppGrayFloat); break; + default: + { + ostringstream string_stream; + string_stream << "Unsupported pixel format specified: " << static_cast(pixel_format); + throw invalid_argument(string_stream.str()); + } + } + + if (Failed(err)) + { + ThrowJxrlibError("'PKImageEncode::SetPixelFormat' failed", err); } + //err = pEncoder->SetPixelFormat(pEncoder, GUID_PKPixelFormat24bppBGR); - err = pEncoder->SetSize(pEncoder, width, height); - err = pEncoder->SetResolution(pEncoder, 96.f, 96.f); + err = upImageEncoder->SetSize(upImageEncoder.get(), static_cast(width), static_cast(height)); + if (Failed(err)) + { + ostringstream string_stream; + string_stream << "'PKImageEncode::SetSize(" << width << "," << height << ")' failed."; + ThrowJxrlibError(string_stream, err); + } - pEncoder->WritePixels(pEncoder, height, (U8*)ptr_bitmap, stride); + err = upImageEncoder->SetResolution(upImageEncoder.get(), 96.f, 96.f); + if (Failed(err)) + { + ThrowJxrlibError("'PKImageEncode::SetResolution' failed", err); + } - return CompressedData(pEncodeStream); - //pEncodeStream->Close(&pEncodeStream); + err = upImageEncoder->WritePixels(upImageEncoder.get(), height, const_cast(static_cast(ptr_bitmap)), stride); + if (Failed(err)) + { + ThrowJxrlibError("'PKImageEncode::WritePixels' failed", err); + } + + return { upEncodeStream.release() }; } +#if 0 void JxrDecode2::Decode( codecHandle h, // const WMPDECAPPARGS* decArgs, @@ -318,33 +461,27 @@ void JxrDecode2::Decode( deliverData(/*JxrDecode2::PixelFormat::_24bppBGR*/pixel_format, width, height, height, pImage, width * bytes_per_pixel); free(pImage); } +#endif -JxrDecode2::PixelFormat JxrPixelFormatGuidToEnum(const GUID& guid) +/*static*/void JxrDecode2::ThrowJxrlibError(const std::string& message, int error_code) { - if (IsEqualGUID(guid, GUID_PKPixelFormat8bppGray)) - { - return JxrDecode2::PixelFormat::kGray8; - } - else if (IsEqualGUID(guid, GUID_PKPixelFormat16bppGray)) - { - return JxrDecode2::PixelFormat::kGray16; - } - else if (IsEqualGUID(guid, GUID_PKPixelFormat24bppBGR)) - { - return JxrDecode2::PixelFormat::kBgr24; - } - else if (IsEqualGUID(guid, GUID_PKPixelFormat48bppRGB)) - { - return JxrDecode2::PixelFormat::kBgr48; - } - else if (IsEqualGUID(guid, GUID_PKPixelFormat32bppGrayFloat)) + ostringstream string_stream(message); + JxrDecode2::ThrowJxrlibError(string_stream, error_code); +} + +/*static*/void JxrDecode2::ThrowJxrlibError(std::ostringstream& message, int error_code) +{ + message << " - ERR=" << error_code; + const char* error_code_string = ERR_to_string(error_code); + if (error_code_string != nullptr) { - return JxrDecode2::PixelFormat::kGray32Float; + message << " (" << error_code_string << ")"; } - return JxrDecode2::PixelFormat::kInvalid; + throw runtime_error(message.str()); } + void ThrowError(const char* error_message, ERR error_code) { ostringstream string_stream; @@ -360,32 +497,6 @@ void ThrowError(const char* error_message, ERR error_code) throw runtime_error(string_stream.str()); } -const char* ERR_to_string(ERR error_code) -{ - switch (error_code) - { - case WMP_errSuccess:return "WMP_errSuccess"; - case WMP_errFail:return "WMP_errFail"; - case WMP_errNotYetImplemented:return "WMP_errNotYetImplemented"; - case WMP_errAbstractMethod:return "WMP_errAbstractMethod"; - case WMP_errOutOfMemory:return "WMP_errOutOfMemory"; - case WMP_errFileIO:return "WMP_errFileIO"; - case WMP_errBufferOverflow:return "WMP_errBufferOverflow"; - case WMP_errInvalidParameter:return "WMP_errInvalidParameter"; - case WMP_errInvalidArgument:return "WMP_errInvalidArgument"; - case WMP_errUnsupportedFormat:return "WMP_errUnsupportedFormat"; - case WMP_errIncorrectCodecVersion:return "WMP_errIncorrectCodecVersion"; - case WMP_errIndexNotFound:return "WMP_errIndexNotFound"; - case WMP_errOutOfSequence:return "WMP_errOutOfSequence"; - case WMP_errNotInitialized:return "WMP_errNotInitialized"; - case WMP_errMustBeMultipleOf16LinesUntilLastCall:return "WMP_errMustBeMultipleOf16LinesUntilLastCall"; - case WMP_errPlanarAlphaBandedEncRequiresTempFile:return "WMP_errPlanarAlphaBandedEncRequiresTempFile"; - case WMP_errAlphaModeCannotBeTranscoded:return "WMP_errAlphaModeCannotBeTranscoded"; - case WMP_errIncorrectCodecSubVersion:return "WMP_errIncorrectCodecSubVersion"; - } - - return "unknown"; -} JxrDecode2::CompressedData::~CompressedData() { diff --git a/Src/JxrDecode/JxrDecode2.h b/Src/JxrDecode/JxrDecode2.h index c3dc14a2..2c90c00d 100644 --- a/Src/JxrDecode/JxrDecode2.h +++ b/Src/JxrDecode/JxrDecode2.h @@ -4,10 +4,13 @@ #include #include #include +#include +/// This class encapsulates the JXR codec. class JxrDecode2 { public: + /// Values that represent the pixel formats supported by the codec. enum class PixelFormat { kInvalid, @@ -16,38 +19,6 @@ class JxrDecode2 kGray8, kGray16, kGray32Float, - /*dontCare, - _24bppBGR, - _1bppBlackWhite, - _8bppGray, - _16bppGray, - _16bppGrayFixedPoint, - _16bppGrayHalf, - _32bppGrayFixedPoint, - _32bppGrayFloat, - _24bppRGB, - _48bppRGB, - _48bppRGBFixedPoint, - _48bppRGBHalf, - _96bppRGBFixedPoint, - _128bppRGBFloat, - _32bppRGBE, - _32bppCMYK, - _64bppCMYK, - _32bppBGRA, - _64bppRGBA, - _64bppRGBAFixedPoint, - _64bppRGBAHalf, - _128bppRGBAFixedPoint, - _128bppRGBAFloat, - _16bppBGR555, - _16bppBGR565, - _32bppBGR101010, - _40bppCMYKA, - _80bppCMYKA, - _32bppBGR, - - invalid*/ }; typedef void* codecHandle; @@ -87,21 +58,23 @@ class JxrDecode2 CompressedData(void* obj_handle) :obj_handle_(obj_handle) {} }; - void Decode( - codecHandle h, - // const WMPDECAPPARGS* decArgs, - const void* ptrData, - size_t size, - const std::function& selectDestPixFmt, - std::function deliverData); + //void Decode( + // codecHandle h, + // // const WMPDECAPPARGS* decArgs, + // const void* ptrData, + // size_t size, + // const std::function& selectDestPixFmt, + // std::function deliverData); /// Decodes the specified data, giving an uncompressed bitmap. /// The course of action is as follows: /// * The decoder will be initialized with the specified compressed data. /// * The characteristics of the compressed data will be determined - i.e the pixel type, width, height, etc. are determined. - /// * The 'get_destination_func' is called, passing in the pixel type, width, and height. - /// * The function should return a pointer to a buffer that can hold the uncompressed bitmap. - /// The tuple it returns is the pixel type, the stride and the pointer to the buffer. + /// * The 'get_destination_func' is called, passing in the pixel type, width, and height (as determined in the step before). + /// * The 'get_destination_func' function now is to check whether it can receive the bitmap (as reported). If it cannot, it + /// must throw an exception (which will be propagated to the caller). Otherwise, it must return a tuple, containing + /// a pointer to a buffer that can hold the uncompressed bitmap and the stride. This buffer must remain valid until the + /// the function returns - either normally or by throwing an exception. /// Notes: /// * The decoder will call the 'get_destination_func' function only once, and the buffer must be valid /// until the method returns. @@ -111,16 +84,19 @@ class JxrDecode2 /// \param ptrData Information describing the pointer. /// \param size The size. /// \param get_destination_func The get destination function. - void Decode( + static void Decode( const void* ptrData, size_t size, - const std::function(PixelFormat pixel_format, std::uint32_t width, std::uint32_t height)>& get_destination_func); + const std::function(PixelFormat pixel_format, std::uint32_t width, std::uint32_t height)>& get_destination_func); - CompressedData Encode( + static CompressedData Encode( JxrDecode2::PixelFormat pixel_format, std::uint32_t width, std::uint32_t height, std::uint32_t stride, const void* ptr_bitmap, float quality = 1.f); +private: + static void ThrowJxrlibError(const std::string& message, int error_code); + [[noreturn]] static void ThrowJxrlibError(std::ostringstream& message, int error_code); }; diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c index 1c73c44e..e17fd02d 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.c @@ -575,12 +575,15 @@ ERR PKImageEncode_SetSize( I32 iWidth, I32 iHeight) { - ERR err = WMP_errSuccess; + if (iWidth > 0 && iHeight > 0) + { + pIE->uWidth = (U32)iWidth; + pIE->uHeight = (U32)iHeight; - pIE->uWidth = (U32)iWidth; - pIE->uHeight = (U32)iHeight; + return WMP_errSuccess; + } - return err; + return WMP_errInvalidParameter; } ERR PKImageEncode_SetResolution( diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c index 8747a4eb..b005c40c 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlueJxr.c @@ -1459,7 +1459,10 @@ ERR PKImageEncode_Release_WMP( ERR err = WMP_errSuccess; PKImageEncode* pIE = *ppIE; - pIE->pStream->Close(&pIE->pStream); + if (pIE->pStream != NULL) + { + pIE->pStream->Close(&pIE->pStream); + } PKFree((void**)&pIE->pbColorContext); pIE->cbColorContext = 0; diff --git a/Src/libCZI/decoder.cpp b/Src/libCZI/decoder.cpp index 9ef7e422..fd4d5440 100644 --- a/Src/libCZI/decoder.cpp +++ b/Src/libCZI/decoder.cpp @@ -82,8 +82,7 @@ std::shared_ptr CJxrLibDecoder::Encode(libCZI::PixelType p throw std::logic_error("unsupported pixel type"); } - JxrDecode2 decoder2; - auto compressed_data = decoder2.Encode( + auto compressed_data = JxrDecode2::Encode( jxrdecode_pixel_format, width, height, @@ -98,14 +97,14 @@ std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, { std::shared_ptr bitmap; bool bitmap_is_locked = false; - JxrDecode2 decoder2; + try { - decoder2.Decode( + JxrDecode2::Decode( ptrData, size, [&](JxrDecode2::PixelFormat actual_pixel_format, std::uint32_t actual_width, std::uint32_t actual_height) - -> tuple + -> tuple { const auto pixel_type_from_compressed_data = PixelTypeFromJxrPixelFormat(actual_pixel_format); if (pixel_type_from_compressed_data == PixelType::Invalid) @@ -120,10 +119,17 @@ std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, throw std::logic_error(ss.str()); } + if (actual_width != width || actual_height != height) + { + ostringstream ss; + ss << "size mismatch: expected " << width << "x" << height << ", but got " << actual_width << "x" << actual_height; + throw std::logic_error(ss.str()); + } + bitmap = GetSite()->CreateBitmap(pixel_type_from_compressed_data , actual_width, actual_height); const auto lock_info = bitmap->Lock(); bitmap_is_locked = true; - return make_tuple(actual_pixel_format, lock_info.stride, lock_info.ptrDataRoi); + return make_tuple(lock_info.ptrDataRoi, lock_info.stride); }); } catch (const std::exception& e) @@ -138,7 +144,6 @@ std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, } bitmap->Unlock(); - return bitmap; } diff --git a/Src/libCZI_UnitTests/test_JxrDecode.cpp b/Src/libCZI_UnitTests/test_JxrDecode.cpp index 9ce6f88a..12a3588d 100644 --- a/Src/libCZI_UnitTests/test_JxrDecode.cpp +++ b/Src/libCZI_UnitTests/test_JxrDecode.cpp @@ -341,9 +341,11 @@ TEST(JxrDecode, CompressLossyAndDecompressCheckForSimilarity_Gray8) ASSERT_LT(size_of_encoded_data, static_cast(Utils::GetBytesPerPixel(bitmap->GetPixelType()) * bitmap->GetWidth() * bitmap->GetHeight())) << "Encoded data is too large (larger than the original data), which is unexpected."; - /*FILE* fp = fopen("N:\\test.jxr", "wb"); - fwrite(encoded_data_ptr, size_of_encoded_data, 1, fp); - fclose(fp);*/ + /* + FILE* fp = fopen("N:\\test.jxr", "wb"); + fwrite(encoded_data_ptr, size_of_encoded_data, 1, fp); + fclose(fp); + */ const auto bitmap_decoded = codec->Decode( encodedData->GetPtr(), @@ -354,3 +356,64 @@ TEST(JxrDecode, CompressLossyAndDecompressCheckForSimilarity_Gray8) const auto max_difference_mean_difference = CalculateMaxDifferenceMeanDifference(bitmap, bitmap_decoded); EXPECT_TRUE(get<0>(max_difference_mean_difference) <= 5 && get<1>(max_difference_mean_difference) < 1) << "Original bitmap and encoded-decoded one are not identical."; } + +TEST(JxrDecode, CallEncoderWithInvalidArgumentsExpectException) +{ + const auto bitmap = CBitmapData::Create(PixelType::Gray8, 5, 5); + const auto codec = CJxrLibDecoder::Create(); + EXPECT_THROW( + { + const ScopedBitmapLockerSP lck{ bitmap }; + codec->Encode( + PixelType::Invalid, + bitmap->GetWidth(), + bitmap->GetHeight(), + lck.stride, + lck.ptrDataRoi); + }, + exception); + EXPECT_THROW( + { + const ScopedBitmapLockerSP lck{ bitmap }; + codec->Encode( + bitmap->GetPixelType(), + bitmap->GetWidth(), + bitmap->GetHeight(), + 4, // invalid stride provided here + lck.ptrDataRoi); + }, + exception); + EXPECT_THROW( + { + const ScopedBitmapLockerSP lck{ bitmap }; + codec->Encode( + bitmap->GetPixelType(), + bitmap->GetWidth(), + 0, + lck.stride, + lck.ptrDataRoi); + }, + exception); + EXPECT_THROW( + { + const ScopedBitmapLockerSP lck{ bitmap }; + codec->Encode( + bitmap->GetPixelType(), + 0, + bitmap->GetHeight(), + lck.stride, + lck.ptrDataRoi); + }, + exception); + EXPECT_THROW( + { + const ScopedBitmapLockerSP lck{ bitmap }; + codec->Encode( + bitmap->GetPixelType(), + bitmap->GetWidth(), + bitmap->GetHeight(), + lck.stride, + nullptr); + }, + exception); +} From bd79940ce47444078606d31c6d7797bbb048810a Mon Sep 17 00:00:00 2001 From: ptahmose Date: Wed, 30 Aug 2023 01:43:01 +0200 Subject: [PATCH 66/98] more tests --- Src/libCZI_UnitTests/test_JxrDecode.cpp | 42 +++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/Src/libCZI_UnitTests/test_JxrDecode.cpp b/Src/libCZI_UnitTests/test_JxrDecode.cpp index 12a3588d..11d1a5f0 100644 --- a/Src/libCZI_UnitTests/test_JxrDecode.cpp +++ b/Src/libCZI_UnitTests/test_JxrDecode.cpp @@ -417,3 +417,45 @@ TEST(JxrDecode, CallEncoderWithInvalidArgumentsExpectException) }, exception); } + +TEST(JxrDecode, CallDecoderWithInvalidArgumentsExpectException) +{ + constexpr size_t ksize_of_encoded_data = 223; + const unique_ptr encoded_data{ malloc(ksize_of_encoded_data), &free }; + for (size_t i= 0; i < ksize_of_encoded_data; ++i) + { + static_cast(encoded_data.get())[i] = static_cast(i); + } + + const auto codec = CJxrLibDecoder::Create(); + EXPECT_THROW( + { + codec->Decode( + encoded_data.get(), + ksize_of_encoded_data, + libCZI::PixelType::Gray8, + 42, + 42); + }, + exception); + EXPECT_THROW( + { + codec->Decode( + nullptr, + ksize_of_encoded_data, + libCZI::PixelType::Gray8, + 42, + 42); + }, + exception); + EXPECT_THROW( + { + codec->Decode( + encoded_data.get(), + 0, + libCZI::PixelType::Gray8, + 42, + 42); + }, + exception); +} From b87d3f9f6591b33c99948aa83145ff9b008c1368 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Thu, 31 Aug 2023 00:22:35 +0200 Subject: [PATCH 67/98] cosmetic --- Src/JxrDecode/JxrDecode2.cpp | 53 ++++++++++++++----------- Src/libCZI_UnitTests/test_JxrDecode.cpp | 35 +++++++++++++--- 2 files changed, 59 insertions(+), 29 deletions(-) diff --git a/Src/JxrDecode/JxrDecode2.cpp b/Src/JxrDecode/JxrDecode2.cpp index 95309179..ad8d9f03 100644 --- a/Src/JxrDecode/JxrDecode2.cpp +++ b/Src/JxrDecode/JxrDecode2.cpp @@ -93,18 +93,37 @@ void JxrDecode2::Decode( size_t size, const std::function(PixelFormat pixel_format, std::uint32_t width, std::uint32_t height)>& get_destination_func) { - if (ptrData == nullptr) { throw invalid_argument("ptrData"); } - if (size == 0) { throw invalid_argument("size"); } - if (!get_destination_func) { throw invalid_argument("get_destination_func"); } + if (ptrData == nullptr) + { + throw invalid_argument("ptrData"); + } + + if (size == 0) + { + throw invalid_argument("size"); + } + + if (!get_destination_func) + { + throw invalid_argument("get_destination_func"); + } WMPStream* pStream; ERR err = CreateWS_Memory(&pStream, const_cast(ptrData), size); - if (Failed(err)) { ThrowJxrlibError("'CreateWS_Memory' failed", err); } + if (Failed(err)) + { + ThrowJxrlibError("'CreateWS_Memory' failed", err); + } + unique_ptr upStream(pStream, [](WMPStream* p)->void {p->Close(&p); }); PKImageDecode* pDecoder; err = PKCodecFactory_CreateDecoderFromStream(pStream, &pDecoder); - if (Failed(err)) { ThrowJxrlibError("'PKCodecFactory_CreateDecoderFromStream' failed", err); } + if (Failed(err)) + { + ThrowJxrlibError("'PKCodecFactory_CreateDecoderFromStream' failed", err); + } + std::unique_ptr upDecoder(pDecoder, [](PKImageDecode* p)->void {p->Release(&p); }); U32 frame_count; @@ -119,7 +138,10 @@ void JxrDecode2::Decode( I32 width, height; upDecoder->GetSize(upDecoder.get(), &width, &height); - if (Failed(err)) { ThrowJxrlibError("'decoder::GetSize' failed", err); } + if (Failed(err)) + { + ThrowJxrlibError("'decoder::GetSize' failed", err); + } PKPixelFormatGUID pixel_format_of_decoder; upDecoder->GetPixelFormat(upDecoder.get(), &pixel_format_of_decoder); @@ -170,7 +192,7 @@ void JxrDecode2::Decode( } unique_ptr upImageEncoder( - pImageEncoder, + pImageEncoder, [](PKImageEncode* p)->void { // If we get here, we need to 'disassociate' the stream from the encoder, @@ -481,23 +503,6 @@ void JxrDecode2::Decode( throw runtime_error(message.str()); } - -void ThrowError(const char* error_message, ERR error_code) -{ - ostringstream string_stream; - if (error_message != nullptr) - { - string_stream << "Error in JXR-decoder -> \"" << error_message << "\" code:" << error_code << " (" << ERR_to_string(error_code) << ")"; - } - else - { - string_stream << "Error in JXR-decoder -> " << error_message << " (" << ERR_to_string(error_code) << ")"; - } - - throw runtime_error(string_stream.str()); -} - - JxrDecode2::CompressedData::~CompressedData() { if (this->obj_handle_ != nullptr) diff --git a/Src/libCZI_UnitTests/test_JxrDecode.cpp b/Src/libCZI_UnitTests/test_JxrDecode.cpp index 11d1a5f0..d2a330ef 100644 --- a/Src/libCZI_UnitTests/test_JxrDecode.cpp +++ b/Src/libCZI_UnitTests/test_JxrDecode.cpp @@ -5,6 +5,7 @@ #include "include_gtest.h" #include #include +#include #include #include "inc_libCZI.h" #include "testImage.h" @@ -420,9 +421,9 @@ TEST(JxrDecode, CallEncoderWithInvalidArgumentsExpectException) TEST(JxrDecode, CallDecoderWithInvalidArgumentsExpectException) { - constexpr size_t ksize_of_encoded_data = 223; - const unique_ptr encoded_data{ malloc(ksize_of_encoded_data), &free }; - for (size_t i= 0; i < ksize_of_encoded_data; ++i) + constexpr size_t kSizeOfEncodedData = 223; + const unique_ptr encoded_data{ malloc(kSizeOfEncodedData), &free }; + for (size_t i = 0; i < kSizeOfEncodedData; ++i) { static_cast(encoded_data.get())[i] = static_cast(i); } @@ -432,7 +433,7 @@ TEST(JxrDecode, CallDecoderWithInvalidArgumentsExpectException) { codec->Decode( encoded_data.get(), - ksize_of_encoded_data, + kSizeOfEncodedData, libCZI::PixelType::Gray8, 42, 42); @@ -442,7 +443,7 @@ TEST(JxrDecode, CallDecoderWithInvalidArgumentsExpectException) { codec->Decode( nullptr, - ksize_of_encoded_data, + kSizeOfEncodedData, libCZI::PixelType::Gray8, 42, 42); @@ -459,3 +460,27 @@ TEST(JxrDecode, CallDecoderWithInvalidArgumentsExpectException) }, exception); } + +TEST(JxrDecode, CallDecoderExpectingADifferentBitmapTypeAndExpectException) +{ + size_t size_encoded_data; + int expected_width, expected_height; + const auto ptrEncodedData = CTestImage::GetJpgXrCompressedImage_Bgr24(&size_encoded_data, &expected_width, &expected_height); + const auto codec = CJxrLibDecoder::Create(); + + static constexpr array kPixelTypesToTest = { PixelType::Gray8, PixelType::Gray16, PixelType::Bgr48, PixelType::Gray32Float }; + + for (const auto pixel_type : kPixelTypesToTest) + { + EXPECT_THROW( + { + codec->Decode( + ptrEncodedData, + size_encoded_data, + pixel_type, + expected_width, + expected_height); + }, + exception); + } +} From 3b940f5e38e4182872366ded546740c1582514e8 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Thu, 31 Aug 2023 00:58:06 +0200 Subject: [PATCH 68/98] cosmetic --- Src/JxrDecode/JxrDecode2.cpp | 2 -- Src/JxrDecode/JxrDecode2.h | 10 ---------- 2 files changed, 12 deletions(-) diff --git a/Src/JxrDecode/JxrDecode2.cpp b/Src/JxrDecode/JxrDecode2.cpp index ad8d9f03..7abae49d 100644 --- a/Src/JxrDecode/JxrDecode2.cpp +++ b/Src/JxrDecode/JxrDecode2.cpp @@ -9,8 +9,6 @@ using namespace std; static void ApplyQuality(float quality, JxrDecode2::PixelFormat pixel_format, std::uint32_t width, PKImageEncode* pEncoder); -static JxrDecode2::PixelFormat JxrPixelFormatGuidToEnum(const GUID& guid); -static void ThrowError(const char* error_message, ERR error_code); static const char* ERR_to_string(ERR error_code) { diff --git a/Src/JxrDecode/JxrDecode2.h b/Src/JxrDecode/JxrDecode2.h index 2c90c00d..d36ef3a4 100644 --- a/Src/JxrDecode/JxrDecode2.h +++ b/Src/JxrDecode/JxrDecode2.h @@ -21,8 +21,6 @@ class JxrDecode2 kGray32Float, }; - typedef void* codecHandle; - /// This class is used to represent a blob containing the compressed data. /// Note that it is movable but not copyable. class CompressedData @@ -58,14 +56,6 @@ class JxrDecode2 CompressedData(void* obj_handle) :obj_handle_(obj_handle) {} }; - //void Decode( - // codecHandle h, - // // const WMPDECAPPARGS* decArgs, - // const void* ptrData, - // size_t size, - // const std::function& selectDestPixFmt, - // std::function deliverData); - /// Decodes the specified data, giving an uncompressed bitmap. /// The course of action is as follows: /// * The decoder will be initialized with the specified compressed data. From 1d92fb61e093f4ec5480f71e20b8b697120879c8 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Thu, 31 Aug 2023 23:23:16 +0200 Subject: [PATCH 69/98] cosmetic --- Src/JxrDecode/jxrlib/image/sys/strcodec.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Src/JxrDecode/jxrlib/image/sys/strcodec.c b/Src/JxrDecode/jxrlib/image/sys/strcodec.c index b1c676ae..b473a11f 100644 --- a/Src/JxrDecode/jxrlib/image/sys/strcodec.c +++ b/Src/JxrDecode/jxrlib/image/sys/strcodec.c @@ -279,17 +279,12 @@ ERR CreateWS_File(struct tagWMPStream** ppWS, const char* szFilename, const char pWS->Read = ReadWS_File; pWS->Write = WriteWS_File; - //pWS->GetLine = GetLineWS_File; pWS->SetPos = SetPosWS_File; pWS->GetPos = GetPosWS_File; - //#ifdef WIN32 - // FailIf(0 != fopen_s(&pWS->state.file.pFile, szFilename, szMode), WMP_errFileIO); - //#else pWS->state.file.pFile = fopen(szFilename, szMode); FailIf(NULL == pWS->state.file.pFile, WMP_errFileIO); - //#endif Cleanup: return err; @@ -314,8 +309,6 @@ Bool EOSWS_File(struct tagWMPStream* pWS) ERR ReadWS_File(struct tagWMPStream* pWS, void* pv, size_t cb) { - // ERR err = WMP_errSuccess; - return (fread(pv, cb, 1, pWS->state.file.pFile) == 1) ? WMP_errSuccess : WMP_errFileIO; } From 5f8a6c3d92b98fc0ee09a03e95a0effda7e2d047 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Thu, 7 Sep 2023 23:36:41 +0200 Subject: [PATCH 70/98] deal with BGR48 vs RGB48 --- Src/JxrDecode/JxrDecode2.h | 16 +++++----- Src/libCZI/decoder.cpp | 64 +++++++++++++++++++++++++++++++------- 2 files changed, 62 insertions(+), 18 deletions(-) diff --git a/Src/JxrDecode/JxrDecode2.h b/Src/JxrDecode/JxrDecode2.h index d36ef3a4..a1c99c44 100644 --- a/Src/JxrDecode/JxrDecode2.h +++ b/Src/JxrDecode/JxrDecode2.h @@ -13,12 +13,14 @@ class JxrDecode2 /// Values that represent the pixel formats supported by the codec. enum class PixelFormat { - kInvalid, - kBgr24, - kBgr48, - kGray8, - kGray16, - kGray32Float, + kInvalid, ///< An enum constant representing the invalid option + kBgr24, ///< An enum constant representing the "BGR24" pixel type - 3 bytes per pixel, 8 bits per channel, in B-G-R order. + kBgr48, ///< An enum constant representing the "BGR48" pixel type - 6 bytes per pixel, 16 bits per channel, in B-G-R order. Note that + ///< there BGR48 is not natively supported by the codec, so it is converted to RGB48. This happens transparently to the user, + ///< but at this point there is a performance penalty. + kGray8, ///< An enum constant representing the "GRAY8" pixel type - 1 byte per pixel, 8 bits per channel. + kGray16, ///< An enum constant representing the "GRAY16" pixel type - 2 bytes per pixel, 16 bits per channel. + kGray32Float, ///< An enum constant representing the "GRAY32Float" pixel type - 4 bytes per pixel, 32 bits per channel. }; /// This class is used to represent a blob containing the compressed data. @@ -77,7 +79,7 @@ class JxrDecode2 static void Decode( const void* ptrData, size_t size, - const std::function(PixelFormat pixel_format, std::uint32_t width, std::uint32_t height)>& get_destination_func); + const std::function(PixelFormat pixel_format, std::uint32_t width, std::uint32_t height)>& get_destination_func); static CompressedData Encode( JxrDecode2::PixelFormat pixel_format, diff --git a/Src/libCZI/decoder.cpp b/Src/libCZI/decoder.cpp index fd4d5440..465bf8c3 100644 --- a/Src/libCZI/decoder.cpp +++ b/Src/libCZI/decoder.cpp @@ -82,15 +82,44 @@ std::shared_ptr CJxrLibDecoder::Encode(libCZI::PixelType p throw std::logic_error("unsupported pixel type"); } - auto compressed_data = JxrDecode2::Encode( - jxrdecode_pixel_format, - width, - height, - stride, - ptrData, - quality); + // Unfortunately, the encoder does not support the pixelformat Bgr48, so we need to convert it to Rgb48 + // before passing it to the encoder (meaning: the resulting encoded data will be Rgb48, not Bgr48). + // TODO(JBL): would be nice if the encoder would support Bgr48 directly somehow + if (jxrdecode_pixel_format == JxrDecode2::PixelFormat::kBgr48) + { + // unfortunately, we have to make a temporary copy + const auto bitmap_rgb48 = GetSite()->CreateBitmap(PixelType::Bgr48, width, height); - return make_shared(std::move(compressed_data)); + const ScopedBitmapLockerSP bmLck(bitmap_rgb48); + CBitmapOperations::CopySamePixelType( + ptrData, + stride, + bmLck.ptrDataRoi, + bmLck.stride, + width, + height, + false); + CBitmapOperations::RGB48ToBGR48(width, height, static_cast(bmLck.ptrDataRoi), bmLck.stride); + auto compressed_data = JxrDecode2::Encode( + jxrdecode_pixel_format, + width, + height, + bmLck.stride, + bmLck.ptrDataRoi, + quality); + return make_shared(std::move(compressed_data)); + } + else + { + auto compressed_data = JxrDecode2::Encode( + jxrdecode_pixel_format, + width, + height, + stride, + ptrData, + quality); + return make_shared(std::move(compressed_data)); + } } std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, size_t size, libCZI::PixelType pixelType, uint32_t width, uint32_t height) @@ -126,7 +155,7 @@ std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, throw std::logic_error(ss.str()); } - bitmap = GetSite()->CreateBitmap(pixel_type_from_compressed_data , actual_width, actual_height); + bitmap = GetSite()->CreateBitmap(pixel_type_from_compressed_data, actual_width, actual_height); const auto lock_info = bitmap->Lock(); bitmap_is_locked = true; return make_tuple(lock_info.ptrDataRoi, lock_info.stride); @@ -144,6 +173,19 @@ std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, } bitmap->Unlock(); + + // if the pixel type was "Rgb48", then we need to convert it to Bgr48 (which is what the rest of the code expects), and unfortunately + // the decoder at this point does not allow to swap the channels, so we need to do it here + if (bitmap->GetPixelType() == PixelType::Bgr48) + { + const ScopedBitmapLockerSP bmLck(bitmap); + CBitmapOperations::RGB48ToBGR48( + bitmap->GetWidth(), + bitmap->GetHeight(), + static_cast(bmLck.ptrDataRoi), + bmLck.stride); + } + return bitmap; } @@ -352,7 +394,7 @@ std::shared_ptr CJxrLibDecoder::Decode2(const void* ptrData { CBitmapOperations::RGB48ToBGR48(width, height, (uint16_t*)bmLckInfo.ptrDataRoi, bmLckInfo.stride); } - }); + }); } catch (std::runtime_error& err) { @@ -380,5 +422,5 @@ std::shared_ptr CJxrLibDecoder::Decode2(const void* ptrData } return bm; -} + } #endif From 75917b952fdbefa2e3e1a5c8e1275b39655c7d77 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 10 Sep 2023 13:54:16 +0200 Subject: [PATCH 71/98] cosmetic --- Src/JxrDecode/JxrDecode2.cpp | 188 +----------------- Src/JxrDecode/JxrDecode2.h | 8 + Src/JxrDecode/jxrlib/common/include/guiddef.h | 90 +-------- Src/libCZI/decoder.h | 2 +- 4 files changed, 20 insertions(+), 268 deletions(-) diff --git a/Src/JxrDecode/JxrDecode2.cpp b/Src/JxrDecode/JxrDecode2.cpp index 7abae49d..fee2db13 100644 --- a/Src/JxrDecode/JxrDecode2.cpp +++ b/Src/JxrDecode/JxrDecode2.cpp @@ -299,190 +299,6 @@ void JxrDecode2::Decode( return { upEncodeStream.release() }; } -#if 0 -void JxrDecode2::Decode( - codecHandle h, - // const WMPDECAPPARGS* decArgs, - const void* ptrData, - size_t size, - const std::function& selectDestPixFmt, - std::function deliverData) -{ - ERR err; - /*PKFactory* pFactory = nullptr; - err = PKCreateFactory(&pFactory, PK_SDK_VERSION); - //if (Failed(err)) { ThrowError("PKCreateFactory failed", err); } - std::unique_ptr upFactory(pFactory, [](PKFactory* p)->void {p->Release(&p); }); - */ - /*PKCodecFactory* pCodecFactory = NULL; - err = PKCreateCodecFactory(&pCodecFactory, WMP_SDK_VERSION); - //if (Failed(err)) { ThrowError("PKCreateCodecFactory failed", err); } - std::unique_ptr upCodecFactory(pCodecFactory, [](PKCodecFactory* p)->void {p->Release(&p); });*/ - - /* const PKIID* pIID = NULL; - - GetImageDecodeIID((const char*)".jxr", &pIID); - PKCodecFactory_CreateCodec(pIID, (void**)&pDecoder); - std::unique_ptr upDecoder(pDecoder, [](PKImageDecode* p)->void {p->Release(&p); });*/ - - WMPStream* pStream; - err = CreateWS_Memory(&pStream, const_cast(ptrData), size); - //unique_ptr upStream(pStream, [](WMPStream* p)->void {p->Close(p); p->Release(p); }); - unique_ptr upStream(pStream, [](WMPStream* p)->void {p->Close(&p); }); - //err = pFactory->CreateStreamFromMemory(&pStream, const_cast(ptrData), size); - - PKImageDecode* pDecoder; - //upCodecFactory->CreateDecoderFromStream(pStream, &pDecoder); - PKCodecFactory_CreateDecoderFromStream(pStream, &pDecoder); - std::unique_ptr upDecoder(pDecoder, [](PKImageDecode* p)->void {p->Release(&p); }); - - - PKPixelFormatGUID args_guidPixFormat; - PKPixelInfo PI; - - // take decoder color format and try to look up better one - // (e.g. 32bppBGR -> 24bppBGR etc.) - PKPixelInfo newPI; - newPI.pGUIDPixFmt = PI.pGUIDPixFmt = &upDecoder->guidPixFormat; - PixelFormatLookup(&newPI, LOOKUP_FORWARD); - PixelFormatLookup(&newPI, LOOKUP_BACKWARD_TIF); - args_guidPixFormat = *newPI.pGUIDPixFmt; - - /*if (decArgs->pixFormat == PixelFormat::dontCare) - { - if (selectDestPixFmt) - { - PI.pGUIDPixFmt = &upDecoder->guidPixFormat; - I32 w, h; - upDecoder->GetSize(upDecoder.get(), &w, &h); - PixelFormat pixFmtFromDecoder = PixelFormatFromPkPixelFormat(upDecoder->guidPixFormat); - PixelFormat destFmtChosen = selectDestPixFmt(pixFmtFromDecoder, w, h); - - args_guidPixFormat = *PkPixelFormatFromPixelFormat(destFmtChosen); - //args_guidPixFormat = selectDestPixFmt(*PI.pGUIDPixFmt); - } - else - { - // take decoder color format and try to look up better one - // (e.g. 32bppBGR -> 24bppBGR etc.) - PKPixelInfo newPI; - newPI.pGUIDPixFmt = PI.pGUIDPixFmt = &upDecoder->guidPixFormat; - PixelFormatLookup(&newPI, LOOKUP_FORWARD); - PixelFormatLookup(&newPI, LOOKUP_BACKWARD_TIF); - args_guidPixFormat = *newPI.pGUIDPixFmt; - } - } - else - { - PI.pGUIDPixFmt = PkPixelFormatFromPixelFormat(decArgs->pixFormat); - args_guidPixFormat = *PI.pGUIDPixFmt; - }*/ - - // == color transcoding, - if (IsEqualGUID(args_guidPixFormat, GUID_PKPixelFormat8bppGray) || IsEqualGUID(args_guidPixFormat, GUID_PKPixelFormat16bppGray)) { // ** => Y transcoding - upDecoder->guidPixFormat = args_guidPixFormat; - upDecoder->WMP.wmiI.cfColorFormat = Y_ONLY; - } - else if (IsEqualGUID(args_guidPixFormat, GUID_PKPixelFormat24bppRGB) && upDecoder->WMP.wmiI.cfColorFormat == CMYK) { // CMYK = > RGB - upDecoder->WMP.wmiI.cfColorFormat = CF_RGB; - upDecoder->guidPixFormat = args_guidPixFormat; - upDecoder->WMP.wmiI.bRGB = 1; //RGB - } - - PixelFormatLookup(&PI, LOOKUP_FORWARD); - - /*std::uint8_t args_uAlphaMode = decArgs->uAlphaMode; - if (255 == args_uAlphaMode)//user didn't set - { - if (!!(PI.grBit & PK_pixfmtHasAlpha)) - args_uAlphaMode = 2;//default is image & alpha for formats with alpha - else - args_uAlphaMode = 0;//otherwise, 0 - }*/ - - upDecoder->WMP.wmiSCP.bfBitstreamFormat = BITSTREAMFORMAT::SPATIAL;// args.bfBitstreamFormat; only used for transcoding? - - upDecoder->WMP.wmiSCP.uAlphaMode = 0;// args_uAlphaMode; - - upDecoder->WMP.wmiSCP.sbSubband = SB_ALL;// (SUBBAND)(std::underlying_type::type)decArgs->sbSubband; - upDecoder->WMP.bIgnoreOverlap = FALSE;// decArgs->bIgnoreOverlap ? 1 : 0; - - upDecoder->WMP.wmiI.cfColorFormat = PI.cfColorFormat; - - upDecoder->WMP.wmiI.bdBitDepth = PI.bdBitDepth; - upDecoder->WMP.wmiI.cBitsPerUnit = PI.cbitUnit; - - //==== Validate thumbnail decode parameters ===== - upDecoder->WMP.wmiI.cThumbnailWidth = upDecoder->WMP.wmiI.cWidth; - upDecoder->WMP.wmiI.cThumbnailHeight = upDecoder->WMP.wmiI.cHeight; - upDecoder->WMP.wmiI.bSkipFlexbits = FALSE; - /*if (args.tThumbnailFactor > 0 && args.tThumbnailFactor != SKIPFLEXBITS) { - size_t tSize = ((size_t)1 << args.tThumbnailFactor); - - pDecoder->WMP.wmiI.cThumbnailWidth = (pDecoder->WMP.wmiI.cWidth + tSize - 1) / tSize; - pDecoder->WMP.wmiI.cThumbnailHeight = (pDecoder->WMP.wmiI.cHeight + tSize - 1) / tSize; - - if (pDecoder->WMP.wmiI.cfColorFormat == YUV_420 || pDecoder->WMP.wmiI.cfColorFormat == YUV_422) { // unsupported thumbnail format - pDecoder->WMP.wmiI.cfColorFormat = YUV_444; - } - } - else if (args.tThumbnailFactor == SKIPFLEXBITS) { - pDecoder->WMP.wmiI.bSkipFlexbits = TRUE; - }*/ - - /* if (decArgs->rWidth == 0 || decArgs->rHeight == 0) - { // no region decode - upDecoder->WMP.wmiI.cROILeftX = 0; - upDecoder->WMP.wmiI.cROITopY = 0; - upDecoder->WMP.wmiI.cROIWidth = upDecoder->WMP.wmiI.cThumbnailWidth; - upDecoder->WMP.wmiI.cROIHeight = upDecoder->WMP.wmiI.cThumbnailHeight; - } - else - { - upDecoder->WMP.wmiI.cROILeftX = decArgs->rLeftX; - upDecoder->WMP.wmiI.cROITopY = decArgs->rTopY; - upDecoder->WMP.wmiI.cROIWidth = decArgs->rWidth; - upDecoder->WMP.wmiI.cROIHeight = decArgs->rHeight; - }*/ - upDecoder->WMP.wmiI.cROILeftX = 0; - upDecoder->WMP.wmiI.cROITopY = 0; - upDecoder->WMP.wmiI.cROIWidth = pDecoder->WMP.wmiI.cWidth; - upDecoder->WMP.wmiI.cROIHeight = upDecoder->WMP.wmiI.cWidth; - - upDecoder->WMP.wmiI.oOrientation = O_NONE;// static_cast(decArgs->oOrientation); - - upDecoder->WMP.wmiI.cPostProcStrength = 0;// decArgs->cPostProcStrength; - - upDecoder->WMP.wmiSCP.bVerbose = 0; - - U32 cFrame; - err = upDecoder->GetFrameCount(upDecoder.get(), &cFrame); - //if (Failed(err)) { ThrowError("GetFrameCount failed", err); } - if (cFrame != 1) - { - //throw std::logic_error("Not expecting to find more than one image here."); - } - - I32 width, height; - pDecoder->GetSize(pDecoder, &width, &height); - size_t bytes_per_pixel = pDecoder->WMP.wmiI.cBitsPerUnit / 8; - - PKRect rc; - rc.X = 0; - rc.Y = 0; - rc.Width = width; - rc.Height = height; - - JxrDecode2::PixelFormat pixel_format = JxrPixelFormatGuidToEnum(pDecoder->guidPixFormat); - - void* pImage = malloc(width * height * bytes_per_pixel); - upDecoder->Copy(upDecoder.get(), &rc, (U8*)pImage, width * bytes_per_pixel); - - deliverData(/*JxrDecode2::PixelFormat::_24bppBGR*/pixel_format, width, height, height, pImage, width * bytes_per_pixel); - free(pImage); -} -#endif - /*static*/void JxrDecode2::ThrowJxrlibError(const std::string& message, int error_code) { ostringstream string_stream(message); @@ -513,7 +329,7 @@ void* JxrDecode2::CompressedData::GetMemory() { void* data = nullptr; GetWS_HeapBackedWriteableStreamBuffer( - (struct tagWMPStream*)this->obj_handle_, + static_cast(this->obj_handle_), &data, nullptr); return data; @@ -523,7 +339,7 @@ size_t JxrDecode2::CompressedData::GetSize() { size_t size = 0; GetWS_HeapBackedWriteableStreamBuffer( - (struct tagWMPStream*)this->obj_handle_, + static_cast(this->obj_handle_), nullptr, &size); return size; diff --git a/Src/JxrDecode/JxrDecode2.h b/Src/JxrDecode/JxrDecode2.h index a1c99c44..88aaa6e6 100644 --- a/Src/JxrDecode/JxrDecode2.h +++ b/Src/JxrDecode/JxrDecode2.h @@ -50,8 +50,16 @@ class JxrDecode2 CompressedData(const CompressedData&) = delete; // prevent copy constructor to be used CompressedData& operator=(const CompressedData&) = delete; // prevent copy assignment to be used + /// Gets a pointer to the memory representing the compressed data. The memory is owned by the object and will be freed when the object is destroyed. + /// + /// \returns A pointer to the memory representing the compressed data. void* GetMemory(); + + /// Gets the size of the compressed data in units of bytes. + /// + /// \returns The size (in bytes). size_t GetSize(); + ~CompressedData(); protected: friend class JxrDecode2; diff --git a/Src/JxrDecode/jxrlib/common/include/guiddef.h b/Src/JxrDecode/jxrlib/common/include/guiddef.h index aebc3801..351c01e8 100644 --- a/Src/JxrDecode/jxrlib/common/include/guiddef.h +++ b/Src/JxrDecode/jxrlib/common/include/guiddef.h @@ -32,28 +32,17 @@ #ifndef GUID_DEFINED #define GUID_DEFINED -#if defined(__midl) -typedef struct { - unsigned long Data1; - unsigned short Data2; - unsigned short Data3; - byte Data4[8]; -} GUID; -#else + +#include +#include + typedef struct _GUID { -#if defined(_WINDOWS_) || !__LP64__ - unsigned long Data1; -#else - unsigned int Data1; -#endif + int32_t Data1; unsigned short Data2; unsigned short Data3; unsigned char Data4[8]; } GUID; #endif -#endif - -#define FAR #ifndef DECLSPEC_SELECTANY #if (_MSC_VER >= 1100) @@ -81,12 +70,12 @@ typedef struct _GUID { = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } #else #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - EXTERN_C const GUID FAR name + EXTERN_C const GUID name #endif // INITGUID -#if _MSC_VER < 1900 -#define DEFINE_OLEGUID(name, l, w1, w2) DEFINE_GUID(name, l, w1, w2, 0xC0,0,0,0,0,0,0,0x46) -#endif +//#if _MSC_VER < 1900 +//#define DEFINE_OLEGUID(name, l, w1, w2) DEFINE_GUID(name, l, w1, w2, 0xC0,0,0,0,0,0,0,0x46) +//#endif #ifndef _GUIDDEF_H_ #define _GUIDDEF_H_ @@ -117,11 +106,7 @@ typedef FMTID* LPFMTID; #define FMTID_NULL GUID_NULL #define IsEqualFMTID(rfmtid1, rfmtid2) IsEqualGUID(rfmtid1, rfmtid2) -#ifdef __midl_proxy -#define __MIDL_CONST -#else #define __MIDL_CONST const -#endif #ifndef _REFGUID_DEFINED #define _REFGUID_DEFINED @@ -161,66 +146,9 @@ typedef FMTID* LPFMTID; #endif // !__IID_DEFINED__ -#if !defined (__midl) -#if !defined (_SYS_GUID_OPERATORS_) -#define _SYS_GUID_OPERATORS_ -#include - -// Faster (but makes code fatter) inline version...use sparingly -#ifdef __cplusplus -__inline int InlineIsEqualGUID(REFGUID rguid1, REFGUID rguid2) -{ - return ( - ((unsigned long*)&rguid1)[0] == ((unsigned long*)&rguid2)[0] && - ((unsigned long*)&rguid1)[1] == ((unsigned long*)&rguid2)[1] && - ((unsigned long*)&rguid1)[2] == ((unsigned long*)&rguid2)[2] && - ((unsigned long*)&rguid1)[3] == ((unsigned long*)&rguid2)[3]); -} - __inline int IsEqualGUID(REFGUID rguid1, REFGUID rguid2) { return !memcmp(&rguid1, &rguid2, sizeof(GUID)); } -#else // ! __cplusplus - -#define InlineIsEqualGUID(rguid1, rguid2) \ - (((unsigned long *) rguid1)[0] == ((unsigned long *) rguid2)[0] && \ - ((unsigned long *) rguid1)[1] == ((unsigned long *) rguid2)[1] && \ - ((unsigned long *) rguid1)[2] == ((unsigned long *) rguid2)[2] && \ - ((unsigned long *) rguid1)[3] == ((unsigned long *) rguid2)[3]) - -#define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID))) - -#endif // __cplusplus - -#ifdef __INLINE_ISEQUAL_GUID -#undef IsEqualGUID -#define IsEqualGUID(rguid1, rguid2) InlineIsEqualGUID(rguid1, rguid2) -#endif - -// Same type, different name - -#define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2) -#define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2) - - -#if !defined _SYS_GUID_OPERATOR_EQ_ && !defined _NO_SYS_GUID_OPERATOR_EQ_ -#define _SYS_GUID_OPERATOR_EQ_ -// A couple of C++ helpers - -#ifdef __cplusplus -__inline int operator==(REFGUID guidOne, REFGUID guidOther) -{ - return IsEqualGUID(guidOne, guidOther); -} - -__inline int operator!=(REFGUID guidOne, REFGUID guidOther) -{ - return !(guidOne == guidOther); -} -#endif -#endif // _SYS_GUID_OPERATOR_EQ_ -#endif // _SYS_GUID_OPERATORS_ -#endif // __midl #endif // _GUIDDEF_H_ diff --git a/Src/libCZI/decoder.h b/Src/libCZI/decoder.h index 4165cac1..ee1a416b 100644 --- a/Src/libCZI/decoder.h +++ b/Src/libCZI/decoder.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2017-2022 Carl Zeiss Microscopy GmbH + // SPDX-FileCopyrightText: 2017-2022 Carl Zeiss Microscopy GmbH // // SPDX-License-Identifier: LGPL-3.0-or-later From 26824396b47a1f944e1f38d2618c2a396210b1be Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 10 Sep 2023 14:05:40 +0200 Subject: [PATCH 72/98] cosmetic --- Src/JxrDecode/JxrDecode2.cpp | 5 ++ Src/JxrDecode/jxrlib/common/include/guiddef.h | 81 +------------------ 2 files changed, 6 insertions(+), 80 deletions(-) diff --git a/Src/JxrDecode/JxrDecode2.cpp b/Src/JxrDecode/JxrDecode2.cpp index fee2db13..d62614de 100644 --- a/Src/JxrDecode/JxrDecode2.cpp +++ b/Src/JxrDecode/JxrDecode2.cpp @@ -10,6 +10,11 @@ using namespace std; static void ApplyQuality(float quality, JxrDecode2::PixelFormat pixel_format, std::uint32_t width, PKImageEncode* pEncoder); +static bool IsEqualGUID(const GUID& guid1, const GUID& guid2) +{ + return memcmp(&guid1, &guid2, sizeof(GUID)) == 0; +} + static const char* ERR_to_string(ERR error_code) { switch (error_code) diff --git a/Src/JxrDecode/jxrlib/common/include/guiddef.h b/Src/JxrDecode/jxrlib/common/include/guiddef.h index 351c01e8..eeba7283 100644 --- a/Src/JxrDecode/jxrlib/common/include/guiddef.h +++ b/Src/JxrDecode/jxrlib/common/include/guiddef.h @@ -42,7 +42,6 @@ typedef struct _GUID { unsigned short Data3; unsigned char Data4[8]; } GUID; -#endif #ifndef DECLSPEC_SELECTANY #if (_MSC_VER >= 1100) @@ -73,82 +72,4 @@ typedef struct _GUID { EXTERN_C const GUID name #endif // INITGUID -//#if _MSC_VER < 1900 -//#define DEFINE_OLEGUID(name, l, w1, w2) DEFINE_GUID(name, l, w1, w2, 0xC0,0,0,0,0,0,0,0x46) -//#endif - -#ifndef _GUIDDEF_H_ -#define _GUIDDEF_H_ - -#ifndef __LPGUID_DEFINED__ -#define __LPGUID_DEFINED__ -typedef GUID* LPGUID; -#endif - -#ifndef __LPCGUID_DEFINED__ -#define __LPCGUID_DEFINED__ -typedef const GUID* LPCGUID; -#endif - -#ifndef __IID_DEFINED__ -#define __IID_DEFINED__ - -typedef GUID IID; -typedef IID* LPIID; -#define IID_NULL GUID_NULL -#define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2) -typedef GUID CLSID; -typedef CLSID* LPCLSID; -#define CLSID_NULL GUID_NULL -#define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2) -typedef GUID FMTID; -typedef FMTID* LPFMTID; -#define FMTID_NULL GUID_NULL -#define IsEqualFMTID(rfmtid1, rfmtid2) IsEqualGUID(rfmtid1, rfmtid2) - -#define __MIDL_CONST const - -#ifndef _REFGUID_DEFINED -#define _REFGUID_DEFINED -#ifdef __cplusplus -#define REFGUID const GUID & -#else -#define REFGUID const GUID * __MIDL_CONST -#endif -#endif - -#ifndef _REFIID_DEFINED -#define _REFIID_DEFINED -#ifdef __cplusplus -#define REFIID const IID & -#else -#define REFIID const IID * __MIDL_CONST -#endif -#endif - -#ifndef _REFCLSID_DEFINED -#define _REFCLSID_DEFINED -#ifdef __cplusplus -#define REFCLSID const IID & -#else -#define REFCLSID const IID * __MIDL_CONST -#endif -#endif - -#ifndef _REFFMTID_DEFINED -#define _REFFMTID_DEFINED -#ifdef __cplusplus -#define REFFMTID const IID & -#else -#define REFFMTID const IID * __MIDL_CONST -#endif -#endif - -#endif // !__IID_DEFINED__ - -__inline int IsEqualGUID(REFGUID rguid1, REFGUID rguid2) -{ - return !memcmp(&rguid1, &rguid2, sizeof(GUID)); -} - -#endif // _GUIDDEF_H_ +#endif // GUID_DEFINED From 3c730bdbfe2299998b2e38150707ad80b12a1454 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 10 Sep 2023 14:12:48 +0200 Subject: [PATCH 73/98] cosmetic --- Src/JxrDecode/jxrlib/common/include/guiddef.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Src/JxrDecode/jxrlib/common/include/guiddef.h b/Src/JxrDecode/jxrlib/common/include/guiddef.h index eeba7283..8445ca7c 100644 --- a/Src/JxrDecode/jxrlib/common/include/guiddef.h +++ b/Src/JxrDecode/jxrlib/common/include/guiddef.h @@ -72,4 +72,15 @@ typedef struct _GUID { EXTERN_C const GUID name #endif // INITGUID +/// Returns a non-zero value if the two GUIDs are equal, and zero otherwise. +/// +/// \param guid1 The first unique identifier to compare. +/// \param guid2 The second unique identifier to compare. +/// +/// \returns A non-zero value if the two GUIDs are equal, and zero otherwise. +inline int IsEqualGUID(const GUID* guid1, const GUID* guid2) +{ + return !memcmp(&guid1, &guid2, sizeof(GUID)); +} + #endif // GUID_DEFINED From 5cd27110f0ac24fe20bb0b593e13ca91664da7e9 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 10 Sep 2023 14:13:24 +0200 Subject: [PATCH 74/98] fix --- Src/JxrDecode/jxrlib/common/include/guiddef.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/JxrDecode/jxrlib/common/include/guiddef.h b/Src/JxrDecode/jxrlib/common/include/guiddef.h index 8445ca7c..70723938 100644 --- a/Src/JxrDecode/jxrlib/common/include/guiddef.h +++ b/Src/JxrDecode/jxrlib/common/include/guiddef.h @@ -80,7 +80,7 @@ typedef struct _GUID { /// \returns A non-zero value if the two GUIDs are equal, and zero otherwise. inline int IsEqualGUID(const GUID* guid1, const GUID* guid2) { - return !memcmp(&guid1, &guid2, sizeof(GUID)); + return !memcmp(guid1, guid2, sizeof(GUID)); } #endif // GUID_DEFINED From da3ce5b6a6252abe1f59b469e6fd4f8d26e0502d Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 10 Sep 2023 23:01:54 +0200 Subject: [PATCH 75/98] cosmetic --- Src/JxrDecode/JxrDecode2.cpp | 26 +++++++++++++------------- Src/libCZI/libCZI_compress.h | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Src/JxrDecode/JxrDecode2.cpp b/Src/JxrDecode/JxrDecode2.cpp index d62614de..fbc9988b 100644 --- a/Src/JxrDecode/JxrDecode2.cpp +++ b/Src/JxrDecode/JxrDecode2.cpp @@ -326,7 +326,7 @@ JxrDecode2::CompressedData::~CompressedData() { if (this->obj_handle_ != nullptr) { - CloseWS_HeapBackedWriteableStream((struct tagWMPStream**)&this->obj_handle_); + CloseWS_HeapBackedWriteableStream(reinterpret_cast(&this->obj_handle_)); } } @@ -511,17 +511,17 @@ size_t JxrDecode2::CompressedData::GetSize() ((pixel_format == JxrDecode2::PixelFormat::kBgr48 || pixel_format == JxrDecode2::PixelFormat::kGray16) ? DPK_QPS_16[qi] : (DPK_QPS_32f[qi])); - pEncoder->WMP.wmiSCP.uiDefaultQPIndex = (U8)(0.5f + - (float)pQPs[0] * (1.f - qf) + (float)(pQPs + 6)[0] * qf); - pEncoder->WMP.wmiSCP.uiDefaultQPIndexU = (U8)(0.5f + - (float)pQPs[1] * (1.f - qf) + (float)(pQPs + 6)[1] * qf); - pEncoder->WMP.wmiSCP.uiDefaultQPIndexV = (U8)(0.5f + - (float)pQPs[2] * (1.f - qf) + (float)(pQPs + 6)[2] * qf); - pEncoder->WMP.wmiSCP.uiDefaultQPIndexYHP = (U8)(0.5f + - (float)pQPs[3] * (1.f - qf) + (float)(pQPs + 6)[3] * qf); - pEncoder->WMP.wmiSCP.uiDefaultQPIndexUHP = (U8)(0.5f + - (float)pQPs[4] * (1.f - qf) + (float)(pQPs + 6)[4] * qf); - pEncoder->WMP.wmiSCP.uiDefaultQPIndexVHP = (U8)(0.5f + - (float)pQPs[5] * (1.f - qf) + (float)(pQPs + 6)[5] * qf); + pEncoder->WMP.wmiSCP.uiDefaultQPIndex = static_cast(0.5f + + static_cast(pQPs[0]) * (1.f - qf) + static_cast((pQPs + 6)[0]) * qf); + pEncoder->WMP.wmiSCP.uiDefaultQPIndexU = static_cast(0.5f + + static_cast(pQPs[1]) * (1.f - qf) + static_cast((pQPs + 6)[1]) * qf); + pEncoder->WMP.wmiSCP.uiDefaultQPIndexV = static_cast(0.5f + + static_cast(pQPs[2]) * (1.f - qf) + static_cast((pQPs + 6)[2]) * qf); + pEncoder->WMP.wmiSCP.uiDefaultQPIndexYHP = static_cast(0.5f + + static_cast(pQPs[3]) * (1.f - qf) + static_cast((pQPs + 6)[3]) * qf); + pEncoder->WMP.wmiSCP.uiDefaultQPIndexUHP = static_cast(0.5f + + static_cast(pQPs[4]) * (1.f - qf) + static_cast((pQPs + 6)[4]) * qf); + pEncoder->WMP.wmiSCP.uiDefaultQPIndexVHP = static_cast(0.5f + + static_cast(pQPs[5]) * (1.f - qf) + static_cast((pQPs + 6)[5]) * qf); } } diff --git a/Src/libCZI/libCZI_compress.h b/Src/libCZI/libCZI_compress.h index aa59606f..b11adaa5 100644 --- a/Src/libCZI/libCZI_compress.h +++ b/Src/libCZI/libCZI_compress.h @@ -145,7 +145,7 @@ namespace libCZI } }; - /// This interface is used for representing "compression parameters". It is a simply property bag. + /// This interface is used for representing "compression parameters". It is a simple property bag. /// Possible values for the key are defined in the "CompressionParameter" class. class LIBCZI_API ICompressParameters { From b4e7c16c1e2ab67fd90215e99281b2369f180077 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Fri, 22 Sep 2023 18:12:09 +0200 Subject: [PATCH 76/98] starting cleanup and finalization --- Src/JxrDecode/CMakeLists.txt | 61 +--- Src/JxrDecode/JxrDecode.cpp | 425 ------------------------ Src/JxrDecode/JxrDecode.h | 139 -------- Src/JxrDecode/JxrDecode2.cpp | 47 ++- Src/JxrDecode/JxrDecode2.h | 23 +- Src/libCZI/CMakeLists.txt | 1 + Src/libCZI/decoder.cpp | 43 ++- Src/libCZI/decoder.h | 3 +- Src/libCZI/jxrlibcompress.cpp | 113 +++++++ Src/libCZI/libCZI_compress.h | 21 +- Src/libCZI_UnitTests/test_JxrDecode.cpp | 70 ++-- 11 files changed, 266 insertions(+), 680 deletions(-) delete mode 100644 Src/JxrDecode/JxrDecode.cpp delete mode 100644 Src/JxrDecode/JxrDecode.h create mode 100644 Src/libCZI/jxrlibcompress.cpp diff --git a/Src/JxrDecode/CMakeLists.txt b/Src/JxrDecode/CMakeLists.txt index 23b40e1e..f62bcdd8 100644 --- a/Src/JxrDecode/CMakeLists.txt +++ b/Src/JxrDecode/CMakeLists.txt @@ -9,70 +9,13 @@ include(CheckSymbolExists) include(CheckCSourceCompiles) add_library(JxrDecodeStatic OBJECT - JxrDecode.cpp - ##stdafx.cpp - ##JxrDecode.h - ##stdafx.h - ##targetver.h - ##Jxr/adapthuff.c - #Jxr/decode.c - ##Jxr/encode.c - ##Jxr/image.c - #Jxr/JXRGlue.c - #Jxr/JXRGlueJxr.c - ##Jxr/JXRGluePFC.c - #Jxr/JXRMeta.c - ##Jxr/JXRTest.c - ##Jxr/JXRTestBmp.c - ##Jxr/JXRTestHdr.c - ##Jxr/JXRTestPnm.c - ##Jxr/JXRTestTif.c - ##Jxr/JXRTestWrapper.c - ##Jxr/JXRTestYUV.c - ##Jxr/JXRTranscode.c - ##Jxr/perfTimerANSI.c - ##Jxr/postprocess.c - #Jxr/segdec.c - ##Jxr/segenc.c - #Jxr/strcodec.c - #Jxr/strdec.c - ##Jxr/strdec_x86.c - ##Jxr/strenc.c - ##Jxr/strenc_x86.c - ##Jxr/strFwdTransform.c - #Jxr/strInvTransform.c - ##Jxr/strPredQuant.c - #Jxr/strPredQuantDec.c - ##Jxr/strPredQuantEnc.c - ##Jxr/strTransform.c - #Jxr/common.h - #Jxr/decode.h - ##Jxr/encode.h - #Jxr/JXRGlue.h - #Jxr/JXRMeta.h - ##Jxr/JXRTest.h - ##Jxr/JXRTestWrapper.h - ##Jxr/perfTimer.h - #Jxr/strcodec.h - #Jxr/strTransform.h - #Jxr/windowsmediaphoto.h - ##Jxr/_x86/_x86.h - ##Jxr/priv_guiddef.h - ##Jxr/wmsal.h - #Jxr/wmspecstring.h - #Jxr/wmspecstrings_adt.h - ##Jxr/wmspecstrings_strict.h - ##Jxr/wmspecstrings_undef.h - ##Jxr/jxr_defines.h - "JxrDecode2.h" "JxrDecode2.cpp" "jxrlib/common/include/guiddef.h" "jxrlib/common/include/log.h" + "jxrlib/common/include/log.h" "jxrlib/common/src/log.c" - #"jxrlib/common/include/wmspecstring.h" - #"jxrlib/common/include/wmspecstrings_adt.h" "jxrlib/image/decode/decode.c" "jxrlib/image/decode/decode.h" @@ -106,7 +49,7 @@ add_library(JxrDecodeStatic OBJECT "jxrlib/jxrgluelib/JXRGlueJxr.c" "jxrlib/jxrgluelib/JXRMeta.h" "jxrlib/jxrgluelib/JXRMeta.c" - "jxrlib/jxrgluelib/JXRGluePFC.c" "jxrlib/common/include/log.h" "jxrlib/common/src/log.c") + "jxrlib/jxrgluelib/JXRGluePFC.c") # prepare the configuration-file "JxrDecode_Config.h" diff --git a/Src/JxrDecode/JxrDecode.cpp b/Src/JxrDecode/JxrDecode.cpp deleted file mode 100644 index 0cf46af9..00000000 --- a/Src/JxrDecode/JxrDecode.cpp +++ /dev/null @@ -1,425 +0,0 @@ -// SPDX-FileCopyrightText: 2017-2022 Carl Zeiss Microscopy GmbH -// -// SPDX-License-Identifier: LGPL-3.0-or-later - -#if false -#include -#include -#include -#include "JxrDecode.h" -//#include "Jxr/JXRTest.h" -//#include "Jxr/JXRTestWrapper.h" -//#include "Jxr/JXRGlue.h" -#include "jxrlib/jxrgluelib/JXRGlue.h" - -using namespace JxrDecode; - -//================================================================ -// Encoder factory on file extension -//================================================================ -ERR WmpDecAppCreateEncoderFromExt( - PKCodecFactory* pCFactory, - const char* szExt, - PKImageEncode** ppIE) -{ - ERR err = WMP_errSuccess; -/* const PKIID* pIID = NULL; - - //UNREFERENCED_PARAMETER(pCFactory); - - // get encod PKIID - GetTestEncodeIID(szExt, &pIID); - - // Create encoder - PKTestFactory_CreateCodec(pIID, reinterpret_cast(ppIE)); - */ - //Cleanup: - return err; -} -//********************************************************************************** -//********************************************************************************** - -static const char* ERR_to_string(ERR err) -{ - switch (err) - { - case WMP_errSuccess:return "WMP_errSuccess"; - case WMP_errFail:return "WMP_errFail"; - case WMP_errNotYetImplemented:return "WMP_errNotYetImplemented"; - case WMP_errAbstractMethod:return "WMP_errAbstractMethod"; - case WMP_errOutOfMemory:return "WMP_errOutOfMemory"; - case WMP_errFileIO:return "WMP_errFileIO"; - case WMP_errBufferOverflow:return "WMP_errBufferOverflow"; - case WMP_errInvalidParameter:return "WMP_errInvalidParameter"; - case WMP_errInvalidArgument:return "WMP_errInvalidArgument"; - case WMP_errUnsupportedFormat:return "WMP_errUnsupportedFormat"; - case WMP_errIncorrectCodecVersion:return "WMP_errIncorrectCodecVersion"; - case WMP_errIndexNotFound:return "WMP_errIndexNotFound"; - case WMP_errOutOfSequence:return "WMP_errOutOfSequence"; - case WMP_errNotInitialized:return "WMP_errNotInitialized"; - case WMP_errMustBeMultipleOf16LinesUntilLastCall:return "WMP_errMustBeMultipleOf16LinesUntilLastCall"; - case WMP_errPlanarAlphaBandedEncRequiresTempFile:return "WMP_errPlanarAlphaBandedEncRequiresTempFile"; - case WMP_errAlphaModeCannotBeTranscoded:return "WMP_errAlphaModeCannotBeTranscoded"; - case WMP_errIncorrectCodecSubVersion:return "WMP_errIncorrectCodecSubVersion"; - } - - return "unknown"; -} - - -static void ThrowError(const char* szMsg, ERR err) -{ - std::stringstream ss; - if (szMsg != nullptr) - { - ss << "Error in JXR-decoder -> \"" << szMsg << "\" code:" << err << " (" << ERR_to_string(err) << ")"; - } - else - { - ss << "Error in JXR-decoder -> " << err << " (" << ERR_to_string(err) << ")"; - } - - throw std::runtime_error(ss.str()); -} - -static void ThrowError(ERR err) -{ - ThrowError(nullptr, err); -} - -static const struct PixelFormatAndPkPixelFormat -{ - const PKPixelFormatGUID* pGuid; - PixelFormat pixFmt; -} PixelFormatAndPkPixelFormat[] = -{ - {&GUID_PKPixelFormat24bppBGR, PixelFormat::_24bppBGR}, - {&GUID_PKPixelFormatBlackWhite, PixelFormat::_1bppBlackWhite}, - {&GUID_PKPixelFormat8bppGray, PixelFormat::_8bppGray }, - {&GUID_PKPixelFormat16bppGray, PixelFormat::_16bppGray }, - {&GUID_PKPixelFormat16bppGrayFixedPoint, PixelFormat::_16bppGrayFixedPoint }, - {&GUID_PKPixelFormat16bppGrayHalf, PixelFormat::_16bppGrayHalf }, - {&GUID_PKPixelFormat32bppGrayFixedPoint, PixelFormat::_32bppGrayFixedPoint }, - {&GUID_PKPixelFormat32bppGrayFloat, PixelFormat::_32bppGrayFloat }, - {&GUID_PKPixelFormat24bppRGB, PixelFormat::_24bppRGB }, - {&GUID_PKPixelFormat48bppRGB, PixelFormat::_48bppRGB }, - {&GUID_PKPixelFormat48bppRGBFixedPoint, PixelFormat::_48bppRGBFixedPoint }, - {&GUID_PKPixelFormat48bppRGBHalf, PixelFormat::_48bppRGBHalf }, - {&GUID_PKPixelFormat96bppRGBFixedPoint, PixelFormat::_96bppRGBFixedPoint }, - {&GUID_PKPixelFormat128bppRGBFloat, PixelFormat::_128bppRGBFloat }, - {&GUID_PKPixelFormat32bppRGBE, PixelFormat::_32bppRGBE }, - {&GUID_PKPixelFormat32bppCMYK, PixelFormat::_32bppCMYK }, - {&GUID_PKPixelFormat64bppCMYK, PixelFormat::_64bppCMYK }, - {&GUID_PKPixelFormat32bppBGRA, PixelFormat::_32bppBGRA }, - {&GUID_PKPixelFormat64bppRGBA, PixelFormat::_64bppRGBA }, - {&GUID_PKPixelFormat64bppRGBAFixedPoint, PixelFormat::_64bppRGBAFixedPoint }, - {&GUID_PKPixelFormat64bppRGBAHalf, PixelFormat::_64bppRGBAHalf }, - {&GUID_PKPixelFormat128bppRGBAFixedPoint, PixelFormat::_128bppRGBAFixedPoint }, - {&GUID_PKPixelFormat128bppRGBAFloat, PixelFormat::_128bppRGBAFloat }, - {&GUID_PKPixelFormat16bppRGB555, PixelFormat::_16bppBGR555 }, - {&GUID_PKPixelFormat16bppRGB565, PixelFormat::_16bppBGR565 }, - {&GUID_PKPixelFormat32bppRGB101010, PixelFormat::_32bppBGR101010 }, - {&GUID_PKPixelFormat40bppCMYKAlpha, PixelFormat::_40bppCMYKA }, - {&GUID_PKPixelFormat80bppCMYKAlpha, PixelFormat::_80bppCMYKA }, - {&GUID_PKPixelFormat32bppBGR, PixelFormat::_32bppBGR} -}; - -static PixelFormat PixelFormatFromPkPixelFormat(const PKPixelFormatGUID& pkFixelFmt) -{ - for (int i = 0; i < static_cast(sizeof(PixelFormatAndPkPixelFormat) / sizeof(PixelFormatAndPkPixelFormat[0])); ++i) - { - if (IsEqualGUID(*(PixelFormatAndPkPixelFormat[i].pGuid), pkFixelFmt)) - { - return PixelFormatAndPkPixelFormat[i].pixFmt; - } - } - - return PixelFormat::invalid; -} - -static const PKPixelFormatGUID* PkPixelFormatFromPixelFormat(JxrDecode::PixelFormat pixfmt) -{ - for (int i = 0; i < static_cast(sizeof(PixelFormatAndPkPixelFormat) / sizeof(PixelFormatAndPkPixelFormat[0])); ++i) - { - if (PixelFormatAndPkPixelFormat[i].pixFmt == pixfmt) - { - return PixelFormatAndPkPixelFormat[i].pGuid; - } - } - - throw std::invalid_argument("unknown pixfmt"); -} - -struct CodecHandle -{ - PKFactory* pFactory; - PKCodecFactory* pCodecFactory; -}; - -JxrDecode::codecHandle JxrDecode::Initialize() -{ - PKFactory* pFactory = nullptr; - ERR err = PKCreateFactory(&pFactory, PK_SDK_VERSION); - if (Failed(err)) { ThrowError("PKCreateFactory failed", err); } - std::unique_ptr upFactory(pFactory, [](PKFactory* p)->void {p->Release(&p); }); - - PKCodecFactory* pCodecFactory = NULL; - err = PKCreateCodecFactory(&pCodecFactory, WMP_SDK_VERSION); - if (Failed(err)) { ThrowError("PKCreateCodecFactory failed", err); } - std::unique_ptr upCodecFactory(pCodecFactory, [](PKCodecFactory* p)->void {p->Release(&p); }); - CodecHandle* ch = new CodecHandle{ upFactory.release(), upCodecFactory.release() }; - return reinterpret_cast(ch); -} - -void JxrDecode::Destroy(codecHandle h) -{ - CodecHandle* ch = static_cast(h); - ch->pFactory->Release(&ch->pFactory); - ch->pCodecFactory->Release(&ch->pCodecFactory); - delete ch; -} - -static void DeliverData( - GUID pixeltype, - unsigned int width, - unsigned int height, - unsigned int cLines, - void* ptrData, - unsigned int stride, - void* userParam) -{ - auto deliver = static_cast*>(userParam); - deliver->operator()(PixelFormatFromPkPixelFormat(pixeltype), width, height, cLines, ptrData, stride); -} - -void JxrDecode::Decode(codecHandle h, const WMPDECAPPARGS* decArgs, const void* ptrData, size_t size, const std::function& selectDestPixFmt, std::function deliverData) -{ - CodecHandle* ch = static_cast(h); - WMPStream* pStream; - ERR err = ch->pFactory->CreateStreamFromMemory(&pStream, const_cast(ptrData), size); - if (Failed(err)) { ThrowError("CreateStreamFromMemory failed", err); } - std::unique_ptr upStream(pStream, [](WMPStream* p)->void {p->Close(&p); }); - - PKImageDecode* pDecoder; - ch->pCodecFactory->CreateDecoderFromStream(upStream.get(), &pDecoder); - if (Failed(err)) { ThrowError("CreateDecoderFromStream failed", err); } - std::unique_ptr upDecoder(pDecoder, [](PKImageDecode* p)->void {p->Release(&p); }); - - PKPixelFormatGUID args_guidPixFormat; - PKPixelInfo PI; - if (decArgs->pixFormat == PixelFormat::dontCare) - { - if (selectDestPixFmt) - { - PI.pGUIDPixFmt = &upDecoder->guidPixFormat; - I32 w, h; - upDecoder->GetSize(upDecoder.get(), &w, &h); - PixelFormat pixFmtFromDecoder = PixelFormatFromPkPixelFormat(upDecoder->guidPixFormat); - PixelFormat destFmtChosen = selectDestPixFmt(pixFmtFromDecoder, w, h); - - args_guidPixFormat = *PkPixelFormatFromPixelFormat(destFmtChosen); - //args_guidPixFormat = selectDestPixFmt(*PI.pGUIDPixFmt); - } - else - { - // take decoder color format and try to look up better one - // (e.g. 32bppBGR -> 24bppBGR etc.) - PKPixelInfo newPI; - newPI.pGUIDPixFmt = PI.pGUIDPixFmt = &upDecoder->guidPixFormat; - PixelFormatLookup(&newPI, LOOKUP_FORWARD); - PixelFormatLookup(&newPI, LOOKUP_BACKWARD_TIF); - args_guidPixFormat = *newPI.pGUIDPixFmt; - } - } - else - { - PI.pGUIDPixFmt = PkPixelFormatFromPixelFormat(decArgs->pixFormat); - args_guidPixFormat = *PI.pGUIDPixFmt; - } - - // == color transcoding, - if (IsEqualGUID(args_guidPixFormat, GUID_PKPixelFormat8bppGray) || IsEqualGUID(args_guidPixFormat, GUID_PKPixelFormat16bppGray)) { // ** => Y transcoding - upDecoder->guidPixFormat = args_guidPixFormat; - upDecoder->WMP.wmiI.cfColorFormat = Y_ONLY; - } - else if (IsEqualGUID(args_guidPixFormat, GUID_PKPixelFormat24bppRGB) && upDecoder->WMP.wmiI.cfColorFormat == CMYK) { // CMYK = > RGB - upDecoder->WMP.wmiI.cfColorFormat = CF_RGB; - upDecoder->guidPixFormat = args_guidPixFormat; - upDecoder->WMP.wmiI.bRGB = 1; //RGB - } - - PixelFormatLookup(&PI, LOOKUP_FORWARD); - - std::uint8_t args_uAlphaMode = decArgs->uAlphaMode; - if (255 == args_uAlphaMode)//user didn't set - { - if (!!(PI.grBit & PK_pixfmtHasAlpha)) - args_uAlphaMode = 2;//default is image & alpha for formats with alpha - else - args_uAlphaMode = 0;//otherwise, 0 - } - - upDecoder->WMP.wmiSCP.bfBitstreamFormat = BITSTREAMFORMAT::SPATIAL;// args.bfBitstreamFormat; only used for transcoding? - - upDecoder->WMP.wmiSCP.uAlphaMode = args_uAlphaMode; - - upDecoder->WMP.wmiSCP.sbSubband = (SUBBAND)(std::underlying_type::type)decArgs->sbSubband; - upDecoder->WMP.bIgnoreOverlap = decArgs->bIgnoreOverlap ? 1 : 0; - - upDecoder->WMP.wmiI.cfColorFormat = PI.cfColorFormat; - - upDecoder->WMP.wmiI.bdBitDepth = PI.bdBitDepth; - upDecoder->WMP.wmiI.cBitsPerUnit = PI.cbitUnit; - - //==== Validate thumbnail decode parameters ===== - upDecoder->WMP.wmiI.cThumbnailWidth = upDecoder->WMP.wmiI.cWidth; - upDecoder->WMP.wmiI.cThumbnailHeight = upDecoder->WMP.wmiI.cHeight; - upDecoder->WMP.wmiI.bSkipFlexbits = FALSE; - /*if (args.tThumbnailFactor > 0 && args.tThumbnailFactor != SKIPFLEXBITS) { - size_t tSize = ((size_t)1 << args.tThumbnailFactor); - - pDecoder->WMP.wmiI.cThumbnailWidth = (pDecoder->WMP.wmiI.cWidth + tSize - 1) / tSize; - pDecoder->WMP.wmiI.cThumbnailHeight = (pDecoder->WMP.wmiI.cHeight + tSize - 1) / tSize; - - if (pDecoder->WMP.wmiI.cfColorFormat == YUV_420 || pDecoder->WMP.wmiI.cfColorFormat == YUV_422) { // unsupported thumbnail format - pDecoder->WMP.wmiI.cfColorFormat = YUV_444; - } - } - else if (args.tThumbnailFactor == SKIPFLEXBITS) { - pDecoder->WMP.wmiI.bSkipFlexbits = TRUE; - }*/ - - if (decArgs->rWidth == 0 || decArgs->rHeight == 0) - { // no region decode - upDecoder->WMP.wmiI.cROILeftX = 0; - upDecoder->WMP.wmiI.cROITopY = 0; - upDecoder->WMP.wmiI.cROIWidth = upDecoder->WMP.wmiI.cThumbnailWidth; - upDecoder->WMP.wmiI.cROIHeight = upDecoder->WMP.wmiI.cThumbnailHeight; - } - else - { - upDecoder->WMP.wmiI.cROILeftX = decArgs->rLeftX; - upDecoder->WMP.wmiI.cROITopY = decArgs->rTopY; - upDecoder->WMP.wmiI.cROIWidth = decArgs->rWidth; - upDecoder->WMP.wmiI.cROIHeight = decArgs->rHeight; - } - - upDecoder->WMP.wmiI.oOrientation = static_cast(decArgs->oOrientation); - - upDecoder->WMP.wmiI.cPostProcStrength = decArgs->cPostProcStrength; - - upDecoder->WMP.wmiSCP.bVerbose = 0; - - U32 cFrame; - err = upDecoder->GetFrameCount(upDecoder.get(), &cFrame); - if (Failed(err)) { ThrowError("GetFrameCount failed", err); } - if (cFrame != 1) - { - throw std::logic_error("Not expecting to find more than one image here."); - } - - Float rX = 0, rY = 0; - PKRect rect = { 0, 0, 0, 0 }; - - //================================ - PKFormatConverter* pConverter; - err = ch->pCodecFactory->CreateFormatConverter(&pConverter); - if (Failed(err)) { ThrowError("CreateFormatConverter failed", err); } - std::unique_ptr upConverter(pConverter, [](PKFormatConverter* p)->void {p->Release(&p); }); - - err = upConverter->Initialize(upConverter.get(), upDecoder.get(), nullptr/*pExt*/, args_guidPixFormat); - if (Failed(err)) { ThrowError("Initialize failed", err); } - - PKImageEncode* pEncoder; - err = WmpDecAppCreateEncoderFromExt(ch->pCodecFactory, "wrapper", &pEncoder); - if (Failed(err)) { ThrowError("WmpDecAppCreateEncoderFromExt failed", err); } - std::unique_ptr upEncoder(pEncoder, [](PKImageEncode* p)->void {p->Release(&p); }); - - /*struct tagJxrTestWrapperInitializeInfo wrapperInfo; - wrapperInfo.userParamPutData = &deliverData; - wrapperInfo.pfnPutData = DeliverData; - - err = upEncoder->Initialize(upEncoder.get(), nullptr, &wrapperInfo, sizeof(wrapperInfo)); -*/ if (Failed(err)) { ThrowError("Encoder::Initialize failed", err); } - err = upEncoder->SetPixelFormat(upEncoder.get(), args_guidPixFormat); - if (Failed(err)) { ThrowError("SetPixelFormat failed", err); } - upEncoder->WMP.wmiSCP.bBlackWhite = upDecoder->WMP.wmiSCP.bBlackWhite; - - rect.Width = static_cast(upDecoder->WMP.wmiI.cROIWidth); - rect.Height = static_cast(upDecoder->WMP.wmiI.cROIHeight); - - if (static_cast::type>(decArgs->oOrientation) > static_cast::type>(Orientation::O_FLIPVH)) - { - // allocate memory for rotated image! - I32 bah = rect.Width; - - rect.Width = rect.Height; - rect.Height = bah; - } - - err = upEncoder->SetSize(upEncoder.get(), rect.Width, rect.Height); - if (Failed(err)) { ThrowError("SetSize failed", err); } - err = upDecoder->GetResolution(upDecoder.get(), &rX, &rY); - if (Failed(err)) { ThrowError("GetResolution failed", err); } - - if (static_cast::type>(decArgs->oOrientation) > static_cast::type>(O_FLIPVH)) - { - upEncoder->SetResolution(upEncoder.get(), rY, rX); - } - else - { - upEncoder->SetResolution(upEncoder.get(), rX, rY); - } - - //================================ - upEncoder->WriteSource = PKImageEncode_Transcode; - err = upEncoder->WriteSource(upEncoder.get(), upConverter.get(), &rect); - if (Failed(err)) { ThrowError("WriteSource failed", err); } - - //================================ - err = upEncoder->Terminate(upEncoder.get()); - if (Failed(err)) { ThrowError("Release (encoder) failed", err); } - - upDecoder->SelectFrame(upDecoder.get(), 1); - if (Failed(err)) { ThrowError("SelectFrame failed", err); } -} - -const char* JxrDecode::PixelFormatAsInformalString(PixelFormat pfmt) -{ - switch (pfmt) - { - case PixelFormat::dontCare:return "dontCare"; - case PixelFormat::_24bppBGR:return "24bppBGR"; - case PixelFormat::_1bppBlackWhite:return "1bppBlackWhite"; - case PixelFormat::_8bppGray:return "8bppGray"; - case PixelFormat::_16bppGray:return "16bppGray"; - case PixelFormat::_16bppGrayFixedPoint:return "16bppGrayFixedPoint"; - case PixelFormat::_16bppGrayHalf:return "16bppGrayHalf"; - case PixelFormat::_32bppGrayFixedPoint:return "32bppGrayFixedPoint"; - case PixelFormat::_32bppGrayFloat:return "32bppGrayFloat"; - case PixelFormat::_24bppRGB:return "24bppRGB"; - case PixelFormat::_48bppRGB:return "48bppRGB"; - case PixelFormat::_48bppRGBFixedPoint:return "48bppRGBFixedPoint"; - case PixelFormat::_48bppRGBHalf:return "48bppRGBHalf"; - case PixelFormat::_96bppRGBFixedPoint:return "96bppRGBFixedPoint"; - case PixelFormat::_128bppRGBFloat:return "128bppRGBFloat"; - case PixelFormat::_32bppRGBE:return "32bppRGBE"; - case PixelFormat::_32bppCMYK:return "32bppCMYK"; - case PixelFormat::_64bppCMYK:return "64bppCMYK"; - case PixelFormat::_32bppBGRA:return "32bppBGRA"; - case PixelFormat::_64bppRGBA:return "64bppRGBA"; - case PixelFormat::_64bppRGBAFixedPoint:return "64bppRGBAFixedPoint"; - case PixelFormat::_64bppRGBAHalf:return "64bppRGBAHalf"; - case PixelFormat::_128bppRGBAFixedPoint:return "128bppRGBAFixedPoint"; - case PixelFormat::_128bppRGBAFloat:return "128bppRGBAFloat"; - case PixelFormat::_16bppBGR555:return "16bppBGR555"; - case PixelFormat::_16bppBGR565:return "16bppBGR565"; - case PixelFormat::_32bppBGR101010:return "32bppBGR101010"; - case PixelFormat::_40bppCMYKA:return "40bppCMYKA"; - case PixelFormat::_80bppCMYKA:return "80bppCMYKA"; - case PixelFormat::_32bppBGR:return "32bppBGR"; - case PixelFormat::invalid:return "invalid"; - default:return "unknwon"; - } -} -#endif diff --git a/Src/JxrDecode/JxrDecode.h b/Src/JxrDecode/JxrDecode.h deleted file mode 100644 index 41b1c081..00000000 --- a/Src/JxrDecode/JxrDecode.h +++ /dev/null @@ -1,139 +0,0 @@ -// SPDX-FileCopyrightText: 2017-2022 Carl Zeiss Microscopy GmbH -// -// SPDX-License-Identifier: LGPL-3.0-or-later - -#pragma once - -#if false -#include -#include -#include - -namespace JxrDecode -{ - enum class PixelFormat - { - dontCare, - _24bppBGR, - _1bppBlackWhite, - _8bppGray, - _16bppGray, - _16bppGrayFixedPoint, - _16bppGrayHalf, - _32bppGrayFixedPoint, - _32bppGrayFloat, - _24bppRGB, - _48bppRGB, - _48bppRGBFixedPoint, - _48bppRGBHalf, - _96bppRGBFixedPoint, - _128bppRGBFloat, - _32bppRGBE, - _32bppCMYK, - _64bppCMYK, - _32bppBGRA, - _64bppRGBA, - _64bppRGBAFixedPoint, - _64bppRGBAHalf, - _128bppRGBAFixedPoint, - _128bppRGBAFloat, - _16bppBGR555, - _16bppBGR565, - _32bppBGR101010, - _40bppCMYKA, - _80bppCMYKA, - _32bppBGR, - - invalid - }; - - const char* PixelFormatAsInformalString(PixelFormat pfmt); - - enum class Orientation :std::uint8_t - { - // 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 - }; - - enum class Subband : std::uint8_t - { - 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 - }; - - struct WMPDECAPPARGS - { - JxrDecode::PixelFormat pixFormat; - - // region decode - size_t rLeftX; - size_t rTopY; - size_t rWidth; - size_t rHeight; - - std::uint8_t cPostProcStrength; - JxrDecode::Orientation oOrientation; - JxrDecode::Subband sbSubband; - /* // thumbnail - size_t tThumbnailFactor; - - // orientation - ORIENTATION oOrientation; - - // post processing - U8 cPostProcStrength; - */ - std::uint8_t uAlphaMode; // 0:no alpha 1: alpha only else: something + alpha - /* - SUBBAND sbSubband; // which subbands to keep (for transcoding) - - BITSTREAMFORMAT bfBitstreamFormat; // desired bitsream format (for transcoding) - - CWMIStrCodecParam wmiSCP; - - Bool bIgnoreOverlap;*/ - bool bIgnoreOverlap; - - void Clear() - { - memset(this, 0, sizeof(*this)); - this->pixFormat = JxrDecode::PixelFormat::dontCare; - //args->bVerbose = FALSE; - //args->tThumbnailFactor = 0; - this->oOrientation = Orientation::O_NONE; - this->cPostProcStrength = 0; - this->uAlphaMode = 255; - this->sbSubband = JxrDecode::Subband::SB_ALL; - } - }; - - - typedef void* codecHandle; - - codecHandle Initialize(); - - void Decode( - codecHandle h, - const WMPDECAPPARGS* decArgs, - const void* ptrData, - size_t size, - const std::function& selectDestPixFmt, - std::function deliverData); - - void Destroy(codecHandle h); -} -#endif diff --git a/Src/JxrDecode/JxrDecode2.cpp b/Src/JxrDecode/JxrDecode2.cpp index fbc9988b..5259c186 100644 --- a/Src/JxrDecode/JxrDecode2.cpp +++ b/Src/JxrDecode/JxrDecode2.cpp @@ -12,7 +12,7 @@ static void ApplyQuality(float quality, JxrDecode2::PixelFormat pixel_format, st static bool IsEqualGUID(const GUID& guid1, const GUID& guid2) { - return memcmp(&guid1, &guid2, sizeof(GUID)) == 0; + return memcmp(&guid1, &guid2, sizeof(GUID)) == 0; } static const char* ERR_to_string(ERR error_code) @@ -187,6 +187,32 @@ void JxrDecode2::Decode( throw invalid_argument("ptr_bitmap"); } + if (quality < 0.f || quality > 1.f) + { + throw invalid_argument("quality"); + } + + if (width == 0) + { + throw invalid_argument("width"); + } + + if (height == 0) + { + throw invalid_argument("height"); + } + + const auto bytes_per_pel = JxrDecode2::GetBytesPerPel(pixel_format); + if (bytes_per_pel == 0xff) + { + throw invalid_argument("pixel_format"); + } + + if (stride < width * bytes_per_pel) + { + throw invalid_argument("stride"); + } + PKImageEncode* pImageEncoder; ERR err = PKCodecFactory_CreateCodec(&IID_PKImageWmpEncode, reinterpret_cast(&pImageEncoder)); if (Failed(err)) @@ -350,6 +376,25 @@ size_t JxrDecode2::CompressedData::GetSize() return size; } +/*static*/std::uint8_t JxrDecode2::GetBytesPerPel(PixelFormat pixel_format) +{ + switch (pixel_format) + { + case PixelFormat::kBgr24: + return 3; + case PixelFormat::kBgr48: + return 6; + case PixelFormat::kGray8: + return 1; + case PixelFormat::kGray16: + return 2; + case PixelFormat::kGray32Float: + return 4; + } + + return 0xff; +} + /*static*/void ApplyQuality(float quality, JxrDecode2::PixelFormat pixel_format, uint32_t width, PKImageEncode* pEncoder) { // this is resembling the code from https://github.com/ptahmose/jxrlib/blob/f7521879862b9085318e814c6157490dd9dbbdb4/jxrencoderdecoder/JxrEncApp.c#L677C1-L738C10 diff --git a/Src/JxrDecode/JxrDecode2.h b/Src/JxrDecode/JxrDecode2.h index 88aaa6e6..ea074d08 100644 --- a/Src/JxrDecode/JxrDecode2.h +++ b/Src/JxrDecode/JxrDecode2.h @@ -31,6 +31,12 @@ class JxrDecode2 void* obj_handle_; public: CompressedData() :obj_handle_(nullptr) {} // default constructor + + /// This method moves a CompressedData object into the current object via swapping. + /// + /// \param other The CompressedData object to move + /// + /// \returns A reference to the current object after the move has been completed. CompressedData& operator=(CompressedData&& other) noexcept { // "other" is soon going to be destroyed, so we let it destroy our current resource instead and we take "other"'s current resource via swapping @@ -38,7 +44,9 @@ class JxrDecode2 return *this; } - // move constructor, takes a rvalue reference && + /// This method moves a CompressedData object into the current object via swapping. + /// + /// \param other The CompressedData object to move CompressedData(CompressedData&& other) noexcept { // we "steal" the resource from "other" @@ -89,6 +97,18 @@ class JxrDecode2 size_t size, const std::function(PixelFormat pixel_format, std::uint32_t width, std::uint32_t height)>& get_destination_func); + /// Compresses the specified bitmap into the JXR (aka JPEG XR) format. + /// + /// \param pixel_format The pixel type. + /// \param width The width of the bitmap in pixels. + /// \param height The height of the bitmap in pixels. + /// \param stride The stride of the bitmap in bytes. + /// \param ptr_bitmap A pointer to the uncompressed bitmap data. + /// \param quality A parameter that controls the quality of the compression. This is a number between 0 and 1, + /// and the higher the number, the better the quality. The default is 1. A value of 1 gives the best + /// possible quality which is loss-less. + /// + /// \returns A CompressedData object containing the compressed data. static CompressedData Encode( JxrDecode2::PixelFormat pixel_format, std::uint32_t width, @@ -99,4 +119,5 @@ class JxrDecode2 private: static void ThrowJxrlibError(const std::string& message, int error_code); [[noreturn]] static void ThrowJxrlibError(std::ostringstream& message, int error_code); + static std::uint8_t GetBytesPerPel(PixelFormat pixel_format); }; diff --git a/Src/libCZI/CMakeLists.txt b/Src/libCZI/CMakeLists.txt index ffd313e8..e2a35ab7 100644 --- a/Src/libCZI/CMakeLists.txt +++ b/Src/libCZI/CMakeLists.txt @@ -103,6 +103,7 @@ set(LIBCZISRCFILES BitmapOperations.hpp pugiconfig.hpp pugixml.hpp + jxrlibcompress.cpp ) # prepare the configuration-file "libCZI_Config.h" diff --git a/Src/libCZI/decoder.cpp b/Src/libCZI/decoder.cpp index 465bf8c3..e2f809ef 100644 --- a/Src/libCZI/decoder.cpp +++ b/Src/libCZI/decoder.cpp @@ -3,7 +3,6 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include "decoder.h" -#include "../JxrDecode/JxrDecode.h" #include "../JxrDecode/JxrDecode2.h" #include "bitmapData.h" #include "stdAllocator.h" @@ -13,25 +12,25 @@ using namespace libCZI; using namespace std; -class MemoryBlockOnCompressedData : public libCZI::IMemoryBlock -{ -private: - mutable JxrDecode2::CompressedData compressed_data_; -public: - MemoryBlockOnCompressedData(JxrDecode2::CompressedData&& compressed_data) - : compressed_data_(std::move(compressed_data)) - {} - - void* GetPtr() override - { - return this->compressed_data_.GetMemory(); - } - - size_t GetSizeOfData() const override - { - return this->compressed_data_.GetSize(); - } -}; +//class MemoryBlockOnCompressedData : public libCZI::IMemoryBlock +//{ +//private: +// mutable JxrDecode2::CompressedData compressed_data_; +//public: +// MemoryBlockOnCompressedData(JxrDecode2::CompressedData&& compressed_data) +// : compressed_data_(std::move(compressed_data)) +// {} +// +// void* GetPtr() override +// { +// return this->compressed_data_.GetMemory(); +// } +// +// size_t GetSizeOfData() const override +// { +// return this->compressed_data_.GetSize(); +// } +//}; static libCZI::PixelType PixelTypeFromJxrPixelFormat(JxrDecode2::PixelFormat pixel_format) { @@ -58,7 +57,7 @@ static libCZI::PixelType PixelTypeFromJxrPixelFormat(JxrDecode2::PixelFormat pix return make_shared(); } -std::shared_ptr CJxrLibDecoder::Encode(libCZI::PixelType pixel_type, std::uint32_t width, std::uint32_t height, std::uint32_t stride, const void* ptrData, float quality) +/*std::shared_ptr CJxrLibDecoder::Encode(libCZI::PixelType pixel_type, std::uint32_t width, std::uint32_t height, std::uint32_t stride, const void* ptrData, float quality) { JxrDecode2::PixelFormat jxrdecode_pixel_format; switch (pixel_type) @@ -120,7 +119,7 @@ std::shared_ptr CJxrLibDecoder::Encode(libCZI::PixelType p quality); return make_shared(std::move(compressed_data)); } -} +}*/ std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, size_t size, libCZI::PixelType pixelType, uint32_t width, uint32_t height) { diff --git a/Src/libCZI/decoder.h b/Src/libCZI/decoder.h index ee1a416b..9cb00041 100644 --- a/Src/libCZI/decoder.h +++ b/Src/libCZI/decoder.h @@ -7,7 +7,6 @@ #include #include "libCZI_Pixels.h" #include "libCZI_compress.h" -#include "../JxrDecode/JxrDecode.h" #include "libCZI_Site.h" class CJxrLibDecoder : public libCZI::IDecoder @@ -25,5 +24,5 @@ class CJxrLibDecoder : public libCZI::IDecoder std::shared_ptr Decode(const void* ptrData, size_t size, libCZI::PixelType, std::uint32_t width, std::uint32_t height) override; //std::shared_ptr Decode2(const void* ptrData, size_t size, libCZI::PixelType, std::uint32_t width, std::uint32_t height); - std::shared_ptr Encode(libCZI::PixelType pixel_type, std::uint32_t width, std::uint32_t height, std::uint32_t stride, const void* ptrData, float quality = 1.f); + // std::shared_ptr Encode(libCZI::PixelType pixel_type, std::uint32_t width, std::uint32_t height, std::uint32_t stride, const void* ptrData, float quality = 1.f); }; diff --git a/Src/libCZI/jxrlibcompress.cpp b/Src/libCZI/jxrlibcompress.cpp new file mode 100644 index 00000000..0c2000ae --- /dev/null +++ b/Src/libCZI/jxrlibcompress.cpp @@ -0,0 +1,113 @@ +// SPDX-FileCopyrightText: 2017-2023 Carl Zeiss Microscopy GmbH +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#include "libCZI_compress.h" +#include "../JxrDecode/JxrDecode2.h" +#include "BitmapOperations.h" +#include "Site.h" + +using namespace libCZI; +using namespace std; + +class MemoryBlockOnCompressedData : public libCZI::IMemoryBlock +{ +private: + mutable JxrDecode2::CompressedData compressed_data_; +public: + MemoryBlockOnCompressedData(JxrDecode2::CompressedData&& compressed_data) + : compressed_data_(std::move(compressed_data)) + {} + + void* GetPtr() override + { + return this->compressed_data_.GetMemory(); + } + + size_t GetSizeOfData() const override + { + return this->compressed_data_.GetSize(); + } +}; + +/*static*/ std::shared_ptr JxrLibCompress::Compress( + libCZI::PixelType pixel_type, + std::uint32_t width, + std::uint32_t height, + std::uint32_t stride, + const void* ptrData, + const ICompressParameters* parameters) +{ + JxrDecode2::PixelFormat jxrdecode_pixel_format; + switch (pixel_type) + { + case PixelType::Bgr24: + jxrdecode_pixel_format = JxrDecode2::PixelFormat::kBgr24; + break; + case PixelType::Bgr48: + jxrdecode_pixel_format = JxrDecode2::PixelFormat::kBgr48; + break; + case PixelType::Gray8: + jxrdecode_pixel_format = JxrDecode2::PixelFormat::kGray8; + break; + case PixelType::Gray16: + jxrdecode_pixel_format = JxrDecode2::PixelFormat::kGray16; + break; + case PixelType::Gray32Float: + jxrdecode_pixel_format = JxrDecode2::PixelFormat::kGray32Float; + break; + default: + throw std::logic_error("unsupported pixel type"); + } + + float quality = 1.f; + if (parameters != nullptr) + { + CompressParameter parameter; + if (parameters->TryGetProperty(CompressionParameterKey::JXRLIB_QUALITY, ¶meter) && + parameter.GetType() == CompressParameter::Type::Uint32) + { + quality = parameter.GetUInt32() / 1000.0f; + quality = std::max(0.0f, std::min(1.0f, quality)); + } + } + + // Unfortunately, the encoder does not support the pixel format Bgr48, so we need to convert it to Rgb48 + // before passing it to the encoder (meaning: the resulting encoded data will be Rgb48, not Bgr48). + // TODO(JBL): would be nice if the encoder would support Bgr48 directly somehow + if (jxrdecode_pixel_format == JxrDecode2::PixelFormat::kBgr48) + { + // unfortunately, we have to make a temporary copy + const auto bitmap_rgb48 = GetSite()->CreateBitmap(PixelType::Bgr48, width, height); + + const ScopedBitmapLockerSP bmLck(bitmap_rgb48); + CBitmapOperations::CopySamePixelType( + ptrData, + stride, + bmLck.ptrDataRoi, + bmLck.stride, + width, + height, + false); + CBitmapOperations::RGB48ToBGR48(width, height, static_cast(bmLck.ptrDataRoi), bmLck.stride); + auto compressed_data = JxrDecode2::Encode( + jxrdecode_pixel_format, + width, + height, + bmLck.stride, + bmLck.ptrDataRoi, + quality); + return make_shared(std::move(compressed_data)); + } + else + { + auto compressed_data = JxrDecode2::Encode( + jxrdecode_pixel_format, + width, + height, + stride, + ptrData, + quality); + return make_shared(std::move(compressed_data)); + } +} diff --git a/Src/libCZI/libCZI_compress.h b/Src/libCZI/libCZI_compress.h index b11adaa5..a9669cd7 100644 --- a/Src/libCZI/libCZI_compress.h +++ b/Src/libCZI/libCZI_compress.h @@ -24,7 +24,12 @@ namespace libCZI /// Whether to do the "lo-hi-byte-packing" preprocessing (type: boolean). /// This parameter is used with the "zstd1" compression scheme only. - ZSTD_PREPROCESS_DOLOHIBYTEPACKING = 2 + ZSTD_PREPROCESS_DOLOHIBYTEPACKING = 2, + + /// The quality parameter for the jxrlib encoder (type: uint32). The range is from 0 to 1000, where 1000 + /// gives the best quality (i.e. loss-less compression). This parameter is used with the "jxrlib" compression scheme only. + /// If value is out-of-range, it will be clipped. + JXRLIB_QUALITY = 3, }; /// Simple variant type used for the compression-parameters-property-bag. @@ -505,7 +510,7 @@ namespace libCZI /// \param sourceWidth Width of the source bitmap in pixels. /// \param sourceHeight Height of the source bitmap in pixels. /// \param sourceStride The stride of the source bitmap in bytes. - /// \param sourcePixeltype The pixeltype of the source bitmap. + /// \param sourcePixeltype The pixel type of the source bitmap. /// \param source Pointer to the source bitmap. /// \param parameters Property bag containing parameters controlling the operation. This argument can be null, in which case default parameters are used. /// \returns A shared pointer to an object representing and owning a block of memory. @@ -518,6 +523,18 @@ namespace libCZI const ICompressParameters* parameters); }; + class LIBCZI_API JxrLibCompress + { + public: + static std::shared_ptr Compress( + libCZI::PixelType pixel_type, + std::uint32_t width, + std::uint32_t height, + std::uint32_t stride, + const void* ptrData, + const ICompressParameters* parameters); + }; + /// Simplistic implementation of the compression-parameters property bag. Note that for high-performance scenarios /// it might be a good idea to re-use instances of this, or have a custom implementation without heap-allocation /// penalty. diff --git a/Src/libCZI_UnitTests/test_JxrDecode.cpp b/Src/libCZI_UnitTests/test_JxrDecode.cpp index d2a330ef..1592fc9e 100644 --- a/Src/libCZI_UnitTests/test_JxrDecode.cpp +++ b/Src/libCZI_UnitTests/test_JxrDecode.cpp @@ -70,18 +70,18 @@ TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Bgr24) const ScopedBitmapLockerSP lck{ bitmap }; CTestImage::CopyBgr24Image(lck.ptrDataRoi, bitmap->GetWidth(), bitmap->GetHeight(), lck.stride); } - - const auto codec = CJxrLibDecoder::Create(); + shared_ptr encodedData; { const ScopedBitmapLockerSP lck{ bitmap }; - encodedData = codec->Encode( + encodedData = JxrLibCompress::Compress( bitmap->GetPixelType(), bitmap->GetWidth(), bitmap->GetHeight(), lck.stride, - lck.ptrDataRoi); + lck.ptrDataRoi, + nullptr); } void* encoded_data_ptr = encodedData->GetPtr(); @@ -90,6 +90,7 @@ TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Bgr24) ASSERT_LT(size_of_encoded_data, static_cast(Utils::GetBytesPerPixel(bitmap->GetPixelType()) * bitmap->GetWidth() * bitmap->GetHeight())) << "Encoded data is too large (larger than the original data), which is unexpected."; + const auto codec = CJxrLibDecoder::Create(); const auto bitmap_decoded = codec->Decode( encodedData->GetPtr(), encodedData->GetSizeOfData(), @@ -119,17 +120,17 @@ TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Gray8) } } - const auto codec = CJxrLibDecoder::Create(); shared_ptr encodedData; { const ScopedBitmapLockerSP lck{ bitmap }; - encodedData = codec->Encode( + encodedData = JxrLibCompress::Compress( bitmap->GetPixelType(), bitmap->GetWidth(), bitmap->GetHeight(), lck.stride, - lck.ptrDataRoi); + lck.ptrDataRoi, + nullptr); } void* encoded_data_ptr = encodedData->GetPtr(); @@ -138,6 +139,7 @@ TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Gray8) ASSERT_LT(size_of_encoded_data, static_cast(Utils::GetBytesPerPixel(bitmap->GetPixelType()) * bitmap->GetWidth() * bitmap->GetHeight())) << "Encoded data is too large (larger than the original data), which is unexpected."; + const auto codec = CJxrLibDecoder::Create(); const auto bitmap_decoded = codec->Decode( encodedData->GetPtr(), encodedData->GetSizeOfData(), @@ -170,17 +172,17 @@ TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Gray16) } } - const auto codec = CJxrLibDecoder::Create(); shared_ptr encodedData; { const ScopedBitmapLockerSP lck{ bitmap_gray16 }; - encodedData = codec->Encode( + encodedData = JxrLibCompress::Compress( bitmap_gray16->GetPixelType(), bitmap_gray16->GetWidth(), bitmap_gray16->GetHeight(), lck.stride, - lck.ptrDataRoi); + lck.ptrDataRoi, + nullptr); } void* encoded_data_ptr = encodedData->GetPtr(); @@ -189,6 +191,7 @@ TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Gray16) ASSERT_LT(size_of_encoded_data, static_cast(Utils::GetBytesPerPixel(bitmap_gray16->GetPixelType()) * bitmap_gray16->GetWidth() * bitmap_gray16->GetHeight())) << "Encoded data is too large (larger than the original data), which is unexpected."; + const auto codec = CJxrLibDecoder::Create(); const auto bitmap_decoded = codec->Decode( encodedData->GetPtr(), encodedData->GetSizeOfData(), @@ -221,17 +224,17 @@ TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Gray32Float) } } - const auto codec = CJxrLibDecoder::Create(); shared_ptr encodedData; { const ScopedBitmapLockerSP lck{ bitmap_gray32float }; - encodedData = codec->Encode( + encodedData = JxrLibCompress::Compress( bitmap_gray32float->GetPixelType(), bitmap_gray32float->GetWidth(), bitmap_gray32float->GetHeight(), lck.stride, - lck.ptrDataRoi); + lck.ptrDataRoi, + nullptr); } void* encoded_data_ptr = encodedData->GetPtr(); @@ -240,6 +243,7 @@ TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Gray32Float) ASSERT_LT(size_of_encoded_data, static_cast(Utils::GetBytesPerPixel(bitmap_gray32float->GetPixelType()) * bitmap_gray32float->GetWidth() * bitmap_gray32float->GetHeight())) << "Encoded data is too large (larger than the original data), which is unexpected."; + const auto codec = CJxrLibDecoder::Create(); const auto bitmap_decoded = codec->Decode( encodedData->GetPtr(), encodedData->GetSizeOfData(), @@ -274,17 +278,17 @@ TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Bgr48) } } - const auto codec = CJxrLibDecoder::Create(); shared_ptr encodedData; { const ScopedBitmapLockerSP lck{ bitmap_bgr48 }; - encodedData = codec->Encode( + encodedData = JxrLibCompress::Compress( bitmap_bgr48->GetPixelType(), bitmap_bgr48->GetWidth(), bitmap_bgr48->GetHeight(), lck.stride, - lck.ptrDataRoi); + lck.ptrDataRoi, + nullptr); } void* encoded_data_ptr = encodedData->GetPtr(); @@ -293,6 +297,7 @@ TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Bgr48) ASSERT_LT(size_of_encoded_data, static_cast(Utils::GetBytesPerPixel(bitmap_bgr48->GetPixelType()) * bitmap_bgr48->GetWidth() * bitmap_bgr48->GetHeight())) << "Encoded data is too large (larger than the original data), which is unexpected."; + const auto codec = CJxrLibDecoder::Create(); const auto bitmap_decoded = codec->Decode( encodedData->GetPtr(), encodedData->GetSizeOfData(), @@ -322,18 +327,19 @@ TEST(JxrDecode, CompressLossyAndDecompressCheckForSimilarity_Gray8) } } - const auto codec = CJxrLibDecoder::Create(); shared_ptr encodedData; { const ScopedBitmapLockerSP lck{ bitmap }; - encodedData = codec->Encode( + libCZI::CompressParametersOnMap params; + params.map[static_cast(libCZI::CompressionParameterKey::JXRLIB_QUALITY)] = libCZI::CompressParameter(900u); + encodedData = JxrLibCompress::Compress( bitmap->GetPixelType(), bitmap->GetWidth(), bitmap->GetHeight(), lck.stride, lck.ptrDataRoi, - 0.9f); + ¶ms); } void* encoded_data_ptr = encodedData->GetPtr(); @@ -348,6 +354,7 @@ TEST(JxrDecode, CompressLossyAndDecompressCheckForSimilarity_Gray8) fclose(fp); */ + const auto codec = CJxrLibDecoder::Create(); const auto bitmap_decoded = codec->Decode( encodedData->GetPtr(), encodedData->GetSizeOfData(), @@ -361,59 +368,64 @@ TEST(JxrDecode, CompressLossyAndDecompressCheckForSimilarity_Gray8) TEST(JxrDecode, CallEncoderWithInvalidArgumentsExpectException) { const auto bitmap = CBitmapData::Create(PixelType::Gray8, 5, 5); - const auto codec = CJxrLibDecoder::Create(); + //const auto codec = CJxrLibDecoder::Create(); EXPECT_THROW( { const ScopedBitmapLockerSP lck{ bitmap }; - codec->Encode( + JxrLibCompress::Compress( PixelType::Invalid, bitmap->GetWidth(), bitmap->GetHeight(), lck.stride, - lck.ptrDataRoi); + lck.ptrDataRoi, + nullptr); }, exception); EXPECT_THROW( { const ScopedBitmapLockerSP lck{ bitmap }; - codec->Encode( + JxrLibCompress::Compress( bitmap->GetPixelType(), bitmap->GetWidth(), bitmap->GetHeight(), 4, // invalid stride provided here - lck.ptrDataRoi); + lck.ptrDataRoi, + nullptr); }, exception); EXPECT_THROW( { const ScopedBitmapLockerSP lck{ bitmap }; - codec->Encode( + JxrLibCompress::Compress( bitmap->GetPixelType(), bitmap->GetWidth(), 0, lck.stride, - lck.ptrDataRoi); + lck.ptrDataRoi, + nullptr); }, exception); EXPECT_THROW( { const ScopedBitmapLockerSP lck{ bitmap }; - codec->Encode( + JxrLibCompress::Compress( bitmap->GetPixelType(), 0, bitmap->GetHeight(), lck.stride, - lck.ptrDataRoi); + lck.ptrDataRoi, + nullptr); }, exception); EXPECT_THROW( { const ScopedBitmapLockerSP lck{ bitmap }; - codec->Encode( + JxrLibCompress::Compress( bitmap->GetPixelType(), bitmap->GetWidth(), bitmap->GetHeight(), lck.stride, + nullptr, nullptr); }, exception); From be8a81a272d3dbf9f56a40aca2a769577d9c7a3a Mon Sep 17 00:00:00 2001 From: ptahmose Date: Fri, 22 Sep 2023 23:09:07 +0200 Subject: [PATCH 77/98] update --- Src/CZICmd/cmdlineoptions.cpp | 4 ++-- Src/CZICmd/cmdlineoptions.h | 6 ++--- Src/CZICmd/executeCreateCzi.cpp | 2 +- Src/CZICmd/utils.cpp | 23 ++++++++++++++++--- Src/CZICmd/utils.h | 5 ++-- Src/JxrDecode/CMakeLists.txt | 4 ++-- .../{JxrDecode2.cpp => JxrDecode.cpp} | 2 +- Src/JxrDecode/{JxrDecode2.h => JxrDecode.h} | 0 Src/libCZI/decoder.cpp | 2 +- Src/libCZI/jxrlibcompress.cpp | 2 +- 10 files changed, 34 insertions(+), 16 deletions(-) rename Src/JxrDecode/{JxrDecode2.cpp => JxrDecode.cpp} (99%) rename Src/JxrDecode/{JxrDecode2.h => JxrDecode.h} (100%) diff --git a/Src/CZICmd/cmdlineoptions.cpp b/Src/CZICmd/cmdlineoptions.cpp index 1a8f9068..b7bdd4da 100644 --- a/Src/CZICmd/cmdlineoptions.cpp +++ b/Src/CZICmd/cmdlineoptions.cpp @@ -1818,9 +1818,9 @@ std::shared_ptr CCmdLineOptions::GetSceneIndexSet() const return CCmdLineOptions::TryParseInt32(s, font_height); } -/*static*/bool CCmdLineOptions::TryParseNewCziFileguid(const std::string& s, GUID* guid) +/*static*/bool CCmdLineOptions::TryParseNewCziFileguid(const std::string& s, libCZI::GUID* guid) { - GUID g; + libCZI::GUID g; bool b = TryParseGuid(convertUtf8ToUCS2(s), &g); if (!b) { diff --git a/Src/CZICmd/cmdlineoptions.h b/Src/CZICmd/cmdlineoptions.h index 30bc5799..c6b9c608 100644 --- a/Src/CZICmd/cmdlineoptions.h +++ b/Src/CZICmd/cmdlineoptions.h @@ -178,7 +178,7 @@ class CCmdLineOptions int fontHeight; bool newCziFileGuidValid; - GUID newCziFileGuid; + libCZI::GUID newCziFileGuid; std::string bitmapGeneratorClassName; @@ -246,7 +246,7 @@ class CCmdLineOptions std::wstring GetFontNameOrFile() const { return this->fontnameOrFile; } int GetFontHeight() const { return this->fontHeight; } bool GetIsFileGuidValid()const { return this->newCziFileGuidValid; } - const GUID& GetFileGuid()const { return this->newCziFileGuid; } + const libCZI::GUID& GetFileGuid()const { return this->newCziFileGuid; } const std::string& GetBitmapGeneratorClassName()const { return this->bitmapGeneratorClassName; } const std::map& GetSubBlockKeyValueMetadata()const { return this->sbBlkMetadataKeyValue; } bool GetHasSubBlockKeyValueMetadata()const { return this->sbBlkMetadataKeyValueValid; } @@ -296,7 +296,7 @@ class CCmdLineOptions static bool TryParseCreateSize(const std::string& s, std::tuple* size); static bool TryParseCreateTileInfo(const std::string& s, CreateTileInfo* create_tile_info); static bool TryParseFontHeight(const std::string& s, int* font_height); - static bool TryParseNewCziFileguid(const std::string& s, GUID* guid); + static bool TryParseNewCziFileguid(const std::string& s, libCZI::GUID* guid); static bool TryParseBitmapGenerator(const std::string& s, std::string* generator_class_name); static bool TryParseSubBlockMetadataKeyValue(const std::string& s, std::map* subblock_metadata_property_bag); static bool TryParseCompressionOptions(const std::string& s, libCZI::Utils::CompressionOption* compression_option); diff --git a/Src/CZICmd/executeCreateCzi.cpp b/Src/CZICmd/executeCreateCzi.cpp index c3c2ce9d..95357244 100644 --- a/Src/CZICmd/executeCreateCzi.cpp +++ b/Src/CZICmd/executeCreateCzi.cpp @@ -211,7 +211,7 @@ class CExecuteCreateCzi // (3) ...both things are not really necessary from a technical point of view, however... consistency- // checking I'd consider an important feature - auto spWriterInfo = make_shared(options.GetIsFileGuidValid() ? options.GetFileGuid() : GUID{ 0,0,0,{ 0,0,0,0,0,0,0,0 } }); + auto spWriterInfo = make_shared(options.GetIsFileGuidValid() ? options.GetFileGuid() : libCZI::GUID{ 0,0,0,{ 0,0,0,0,0,0,0,0 } }); //spWriterInfo->SetReservedSizeForMetadataSegment(true, 10 * 1024); //spWriterInfo->SetReservedSizeForSubBlockDirectory(true, 400); writer->Create(outStream, spWriterInfo); diff --git a/Src/CZICmd/utils.cpp b/Src/CZICmd/utils.cpp index 030c347c..8a6532aa 100644 --- a/Src/CZICmd/utils.cpp +++ b/Src/CZICmd/utils.cpp @@ -22,6 +22,23 @@ using namespace std; +std::ostream& operator<<(std::ostream& os, const GUID& guid) +{ + os << std::hex << std::setfill('0') + << std::setw(8) << guid.Data1 << '-' + << std::setw(4) << guid.Data2 << '-' + << std::setw(4) << guid.Data3 << '-' + << std::setw(2) << static_cast(guid.Data4[0]) + << std::setw(2) << static_cast(guid.Data4[1]) << '-' + << std::setw(2) << static_cast(guid.Data4[2]) + << std::setw(2) << static_cast(guid.Data4[3]) + << std::setw(2) << static_cast(guid.Data4[4]) + << std::setw(2) << static_cast(guid.Data4[5]) + << std::setw(2) << static_cast(guid.Data4[6]) + << std::setw(2) << static_cast(guid.Data4[7]); + return os; +} + std::string convertToUtf8(const std::wstring& str) { #if defined(HAS_CODECVT) @@ -325,7 +342,7 @@ const wchar_t* skipWhiteSpaceAndOneOfThese(const wchar_t* s, const wchar_t* char return s; } -std::ostream& operator<<(std::ostream& os, const GUID& guid) +std::ostream& operator<<(std::ostream& os, const libCZI::GUID& guid) { os << std::uppercase; os.width(8); @@ -361,7 +378,7 @@ std::ostream& operator<<(std::ostream& os, const GUID& guid) /// \param [in,out] outGuid If non-null, the Guid will be put here if successful. /// /// \return True if it succeeds, false if it fails. -bool TryParseGuid(const std::wstring& str, GUID* outGuid) +bool TryParseGuid(const std::wstring& str, libCZI::GUID* outGuid) { auto strTrimmed = trim(str); if (strTrimmed.empty() || strTrimmed.length() < 2) @@ -377,7 +394,7 @@ bool TryParseGuid(const std::wstring& str, GUID* outGuid) std::wregex guidRegex(LR"([0-9A-Fa-f]{8}[-]([0-9A-Fa-f]{4}[-]){3}[0-9A-Fa-f]{12})"); if (std::regex_match(strTrimmed, guidRegex)) { - GUID g; + libCZI::GUID g; uint32_t value; char sz[9]; for (int i = 0; i < 8; ++i) diff --git a/Src/CZICmd/utils.h b/Src/CZICmd/utils.h index b67222f1..a73c1077 100644 --- a/Src/CZICmd/utils.h +++ b/Src/CZICmd/utils.h @@ -8,6 +8,7 @@ #include #include "inc_libCZI.h" + std::string convertToUtf8(const std::wstring& str); std::wstring convertUtf8ToUCS2(const std::string& str); @@ -29,9 +30,9 @@ std::vector wrap(const char* text, size_t line_length/* = 72*/); const wchar_t* skipWhiteSpaceAndOneOfThese(const wchar_t* s, const wchar_t* charToSkipOnce); const char* skipWhiteSpaceAndOneOfThese(const char* s, const char* charsToSkipOnce); -std::ostream& operator<<(std::ostream& os, const GUID& guid); +std::ostream& operator<<(std::ostream& os, const libCZI::GUID& guid); -bool TryParseGuid(const std::wstring& str, GUID* g); +bool TryParseGuid(const std::wstring& str, libCZI::GUID* g); /// This is an utility in order to implement a "scope guard" - an object that when gets out-of-scope is executing /// a functor which may implement any kind of clean-up - akin to a finally-clause in C#. C.f. https://www.heise.de/blog/C-Core-Guidelines-finally-in-C-4133759.html diff --git a/Src/JxrDecode/CMakeLists.txt b/Src/JxrDecode/CMakeLists.txt index f62bcdd8..382c2d78 100644 --- a/Src/JxrDecode/CMakeLists.txt +++ b/Src/JxrDecode/CMakeLists.txt @@ -9,8 +9,8 @@ include(CheckSymbolExists) include(CheckCSourceCompiles) add_library(JxrDecodeStatic OBJECT - "JxrDecode2.h" - "JxrDecode2.cpp" + "JxrDecode.h" + "JxrDecode.cpp" "jxrlib/common/include/guiddef.h" "jxrlib/common/include/log.h" diff --git a/Src/JxrDecode/JxrDecode2.cpp b/Src/JxrDecode/JxrDecode.cpp similarity index 99% rename from Src/JxrDecode/JxrDecode2.cpp rename to Src/JxrDecode/JxrDecode.cpp index 5259c186..75e33d37 100644 --- a/Src/JxrDecode/JxrDecode2.cpp +++ b/Src/JxrDecode/JxrDecode.cpp @@ -1,4 +1,4 @@ -#include "JxrDecode2.h" +#include "JxrDecode.h" #include #include #include diff --git a/Src/JxrDecode/JxrDecode2.h b/Src/JxrDecode/JxrDecode.h similarity index 100% rename from Src/JxrDecode/JxrDecode2.h rename to Src/JxrDecode/JxrDecode.h diff --git a/Src/libCZI/decoder.cpp b/Src/libCZI/decoder.cpp index e2f809ef..5f92e7f3 100644 --- a/Src/libCZI/decoder.cpp +++ b/Src/libCZI/decoder.cpp @@ -3,7 +3,7 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include "decoder.h" -#include "../JxrDecode/JxrDecode2.h" +#include "../JxrDecode/JxrDecode.h" #include "bitmapData.h" #include "stdAllocator.h" #include "BitmapOperations.h" diff --git a/Src/libCZI/jxrlibcompress.cpp b/Src/libCZI/jxrlibcompress.cpp index 0c2000ae..bb9f6e8b 100644 --- a/Src/libCZI/jxrlibcompress.cpp +++ b/Src/libCZI/jxrlibcompress.cpp @@ -3,7 +3,7 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include "libCZI_compress.h" -#include "../JxrDecode/JxrDecode2.h" +#include "../JxrDecode/JxrDecode.h" #include "BitmapOperations.h" #include "Site.h" From 40e6404b6f8987233e197fa879ae772caff03503 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Fri, 22 Sep 2023 23:14:27 +0200 Subject: [PATCH 78/98] fix --- Src/CZICmd/utils.cpp | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/Src/CZICmd/utils.cpp b/Src/CZICmd/utils.cpp index 8a6532aa..f5092e23 100644 --- a/Src/CZICmd/utils.cpp +++ b/Src/CZICmd/utils.cpp @@ -22,23 +22,6 @@ using namespace std; -std::ostream& operator<<(std::ostream& os, const GUID& guid) -{ - os << std::hex << std::setfill('0') - << std::setw(8) << guid.Data1 << '-' - << std::setw(4) << guid.Data2 << '-' - << std::setw(4) << guid.Data3 << '-' - << std::setw(2) << static_cast(guid.Data4[0]) - << std::setw(2) << static_cast(guid.Data4[1]) << '-' - << std::setw(2) << static_cast(guid.Data4[2]) - << std::setw(2) << static_cast(guid.Data4[3]) - << std::setw(2) << static_cast(guid.Data4[4]) - << std::setw(2) << static_cast(guid.Data4[5]) - << std::setw(2) << static_cast(guid.Data4[6]) - << std::setw(2) << static_cast(guid.Data4[7]); - return os; -} - std::string convertToUtf8(const std::wstring& str) { #if defined(HAS_CODECVT) From 019d41901780fa29987a44ed164274ff538d183c Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sat, 23 Sep 2023 01:16:51 +0200 Subject: [PATCH 79/98] rename JxrDecode2 -> JxrDecode --- Src/JxrDecode/JxrDecode.cpp | 50 +++++++++++++------------- Src/JxrDecode/JxrDecode.h | 6 ++-- Src/libCZI/decoder.cpp | 67 +++++++++++++---------------------- Src/libCZI/jxrlibcompress.cpp | 22 ++++++------ 4 files changed, 63 insertions(+), 82 deletions(-) diff --git a/Src/JxrDecode/JxrDecode.cpp b/Src/JxrDecode/JxrDecode.cpp index 75e33d37..f697acb7 100644 --- a/Src/JxrDecode/JxrDecode.cpp +++ b/Src/JxrDecode/JxrDecode.cpp @@ -8,7 +8,7 @@ using namespace std; -static void ApplyQuality(float quality, JxrDecode2::PixelFormat pixel_format, std::uint32_t width, PKImageEncode* pEncoder); +static void ApplyQuality(float quality, JxrDecode::PixelFormat pixel_format, std::uint32_t width, PKImageEncode* pEncoder); static bool IsEqualGUID(const GUID& guid1, const GUID& guid2) { @@ -42,30 +42,30 @@ static const char* ERR_to_string(ERR error_code) return nullptr; } -static JxrDecode2::PixelFormat JxrPixelFormatGuidToEnum(const GUID& guid) +static JxrDecode::PixelFormat JxrPixelFormatGuidToEnum(const GUID& guid) { if (IsEqualGUID(guid, GUID_PKPixelFormat8bppGray)) { - return JxrDecode2::PixelFormat::kGray8; + return JxrDecode::PixelFormat::kGray8; } else if (IsEqualGUID(guid, GUID_PKPixelFormat16bppGray)) { - return JxrDecode2::PixelFormat::kGray16; + return JxrDecode::PixelFormat::kGray16; } else if (IsEqualGUID(guid, GUID_PKPixelFormat24bppBGR)) { - return JxrDecode2::PixelFormat::kBgr24; + return JxrDecode::PixelFormat::kBgr24; } else if (IsEqualGUID(guid, GUID_PKPixelFormat48bppRGB)) { - return JxrDecode2::PixelFormat::kBgr48; + return JxrDecode::PixelFormat::kBgr48; } else if (IsEqualGUID(guid, GUID_PKPixelFormat32bppGrayFloat)) { - return JxrDecode2::PixelFormat::kGray32Float; + return JxrDecode::PixelFormat::kGray32Float; } - return JxrDecode2::PixelFormat::kInvalid; + return JxrDecode::PixelFormat::kInvalid; } static void WriteGuidToStream(ostringstream& string_stream, const GUID& guid) @@ -91,7 +91,7 @@ static void WriteGuidToStream(ostringstream& string_stream, const GUID& guid) string_stream << std::nouppercase; } -void JxrDecode2::Decode( +void JxrDecode::Decode( const void* ptrData, size_t size, const std::function(PixelFormat pixel_format, std::uint32_t width, std::uint32_t height)>& get_destination_func) @@ -151,7 +151,7 @@ void JxrDecode2::Decode( if (Failed(err)) { ThrowJxrlibError("'decoder::GetPixelFormat' failed", err); } const auto jxrpixel_format = JxrPixelFormatGuidToEnum(pixel_format_of_decoder); - if (jxrpixel_format == JxrDecode2::PixelFormat::kInvalid) + if (jxrpixel_format == JxrDecode::PixelFormat::kInvalid) { ostringstream string_stream; string_stream << "Unsupported pixel format: {"; @@ -174,8 +174,8 @@ void JxrDecode2::Decode( if (Failed(err)) { ThrowJxrlibError("decoder::Copy failed", err); } } -/*static*/JxrDecode2::CompressedData JxrDecode2::Encode( - JxrDecode2::PixelFormat pixel_format, +/*static*/JxrDecode::CompressedData JxrDecode::Encode( + JxrDecode::PixelFormat pixel_format, std::uint32_t width, std::uint32_t height, std::uint32_t stride, @@ -202,7 +202,7 @@ void JxrDecode2::Decode( throw invalid_argument("height"); } - const auto bytes_per_pel = JxrDecode2::GetBytesPerPel(pixel_format); + const auto bytes_per_pel = JxrDecode::GetBytesPerPel(pixel_format); if (bytes_per_pel == 0xff) { throw invalid_argument("pixel_format"); @@ -330,13 +330,13 @@ void JxrDecode2::Decode( return { upEncodeStream.release() }; } -/*static*/void JxrDecode2::ThrowJxrlibError(const std::string& message, int error_code) +/*static*/void JxrDecode::ThrowJxrlibError(const std::string& message, int error_code) { ostringstream string_stream(message); - JxrDecode2::ThrowJxrlibError(string_stream, error_code); + JxrDecode::ThrowJxrlibError(string_stream, error_code); } -/*static*/void JxrDecode2::ThrowJxrlibError(std::ostringstream& message, int error_code) +/*static*/void JxrDecode::ThrowJxrlibError(std::ostringstream& message, int error_code) { message << " - ERR=" << error_code; const char* error_code_string = ERR_to_string(error_code); @@ -348,7 +348,7 @@ void JxrDecode2::Decode( throw runtime_error(message.str()); } -JxrDecode2::CompressedData::~CompressedData() +JxrDecode::CompressedData::~CompressedData() { if (this->obj_handle_ != nullptr) { @@ -356,7 +356,7 @@ JxrDecode2::CompressedData::~CompressedData() } } -void* JxrDecode2::CompressedData::GetMemory() +void* JxrDecode::CompressedData::GetMemory() { void* data = nullptr; GetWS_HeapBackedWriteableStreamBuffer( @@ -366,7 +366,7 @@ void* JxrDecode2::CompressedData::GetMemory() return data; } -size_t JxrDecode2::CompressedData::GetSize() +size_t JxrDecode::CompressedData::GetSize() { size_t size = 0; GetWS_HeapBackedWriteableStreamBuffer( @@ -376,7 +376,7 @@ size_t JxrDecode2::CompressedData::GetSize() return size; } -/*static*/std::uint8_t JxrDecode2::GetBytesPerPel(PixelFormat pixel_format) +/*static*/std::uint8_t JxrDecode::GetBytesPerPel(PixelFormat pixel_format) { switch (pixel_format) { @@ -395,7 +395,7 @@ size_t JxrDecode2::CompressedData::GetSize() return 0xff; } -/*static*/void ApplyQuality(float quality, JxrDecode2::PixelFormat pixel_format, uint32_t width, PKImageEncode* pEncoder) +/*static*/void ApplyQuality(float quality, JxrDecode::PixelFormat pixel_format, uint32_t width, PKImageEncode* pEncoder) { // this is resembling the code from https://github.com/ptahmose/jxrlib/blob/f7521879862b9085318e814c6157490dd9dbbdb4/jxrencoderdecoder/JxrEncApp.c#L677C1-L738C10 #if 1 @@ -513,7 +513,7 @@ size_t JxrDecode2::CompressedData::GetSize() //if (!args.bColorFormatSet) //{ - if (quality >= 0.5F || /*PI.uBitsPerSample > 8*/(pixel_format == JxrDecode2::PixelFormat::kBgr48 || pixel_format == JxrDecode2::PixelFormat::kGray16)) + if (quality >= 0.5F || /*PI.uBitsPerSample > 8*/(pixel_format == JxrDecode::PixelFormat::kBgr48 || pixel_format == JxrDecode::PixelFormat::kGray16)) pEncoder->WMP.wmiSCP.cfColorFormat = YUV_444; else pEncoder->WMP.wmiSCP.cfColorFormat = YUV_420; @@ -532,7 +532,7 @@ size_t JxrDecode2::CompressedData::GetSize() float qf; const int* pQPs; if (/*args.fltImageQuality*/quality > 0.8f && /*PI.bdBitDepth == BD_8*/ - (pixel_format == JxrDecode2::PixelFormat::kBgr24 || pixel_format == JxrDecode2::PixelFormat::kGray8) && + (pixel_format == JxrDecode::PixelFormat::kBgr24 || pixel_format == JxrDecode::PixelFormat::kGray8) && pEncoder->WMP.wmiSCP.cfColorFormat != YUV_420 && pEncoder->WMP.wmiSCP.cfColorFormat != YUV_422) quality/*args.fltImageQuality*/ = 0.8f + (quality/*args.fltImageQuality*/ - 0.8f) * 1.5f; @@ -552,8 +552,8 @@ size_t JxrDecode2::CompressedData::GetSize() (pEncoder->WMP.wmiSCP.cfColorFormat == YUV_420 || pEncoder->WMP.wmiSCP.cfColorFormat == YUV_422) ? DPK_QPS_420[qi] : - (pixel_format == JxrDecode2::PixelFormat::kBgr24 || pixel_format == JxrDecode2::PixelFormat::kGray8) ? DPK_QPS_8[qi] : - ((pixel_format == JxrDecode2::PixelFormat::kBgr48 || pixel_format == JxrDecode2::PixelFormat::kGray16) ? DPK_QPS_16[qi] : + (pixel_format == JxrDecode::PixelFormat::kBgr24 || pixel_format == JxrDecode::PixelFormat::kGray8) ? DPK_QPS_8[qi] : + ((pixel_format == JxrDecode::PixelFormat::kBgr48 || pixel_format == JxrDecode::PixelFormat::kGray16) ? DPK_QPS_16[qi] : (DPK_QPS_32f[qi])); pEncoder->WMP.wmiSCP.uiDefaultQPIndex = static_cast(0.5f + diff --git a/Src/JxrDecode/JxrDecode.h b/Src/JxrDecode/JxrDecode.h index ea074d08..b12860ba 100644 --- a/Src/JxrDecode/JxrDecode.h +++ b/Src/JxrDecode/JxrDecode.h @@ -7,7 +7,7 @@ #include /// This class encapsulates the JXR codec. -class JxrDecode2 +class JxrDecode { public: /// Values that represent the pixel formats supported by the codec. @@ -70,7 +70,7 @@ class JxrDecode2 ~CompressedData(); protected: - friend class JxrDecode2; + friend class JxrDecode; CompressedData(void* obj_handle) :obj_handle_(obj_handle) {} }; @@ -110,7 +110,7 @@ class JxrDecode2 /// /// \returns A CompressedData object containing the compressed data. static CompressedData Encode( - JxrDecode2::PixelFormat pixel_format, + JxrDecode::PixelFormat pixel_format, std::uint32_t width, std::uint32_t height, std::uint32_t stride, diff --git a/Src/libCZI/decoder.cpp b/Src/libCZI/decoder.cpp index 5f92e7f3..e0f6d163 100644 --- a/Src/libCZI/decoder.cpp +++ b/Src/libCZI/decoder.cpp @@ -12,39 +12,20 @@ using namespace libCZI; using namespace std; -//class MemoryBlockOnCompressedData : public libCZI::IMemoryBlock -//{ -//private: -// mutable JxrDecode2::CompressedData compressed_data_; -//public: -// MemoryBlockOnCompressedData(JxrDecode2::CompressedData&& compressed_data) -// : compressed_data_(std::move(compressed_data)) -// {} -// -// void* GetPtr() override -// { -// return this->compressed_data_.GetMemory(); -// } -// -// size_t GetSizeOfData() const override -// { -// return this->compressed_data_.GetSize(); -// } -//}; -static libCZI::PixelType PixelTypeFromJxrPixelFormat(JxrDecode2::PixelFormat pixel_format) +static libCZI::PixelType PixelTypeFromJxrPixelFormat(JxrDecode::PixelFormat pixel_format) { switch (pixel_format) { - case JxrDecode2::PixelFormat::kBgr24: + case JxrDecode::PixelFormat::kBgr24: return PixelType::Bgr24; - case JxrDecode2::PixelFormat::kGray8: + case JxrDecode::PixelFormat::kGray8: return PixelType::Gray8; - case JxrDecode2::PixelFormat::kBgr48: + case JxrDecode::PixelFormat::kBgr48: return PixelType::Bgr48; - case JxrDecode2::PixelFormat::kGray16: + case JxrDecode::PixelFormat::kGray16: return PixelType::Gray16; - case JxrDecode2::PixelFormat::kGray32Float: + case JxrDecode::PixelFormat::kGray32Float: return PixelType::Gray32Float; default: return PixelType::Invalid; @@ -59,23 +40,23 @@ static libCZI::PixelType PixelTypeFromJxrPixelFormat(JxrDecode2::PixelFormat pix /*std::shared_ptr CJxrLibDecoder::Encode(libCZI::PixelType pixel_type, std::uint32_t width, std::uint32_t height, std::uint32_t stride, const void* ptrData, float quality) { - JxrDecode2::PixelFormat jxrdecode_pixel_format; + JxrDecode::PixelFormat jxrdecode_pixel_format; switch (pixel_type) { case PixelType::Bgr24: - jxrdecode_pixel_format = JxrDecode2::PixelFormat::kBgr24; + jxrdecode_pixel_format = JxrDecode::PixelFormat::kBgr24; break; case PixelType::Bgr48: - jxrdecode_pixel_format = JxrDecode2::PixelFormat::kBgr48; + jxrdecode_pixel_format = JxrDecode::PixelFormat::kBgr48; break; case PixelType::Gray8: - jxrdecode_pixel_format = JxrDecode2::PixelFormat::kGray8; + jxrdecode_pixel_format = JxrDecode::PixelFormat::kGray8; break; case PixelType::Gray16: - jxrdecode_pixel_format = JxrDecode2::PixelFormat::kGray16; + jxrdecode_pixel_format = JxrDecode::PixelFormat::kGray16; break; case PixelType::Gray32Float: - jxrdecode_pixel_format = JxrDecode2::PixelFormat::kGray32Float; + jxrdecode_pixel_format = JxrDecode::PixelFormat::kGray32Float; break; default: throw std::logic_error("unsupported pixel type"); @@ -84,7 +65,7 @@ static libCZI::PixelType PixelTypeFromJxrPixelFormat(JxrDecode2::PixelFormat pix // Unfortunately, the encoder does not support the pixelformat Bgr48, so we need to convert it to Rgb48 // before passing it to the encoder (meaning: the resulting encoded data will be Rgb48, not Bgr48). // TODO(JBL): would be nice if the encoder would support Bgr48 directly somehow - if (jxrdecode_pixel_format == JxrDecode2::PixelFormat::kBgr48) + if (jxrdecode_pixel_format == JxrDecode::PixelFormat::kBgr48) { // unfortunately, we have to make a temporary copy const auto bitmap_rgb48 = GetSite()->CreateBitmap(PixelType::Bgr48, width, height); @@ -99,7 +80,7 @@ static libCZI::PixelType PixelTypeFromJxrPixelFormat(JxrDecode2::PixelFormat pix height, false); CBitmapOperations::RGB48ToBGR48(width, height, static_cast(bmLck.ptrDataRoi), bmLck.stride); - auto compressed_data = JxrDecode2::Encode( + auto compressed_data = JxrDecode::Encode( jxrdecode_pixel_format, width, height, @@ -110,7 +91,7 @@ static libCZI::PixelType PixelTypeFromJxrPixelFormat(JxrDecode2::PixelFormat pix } else { - auto compressed_data = JxrDecode2::Encode( + auto compressed_data = JxrDecode::Encode( jxrdecode_pixel_format, width, height, @@ -128,10 +109,10 @@ std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, try { - JxrDecode2::Decode( + JxrDecode::Decode( ptrData, size, - [&](JxrDecode2::PixelFormat actual_pixel_format, std::uint32_t actual_width, std::uint32_t actual_height) + [&](JxrDecode::PixelFormat actual_pixel_format, std::uint32_t actual_width, std::uint32_t actual_height) -> tuple { const auto pixel_type_from_compressed_data = PixelTypeFromJxrPixelFormat(actual_pixel_format); @@ -192,12 +173,12 @@ std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, size_t size, libCZI::PixelType pixelType, uint32_t width, uint32_t height) { std::shared_ptr bm; - JxrDecode2 decoder2; + JxrDecode decoder2; decoder2.Decode(nullptr, ptrData, size, nullptr, - [&](JxrDecode2::PixelFormat pixFmt, std::uint32_t width, std::uint32_t height, std::uint32_t linesCount, const void* ptrData, std::uint32_t stride)->void + [&](JxrDecode::PixelFormat pixFmt, std::uint32_t width, std::uint32_t height, std::uint32_t linesCount, const void* ptrData, std::uint32_t stride)->void { /* if (GetSite()->IsEnabled(LOGLEVEL_CHATTYINFORMATION)) { @@ -209,11 +190,11 @@ std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, PixelType px_type; switch (pixFmt) { - case JxrDecode2::PixelFormat::kBgr24: px_type = PixelType::Bgr24; break; - case JxrDecode2::PixelFormat::kGray8: px_type = PixelType::Gray8; break; - case JxrDecode2::PixelFormat::kBgr48: px_type = PixelType::Bgr48; break; - case JxrDecode2::PixelFormat::kGray16: px_type = PixelType::Gray16; break; - //case JxrDecode2::PixelFormat::_32bppGrayFloat: px_type = PixelType::Gray32Float; break; + case JxrDecode::PixelFormat::kBgr24: px_type = PixelType::Bgr24; break; + case JxrDecode::PixelFormat::kGray8: px_type = PixelType::Gray8; break; + case JxrDecode::PixelFormat::kBgr48: px_type = PixelType::Bgr48; break; + case JxrDecode::PixelFormat::kGray16: px_type = PixelType::Gray16; break; + //case JxrDecode::PixelFormat::_32bppGrayFloat: px_type = PixelType::Gray32Float; break; default: throw std::logic_error("need to look into these formats..."); } diff --git a/Src/libCZI/jxrlibcompress.cpp b/Src/libCZI/jxrlibcompress.cpp index bb9f6e8b..972d02c7 100644 --- a/Src/libCZI/jxrlibcompress.cpp +++ b/Src/libCZI/jxrlibcompress.cpp @@ -13,9 +13,9 @@ using namespace std; class MemoryBlockOnCompressedData : public libCZI::IMemoryBlock { private: - mutable JxrDecode2::CompressedData compressed_data_; + mutable JxrDecode::CompressedData compressed_data_; public: - MemoryBlockOnCompressedData(JxrDecode2::CompressedData&& compressed_data) + MemoryBlockOnCompressedData(JxrDecode::CompressedData&& compressed_data) : compressed_data_(std::move(compressed_data)) {} @@ -38,23 +38,23 @@ class MemoryBlockOnCompressedData : public libCZI::IMemoryBlock const void* ptrData, const ICompressParameters* parameters) { - JxrDecode2::PixelFormat jxrdecode_pixel_format; + JxrDecode::PixelFormat jxrdecode_pixel_format; switch (pixel_type) { case PixelType::Bgr24: - jxrdecode_pixel_format = JxrDecode2::PixelFormat::kBgr24; + jxrdecode_pixel_format = JxrDecode::PixelFormat::kBgr24; break; case PixelType::Bgr48: - jxrdecode_pixel_format = JxrDecode2::PixelFormat::kBgr48; + jxrdecode_pixel_format = JxrDecode::PixelFormat::kBgr48; break; case PixelType::Gray8: - jxrdecode_pixel_format = JxrDecode2::PixelFormat::kGray8; + jxrdecode_pixel_format = JxrDecode::PixelFormat::kGray8; break; case PixelType::Gray16: - jxrdecode_pixel_format = JxrDecode2::PixelFormat::kGray16; + jxrdecode_pixel_format = JxrDecode::PixelFormat::kGray16; break; case PixelType::Gray32Float: - jxrdecode_pixel_format = JxrDecode2::PixelFormat::kGray32Float; + jxrdecode_pixel_format = JxrDecode::PixelFormat::kGray32Float; break; default: throw std::logic_error("unsupported pixel type"); @@ -75,7 +75,7 @@ class MemoryBlockOnCompressedData : public libCZI::IMemoryBlock // Unfortunately, the encoder does not support the pixel format Bgr48, so we need to convert it to Rgb48 // before passing it to the encoder (meaning: the resulting encoded data will be Rgb48, not Bgr48). // TODO(JBL): would be nice if the encoder would support Bgr48 directly somehow - if (jxrdecode_pixel_format == JxrDecode2::PixelFormat::kBgr48) + if (jxrdecode_pixel_format == JxrDecode::PixelFormat::kBgr48) { // unfortunately, we have to make a temporary copy const auto bitmap_rgb48 = GetSite()->CreateBitmap(PixelType::Bgr48, width, height); @@ -90,7 +90,7 @@ class MemoryBlockOnCompressedData : public libCZI::IMemoryBlock height, false); CBitmapOperations::RGB48ToBGR48(width, height, static_cast(bmLck.ptrDataRoi), bmLck.stride); - auto compressed_data = JxrDecode2::Encode( + auto compressed_data = JxrDecode::Encode( jxrdecode_pixel_format, width, height, @@ -101,7 +101,7 @@ class MemoryBlockOnCompressedData : public libCZI::IMemoryBlock } else { - auto compressed_data = JxrDecode2::Encode( + auto compressed_data = JxrDecode::Encode( jxrdecode_pixel_format, width, height, From 4aadb018479c9cb04676b9f68c3975cb545c41fa Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sat, 23 Sep 2023 01:17:56 +0200 Subject: [PATCH 80/98] forward C/C++-Compiler to external project --- cmake/ExternalEIGEN3.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/ExternalEIGEN3.cmake b/cmake/ExternalEIGEN3.cmake index 3b23aadd..0f5e357d 100644 --- a/cmake/ExternalEIGEN3.cmake +++ b/cmake/ExternalEIGEN3.cmake @@ -12,6 +12,9 @@ ExternalProject_Add( CMAKE_ARGS -DEIGEN_BUILD_PKGCONFIG=OFF -DBUILD_TESTING=OFF + CMAKE_CACHE_ARGS + "-DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}" + "-DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER}" UPDATE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" From 823be684106e06927da9ab1d7ad9932b58bf1b92 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sat, 23 Sep 2023 01:22:39 +0200 Subject: [PATCH 81/98] fix include --- Src/libCZI_UnitTests/test_CZIParse.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/libCZI_UnitTests/test_CZIParse.cpp b/Src/libCZI_UnitTests/test_CZIParse.cpp index 51f9596d..b349b173 100644 --- a/Src/libCZI_UnitTests/test_CZIParse.cpp +++ b/Src/libCZI_UnitTests/test_CZIParse.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "pch.h" +#include "include_gtest.h" #include "MemInputOutputStream.h" #include "../libCZI/CziParse.h" From f17a62e721f08111028ecc48cc332b252c8e13f3 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sat, 23 Sep 2023 20:55:38 +0200 Subject: [PATCH 82/98] fix inline problem (seen on MacOS) --- Src/JxrDecode/jxrlib/common/include/guiddef.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/JxrDecode/jxrlib/common/include/guiddef.h b/Src/JxrDecode/jxrlib/common/include/guiddef.h index 70723938..8e20f7df 100644 --- a/Src/JxrDecode/jxrlib/common/include/guiddef.h +++ b/Src/JxrDecode/jxrlib/common/include/guiddef.h @@ -78,7 +78,7 @@ typedef struct _GUID { /// \param guid2 The second unique identifier to compare. /// /// \returns A non-zero value if the two GUIDs are equal, and zero otherwise. -inline int IsEqualGUID(const GUID* guid1, const GUID* guid2) +static inline int IsEqualGUID(const GUID* guid1, const GUID* guid2) { return !memcmp(guid1, guid2, sizeof(GUID)); } From 2c53cc002f5c340713da3b75d40ce01b7c7015c9 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sat, 23 Sep 2023 20:57:36 +0200 Subject: [PATCH 83/98] cosmetic & OSS-license-header --- .reuse/dep5 | 2 +- Src/JxrDecode/CMakeLists.txt | 11 +---------- Src/JxrDecode/JxrDecode.cpp | 6 +++++- Src/JxrDecode/JxrDecode.h | 4 ++++ Src/JxrDecode/JxrDecode_Config.h.in | 2 +- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/.reuse/dep5 b/.reuse/dep5 index 64490a23..3cfd7620 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -11,7 +11,7 @@ Files: cla_*.txt CMakeLists.txt CMakeSettings.json CODE_OF_CONDUCT.md CONTRIBUTI Copyright: 2017-2022 Carl Zeiss Microscopy GmbH License: LGPL-3.0-or-later -Files: Src/JxrDecode/Jxr/* +Files: Src/JxrDecode/jxrlib/* Copyright: Microsoft Corp. License: BSD-3-Clause diff --git a/Src/JxrDecode/CMakeLists.txt b/Src/JxrDecode/CMakeLists.txt index 382c2d78..9ea8f811 100644 --- a/Src/JxrDecode/CMakeLists.txt +++ b/Src/JxrDecode/CMakeLists.txt @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2017-2022 Carl Zeiss Microscopy GmbH +# SPDX-FileCopyrightText: 2017-2023 Carl Zeiss Microscopy GmbH # # SPDX-License-Identifier: LGPL-3.0-or-later @@ -115,12 +115,3 @@ set_target_properties(JxrDecodeStatic PROPERTIES CXX_STANDARD 11) # shared libraries need PIC set_property(TARGET JxrDecodeStatic PROPERTY POSITION_INDEPENDENT_CODE ON) -#[[ -if (IS_BIG_ENDIAN) - target_compile_definitions(JxrDecodeStatic PRIVATE _BIG__ENDIAN_) -endif(IS_BIG_ENDIAN) - -if (CRASH_ON_UNALIGNED_ACCESS) - target_compile_definitions(JxrDecodeStatic PRIVATE _NO_UNALIGNED_LOAD_) -endif() -]]# diff --git a/Src/JxrDecode/JxrDecode.cpp b/Src/JxrDecode/JxrDecode.cpp index f697acb7..2662365f 100644 --- a/Src/JxrDecode/JxrDecode.cpp +++ b/Src/JxrDecode/JxrDecode.cpp @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2023 Carl Zeiss Microscopy GmbH +// +// SPDX-License-Identifier: LGPL-3.0-or-later + #include "JxrDecode.h" #include #include @@ -12,7 +16,7 @@ static void ApplyQuality(float quality, JxrDecode::PixelFormat pixel_format, std static bool IsEqualGUID(const GUID& guid1, const GUID& guid2) { - return memcmp(&guid1, &guid2, sizeof(GUID)) == 0; + return IsEqualGUID(&guid1, &guid2) != 0; } static const char* ERR_to_string(ERR error_code) diff --git a/Src/JxrDecode/JxrDecode.h b/Src/JxrDecode/JxrDecode.h index b12860ba..526fe47c 100644 --- a/Src/JxrDecode/JxrDecode.h +++ b/Src/JxrDecode/JxrDecode.h @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2023 Carl Zeiss Microscopy GmbH +// +// SPDX-License-Identifier: LGPL-3.0-or-later + #pragma once #include diff --git a/Src/JxrDecode/JxrDecode_Config.h.in b/Src/JxrDecode/JxrDecode_Config.h.in index ad984d91..a4105dfd 100644 --- a/Src/JxrDecode/JxrDecode_Config.h.in +++ b/Src/JxrDecode/JxrDecode_Config.h.in @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2017-2022 Carl Zeiss Microscopy GmbH +// SPDX-FileCopyrightText: 2017-2023 Carl Zeiss Microscopy GmbH // // SPDX-License-Identifier: LGPL-3.0-or-later From c43b288b829a62c406d7d3a207d75713fbe46950 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sat, 23 Sep 2023 21:57:00 +0200 Subject: [PATCH 84/98] cosmetic --- Src/JxrDecode/JxrDecode.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Src/JxrDecode/JxrDecode.cpp b/Src/JxrDecode/JxrDecode.cpp index 2662365f..05787db1 100644 --- a/Src/JxrDecode/JxrDecode.cpp +++ b/Src/JxrDecode/JxrDecode.cpp @@ -14,7 +14,7 @@ using namespace std; static void ApplyQuality(float quality, JxrDecode::PixelFormat pixel_format, std::uint32_t width, PKImageEncode* pEncoder); -static bool IsEqualGUID(const GUID& guid1, const GUID& guid2) +static bool IsEqualGuid(const GUID& guid1, const GUID& guid2) { return IsEqualGUID(&guid1, &guid2) != 0; } @@ -48,23 +48,23 @@ static const char* ERR_to_string(ERR error_code) static JxrDecode::PixelFormat JxrPixelFormatGuidToEnum(const GUID& guid) { - if (IsEqualGUID(guid, GUID_PKPixelFormat8bppGray)) + if (IsEqualGuid(guid, GUID_PKPixelFormat8bppGray)) { return JxrDecode::PixelFormat::kGray8; } - else if (IsEqualGUID(guid, GUID_PKPixelFormat16bppGray)) + else if (IsEqualGuid(guid, GUID_PKPixelFormat16bppGray)) { return JxrDecode::PixelFormat::kGray16; } - else if (IsEqualGUID(guid, GUID_PKPixelFormat24bppBGR)) + else if (IsEqualGuid(guid, GUID_PKPixelFormat24bppBGR)) { return JxrDecode::PixelFormat::kBgr24; } - else if (IsEqualGUID(guid, GUID_PKPixelFormat48bppRGB)) + else if (IsEqualGuid(guid, GUID_PKPixelFormat48bppRGB)) { return JxrDecode::PixelFormat::kBgr48; } - else if (IsEqualGUID(guid, GUID_PKPixelFormat32bppGrayFloat)) + else if (IsEqualGuid(guid, GUID_PKPixelFormat32bppGrayFloat)) { return JxrDecode::PixelFormat::kGray32Float; } @@ -280,7 +280,7 @@ void JxrDecode::Decode( ApplyQuality(quality, pixel_format, width, upImageEncoder.get()); } - switch (pixel_format) + switch (pixel_format) // NOLINT(clang-diagnostic-switch-enum) { case PixelFormat::kBgr24: err = upImageEncoder->SetPixelFormat(upImageEncoder.get(), GUID_PKPixelFormat24bppBGR); @@ -394,9 +394,9 @@ size_t JxrDecode::CompressedData::GetSize() return 2; case PixelFormat::kGray32Float: return 4; + default: + return 0xff; } - - return 0xff; } /*static*/void ApplyQuality(float quality, JxrDecode::PixelFormat pixel_format, uint32_t width, PKImageEncode* pEncoder) From 8b34c53eb5c7e61e55f345d1ffa667276bf6e7af Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sat, 23 Sep 2023 22:54:27 +0200 Subject: [PATCH 85/98] cosmetic --- Src/JxrDecode/JxrDecode.cpp | 156 +++++++++++++++++------------------- Src/JxrDecode/JxrDecode.h | 4 +- 2 files changed, 75 insertions(+), 85 deletions(-) diff --git a/Src/JxrDecode/JxrDecode.cpp b/Src/JxrDecode/JxrDecode.cpp index 05787db1..1a30d5f9 100644 --- a/Src/JxrDecode/JxrDecode.cpp +++ b/Src/JxrDecode/JxrDecode.cpp @@ -175,7 +175,10 @@ void JxrDecode::Decode( &rc, static_cast(get<0>(decode_info)), get<1>(decode_info)); - if (Failed(err)) { ThrowJxrlibError("decoder::Copy failed", err); } + if (Failed(err)) + { + ThrowJxrlibError("decoder::Copy failed", err); + } } /*static*/JxrDecode::CompressedData JxrDecode::Encode( @@ -237,10 +240,8 @@ void JxrDecode::Decode( }); CWMIStrCodecParam codec_parameters = {}; - //codec_parameters.guidPixFormat = GUID_PKPixelFormat24bppBGR; codec_parameters.bVerbose = FALSE; codec_parameters.cfColorFormat = YUV_444; - // args->bFlagRGB_BGR = FALSE; //default BGR codec_parameters.bdBitDepth = BD_LONG; codec_parameters.bfBitstreamFormat = FREQUENCY; codec_parameters.bProgressiveMode = TRUE; @@ -249,18 +250,9 @@ void JxrDecode::Decode( codec_parameters.sbSubband = SB_ALL; codec_parameters.uAlphaMode = 0; codec_parameters.uiDefaultQPIndex = 1; - codec_parameters.uiDefaultQPIndexAlpha = 1; - - //codec_parameters.fltImageQuality = 1.f; - //codec_parameters.bOverlapSet = 0; - //codec_parameters.bColorFormatSet = 0; - - - // { &GUID_PKPixelFormat24bppBGR, 3, CF_RGB, BD_8, 24, PK_pixfmtBGR, 2, 3, 8, 1 }, - - struct tagWMPStream* pEncodeStream = NULL; - //CreateWS_File(&pEncodeStream, "C:\\temp\\test.jxr", "wb"); + + struct tagWMPStream* pEncodeStream = nullptr; err = CreateWS_HeapBackedWriteableStream(&pEncodeStream, 1024, 0); if (Failed(err)) { @@ -310,7 +302,6 @@ void JxrDecode::Decode( ThrowJxrlibError("'PKImageEncode::SetPixelFormat' failed", err); } - //err = pEncoder->SetPixelFormat(pEncoder, GUID_PKPixelFormat24bppBGR); err = upImageEncoder->SetSize(upImageEncoder.get(), static_cast(width), static_cast(height)); if (Failed(err)) { @@ -360,7 +351,7 @@ JxrDecode::CompressedData::~CompressedData() } } -void* JxrDecode::CompressedData::GetMemory() +void* JxrDecode::CompressedData::GetMemory() const { void* data = nullptr; GetWS_HeapBackedWriteableStreamBuffer( @@ -370,7 +361,7 @@ void* JxrDecode::CompressedData::GetMemory() return data; } -size_t JxrDecode::CompressedData::GetSize() +size_t JxrDecode::CompressedData::GetSize() const { size_t size = 0; GetWS_HeapBackedWriteableStreamBuffer( @@ -399,12 +390,20 @@ size_t JxrDecode::CompressedData::GetSize() } } +/// Makes adjustments to the encoder object, based on the quality parameter. The quality parameter is expected to be a number between 0 and 1. +/// +/// \param quality The quality (must be between 0 and 1). +/// \param pixel_format The pixel format. +/// \param width The width in pixels. +/// \param [in,out] pEncoder The encoder object (where the adjustments, according to the quality setting, are made). /*static*/void ApplyQuality(float quality, JxrDecode::PixelFormat pixel_format, uint32_t width, PKImageEncode* pEncoder) { // this is resembling the code from https://github.com/ptahmose/jxrlib/blob/f7521879862b9085318e814c6157490dd9dbbdb4/jxrencoderdecoder/JxrEncApp.c#L677C1-L738C10 + // It has been tweaked to our more limited case (i.e. only 8 bit and 16 bit, and only 1 channel) #if 1 // optimized for PSNR - static const int DPK_QPS_420[11][6] = { // for 8 bit only + static const int DPK_QPS_420[11][6] = + { // for 8 bit only { 66, 65, 70, 72, 72, 77 }, { 59, 58, 63, 64, 63, 68 }, { 52, 51, 57, 56, 56, 61 }, @@ -418,7 +417,8 @@ size_t JxrDecode::CompressedData::GetSize() { 2, 2, 3, 2, 2, 2 } }; - static const int DPK_QPS_8[12][6] = { + static const int DPK_QPS_8[12][6] = + { { 67, 79, 86, 72, 90, 98 }, { 59, 74, 80, 64, 83, 89 }, { 53, 68, 75, 57, 76, 83 }, @@ -434,7 +434,8 @@ size_t JxrDecode::CompressedData::GetSize() }; #else // optimized for SSIM - static const int DPK_QPS_420[11][6] = { // for 8 bit only + static const int DPK_QPS_420[11][6] = + { // for 8 bit only { 67, 77, 80, 75, 82, 86 }, { 58, 67, 71, 63, 74, 78 }, { 50, 60, 64, 54, 66, 69 }, @@ -448,7 +449,8 @@ size_t JxrDecode::CompressedData::GetSize() { 4, 6, 7, 3, 5, 5 } }; - static const int DPK_QPS_8[12][6] = { + static const int DPK_QPS_8[12][6] = + { { 67, 93, 98, 71, 98, 104 }, { 59, 83, 88, 61, 89, 95 }, { 50, 76, 81, 53, 85, 90 }, @@ -464,7 +466,8 @@ size_t JxrDecode::CompressedData::GetSize() }; #endif - static const int DPK_QPS_16[11][6] = { + static const int DPK_QPS_16[11][6] = + { { 197, 203, 210, 202, 207, 213 }, { 174, 188, 193, 180, 189, 196 }, { 152, 167, 173, 156, 169, 174 }, @@ -478,7 +481,7 @@ size_t JxrDecode::CompressedData::GetSize() { 5, 8, 9, 4, 7, 8 } }; - static const int DPK_QPS_16f[11][6] = { + /*static const int DPK_QPS_16f[11][6] = { { 148, 177, 171, 165, 187, 191 }, { 133, 155, 153, 147, 172, 181 }, { 114, 133, 138, 130, 157, 167 }, @@ -490,9 +493,10 @@ size_t JxrDecode::CompressedData::GetSize() { 16, 30, 35, 14, 29, 34 }, { 8, 14, 17, 7, 13, 17 }, { 3, 5, 7, 3, 5, 6 } - }; + };*/ - static const int DPK_QPS_32f[11][6] = { + static const int DPK_QPS_32f[11][6] = + { { 194, 206, 209, 204, 211, 217 }, { 175, 187, 196, 186, 193, 205 }, { 157, 170, 177, 167, 180, 190 }, @@ -506,71 +510,57 @@ size_t JxrDecode::CompressedData::GetSize() { 3, 22, 24, 2, 21, 22 } }; - //if (!args.bOverlapSet) - //{ - // Image width must be at least 2 MB wide for subsampled chroma and two levels of overlap! - if (quality >= 0.5F || /*rect.Width*/width < 2 * MB_WIDTH_PIXEL) + // Image width must be at least 2 MB wide for subsampled chroma and two levels of overlap! + if (quality >= 0.5F || width < 2 * MB_WIDTH_PIXEL) + { pEncoder->WMP.wmiSCP.olOverlap = OL_ONE; + } else + { pEncoder->WMP.wmiSCP.olOverlap = OL_TWO; - //} + } - //if (!args.bColorFormatSet) - //{ if (quality >= 0.5F || /*PI.uBitsPerSample > 8*/(pixel_format == JxrDecode::PixelFormat::kBgr48 || pixel_format == JxrDecode::PixelFormat::kGray16)) + { pEncoder->WMP.wmiSCP.cfColorFormat = YUV_444; + } else + { pEncoder->WMP.wmiSCP.cfColorFormat = YUV_420; - //} - - //if (PI.bdBitDepth == BD_1) - //{ - // pEncoder->WMP.wmiSCP.uiDefaultQPIndex = (U8)(8 - 5.0F * - // quality/*args.fltImageQuality*/ + 0.5F); - //} - //else - { - // remap [0.8, 0.866, 0.933, 1.0] to [0.8, 0.9, 1.0, 1.1] - // to use 8-bit DPK QP table (0.933 == Photoshop JPEG 100) - int qi; - float qf; - const int* pQPs; - if (/*args.fltImageQuality*/quality > 0.8f && /*PI.bdBitDepth == BD_8*/ - (pixel_format == JxrDecode::PixelFormat::kBgr24 || pixel_format == JxrDecode::PixelFormat::kGray8) && - pEncoder->WMP.wmiSCP.cfColorFormat != YUV_420 && - pEncoder->WMP.wmiSCP.cfColorFormat != YUV_422) - quality/*args.fltImageQuality*/ = 0.8f + (quality/*args.fltImageQuality*/ - 0.8f) * 1.5f; - - qi = (int)(10.f * quality/*args.fltImageQuality*/); - qf = 10.f * quality/*args.fltImageQuality*/ - (float)qi; - - /*pQPs = - (pEncoder->WMP.wmiSCP.cfColorFormat == YUV_420 || - pEncoder->WMP.wmiSCP.cfColorFormat == YUV_422) ? - DPK_QPS_420[qi] : - (PI.bdBitDepth == BD_8 ? DPK_QPS_8[qi] : - (PI.bdBitDepth == BD_16 ? DPK_QPS_16[qi] : - (PI.bdBitDepth == BD_16F ? DPK_QPS_16f[qi] : - DPK_QPS_32f[qi])));*/ - pQPs = - (pEncoder->WMP.wmiSCP.cfColorFormat == YUV_420 || - pEncoder->WMP.wmiSCP.cfColorFormat == YUV_422) ? - DPK_QPS_420[qi] : - (pixel_format == JxrDecode::PixelFormat::kBgr24 || pixel_format == JxrDecode::PixelFormat::kGray8) ? DPK_QPS_8[qi] : - ((pixel_format == JxrDecode::PixelFormat::kBgr48 || pixel_format == JxrDecode::PixelFormat::kGray16) ? DPK_QPS_16[qi] : - (DPK_QPS_32f[qi])); - - pEncoder->WMP.wmiSCP.uiDefaultQPIndex = static_cast(0.5f + - static_cast(pQPs[0]) * (1.f - qf) + static_cast((pQPs + 6)[0]) * qf); - pEncoder->WMP.wmiSCP.uiDefaultQPIndexU = static_cast(0.5f + - static_cast(pQPs[1]) * (1.f - qf) + static_cast((pQPs + 6)[1]) * qf); - pEncoder->WMP.wmiSCP.uiDefaultQPIndexV = static_cast(0.5f + - static_cast(pQPs[2]) * (1.f - qf) + static_cast((pQPs + 6)[2]) * qf); - pEncoder->WMP.wmiSCP.uiDefaultQPIndexYHP = static_cast(0.5f + - static_cast(pQPs[3]) * (1.f - qf) + static_cast((pQPs + 6)[3]) * qf); - pEncoder->WMP.wmiSCP.uiDefaultQPIndexUHP = static_cast(0.5f + - static_cast(pQPs[4]) * (1.f - qf) + static_cast((pQPs + 6)[4]) * qf); - pEncoder->WMP.wmiSCP.uiDefaultQPIndexVHP = static_cast(0.5f + - static_cast(pQPs[5]) * (1.f - qf) + static_cast((pQPs + 6)[5]) * qf); } + + // remap [0.8, 0.866, 0.933, 1.0] to [0.8, 0.9, 1.0, 1.1] + // to use 8-bit DPK QP table (0.933 == Photoshop JPEG 100) + + if (quality > 0.8f && + (pixel_format == JxrDecode::PixelFormat::kBgr24 || pixel_format == JxrDecode::PixelFormat::kGray8) && + pEncoder->WMP.wmiSCP.cfColorFormat != YUV_420 && + pEncoder->WMP.wmiSCP.cfColorFormat != YUV_422) + { + quality = 0.8f + (quality - 0.8f) * 1.5f; + } + + const int qi = static_cast(10.f * quality); + const float qf = 10.f * quality - static_cast(qi); + + const int* pQPs = + (pEncoder->WMP.wmiSCP.cfColorFormat == YUV_420 || + pEncoder->WMP.wmiSCP.cfColorFormat == YUV_422) ? + DPK_QPS_420[qi] : + (pixel_format == JxrDecode::PixelFormat::kBgr24 || pixel_format == JxrDecode::PixelFormat::kGray8) ? DPK_QPS_8[qi] : + ((pixel_format == JxrDecode::PixelFormat::kBgr48 || pixel_format == JxrDecode::PixelFormat::kGray16) ? DPK_QPS_16[qi] : + (DPK_QPS_32f[qi])); + + pEncoder->WMP.wmiSCP.uiDefaultQPIndex = static_cast(0.5f + + static_cast(pQPs[0]) * (1.f - qf) + static_cast((pQPs + 6)[0]) * qf); + pEncoder->WMP.wmiSCP.uiDefaultQPIndexU = static_cast(0.5f + + static_cast(pQPs[1]) * (1.f - qf) + static_cast((pQPs + 6)[1]) * qf); + pEncoder->WMP.wmiSCP.uiDefaultQPIndexV = static_cast(0.5f + + static_cast(pQPs[2]) * (1.f - qf) + static_cast((pQPs + 6)[2]) * qf); + pEncoder->WMP.wmiSCP.uiDefaultQPIndexYHP = static_cast(0.5f + + static_cast(pQPs[3]) * (1.f - qf) + static_cast((pQPs + 6)[3]) * qf); + pEncoder->WMP.wmiSCP.uiDefaultQPIndexUHP = static_cast(0.5f + + static_cast(pQPs[4]) * (1.f - qf) + static_cast((pQPs + 6)[4]) * qf); + pEncoder->WMP.wmiSCP.uiDefaultQPIndexVHP = static_cast(0.5f + + static_cast(pQPs[5]) * (1.f - qf) + static_cast((pQPs + 6)[5]) * qf); } diff --git a/Src/JxrDecode/JxrDecode.h b/Src/JxrDecode/JxrDecode.h index 526fe47c..dbfda81c 100644 --- a/Src/JxrDecode/JxrDecode.h +++ b/Src/JxrDecode/JxrDecode.h @@ -65,12 +65,12 @@ class JxrDecode /// Gets a pointer to the memory representing the compressed data. The memory is owned by the object and will be freed when the object is destroyed. /// /// \returns A pointer to the memory representing the compressed data. - void* GetMemory(); + void* GetMemory() const; /// Gets the size of the compressed data in units of bytes. /// /// \returns The size (in bytes). - size_t GetSize(); + size_t GetSize() const; ~CompressedData(); protected: From a3daeca25b7ba167e941c535886345babc2243bb Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sat, 23 Sep 2023 23:40:04 +0200 Subject: [PATCH 86/98] typo --- Src/JxrDecode/JxrDecode_Config.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/JxrDecode/JxrDecode_Config.h.in b/Src/JxrDecode/JxrDecode_Config.h.in index a4105dfd..79a3495c 100644 --- a/Src/JxrDecode/JxrDecode_Config.h.in +++ b/Src/JxrDecode/JxrDecode_Config.h.in @@ -15,7 +15,7 @@ // whether the intrinsic "__builtin_bswap32" is available (in the header-file byteswap.h) #define JXRDECODE_HAS_BUILTIN_BSWAP32 @jxrdecode_Has_builtin_bswap32@ -// whether the function ""_byteswap_ulong" is available (in the header-file stdlib.h) +// whether the function "_byteswap_ulong" is available (in the header-file stdlib.h) #define JXRDECODE_HAS_BYTESWAP_IN_STDLIB @jxrdecode_Has_byteswap_long_in_stdlib@ // whether the function "bswap32" is available (in the header-file sys/endian.h) From ea8fc5f15e0f1163eb05e8402abcd813a006b75f Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 24 Sep 2023 00:44:41 +0200 Subject: [PATCH 87/98] bump version --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 96073bb3..13aa01dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.15) cmake_policy(SET CMP0091 NEW) # enable new "MSVC runtime library selection" (https://cmake.org/cmake/help/latest/variable/CMAKE_MSVC_RUNTIME_LIBRARY.html) project(libCZI - VERSION 0.52.0 + VERSION 0.53.0 HOMEPAGE_URL "https://github.com/ZEISS/libczi" DESCRIPTION "libCZI is an Open Source Cross-Platform C++ library to read and write CZI") From 44bf0b8ec28443bac0b2ed77d8ae5fa2fd34b1d1 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 24 Sep 2023 01:02:54 +0200 Subject: [PATCH 88/98] cleanup --- Src/libCZI/decoder.cpp | 301 ----------------------------------------- Src/libCZI/decoder.h | 10 -- 2 files changed, 311 deletions(-) diff --git a/Src/libCZI/decoder.cpp b/Src/libCZI/decoder.cpp index e0f6d163..db48ff8d 100644 --- a/Src/libCZI/decoder.cpp +++ b/Src/libCZI/decoder.cpp @@ -34,74 +34,9 @@ static libCZI::PixelType PixelTypeFromJxrPixelFormat(JxrDecode::PixelFormat pixe /*static*/std::shared_ptr CJxrLibDecoder::Create() { - //return make_shared(JxrDecode::Initialize()); return make_shared(); } -/*std::shared_ptr CJxrLibDecoder::Encode(libCZI::PixelType pixel_type, std::uint32_t width, std::uint32_t height, std::uint32_t stride, const void* ptrData, float quality) -{ - JxrDecode::PixelFormat jxrdecode_pixel_format; - switch (pixel_type) - { - case PixelType::Bgr24: - jxrdecode_pixel_format = JxrDecode::PixelFormat::kBgr24; - break; - case PixelType::Bgr48: - jxrdecode_pixel_format = JxrDecode::PixelFormat::kBgr48; - break; - case PixelType::Gray8: - jxrdecode_pixel_format = JxrDecode::PixelFormat::kGray8; - break; - case PixelType::Gray16: - jxrdecode_pixel_format = JxrDecode::PixelFormat::kGray16; - break; - case PixelType::Gray32Float: - jxrdecode_pixel_format = JxrDecode::PixelFormat::kGray32Float; - break; - default: - throw std::logic_error("unsupported pixel type"); - } - - // Unfortunately, the encoder does not support the pixelformat Bgr48, so we need to convert it to Rgb48 - // before passing it to the encoder (meaning: the resulting encoded data will be Rgb48, not Bgr48). - // TODO(JBL): would be nice if the encoder would support Bgr48 directly somehow - if (jxrdecode_pixel_format == JxrDecode::PixelFormat::kBgr48) - { - // unfortunately, we have to make a temporary copy - const auto bitmap_rgb48 = GetSite()->CreateBitmap(PixelType::Bgr48, width, height); - - const ScopedBitmapLockerSP bmLck(bitmap_rgb48); - CBitmapOperations::CopySamePixelType( - ptrData, - stride, - bmLck.ptrDataRoi, - bmLck.stride, - width, - height, - false); - CBitmapOperations::RGB48ToBGR48(width, height, static_cast(bmLck.ptrDataRoi), bmLck.stride); - auto compressed_data = JxrDecode::Encode( - jxrdecode_pixel_format, - width, - height, - bmLck.stride, - bmLck.ptrDataRoi, - quality); - return make_shared(std::move(compressed_data)); - } - else - { - auto compressed_data = JxrDecode::Encode( - jxrdecode_pixel_format, - width, - height, - stride, - ptrData, - quality); - return make_shared(std::move(compressed_data)); - } -}*/ - std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, size_t size, libCZI::PixelType pixelType, uint32_t width, uint32_t height) { std::shared_ptr bitmap; @@ -168,239 +103,3 @@ std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, return bitmap; } - -#if false -std::shared_ptr CJxrLibDecoder::Decode(const void* ptrData, size_t size, libCZI::PixelType pixelType, uint32_t width, uint32_t height) -{ - std::shared_ptr bm; - JxrDecode decoder2; - decoder2.Decode(nullptr, - ptrData, - size, - nullptr, - [&](JxrDecode::PixelFormat pixFmt, std::uint32_t width, std::uint32_t height, std::uint32_t linesCount, const void* ptrData, std::uint32_t stride)->void - { - /* if (GetSite()->IsEnabled(LOGLEVEL_CHATTYINFORMATION)) - { - stringstream ss; ss << "JxrDecode: decode done - pixelfmt=" << JxrDecode::PixelFormatAsInformalString(pixFmt) << " width=" << width << " height=" << height << " linesCount=" << linesCount << " stride=" << stride; - GetSite()->Log(LOGLEVEL_CHATTYINFORMATION, ss.str()); - }*/ - - // TODO: it seems feasible to directly decode to the buffer (saving us the copy) - PixelType px_type; - switch (pixFmt) - { - case JxrDecode::PixelFormat::kBgr24: px_type = PixelType::Bgr24; break; - case JxrDecode::PixelFormat::kGray8: px_type = PixelType::Gray8; break; - case JxrDecode::PixelFormat::kBgr48: px_type = PixelType::Bgr48; break; - case JxrDecode::PixelFormat::kGray16: px_type = PixelType::Gray16; break; - //case JxrDecode::PixelFormat::_32bppGrayFloat: px_type = PixelType::Gray32Float; break; - default: throw std::logic_error("need to look into these formats..."); - } - - bm = GetSite()->CreateBitmap(px_type, width, height); - auto bmLckInfo = ScopedBitmapLockerSP(bm); - if (bmLckInfo.stride != stride) - { - for (uint32_t i = 0; i < linesCount; ++i) - { - memcpy(static_cast(bmLckInfo.ptrDataRoi) + i * bmLckInfo.stride, static_cast(ptrData) + i * stride, stride); - } - } - else - { - memcpy(bmLckInfo.ptrDataRoi, ptrData, static_cast(stride) * linesCount); - } - - // since BGR48 is not available as output, we need to convert (#36) - if (px_type == PixelType::Bgr48) - { - CBitmapOperations::RGB48ToBGR48(width, height, (uint16_t*)bmLckInfo.ptrDataRoi, bmLckInfo.stride); - } -} - ); - - return bm; -} -#endif - -#if false -std::shared_ptr CJxrLibDecoder::Decode2(const void* ptrData, size_t size, libCZI::PixelType pixelType, uint32_t width, uint32_t height) -{ - std::shared_ptr bm; - - JxrDecode::WMPDECAPPARGS args; args.Clear(); - args.uAlphaMode = 0; // we don't need any alpha, never - - try - { - if (GetSite()->IsEnabled(LOGLEVEL_CHATTYINFORMATION)) - { - stringstream ss; ss << "Begin JxrDecode with " << size << " bytes"; - GetSite()->Log(LOGLEVEL_CHATTYINFORMATION, ss.str()); - } - - JxrDecode::Decode(this->handle, &args, ptrData, size, - [pixelType, width, height](JxrDecode::PixelFormat decPixFmt, int decodedWidth, int decodedHeight)->JxrDecode::PixelFormat - { - // We get the "original pixelformat" of the compressed data, and we need to respond - // which pixelformat we want to get from the decoder. - // ...one problem is that not all format-conversions are possible - we choose the "closest" - JxrDecode::PixelFormat destFmt; - switch (decPixFmt) - { - case JxrDecode::PixelFormat::_24bppBGR: - case JxrDecode::PixelFormat::_32bppRGBE: - case JxrDecode::PixelFormat::_32bppCMYK: - case JxrDecode::PixelFormat::_32bppBGR: - case JxrDecode::PixelFormat::_16bppBGR555: - case JxrDecode::PixelFormat::_16bppBGR565: - case JxrDecode::PixelFormat::_32bppBGR101010: - case JxrDecode::PixelFormat::_24bppRGB: - case JxrDecode::PixelFormat::_32bppBGRA: - destFmt = JxrDecode::PixelFormat::_24bppBGR; - if (pixelType != libCZI::PixelType::Bgr24) - { - throw std::runtime_error("pixel type validation failed..."); - } - - break; - case JxrDecode::PixelFormat::_1bppBlackWhite: - case JxrDecode::PixelFormat::_8bppGray: - destFmt = JxrDecode::PixelFormat::_8bppGray; - if (pixelType != libCZI::PixelType::Gray8) - { - throw std::runtime_error("pixel type validation failed..."); - } - - break; - case JxrDecode::PixelFormat::_16bppGray: - case JxrDecode::PixelFormat::_16bppGrayFixedPoint: - case JxrDecode::PixelFormat::_16bppGrayHalf: - destFmt = JxrDecode::PixelFormat::_16bppGray; - if (pixelType != libCZI::PixelType::Gray16) - { - throw std::runtime_error("pixel type validation failed..."); - } - - break; - case JxrDecode::PixelFormat::_32bppGrayFixedPoint: - case JxrDecode::PixelFormat::_32bppGrayFloat: - destFmt = JxrDecode::PixelFormat::_32bppGrayFloat; - if (pixelType != libCZI::PixelType::Bgra32) - { - throw std::runtime_error("pixel type validation failed..."); - } - - break; - case JxrDecode::PixelFormat::_48bppRGB: - destFmt = JxrDecode::PixelFormat::_48bppRGB; - if (pixelType != libCZI::PixelType::Bgr48) - { - throw std::runtime_error("pixel type validation failed..."); - } - - break; - case JxrDecode::PixelFormat::_48bppRGBFixedPoint: - case JxrDecode::PixelFormat::_48bppRGBHalf: - case JxrDecode::PixelFormat::_96bppRGBFixedPoint: - case JxrDecode::PixelFormat::_128bppRGBFloat: - case JxrDecode::PixelFormat::_64bppCMYK: - case JxrDecode::PixelFormat::_64bppRGBA: - case JxrDecode::PixelFormat::_64bppRGBAFixedPoint: - case JxrDecode::PixelFormat::_64bppRGBAHalf: - case JxrDecode::PixelFormat::_128bppRGBAFixedPoint: - case JxrDecode::PixelFormat::_128bppRGBAFloat: - case JxrDecode::PixelFormat::_40bppCMYKA: - case JxrDecode::PixelFormat::_80bppCMYKA: - default: - throw std::logic_error("need to look into these formats..."); - } - - if (width != decodedWidth || height != decodedHeight) - { - throw std::runtime_error("width and/or height validation failed..."); - } - - if (GetSite()->IsEnabled(LOGLEVEL_CHATTYINFORMATION)) - { - stringstream ss; ss << "JxrDecode: original pixelfmt: " << JxrDecode::PixelFormatAsInformalString(decPixFmt) << ", requested pixelfmt: " << JxrDecode::PixelFormatAsInformalString(destFmt); - GetSite()->Log(LOGLEVEL_CHATTYINFORMATION, ss.str()); - } - - if (destFmt == JxrDecode::PixelFormat::invalid) - { - throw std::logic_error("need to look into these formats..."); - } - - return destFmt; - }, - [&](JxrDecode::PixelFormat pixFmt, std::uint32_t width, std::uint32_t height, std::uint32_t linesCount, const void* ptrData, std::uint32_t stride)->void - { - if (GetSite()->IsEnabled(LOGLEVEL_CHATTYINFORMATION)) - { - stringstream ss; ss << "JxrDecode: decode done - pixelfmt=" << JxrDecode::PixelFormatAsInformalString(pixFmt) << " width=" << width << " height=" << height << " linesCount=" << linesCount << " stride=" << stride; - GetSite()->Log(LOGLEVEL_CHATTYINFORMATION, ss.str()); - } - - // TODO: it seems feasible to directly decode to the buffer (saving us the copy) - PixelType px_type; - switch (pixFmt) - { - case JxrDecode::PixelFormat::_24bppBGR: px_type = PixelType::Bgr24; break; - case JxrDecode::PixelFormat::_8bppGray: px_type = PixelType::Gray8; break; - case JxrDecode::PixelFormat::_48bppRGB: px_type = PixelType::Bgr48; break; - case JxrDecode::PixelFormat::_16bppGray: px_type = PixelType::Gray16; break; - case JxrDecode::PixelFormat::_32bppGrayFloat: px_type = PixelType::Gray32Float; break; - default: throw std::logic_error("need to look into these formats..."); - } - - bm = GetSite()->CreateBitmap(px_type, width, height); - auto bmLckInfo = ScopedBitmapLockerSP(bm); - if (bmLckInfo.stride != stride) - { - for (uint32_t i = 0; i < linesCount; ++i) - { - memcpy(static_cast(bmLckInfo.ptrDataRoi) + i * bmLckInfo.stride, static_cast(ptrData) + i * stride, stride); - } - } - else - { - memcpy(bmLckInfo.ptrDataRoi, ptrData, static_cast(stride) * linesCount); - } - - // since BGR48 is not available as output, we need to convert (#36) - if (px_type == PixelType::Bgr48) - { - CBitmapOperations::RGB48ToBGR48(width, height, (uint16_t*)bmLckInfo.ptrDataRoi, bmLckInfo.stride); - } - }); - } - catch (std::runtime_error& err) - { - // TODO: now what...? - if (GetSite()->IsEnabled(LOGLEVEL_ERROR)) - { - stringstream ss; - ss << "Exception 'runtime_error' caught from JXR-decoder-invocation -> \"" << err.what() << "\"."; - GetSite()->Log(LOGLEVEL_ERROR, ss); - } - - throw; - } - catch (std::exception& excp) - { - // TODO: now what...? - if (GetSite()->IsEnabled(LOGLEVEL_ERROR)) - { - stringstream ss; - ss << "Exception caught from JXR-decoder-invocation -> \"" << excp.what() << "\"."; - GetSite()->Log(LOGLEVEL_ERROR, ss); - } - - throw; - } - - return bm; - } -#endif diff --git a/Src/libCZI/decoder.h b/Src/libCZI/decoder.h index 9cb00041..c44d00ec 100644 --- a/Src/libCZI/decoder.h +++ b/Src/libCZI/decoder.h @@ -11,18 +11,8 @@ class CJxrLibDecoder : public libCZI::IDecoder { -private: -// JxrDecode::codecHandle handle; public: static std::shared_ptr Create(); - /* explicit CJxrLibDecoder(JxrDecode::codecHandle handle) - : handle(handle) - {}*/ - -public: std::shared_ptr Decode(const void* ptrData, size_t size, libCZI::PixelType, std::uint32_t width, std::uint32_t height) override; - //std::shared_ptr Decode2(const void* ptrData, size_t size, libCZI::PixelType, std::uint32_t width, std::uint32_t height); - - // std::shared_ptr Encode(libCZI::PixelType pixel_type, std::uint32_t width, std::uint32_t height, std::uint32_t stride, const void* ptrData, float quality = 1.f); }; From acacb2bb9764992a30d91753e572ef4a302e9aac Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 24 Sep 2023 11:17:24 +0200 Subject: [PATCH 89/98] documentation --- Src/libCZI/libCZI_compress.h | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Src/libCZI/libCZI_compress.h b/Src/libCZI/libCZI_compress.h index a9669cd7..f9bea2b6 100644 --- a/Src/libCZI/libCZI_compress.h +++ b/Src/libCZI/libCZI_compress.h @@ -14,7 +14,7 @@ namespace libCZI { /// Values that represent well-known keys for the compression-parameters property bag. Note that - /// the property-bag API is modelled with an int as key, which is by intention in order to allow + /// the property-bag API is modeled with an int as key, which is by intention in order to allow /// for private keys. enum class CompressionParameterKey { @@ -198,7 +198,7 @@ namespace libCZI }; /// The functions found here deal with zstd-compression (the compression-part in particular). - /// TThose functions are rather low-level, and the common theme is - given a source bitmap, create a blob + /// Those functions are rather low-level, and the common theme is - given a source bitmap, create a blob /// (containing the compressed bitmap data) which is suitable to be placed in a subblock's data. /// Several overloads are provided, for performance critical scenarios we provide functions which write /// directly into caller-provided memory, and there are versions which use caller-provided functions for @@ -523,9 +523,25 @@ namespace libCZI const ICompressParameters* parameters); }; + /// The functions found here deal with JXR-compression - as implemented by jxrlib (the JPEG XR + /// Image Codec reference implementation library released by Microsoft under BSD-2-Clause License). + /// Those functions are rather low-level, and the common theme is - given a source bitmap, create a blob + /// (containing the compressed bitmap data) which is suitable to be placed in a subblock's data. class LIBCZI_API JxrLibCompress { public: + /// Compress the specified bitmap in "JXR"-format. This method will compress the + /// specified source-bitmap according to the "JXR-scheme" to a newly allocated block of memory. + /// Parameters controlling the operation are provided in an optional property bag. + /// + /// \param pixel_type The pixel type of the source bitmap. + /// \param width Width of the source bitmap in pixels. + /// \param height Height of the source bitmap in pixels. + /// \param stride The stride of the source bitmap in bytes. + /// \param ptrData Pointer to the source bitmap. + /// \param parameters Property bag containing parameters controlling the operation. This argument can be null, in which case default parameters are used. + /// + /// \returns A shared pointer to an object representing and owning a block of memory, containing the JXR-compressed bitmap. static std::shared_ptr Compress( libCZI::PixelType pixel_type, std::uint32_t width, From d1424ed3eb14bd08ed345e1c4e26faf40bfd8db1 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 24 Sep 2023 11:20:44 +0200 Subject: [PATCH 90/98] linter --- Src/JxrDecode/JxrDecode.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Src/JxrDecode/JxrDecode.cpp b/Src/JxrDecode/JxrDecode.cpp index 1a30d5f9..73e5fd75 100644 --- a/Src/JxrDecode/JxrDecode.cpp +++ b/Src/JxrDecode/JxrDecode.cpp @@ -96,9 +96,9 @@ static void WriteGuidToStream(ostringstream& string_stream, const GUID& guid) } void JxrDecode::Decode( - const void* ptrData, - size_t size, - const std::function(PixelFormat pixel_format, std::uint32_t width, std::uint32_t height)>& get_destination_func) + const void* ptrData, + size_t size, + const std::function(PixelFormat pixel_format, std::uint32_t width, std::uint32_t height)>& get_destination_func) { if (ptrData == nullptr) { @@ -251,7 +251,7 @@ void JxrDecode::Decode( codec_parameters.uAlphaMode = 0; codec_parameters.uiDefaultQPIndex = 1; codec_parameters.uiDefaultQPIndexAlpha = 1; - + struct tagWMPStream* pEncodeStream = nullptr; err = CreateWS_HeapBackedWriteableStream(&pEncodeStream, 1024, 0); if (Failed(err)) @@ -466,7 +466,7 @@ size_t JxrDecode::CompressedData::GetSize() const }; #endif - static const int DPK_QPS_16[11][6] = + static const int DPK_QPS_16[11][6] = { { 197, 203, 210, 202, 207, 213 }, { 174, 188, 193, 180, 189, 196 }, @@ -495,7 +495,7 @@ size_t JxrDecode::CompressedData::GetSize() const { 3, 5, 7, 3, 5, 6 } };*/ - static const int DPK_QPS_32f[11][6] = + static const int DPK_QPS_32f[11][6] = { { 194, 206, 209, 204, 211, 217 }, { 175, 187, 196, 186, 193, 205 }, @@ -544,8 +544,7 @@ size_t JxrDecode::CompressedData::GetSize() const const float qf = 10.f * quality - static_cast(qi); const int* pQPs = - (pEncoder->WMP.wmiSCP.cfColorFormat == YUV_420 || - pEncoder->WMP.wmiSCP.cfColorFormat == YUV_422) ? + (pEncoder->WMP.wmiSCP.cfColorFormat == YUV_420 || pEncoder->WMP.wmiSCP.cfColorFormat == YUV_422) ? DPK_QPS_420[qi] : (pixel_format == JxrDecode::PixelFormat::kBgr24 || pixel_format == JxrDecode::PixelFormat::kGray8) ? DPK_QPS_8[qi] : ((pixel_format == JxrDecode::PixelFormat::kBgr48 || pixel_format == JxrDecode::PixelFormat::kGray16) ? DPK_QPS_16[qi] : From ae0a4794324e68f3c29871dee3b64c28c6774949 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 24 Sep 2023 11:24:57 +0200 Subject: [PATCH 91/98] fix CodeQL-issue --- Src/JxrDecode/jxrlib/image/sys/strcodec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/JxrDecode/jxrlib/image/sys/strcodec.c b/Src/JxrDecode/jxrlib/image/sys/strcodec.c index b473a11f..fc1c3865 100644 --- a/Src/JxrDecode/jxrlib/image/sys/strcodec.c +++ b/Src/JxrDecode/jxrlib/image/sys/strcodec.c @@ -912,7 +912,7 @@ Int allocateBitIOInfo(CWMImageStrCodec* pSC) // allocate index table if (cNumBitIO > MAX_TILES * 4 || pSC->WMISCP.cNumOfSliceMinus1H >= MAX_TILES) return ICERR_ERROR; - pSC->pIndexTable = malloc(cNumBitIO * (pSC->WMISCP.cNumOfSliceMinus1H + 1) * sizeof(size_t)); + pSC->pIndexTable = malloc((pSC->WMISCP.cNumOfSliceMinus1H + 1) * sizeof(size_t) * cNumBitIO); if (NULL == pSC->pIndexTable) return ICERR_ERROR; } From 2effa77cc57de6a32b8b61e54ed0058efa682c71 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 24 Sep 2023 11:51:20 +0200 Subject: [PATCH 92/98] cosmetic / lint --- Src/JxrDecode/JxrDecode.cpp | 14 +++++------ Src/JxrDecode/jxrlib/common/include/guiddef.h | 2 +- Src/JxrDecode/jxrlib/image/sys/common.h | 2 +- .../jxrlib/image/sys/windowsmediaphoto.h | 2 +- Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h | 7 +++--- Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h | 8 +++---- Src/libCZI/StreamImpl.h | 2 +- Src/libCZI/decoder.h | 2 +- Src/libCZI_UnitTests/test_JxrDecode.cpp | 24 +++++++++---------- 9 files changed, 31 insertions(+), 32 deletions(-) diff --git a/Src/JxrDecode/JxrDecode.cpp b/Src/JxrDecode/JxrDecode.cpp index 73e5fd75..e1c51b3c 100644 --- a/Src/JxrDecode/JxrDecode.cpp +++ b/Src/JxrDecode/JxrDecode.cpp @@ -182,12 +182,12 @@ void JxrDecode::Decode( } /*static*/JxrDecode::CompressedData JxrDecode::Encode( - JxrDecode::PixelFormat pixel_format, - std::uint32_t width, - std::uint32_t height, - std::uint32_t stride, - const void* ptr_bitmap, - float quality/*=1.f*/) + JxrDecode::PixelFormat pixel_format, + std::uint32_t width, + std::uint32_t height, + std::uint32_t stride, + const void* ptr_bitmap, + float quality/*=1.f*/) { if (ptr_bitmap == nullptr) { @@ -272,7 +272,7 @@ void JxrDecode::Decode( ApplyQuality(quality, pixel_format, width, upImageEncoder.get()); } - switch (pixel_format) // NOLINT(clang-diagnostic-switch-enum) + switch (pixel_format) { case PixelFormat::kBgr24: err = upImageEncoder->SetPixelFormat(upImageEncoder.get(), GUID_PKPixelFormat24bppBGR); diff --git a/Src/JxrDecode/jxrlib/common/include/guiddef.h b/Src/JxrDecode/jxrlib/common/include/guiddef.h index 8e20f7df..f24e72c9 100644 --- a/Src/JxrDecode/jxrlib/common/include/guiddef.h +++ b/Src/JxrDecode/jxrlib/common/include/guiddef.h @@ -80,7 +80,7 @@ typedef struct _GUID { /// \returns A non-zero value if the two GUIDs are equal, and zero otherwise. static inline int IsEqualGUID(const GUID* guid1, const GUID* guid2) { - return !memcmp(guid1, guid2, sizeof(GUID)); + return !memcmp(guid1, guid2, sizeof(GUID)); } #endif // GUID_DEFINED diff --git a/Src/JxrDecode/jxrlib/image/sys/common.h b/Src/JxrDecode/jxrlib/image/sys/common.h index 5aa41ba4..861044d3 100644 --- a/Src/JxrDecode/jxrlib/image/sys/common.h +++ b/Src/JxrDecode/jxrlib/image/sys/common.h @@ -81,7 +81,7 @@ typedef struct CAdaptiveHuffman /************************************************************************************ - Context structures + Context structures ************************************************************************************/ typedef struct CAdaptiveModel { Int m_iFlcState[2]; diff --git a/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h b/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h index 88a904eb..d56bb118 100644 --- a/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h +++ b/Src/JxrDecode/jxrlib/image/sys/windowsmediaphoto.h @@ -44,7 +44,7 @@ #endif // __cplusplus /******************************************************************************** - Type definitions + Type definitions ********************************************************************************/ typedef int Bool; typedef char Char; diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h index 6b5f0e00..8adfee68 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRGlue.h @@ -557,8 +557,7 @@ extern "C" { typedef struct tagPKFormatConverter { ERR(*Initialize)(PKFormatConverter*, PKImageDecode*, char* pExt, PKPixelFormatGUID); - ERR(*InitializeConvert)(PKFormatConverter* pFC, const PKPixelFormatGUID enPFFrom, - char* pExt, PKPixelFormatGUID enPFTTo); + ERR(*InitializeConvert)(PKFormatConverter* pFC, const PKPixelFormatGUID enPFFrom, char* pExt, PKPixelFormatGUID enPFTTo); ERR(*GetPixelFormat)(PKFormatConverter*, PKPixelFormatGUID*); ERR(*GetSourcePixelFormat)(PKFormatConverter*, PKPixelFormatGUID*); @@ -590,8 +589,8 @@ extern "C" { // Think of this as static member of PKFormatConverter "class" ERR PKFormatConverter_EnumConversions(const PKPixelFormatGUID* pguidSourcePF, - const U32 iIndex, - const PKPixelFormatGUID** ppguidTargetPF); + const U32 iIndex, + const PKPixelFormatGUID** ppguidTargetPF); ERR PKCodecFactory_CreateFormatConverter(PKFormatConverter** ppFConverter); diff --git a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h index 2335b1df..81143cf0 100644 --- a/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h +++ b/Src/JxrDecode/jxrlib/jxrgluelib/JXRMeta.h @@ -219,10 +219,10 @@ EXTERN_C ERR WriteWmpDE( EXTERN_C ERR ReadPropvar(struct tagWMPStream* pWS, - const U16 uType, - const U32 uCount, - const U32 uValue, - DPKPROPVARIANT* pvar); + const U16 uType, + const U32 uCount, + const U32 uValue, + DPKPROPVARIANT* pvar); diff --git a/Src/libCZI/StreamImpl.h b/Src/libCZI/StreamImpl.h index c5f2810c..0f554b73 100644 --- a/Src/libCZI/StreamImpl.h +++ b/Src/libCZI/StreamImpl.h @@ -9,7 +9,7 @@ #include "inc_libCZI_Config.h" #include #if defined(_WIN32) - #include + #include #endif /// A simplistic stream implementation (based on C-runtime fopen). Note that this implementation is NOT thread-safe. diff --git a/Src/libCZI/decoder.h b/Src/libCZI/decoder.h index c44d00ec..fe9e99a4 100644 --- a/Src/libCZI/decoder.h +++ b/Src/libCZI/decoder.h @@ -1,4 +1,4 @@ - // SPDX-FileCopyrightText: 2017-2022 Carl Zeiss Microscopy GmbH +// SPDX-FileCopyrightText: 2017-2022 Carl Zeiss Microscopy GmbH // // SPDX-License-Identifier: LGPL-3.0-or-later diff --git a/Src/libCZI_UnitTests/test_JxrDecode.cpp b/Src/libCZI_UnitTests/test_JxrDecode.cpp index 1592fc9e..e9349b02 100644 --- a/Src/libCZI_UnitTests/test_JxrDecode.cpp +++ b/Src/libCZI_UnitTests/test_JxrDecode.cpp @@ -397,12 +397,12 @@ TEST(JxrDecode, CallEncoderWithInvalidArgumentsExpectException) { const ScopedBitmapLockerSP lck{ bitmap }; JxrLibCompress::Compress( - bitmap->GetPixelType(), - bitmap->GetWidth(), - 0, - lck.stride, - lck.ptrDataRoi, - nullptr); + bitmap->GetPixelType(), + bitmap->GetWidth(), + 0, + lck.stride, + lck.ptrDataRoi, + nullptr); }, exception); EXPECT_THROW( @@ -421,12 +421,12 @@ TEST(JxrDecode, CallEncoderWithInvalidArgumentsExpectException) { const ScopedBitmapLockerSP lck{ bitmap }; JxrLibCompress::Compress( - bitmap->GetPixelType(), - bitmap->GetWidth(), - bitmap->GetHeight(), - lck.stride, - nullptr, - nullptr); + bitmap->GetPixelType(), + bitmap->GetWidth(), + bitmap->GetHeight(), + lck.stride, + nullptr, + nullptr); }, exception); } From 59663ba4c2af5d99e13826d028b4b9f556ff3895 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Sun, 24 Sep 2023 13:47:40 +0200 Subject: [PATCH 93/98] cosmetc - rename --- Src/libCZI_UnitTests/CMakeLists.txt | 2 +- ...est_JxrDecode.cpp => test_JxrlibCodec.cpp} | 24 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) rename Src/libCZI_UnitTests/{test_JxrDecode.cpp => test_JxrlibCodec.cpp} (96%) diff --git a/Src/libCZI_UnitTests/CMakeLists.txt b/Src/libCZI_UnitTests/CMakeLists.txt index a6772e42..c1928e58 100644 --- a/Src/libCZI_UnitTests/CMakeLists.txt +++ b/Src/libCZI_UnitTests/CMakeLists.txt @@ -36,7 +36,7 @@ ADD_EXECUTABLE(libCZI_UnitTests test_StreamImplementations.cpp MemInputOutputStream.h test_bitmapOperations.cpp - test_JxrDecode.cpp + test_JxrlibCodec.cpp test_Utilities.cpp MemOutputStream.cpp test_CziSubBlockDirectory.cpp diff --git a/Src/libCZI_UnitTests/test_JxrDecode.cpp b/Src/libCZI_UnitTests/test_JxrlibCodec.cpp similarity index 96% rename from Src/libCZI_UnitTests/test_JxrDecode.cpp rename to Src/libCZI_UnitTests/test_JxrlibCodec.cpp index e9349b02..70493b74 100644 --- a/Src/libCZI_UnitTests/test_JxrDecode.cpp +++ b/Src/libCZI_UnitTests/test_JxrlibCodec.cpp @@ -15,7 +15,7 @@ using namespace libCZI; using namespace std; -TEST(JxrDecode, DecodeBgr24) +TEST(JxrlibCodec, DecodeBgr24) { const auto dec = CJxrLibDecoder::Create(); size_t sizeEncoded; int expectedWidth, expectedHeight; @@ -32,7 +32,7 @@ TEST(JxrDecode, DecodeBgr24) EXPECT_TRUE(memcmp(hash, expectedResult, 16) == 0) << "Incorrect result"; } -TEST(JxrDecode, DecodeGray8) +TEST(JxrlibCodec, DecodeGray8) { const auto dec = CJxrLibDecoder::Create(); size_t sizeEncoded; int expectedWidth, expectedHeight; @@ -49,7 +49,7 @@ TEST(JxrDecode, DecodeGray8) EXPECT_TRUE(memcmp(hash, expectedResult, 16) == 0) << "Incorrect result"; } -TEST(JxrDecode, TryDecodeInvalidDataExpectException) +TEST(JxrlibCodec, TryDecodeInvalidDataExpectException) { // pass invalid data to decoder, and expect an exception const auto dec = CJxrLibDecoder::Create(); @@ -63,7 +63,7 @@ TEST(JxrDecode, TryDecodeInvalidDataExpectException) EXPECT_ANY_THROW(dec->Decode(encoded_data.get(), sizeEncoded, libCZI::PixelType::Invalid, 0, 0)); } -TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Bgr24) +TEST(JxrlibCodec, CompressNonLossyAndDecompressCheckForSameContent_Bgr24) { const auto bitmap = CBitmapData::Create(PixelType::Bgr24, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); { @@ -101,7 +101,7 @@ TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Bgr24) EXPECT_TRUE(are_equal) << "Original bitmap and encoded-decoded one are not identical."; } -TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Gray8) +TEST(JxrlibCodec, CompressNonLossyAndDecompressCheckForSameContent_Gray8) { const auto bitmap = CBitmapData::Create(PixelType::Gray8, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); { @@ -150,7 +150,7 @@ TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Gray8) EXPECT_TRUE(are_equal) << "Original bitmap and encoded-decoded one are not identical."; } -TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Gray16) +TEST(JxrlibCodec, CompressNonLossyAndDecompressCheckForSameContent_Gray16) { const auto bitmap_gray16 = CBitmapData::Create(PixelType::Gray16, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); { @@ -202,7 +202,7 @@ TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Gray16) EXPECT_TRUE(are_equal) << "Original bitmap and encoded-decoded one are not identical."; } -TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Gray32Float) +TEST(JxrlibCodec, CompressNonLossyAndDecompressCheckForSameContent_Gray32Float) { const auto bitmap_gray32float = CBitmapData::Create(PixelType::Gray32Float, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); { @@ -254,7 +254,7 @@ TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Gray32Float) EXPECT_TRUE(are_equal) << "Original bitmap and encoded-decoded one are not identical."; } -TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Bgr48) +TEST(JxrlibCodec, CompressNonLossyAndDecompressCheckForSameContent_Bgr48) { const auto bitmap_bgr48 = CBitmapData::Create(PixelType::Bgr48, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); { @@ -308,7 +308,7 @@ TEST(JxrDecode, CompressNonLossyAndDecompressCheckForSameContent_Bgr48) EXPECT_TRUE(are_equal) << "Original bitmap and encoded-decoded one are not identical."; } -TEST(JxrDecode, CompressLossyAndDecompressCheckForSimilarity_Gray8) +TEST(JxrlibCodec, CompressLossyAndDecompressCheckForSimilarity_Gray8) { const auto bitmap = CBitmapData::Create(PixelType::Gray8, CTestImage::BGR24TESTIMAGE_WIDTH, CTestImage::BGR24TESTIMAGE_HEIGHT); { @@ -365,7 +365,7 @@ TEST(JxrDecode, CompressLossyAndDecompressCheckForSimilarity_Gray8) EXPECT_TRUE(get<0>(max_difference_mean_difference) <= 5 && get<1>(max_difference_mean_difference) < 1) << "Original bitmap and encoded-decoded one are not identical."; } -TEST(JxrDecode, CallEncoderWithInvalidArgumentsExpectException) +TEST(JxrlibCodec, CallEncoderWithInvalidArgumentsExpectException) { const auto bitmap = CBitmapData::Create(PixelType::Gray8, 5, 5); //const auto codec = CJxrLibDecoder::Create(); @@ -431,7 +431,7 @@ TEST(JxrDecode, CallEncoderWithInvalidArgumentsExpectException) exception); } -TEST(JxrDecode, CallDecoderWithInvalidArgumentsExpectException) +TEST(JxrlibCodec, CallDecoderWithInvalidArgumentsExpectException) { constexpr size_t kSizeOfEncodedData = 223; const unique_ptr encoded_data{ malloc(kSizeOfEncodedData), &free }; @@ -473,7 +473,7 @@ TEST(JxrDecode, CallDecoderWithInvalidArgumentsExpectException) exception); } -TEST(JxrDecode, CallDecoderExpectingADifferentBitmapTypeAndExpectException) +TEST(JxrlibCodec, CallDecoderExpectingADifferentBitmapTypeAndExpectException) { size_t size_encoded_data; int expected_width, expected_height; From ed9f87199b4f137d4f4d90f582f4eded8d4c7c08 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Tue, 26 Sep 2023 00:20:13 +0200 Subject: [PATCH 94/98] fix valgrind-reported issue --- Src/libCZI_UnitTests/test_JxrlibCodec.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Src/libCZI_UnitTests/test_JxrlibCodec.cpp b/Src/libCZI_UnitTests/test_JxrlibCodec.cpp index 70493b74..5c0829d3 100644 --- a/Src/libCZI_UnitTests/test_JxrlibCodec.cpp +++ b/Src/libCZI_UnitTests/test_JxrlibCodec.cpp @@ -38,8 +38,8 @@ TEST(JxrlibCodec, DecodeGray8) size_t sizeEncoded; int expectedWidth, expectedHeight; const auto ptrEncodedData = CTestImage::GetJpgXrCompressedImage_Gray8(&sizeEncoded, &expectedWidth, &expectedHeight); const auto bmDecoded = dec->Decode(ptrEncodedData, sizeEncoded, libCZI::PixelType::Gray8, expectedWidth, expectedHeight); - EXPECT_EQ((uint32_t)expectedWidth, bmDecoded->GetWidth()) << "Width is expected to be equal"; - EXPECT_EQ((uint32_t)expectedHeight, bmDecoded->GetHeight()) << "Height is expected to be equal"; + EXPECT_EQ(static_cast(expectedWidth), bmDecoded->GetWidth()) << "Width is expected to be equal"; + EXPECT_EQ(static_cast(expectedHeight), bmDecoded->GetHeight()) << "Height is expected to be equal"; EXPECT_EQ(bmDecoded->GetPixelType(), PixelType::Gray8) << "Not the correct pixeltype."; uint8_t hash[16] = { 0 }; @@ -54,7 +54,7 @@ TEST(JxrlibCodec, TryDecodeInvalidDataExpectException) // pass invalid data to decoder, and expect an exception const auto dec = CJxrLibDecoder::Create(); constexpr size_t sizeEncoded = 2345; - const unique_ptr encoded_data(new uint8_t[sizeEncoded]); + const unique_ptr encoded_data(new uint8_t[sizeEncoded]); for (size_t i = 0; i < sizeEncoded; i++) { encoded_data.get()[i] = static_cast(i); From 50b7cf9ca9a3e2f6b320fd4b188ac6091f59b13d Mon Sep 17 00:00:00 2001 From: ptahmose Date: Wed, 27 Sep 2023 00:23:47 +0200 Subject: [PATCH 95/98] test --- Src/JxrDecode/JxrDecode.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Src/JxrDecode/JxrDecode.cpp b/Src/JxrDecode/JxrDecode.cpp index e1c51b3c..445febec 100644 --- a/Src/JxrDecode/JxrDecode.cpp +++ b/Src/JxrDecode/JxrDecode.cpp @@ -124,10 +124,15 @@ void JxrDecode::Decode( unique_ptr upStream(pStream, [](WMPStream* p)->void {p->Close(&p); }); - PKImageDecode* pDecoder; + PKImageDecode* pDecoder = nullptr; err = PKCodecFactory_CreateDecoderFromStream(pStream, &pDecoder); if (Failed(err)) { + if (pDecoder != nullptr) + { + pDecoder->Release(&pDecoder); + } + ThrowJxrlibError("'PKCodecFactory_CreateDecoderFromStream' failed", err); } From db7b38c97ce027f77e07fb1170988e353df132ea Mon Sep 17 00:00:00 2001 From: ptahmose Date: Wed, 27 Sep 2023 00:35:40 +0200 Subject: [PATCH 96/98] fix memory leak (reported by valgrind) in case of decoder-object construction failing --- Src/JxrDecode/JxrDecode.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Src/JxrDecode/JxrDecode.cpp b/Src/JxrDecode/JxrDecode.cpp index 445febec..b1b9b04f 100644 --- a/Src/JxrDecode/JxrDecode.cpp +++ b/Src/JxrDecode/JxrDecode.cpp @@ -115,10 +115,12 @@ void JxrDecode::Decode( throw invalid_argument("get_destination_func"); } - WMPStream* pStream; + WMPStream* pStream = nullptr; ERR err = CreateWS_Memory(&pStream, const_cast(ptrData), size); if (Failed(err)) { + // note: the call "CreateWS_Memory" cannot fail (or the only way it can fail is that the memory allocation fails), + // so we do not have to release/free the stream object here. ThrowJxrlibError("'CreateWS_Memory' failed", err); } @@ -128,6 +130,8 @@ void JxrDecode::Decode( err = PKCodecFactory_CreateDecoderFromStream(pStream, &pDecoder); if (Failed(err)) { + // unfortunately, "PKCodecFactory_CreateDecoderFromStream" may fail leaving us with a partially constructed + // decoder object, so we need to release/free the decoder object here. if (pDecoder != nullptr) { pDecoder->Release(&pDecoder); @@ -136,6 +140,7 @@ void JxrDecode::Decode( ThrowJxrlibError("'PKCodecFactory_CreateDecoderFromStream' failed", err); } + // construct a smart pointer which will destroy the decoder object when it goes out of scope std::unique_ptr upDecoder(pDecoder, [](PKImageDecode* p)->void {p->Release(&p); }); U32 frame_count; From 0e8aae9ee9cf4339e446d79c861e928641323c25 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Wed, 27 Sep 2023 23:56:53 +0200 Subject: [PATCH 97/98] cosmetic --- Src/JxrDecode/JxrDecode.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Src/JxrDecode/JxrDecode.cpp b/Src/JxrDecode/JxrDecode.cpp index b1b9b04f..bf831323 100644 --- a/Src/JxrDecode/JxrDecode.cpp +++ b/Src/JxrDecode/JxrDecode.cpp @@ -145,7 +145,11 @@ void JxrDecode::Decode( U32 frame_count; err = upDecoder->GetFrameCount(upDecoder.get(), &frame_count); - if (Failed(err)) { ThrowJxrlibError("'decoder::GetFrameCount' failed", err); } + if (Failed(err)) + { + ThrowJxrlibError("'decoder::GetFrameCount' failed", err); + } + if (frame_count != 1) { ostringstream string_stream; @@ -162,7 +166,10 @@ void JxrDecode::Decode( PKPixelFormatGUID pixel_format_of_decoder; upDecoder->GetPixelFormat(upDecoder.get(), &pixel_format_of_decoder); - if (Failed(err)) { ThrowJxrlibError("'decoder::GetPixelFormat' failed", err); } + if (Failed(err)) + { + ThrowJxrlibError("'decoder::GetPixelFormat' failed", err); + } const auto jxrpixel_format = JxrPixelFormatGuidToEnum(pixel_format_of_decoder); if (jxrpixel_format == JxrDecode::PixelFormat::kInvalid) From 75d6792389d196c6e31cb8573ff0e012abebfdb4 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Thu, 28 Sep 2023 00:08:53 +0200 Subject: [PATCH 98/98] test --- .mega-linter.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.mega-linter.yml b/.mega-linter.yml index d5a68f58..e837e2b4 100644 --- a/.mega-linter.yml +++ b/.mega-linter.yml @@ -10,6 +10,8 @@ DISABLE: - SPELL # Comment to enable checks of spelling mistakes DISABLE_ERRORS_LINTERS: - MARKDOWN_MARKDOWN_LINK_CHECK # Make non-blocking due to network timeouts etc. +DISABLE_LINTERS: + - REPOSITORY_TRIVY # this linter seems currently broken, so we disable it here for now C_CPPLINT_ARGUMENTS: --verbose=2 CPP_CPPLINT_ARGUMENTS: --verbose=2 SHOW_ELAPSED_TIME: true