//*@@@+++@@@@****************************************************************** // // 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 //================================================================ const PKIID IID_PKImageScanEncode = 1; const PKIID IID_PKImageFrameEncode = 2; const PKIID IID_PKImageUnsupported = 100; const PKIID IID_PKImageWmpEncode = 101; const PKIID IID_PKImageWmpDecode = 201; //================================================================ // Misc supporting functions //================================================================ ERR PKAlloc(void** ppv, size_t cb) { *ppv = calloc(1, cb); return *ppv ? WMP_errSuccess : WMP_errOutOfMemory; } ERR PKFree(void** ppv) { if (ppv) { free(*ppv); *ppv = NULL; } return WMP_errSuccess; } ERR PKAllocAligned(void** ppv, size_t cb, size_t iAlign) { U8 *pOrigPtr; U8 *pReturnedPtr; size_t iAlignmentCorrection; const size_t c_cbBlockSize = cb + sizeof(void*) + iAlign - 1; *ppv = NULL; pOrigPtr = calloc(1, c_cbBlockSize); if (NULL == pOrigPtr) return WMP_errOutOfMemory; iAlignmentCorrection = iAlign - ((size_t)pOrigPtr % iAlign); if (iAlignmentCorrection < sizeof(void*)) // Alignment correction won't leave us enough space to store pOrigPtr - advance to next block iAlignmentCorrection += iAlign; assert(iAlignmentCorrection >= sizeof(void*)); // Alignment correction must have space for pOrigPtr assert(iAlignmentCorrection + cb <= c_cbBlockSize); // Don't exceed right edge of memory block pReturnedPtr = pOrigPtr + iAlignmentCorrection; *(void**)(pReturnedPtr - sizeof(void*)) = pOrigPtr; assert(0 == ((size_t)pReturnedPtr % iAlign)); // Are we in fact aligned? *ppv = pReturnedPtr; return WMP_errSuccess; } ERR PKFreeAligned(void** ppv) { if (ppv && *ppv) { U8 **ppOrigPtr = (U8**)((U8*)(*ppv) - sizeof(void*)); assert(*ppOrigPtr <= (U8*)ppOrigPtr); // Something's wrong if pOrigPtr points forward free(*ppOrigPtr); *ppv = NULL; } return WMP_errSuccess; } int PKStrnicmp(const char* s1, const char* s2, size_t c) { for(; tolower(*s1) == tolower(*s2) && *s1 && *s2 && c; ++s1, ++s2, --c); return c ? *s1 - *s2 : 0; } static const PKPixelInfo pixelInfo[] = { {&GUID_PKPixelFormatDontCare, 1, Y_ONLY, BD_8, 8, PK_pixfmtNul, 0, 0, 0, 0}, // Gray //{&GUID_PKPixelFormat2bppGray, 1, Y_ONLY, BD_8, 2, PK_pixfmtNul}, //{&GUID_PKPixelFormat4bppGray, 1, Y_ONLY, BD_8, 4, PK_pixfmtNul}, {&GUID_PKPixelFormatBlackWhite, 1, Y_ONLY, BD_1, 1, PK_pixfmtNul, 1, 1, 1, 1},//BlackIsZero is default for GUID_PKPixelFormatBlackWhite {&GUID_PKPixelFormatBlackWhite, 1, Y_ONLY, BD_1, 1, PK_pixfmtNul, 0, 1, 1, 1},//WhiteIsZero {&GUID_PKPixelFormat8bppGray, 1, Y_ONLY, BD_8, 8, PK_pixfmtNul, 1, 1, 8, 1}, {&GUID_PKPixelFormat16bppGray, 1, Y_ONLY, BD_16, 16, PK_pixfmtNul, 1, 1, 16, 1}, {&GUID_PKPixelFormat16bppGrayFixedPoint, 1, Y_ONLY, BD_16S, 16, PK_pixfmtNul, 1, 1, 16, 2}, {&GUID_PKPixelFormat16bppGrayHalf, 1, Y_ONLY, BD_16F, 16, PK_pixfmtNul, 1, 1, 16, 3}, //{&GUID_PKPixelFormat32bppGray, 1, Y_ONLY, BD_32, 32, PK_pixfmtNul, 1, 1, 32, 1}, {&GUID_PKPixelFormat32bppGrayFixedPoint, 1, Y_ONLY, BD_32S, 32, PK_pixfmtNul, 1, 1, 32, 2}, {&GUID_PKPixelFormat32bppGrayFloat, 1, Y_ONLY, BD_32F, 32, PK_pixfmtNul, 1, 1, 32, 3}, // RGB {&GUID_PKPixelFormat24bppRGB, 3, CF_RGB, BD_8, 24, PK_pixfmtNul, 2, 3, 8, 1}, {&GUID_PKPixelFormat24bppBGR, 3, CF_RGB, BD_8, 24, PK_pixfmtBGR, 2, 3, 8, 1}, {&GUID_PKPixelFormat32bppRGB, 3, CF_RGB, BD_8, 32, PK_pixfmtNul, 2, 3, 8, 1}, {&GUID_PKPixelFormat32bppBGR, 3, CF_RGB, BD_8, 32, PK_pixfmtBGR, 2, 3, 8, 1}, {&GUID_PKPixelFormat48bppRGB, 3, CF_RGB, BD_16, 48, PK_pixfmtNul, 2, 3, 16, 1}, {&GUID_PKPixelFormat48bppRGBFixedPoint, 3, CF_RGB, BD_16S, 48, PK_pixfmtNul, 2, 3, 16, 2}, {&GUID_PKPixelFormat48bppRGBHalf, 3, CF_RGB, BD_16F, 48, PK_pixfmtNul, 2, 3, 16, 3}, {&GUID_PKPixelFormat64bppRGBFixedPoint, 3, CF_RGB, BD_16S, 64, PK_pixfmtNul, 2, 3, 16, 2}, {&GUID_PKPixelFormat64bppRGBHalf, 3, CF_RGB, BD_16F, 64, PK_pixfmtNul, 2, 3, 16, 3}, //{&GUID_PKPixelFormat96bppRGB, 3, CF_RGB, BD_32, 96, PK_pixfmtNul, 2, 3, 32, 1}, {&GUID_PKPixelFormat96bppRGBFixedPoint, 3, CF_RGB, BD_32S, 96, PK_pixfmtNul, 2, 3, 32, 2}, {&GUID_PKPixelFormat96bppRGBFloat, 3, CF_RGB, BD_32F, 96, PK_pixfmtNul, 2, 3, 32, 3}, {&GUID_PKPixelFormat128bppRGBFixedPoint, 3, CF_RGB, BD_32S, 128, PK_pixfmtNul, 2, 3, 32, 2}, {&GUID_PKPixelFormat128bppRGBFloat, 3, CF_RGB, BD_32F, 128, PK_pixfmtNul, 2, 3, 32, 3}, // RGBA {&GUID_PKPixelFormat32bppBGRA, 4, CF_RGB, BD_8, 32, PK_pixfmtHasAlpha | PK_pixfmtBGR, 2, 4, 8, 1}, {&GUID_PKPixelFormat32bppRGBA, 4, CF_RGB, BD_8, 32, PK_pixfmtHasAlpha, 2, 4, 8, 1}, {&GUID_PKPixelFormat64bppRGBA, 4, CF_RGB, BD_16, 64, PK_pixfmtHasAlpha, 2, 4, 16, 1}, {&GUID_PKPixelFormat64bppRGBAFixedPoint, 4, CF_RGB, BD_16S, 64, PK_pixfmtHasAlpha, 2, 4, 16, 2}, {&GUID_PKPixelFormat64bppRGBAHalf, 4, CF_RGB, BD_16F, 64, PK_pixfmtHasAlpha, 2, 4, 16, 3}, //{&GUID_PKPixelFormat128bppRGBA, 4, CF_RGB, BD_32, 128, PK_pixfmtHasAlpha, 2, 4, 32, 1}, {&GUID_PKPixelFormat128bppRGBAFixedPoint, 4, CF_RGB, BD_32S, 128, PK_pixfmtHasAlpha, 2, 4, 32, 2}, {&GUID_PKPixelFormat128bppRGBAFloat, 4, CF_RGB, BD_32F, 128, PK_pixfmtHasAlpha, 2, 4, 32, 3}, // PRGBA {&GUID_PKPixelFormat32bppPBGRA, 4, CF_RGB, BD_8, 32, PK_pixfmtHasAlpha | PK_pixfmtPreMul | PK_pixfmtBGR, 2, 4, 8, 1}, {&GUID_PKPixelFormat32bppPRGBA, 4, CF_RGB, BD_8, 32, PK_pixfmtHasAlpha | PK_pixfmtPreMul, 2, 4, 8, 1}, {&GUID_PKPixelFormat64bppPRGBA, 4, CF_RGB, BD_16, 64, PK_pixfmtHasAlpha | PK_pixfmtPreMul, 2, 4, 16, 1}, //{&GUID_PKPixelFormat64bppPRGBAFixedPoint, 4, CF_RGB, BD_16S, 64, PK_pixfmtHasAlpha, 2, 4, 16, 2}, //{&GUID_PKPixelFormat64bppPRGBAHalf, 4, CF_RGB, BD_16F, 64, PK_pixfmtHasAlpha, 2, 4, 16, 3}, //{&GUID_PKPixelFormat128bppPRGBAFixedPoint, 4, CF_RGB, BD_32S, 128, PK_pixfmtHasAlpha, 2, 4, 32, 2}, {&GUID_PKPixelFormat128bppPRGBAFloat, 4, CF_RGB, BD_32F, 128, PK_pixfmtHasAlpha | PK_pixfmtPreMul, 2, 4, 32, 3}, // Packed formats {&GUID_PKPixelFormat16bppRGB555, 3, CF_RGB, BD_5, 16, PK_pixfmtNul, 2, 3, 5, 1}, {&GUID_PKPixelFormat16bppRGB565, 3, CF_RGB, BD_565, 16, PK_pixfmtNul, 2, 3, 6, 1}, {&GUID_PKPixelFormat32bppRGB101010, 3, CF_RGB, BD_10, 32, PK_pixfmtNul, 2, 3, 10, 1}, // CMYK {&GUID_PKPixelFormat32bppCMYK, 4, CMYK, BD_8, 32, PK_pixfmtNul, 5, 4, 8, 1}, {&GUID_PKPixelFormat40bppCMYKAlpha, 5, CMYK, BD_8, 40, PK_pixfmtHasAlpha, 5, 5, 8, 1}, {&GUID_PKPixelFormat64bppCMYK, 4, CMYK, BD_16, 64, PK_pixfmtNul, 5, 4, 16, 1}, {&GUID_PKPixelFormat80bppCMYKAlpha, 5, CMYK, BD_16, 80, PK_pixfmtHasAlpha, 5, 5, 16, 1}, // N_CHANNEL {&GUID_PKPixelFormat24bpp3Channels, 3, NCOMPONENT, BD_8, 24, PK_pixfmtNul, PK_PI_NCH, 3, 8, 1},//the N channel TIF by PS has PhotometricInterpretation of PK_PI_RGB {&GUID_PKPixelFormat32bpp4Channels, 4, NCOMPONENT, BD_8, 32, PK_pixfmtNul, PK_PI_NCH, 4, 8, 1}, {&GUID_PKPixelFormat40bpp5Channels, 5, NCOMPONENT, BD_8, 40, PK_pixfmtNul, PK_PI_NCH, 5, 8, 1}, {&GUID_PKPixelFormat48bpp6Channels, 6, NCOMPONENT, BD_8, 48, PK_pixfmtNul, PK_PI_NCH, 6, 8, 1}, {&GUID_PKPixelFormat56bpp7Channels, 7, NCOMPONENT, BD_8, 56, PK_pixfmtNul, PK_PI_NCH, 7, 8, 1}, {&GUID_PKPixelFormat64bpp8Channels, 8, NCOMPONENT, BD_8, 64, PK_pixfmtNul, PK_PI_NCH, 8, 8, 1}, {&GUID_PKPixelFormat32bpp3ChannelsAlpha, 4, NCOMPONENT, BD_8, 32, PK_pixfmtHasAlpha, PK_PI_NCH, 4, 8, 1}, {&GUID_PKPixelFormat40bpp4ChannelsAlpha, 5, NCOMPONENT, BD_8, 40, PK_pixfmtHasAlpha, PK_PI_NCH, 5, 8, 1}, {&GUID_PKPixelFormat48bpp5ChannelsAlpha, 6, NCOMPONENT, BD_8, 48, PK_pixfmtHasAlpha, PK_PI_NCH, 6, 8, 1}, {&GUID_PKPixelFormat56bpp6ChannelsAlpha, 7, NCOMPONENT, BD_8, 56, PK_pixfmtHasAlpha, PK_PI_NCH, 7, 8, 1}, {&GUID_PKPixelFormat64bpp7ChannelsAlpha, 8, NCOMPONENT, BD_8, 64, PK_pixfmtHasAlpha, PK_PI_NCH, 8, 8, 1}, {&GUID_PKPixelFormat72bpp8ChannelsAlpha, 9, NCOMPONENT, BD_8, 72, PK_pixfmtHasAlpha, PK_PI_NCH, 9, 8, 1}, {&GUID_PKPixelFormat48bpp3Channels, 3, NCOMPONENT, BD_16, 48, PK_pixfmtNul, PK_PI_NCH, 3, 16, 1}, {&GUID_PKPixelFormat64bpp4Channels, 4, NCOMPONENT, BD_16, 64, PK_pixfmtNul, PK_PI_NCH, 4, 16, 1}, {&GUID_PKPixelFormat80bpp5Channels, 5, NCOMPONENT, BD_16, 80, PK_pixfmtNul, PK_PI_NCH, 5, 16, 1}, {&GUID_PKPixelFormat96bpp6Channels, 6, NCOMPONENT, BD_16, 96, PK_pixfmtNul, PK_PI_NCH, 6, 16, 1}, {&GUID_PKPixelFormat112bpp7Channels, 7, NCOMPONENT, BD_16, 112, PK_pixfmtNul, PK_PI_NCH, 7, 16, 1}, {&GUID_PKPixelFormat128bpp8Channels, 8, NCOMPONENT, BD_16, 128, PK_pixfmtNul, PK_PI_NCH, 8, 16, 1}, {&GUID_PKPixelFormat64bpp3ChannelsAlpha, 4, NCOMPONENT, BD_16, 64, PK_pixfmtHasAlpha, PK_PI_NCH, 4, 16, 1}, {&GUID_PKPixelFormat80bpp4ChannelsAlpha, 5, NCOMPONENT, BD_16, 80, PK_pixfmtHasAlpha, PK_PI_NCH, 5, 16, 1}, {&GUID_PKPixelFormat96bpp5ChannelsAlpha, 6, NCOMPONENT, BD_16, 96, PK_pixfmtHasAlpha, PK_PI_NCH, 6, 16, 1}, {&GUID_PKPixelFormat112bpp6ChannelsAlpha, 7, NCOMPONENT, BD_16, 112, PK_pixfmtHasAlpha, PK_PI_NCH, 7, 16, 1}, {&GUID_PKPixelFormat128bpp7ChannelsAlpha, 8, NCOMPONENT, BD_16, 128, PK_pixfmtHasAlpha, PK_PI_NCH, 8, 16, 1}, {&GUID_PKPixelFormat144bpp8ChannelsAlpha, 9, NCOMPONENT, BD_16, 144, PK_pixfmtHasAlpha, PK_PI_NCH, 9, 16, 1}, //RGBE {&GUID_PKPixelFormat32bppRGBE, 4, CF_RGBE, BD_8, 32, PK_pixfmtNul, PK_PI_RGBE, 4, 8, 1}, //YUV {&GUID_PKPixelFormat12bppYUV420, 3, YUV_420, BD_8, 48, PK_pixfmtNul}, {&GUID_PKPixelFormat16bppYUV422, 3, YUV_422, BD_8, 32, PK_pixfmtNul}, {&GUID_PKPixelFormat24bppYUV444, 3, YUV_444, BD_8, 24, PK_pixfmtNul}, }; //---------------------------------------------------------------- //ERR GetPixelInfo(PKPixelFormatGUID enPixelFormat, const PKPixelInfo** ppPI) ERR PixelFormatLookup(PKPixelInfo* pPI, U8 uLookupType) { ERR err = WMP_errSuccess; size_t i; for (i = 0; i < sizeof2(pixelInfo); ++i) { if (LOOKUP_FORWARD == uLookupType) { if (IsEqualGUID(pPI->pGUIDPixFmt, pixelInfo[i].pGUIDPixFmt)) { *pPI = pixelInfo[i]; goto Cleanup; } } else if (LOOKUP_BACKWARD_TIF == uLookupType) { if (pPI->uSamplePerPixel == pixelInfo[i].uSamplePerPixel && pPI->uBitsPerSample == pixelInfo[i].uBitsPerSample && pPI->uSampleFormat == pixelInfo[i].uSampleFormat && pPI->uInterpretation == pixelInfo[i].uInterpretation) { // match alpha & premult if ((pPI->grBit & (PK_pixfmtHasAlpha | PK_pixfmtPreMul)) == (pixelInfo[i].grBit & (PK_pixfmtHasAlpha | PK_pixfmtPreMul))) { *pPI = pixelInfo[i]; goto Cleanup; } } } } Call(WMP_errUnsupportedFormat); Cleanup: return err; } const PKPixelFormatGUID* GetPixelFormatFromHash(const U8 uPFHash) { int i; for (i = 0; i < sizeof2(pixelInfo); i++) { if (pixelInfo[i].pGUIDPixFmt->Data4[7] == uPFHash) return pixelInfo[i].pGUIDPixFmt; } // If we reached this point, we did not find anything which matched the hash return NULL; } //---------------------------------------------------------------- typedef struct tagPKIIDInfo { const char* szExt; const PKIID* pIIDEnc; const PKIID* pIIDDec; } PKIIDInfo; static ERR GetIIDInfo(const char* szExt, const PKIIDInfo** ppInfo) { ERR err = WMP_errSuccess; static PKIIDInfo iidInfo[] = { {".jxr", &IID_PKImageWmpEncode, &IID_PKImageWmpDecode}, {".wdp", &IID_PKImageUnsupported, &IID_PKImageWmpDecode}, {".hdp", &IID_PKImageUnsupported, &IID_PKImageWmpDecode}, }; size_t i = 0; *ppInfo = NULL; for (i = 0; i < sizeof2(iidInfo); ++i) { if (0 == PKStrnicmp(szExt, iidInfo[i].szExt, strlen(iidInfo[i].szExt))) { *ppInfo = &iidInfo[i]; goto Cleanup; } } Call(WMP_errUnsupportedFormat); Cleanup: return err; } ERR GetImageEncodeIID(const char* szExt, const PKIID** ppIID) { ERR err = WMP_errSuccess; const PKIIDInfo* pInfo = NULL; Call(GetIIDInfo(szExt, &pInfo)); *ppIID = pInfo->pIIDEnc; Cleanup: return err; } ERR GetImageDecodeIID(const char* szExt, const PKIID** ppIID) { ERR err = WMP_errSuccess; const PKIIDInfo* pInfo = NULL; Call(GetIIDInfo(szExt, &pInfo)); *ppIID = pInfo->pIIDDec; Cleanup: return err; } //================================================================ // PKFactory //================================================================ ERR PKCreateFactory_CreateStream(PKStream** ppStream) { ERR err = WMP_errSuccess; Call(PKAlloc((void **) ppStream, sizeof(**ppStream))); Cleanup: return err; } ERR PKCreateFactory_Release(PKFactory** ppFactory) { ERR err = WMP_errSuccess; Call(PKFree((void **) ppFactory)); Cleanup: return err; } //---------------------------------------------------------------- ERR PKCreateFactory(PKFactory** ppFactory, U32 uVersion) { ERR err = WMP_errSuccess; PKFactory* pFactory = NULL; UNREFERENCED_PARAMETER( uVersion ); Call(PKAlloc((void **) ppFactory, sizeof(**ppFactory))); pFactory = *ppFactory; pFactory->CreateStream = PKCreateFactory_CreateStream; pFactory->CreateStreamFromFilename = CreateWS_File; pFactory->CreateStreamFromMemory = CreateWS_Memory; pFactory->Release = PKCreateFactory_Release; Cleanup: return err; } //================================================================ // PKCodecFactory //================================================================ ERR PKCodecFactory_CreateCodec(const PKIID* iid, void** ppv) { ERR err = WMP_errSuccess; if (IID_PKImageWmpEncode == *iid) { Call(PKImageEncode_Create_WMP((PKImageEncode**)ppv)); } else if (IID_PKImageWmpDecode == *iid) { Call(PKImageDecode_Create_WMP((PKImageDecode**)ppv)); } else { Call(WMP_errUnsupportedFormat); } Cleanup: return err; } ERR PKCodecFactory_CreateDecoderFromFile(const char* szFilename, PKImageDecode** ppDecoder) { ERR err = WMP_errSuccess; char *pExt = NULL; const PKIID* pIID = NULL; struct WMPStream* pStream = NULL; PKImageDecode* pDecoder = NULL; // get file extension pExt = strrchr(szFilename, '.'); FailIf(NULL == pExt, WMP_errUnsupportedFormat); // get decode PKIID Call(GetImageDecodeIID(pExt, &pIID)); // create stream Call(CreateWS_File(&pStream, szFilename, "rb")); // Create decoder Call(PKCodecFactory_CreateCodec(pIID, (void **) ppDecoder)); pDecoder = *ppDecoder; // attach stream to decoder Call(pDecoder->Initialize(pDecoder, pStream)); pDecoder->fStreamOwner = !0; Cleanup: return err; } ERR PKCodecFactory_CreateFormatConverter(PKFormatConverter** ppFConverter) { ERR err = WMP_errSuccess; PKFormatConverter* pFC = NULL; Call(PKAlloc((void **) ppFConverter, sizeof(**ppFConverter))); pFC = *ppFConverter; pFC->Initialize = PKFormatConverter_Initialize; pFC->InitializeConvert = PKFormatConverter_InitializeConvert; pFC->GetPixelFormat = PKFormatConverter_GetPixelFormat; pFC->GetSourcePixelFormat = PKFormatConverter_GetSourcePixelFormat; pFC->GetSize = PKFormatConverter_GetSize; pFC->GetResolution = PKFormatConverter_GetResolution; pFC->Copy = PKFormatConverter_Copy; pFC->Convert = PKFormatConverter_Convert; pFC->Release = PKFormatConverter_Release; Cleanup: return err; } ERR PKCreateCodecFactory_Release(PKCodecFactory** ppCFactory) { ERR err = WMP_errSuccess; Call(PKFree((void **) ppCFactory)); Cleanup: return err; } ERR PKCreateCodecFactory(PKCodecFactory** ppCFactory, U32 uVersion) { ERR err = WMP_errSuccess; PKCodecFactory* pCFactory = NULL; UNREFERENCED_PARAMETER( uVersion ); Call(PKAlloc((void **) ppCFactory, sizeof(**ppCFactory))); pCFactory = *ppCFactory; pCFactory->CreateCodec = PKCodecFactory_CreateCodec; pCFactory->CreateDecoderFromFile = PKCodecFactory_CreateDecoderFromFile; pCFactory->CreateFormatConverter = PKCodecFactory_CreateFormatConverter; pCFactory->Release = PKCreateCodecFactory_Release; Cleanup: return err; } //================================================================ // PKImageEncode //================================================================ ERR PKImageEncode_Initialize( PKImageEncode* pIE, struct WMPStream* pStream, void* pvParam, size_t cbParam) { ERR err = WMP_errSuccess; UNREFERENCED_PARAMETER( pIE ); UNREFERENCED_PARAMETER( pvParam ); UNREFERENCED_PARAMETER( cbParam ); pIE->pStream = pStream; pIE->guidPixFormat = GUID_PKPixelFormatDontCare; pIE->fResX = 96; pIE->fResY = 96; pIE->cFrame = 1; Call(pIE->pStream->GetPos(pIE->pStream, &pIE->offStart)); Cleanup: return err; } ERR PKImageEncode_Terminate( PKImageEncode* pIE) { UNREFERENCED_PARAMETER( pIE ); return WMP_errSuccess; } ERR PKImageEncode_SetPixelFormat( PKImageEncode* pIE, PKPixelFormatGUID enPixelFormat) { pIE->guidPixFormat = enPixelFormat; return WMP_errSuccess; } ERR PKImageEncode_SetSize( PKImageEncode* pIE, I32 iWidth, I32 iHeight) { ERR err = WMP_errSuccess; pIE->uWidth = (U32)iWidth; pIE->uHeight = (U32)iHeight; return err; } ERR PKImageEncode_SetResolution( PKImageEncode* pIE, Float fResX, Float fResY) { pIE->fResX = fResX; pIE->fResY = fResY; return WMP_errSuccess; } ERR PKImageEncode_SetColorContext(PKImageEncode *pIE, const U8 *pbColorContext, U32 cbColorContext) { UNREFERENCED_PARAMETER( pIE ); UNREFERENCED_PARAMETER( pbColorContext ); UNREFERENCED_PARAMETER( cbColorContext ); return WMP_errNotYetImplemented; } ERR PKImageEncode_SetDescriptiveMetadata(PKImageEncode *pIE, const DESCRIPTIVEMETADATA *pDescMetadata) { UNREFERENCED_PARAMETER( pIE ); UNREFERENCED_PARAMETER( pDescMetadata ); return WMP_errNotYetImplemented; } ERR PKImageEncode_WritePixels( PKImageEncode* pIE, U32 cLine, U8* pbPixels, U32 cbStride) { UNREFERENCED_PARAMETER( pIE ); UNREFERENCED_PARAMETER( cLine ); UNREFERENCED_PARAMETER( pbPixels ); UNREFERENCED_PARAMETER( cbStride ); return WMP_errAbstractMethod; } ERR PKImageEncode_WriteSource( PKImageEncode* pIE, PKFormatConverter* pFC, PKRect* pRect) { ERR err = WMP_errSuccess; PKPixelFormatGUID enPFFrom = GUID_PKPixelFormatDontCare; PKPixelFormatGUID enPFTo = GUID_PKPixelFormatDontCare; PKPixelInfo pPIFrom; PKPixelInfo pPITo; U32 cbStrideTo = 0; U32 cbStrideFrom = 0; U32 cbStride = 0; U8* pb = NULL; // CWMTranscodingParam* pParam = NULL; // get pixel format Call(pFC->GetSourcePixelFormat(pFC, &enPFFrom)); Call(pFC->GetPixelFormat(pFC, &enPFTo)); FailIf(!IsEqualGUID(&pIE->guidPixFormat, &enPFTo), WMP_errUnsupportedFormat); // calc common stride // Call(GetPixelInfo(enPFFrom, &pPIFrom)); pPIFrom.pGUIDPixFmt = &enPFFrom; PixelFormatLookup(&pPIFrom, LOOKUP_FORWARD); // Call(GetPixelInfo(enPFTo, &pPITo)); pPITo.pGUIDPixFmt = &enPFTo; PixelFormatLookup(&pPITo, LOOKUP_FORWARD); // cbStrideFrom = (pPIFrom->cbPixel * pRect->Width + pPIFrom->cbPixelDenom - 1) / pPIFrom->cbPixelDenom; cbStrideFrom = (BD_1 == pPIFrom.bdBitDepth ? ((pPIFrom.cbitUnit * pRect->Width + 7) >> 3) : (((pPIFrom.cbitUnit + 7) >> 3) * pRect->Width)); if (&GUID_PKPixelFormat12bppYUV420 == pPIFrom.pGUIDPixFmt || &GUID_PKPixelFormat16bppYUV422 == pPIFrom.pGUIDPixFmt) cbStrideFrom >>= 1; // cbStrideTo = (pPITo->cbPixel * pIE->uWidth + pPITo->cbPixelDenom - 1) / pPITo->cbPixelDenom; cbStrideTo = (BD_1 == pPITo.bdBitDepth ? ((pPITo.cbitUnit * pIE->uWidth + 7) >> 3) : (((pPITo.cbitUnit + 7) >> 3) * pIE->uWidth)); if (&GUID_PKPixelFormat12bppYUV420 == pPITo.pGUIDPixFmt || &GUID_PKPixelFormat16bppYUV422 == pPITo.pGUIDPixFmt) cbStrideTo >>= 1; cbStride = max(cbStrideFrom, cbStrideTo); // actual dec/enc with local buffer Call(PKAllocAligned((void **) &pb, cbStride * pRect->Height, 128)); Call(pFC->Copy(pFC, pRect, pb, cbStride)); Call(pIE->WritePixels(pIE, pRect->Height, pb, cbStride)); Cleanup: PKFreeAligned((void **) &pb); return err; } ERR PKImageEncode_WritePixelsBandedBegin(PKImageEncode* pEncoder, struct WMPStream *pPATempFile) { UNREFERENCED_PARAMETER( pEncoder ); UNREFERENCED_PARAMETER( pPATempFile ); return WMP_errAbstractMethod; } ERR PKImageEncode_WritePixelsBanded(PKImageEncode* pEncoder, U32 cLines, U8* pbPixels, U32 cbStride, Bool fLastCall) { UNREFERENCED_PARAMETER( pEncoder ); UNREFERENCED_PARAMETER( cLines ); UNREFERENCED_PARAMETER( pbPixels ); UNREFERENCED_PARAMETER( cbStride ); UNREFERENCED_PARAMETER( fLastCall ); return WMP_errAbstractMethod; } ERR PKImageEncode_WritePixelsBandedEnd(PKImageEncode* pEncoder) { UNREFERENCED_PARAMETER( pEncoder ); return WMP_errAbstractMethod; } ERR PKImageEncode_Transcode( PKImageEncode* pIE, PKFormatConverter* pFC, PKRect* pRect) { ERR err = WMP_errSuccess; PKPixelFormatGUID enPFFrom = GUID_PKPixelFormatDontCare; PKPixelFormatGUID enPFTo = GUID_PKPixelFormatDontCare; PKPixelInfo pPIFrom; PKPixelInfo pPITo; U32 cbStrideTo = 0; U32 cbStrideFrom = 0; U32 cbStride = 0; U8* pb = NULL; CWMTranscodingParam cParam = {0}; // get pixel format Call(pFC->GetSourcePixelFormat(pFC, &enPFFrom)); Call(pFC->GetPixelFormat(pFC, &enPFTo)); FailIf(!IsEqualGUID(&pIE->guidPixFormat, &enPFTo), WMP_errUnsupportedFormat); // calc common stride // Call(GetPixelInfo(enPFFrom, &pPIFrom)); pPIFrom.pGUIDPixFmt = &enPFFrom; PixelFormatLookup(&pPIFrom, LOOKUP_FORWARD); // Call(GetPixelInfo(enPFTo, &pPITo)); pPITo.pGUIDPixFmt = &enPFTo; PixelFormatLookup(&pPITo, LOOKUP_FORWARD); // cbStrideFrom = (pPIFrom->cbPixel * pRect->Width + pPIFrom->cbPixelDenom - 1) / pPIFrom->cbPixelDenom; cbStrideFrom = (BD_1 == pPIFrom.bdBitDepth ? ((pPIFrom.cbitUnit * pRect->Width + 7) >> 3) : (((pPIFrom.cbitUnit + 7) >> 3) * pRect->Width)); if (&GUID_PKPixelFormat12bppYUV420 == pPIFrom.pGUIDPixFmt || &GUID_PKPixelFormat16bppYUV422 == pPIFrom.pGUIDPixFmt) cbStrideFrom >>= 1; // cbStrideTo = (pPITo->cbPixel * pIE->uWidth + pPITo->cbPixelDenom - 1) / pPITo->cbPixelDenom; cbStrideTo = (BD_1 == pPITo.bdBitDepth ? ((pPITo.cbitUnit * pIE->uWidth + 7) >> 3) : (((pPITo.cbitUnit + 7) >> 3) * pIE->uWidth)); if (&GUID_PKPixelFormat12bppYUV420 == pPITo.pGUIDPixFmt || &GUID_PKPixelFormat16bppYUV422 == pPITo.pGUIDPixFmt) cbStrideTo >>= 1; cbStride = max(cbStrideFrom, cbStrideTo); if(pIE->bWMP){ cParam.cLeftX = pFC->pDecoder->WMP.wmiI.cROILeftX; cParam.cTopY = pFC->pDecoder->WMP.wmiI.cROITopY; cParam.cWidth = pFC->pDecoder->WMP.wmiI.cROIWidth; cParam.cHeight = pFC->pDecoder->WMP.wmiI.cROIHeight; cParam.oOrientation = pFC->pDecoder->WMP.wmiI.oOrientation; // cParam.cfColorFormat = pFC->pDecoder->WMP.wmiI.cfColorFormat; cParam.uAlphaMode = pFC->pDecoder->WMP.wmiSCP.uAlphaMode; cParam.bfBitstreamFormat = pFC->pDecoder->WMP.wmiSCP.bfBitstreamFormat; cParam.sbSubband = pFC->pDecoder->WMP.wmiSCP.sbSubband; cParam.bIgnoreOverlap = pFC->pDecoder->WMP.bIgnoreOverlap; Call(pIE->Transcode(pIE, pFC->pDecoder, &cParam)); } else { // actual dec/enc with local buffer Call(PKAllocAligned((void **) &pb, cbStride * pRect->Height, 128)); Call(pFC->Copy(pFC, pRect, pb, cbStride)); Call(pIE->WritePixels(pIE, pRect->Height, pb, cbStride)); } Cleanup: PKFreeAligned((void **) &pb); return err; } ERR PKImageEncode_CreateNewFrame( PKImageEncode* pIE, void* pvParam, size_t cbParam) { UNREFERENCED_PARAMETER( pIE ); UNREFERENCED_PARAMETER( pvParam ); UNREFERENCED_PARAMETER( cbParam ); // NYI return WMP_errSuccess; } ERR PKImageEncode_Release( PKImageEncode** ppIE) { PKImageEncode *pIE = *ppIE; pIE->pStream->Close(&pIE->pStream); return PKFree((void **) ppIE); } ERR PKImageEncode_Create(PKImageEncode** ppIE) { ERR err = WMP_errSuccess; PKImageEncode* pIE = NULL; Call(PKAlloc((void **) ppIE, sizeof(**ppIE))); pIE = *ppIE; pIE->Initialize = PKImageEncode_Initialize; pIE->Terminate = PKImageEncode_Terminate; pIE->SetPixelFormat = PKImageEncode_SetPixelFormat; pIE->SetSize = PKImageEncode_SetSize; pIE->SetResolution = PKImageEncode_SetResolution; pIE->SetColorContext = PKImageEncode_SetColorContext; pIE->SetDescriptiveMetadata = PKImageEncode_SetDescriptiveMetadata; pIE->WritePixels = PKImageEncode_WritePixels; // pIE->WriteSource = PKImageEncode_WriteSource; pIE->WritePixelsBandedBegin = PKImageEncode_WritePixelsBandedBegin; pIE->WritePixelsBanded = PKImageEncode_WritePixelsBanded; pIE->WritePixelsBandedEnd = PKImageEncode_WritePixelsBandedEnd; pIE->CreateNewFrame = PKImageEncode_CreateNewFrame; pIE->Release = PKImageEncode_Release; pIE->bWMP = FALSE; Cleanup: return err; } //================================================================ // PKImageDecode //================================================================ ERR PKImageDecode_Initialize( PKImageDecode* pID, struct WMPStream* pStream) { ERR err = WMP_errSuccess; pID->pStream = pStream; pID->guidPixFormat = GUID_PKPixelFormatDontCare; pID->fResX = 96; pID->fResY = 96; pID->cFrame = 1; Call(pID->pStream->GetPos(pID->pStream, &pID->offStart)); memset(&pID->WMP.wmiDEMisc, 0, sizeof(pID->WMP.wmiDEMisc)); Cleanup: return WMP_errSuccess; } ERR PKImageDecode_GetPixelFormat( PKImageDecode* pID, PKPixelFormatGUID* pPF) { *pPF = pID->guidPixFormat; return WMP_errSuccess; } ERR PKImageDecode_GetSize( PKImageDecode* pID, I32* piWidth, I32* piHeight) { *piWidth = (I32)pID->uWidth; *piHeight = (I32)pID->uHeight; return WMP_errSuccess; } ERR PKImageDecode_GetResolution( PKImageDecode* pID, Float* pfResX, Float* pfResY) { *pfResX = pID->fResX; *pfResY = pID->fResY; return WMP_errSuccess; } ERR PKImageDecode_GetColorContext(PKImageDecode *pID, U8 *pbColorContext, U32 *pcbColorContext) { UNREFERENCED_PARAMETER( pID ); UNREFERENCED_PARAMETER( pbColorContext ); UNREFERENCED_PARAMETER( pcbColorContext ); return WMP_errNotYetImplemented; } ERR PKImageDecode_GetDescriptiveMetadata(PKImageDecode *pIE, DESCRIPTIVEMETADATA *pDescMetadata) { UNREFERENCED_PARAMETER( pIE ); UNREFERENCED_PARAMETER( pDescMetadata ); return WMP_errNotYetImplemented; } ERR PKImageDecode_Copy( PKImageDecode* pID, const PKRect* pRect, U8* pb, U32 cbStride) { UNREFERENCED_PARAMETER( pID ); UNREFERENCED_PARAMETER( pRect ); UNREFERENCED_PARAMETER( pb ); UNREFERENCED_PARAMETER( cbStride ); return WMP_errAbstractMethod; } ERR PKImageDecode_GetFrameCount( PKImageDecode* pID, U32* puCount) { *puCount = pID->cFrame; return WMP_errSuccess; } ERR PKImageDecode_SelectFrame( PKImageDecode* pID, U32 uFrame) { UNREFERENCED_PARAMETER( pID ); UNREFERENCED_PARAMETER( uFrame ); // NYI return WMP_errSuccess; } ERR PKImageDecode_Release( PKImageDecode** ppID) { PKImageDecode* pID = *ppID; pID->fStreamOwner && pID->pStream->Close(&pID->pStream); return PKFree((void **) ppID); } ERR PKImageDecode_Create( PKImageDecode** ppID) { ERR err = WMP_errSuccess; PKImageDecode* pID = NULL; Call(PKAlloc((void **) ppID, sizeof(**ppID))); pID = *ppID; pID->Initialize = PKImageDecode_Initialize; pID->GetPixelFormat = PKImageDecode_GetPixelFormat; pID->GetSize = PKImageDecode_GetSize; pID->GetResolution = PKImageDecode_GetResolution; pID->GetColorContext = PKImageDecode_GetColorContext; pID->GetDescriptiveMetadata = PKImageDecode_GetDescriptiveMetadata; pID->Copy = PKImageDecode_Copy; pID->GetFrameCount = PKImageDecode_GetFrameCount; pID->SelectFrame = PKImageDecode_SelectFrame; pID->Release = PKImageDecode_Release; Cleanup: return err; }