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 #if 0 Call(PKCodecFactory_CreateCodec(pIID, (void **) ppDecoder)); #else // We know we are creating a decoder here Call(PKImageDecode_Create_WMP(ppDecoder)); #endif pDecoder = *ppDecoder; // attach stream to decoder Call(pDecoder->Initialize(pDecoder, pStream)); pDecoder->fStreamOwner = !0; Cleanup: return err; }
static FIBITMAP * DLL_CALLCONV Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) { PKImageDecode *pDecoder = NULL; // decoder interface ERR error_code = 0; // error code as returned by the interface PKPixelFormatGUID guid_format; // loaded pixel format (== input file pixel format if no conversion needed) FREE_IMAGE_TYPE image_type = FIT_UNKNOWN; // input image type unsigned bpp = 0; // input image bit depth FIBITMAP *dib = NULL; // get the I/O stream wrapper WMPStream *pDecodeStream = (WMPStream*)data; if(!handle || !pDecodeStream) { return NULL; } BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS; try { int width, height; // image dimensions (in pixels) // create a JXR decoder interface and initialize function pointers with *_WMP functions error_code = PKImageDecode_Create_WMP(&pDecoder); JXR_CHECK(error_code); // attach the stream to the decoder ... // ... then read the image container and the metadata error_code = pDecoder->Initialize(pDecoder, pDecodeStream); JXR_CHECK(error_code); // set decoder parameters SetDecoderParameters(pDecoder, flags); // get dst image format specifications unsigned red_mask = 0, green_mask = 0, blue_mask = 0; error_code = GetInputPixelFormat(pDecoder, &guid_format, &image_type, &bpp, &red_mask, &green_mask, &blue_mask); JXR_CHECK(error_code); // get image dimensions pDecoder->GetSize(pDecoder, &width, &height); // allocate dst image { dib = FreeImage_AllocateHeaderT(header_only, image_type, width, height, bpp, red_mask, green_mask, blue_mask); if(!dib) { throw FI_MSG_ERROR_DIB_MEMORY; } if(FreeImage_GetBPP(dib) == 1) { // BD_1 - build a FIC_MINISBLACK palette RGBQUAD *pal = FreeImage_GetPalette(dib); pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 0; pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 255; } } // get image resolution { float resX, resY; // image resolution (in dots per inch) // convert from English units, i.e. dots per inch to universal units, i.e. dots per meter pDecoder->GetResolution(pDecoder, &resX, &resY); FreeImage_SetDotsPerMeterX(dib, (unsigned)(resX / 0.0254F + 0.5F)); FreeImage_SetDotsPerMeterY(dib, (unsigned)(resY / 0.0254F + 0.5F)); } // get metadata & ICC profile error_code = ReadMetadata(pDecoder, dib); JXR_CHECK(error_code); if(header_only) { // header only mode ... // free the decoder pDecoder->Release(&pDecoder); assert(pDecoder == NULL); return dib; } // copy pixels into the dib, perform pixel conversion if needed error_code = CopyPixels(pDecoder, guid_format, dib, width, height); JXR_CHECK(error_code); // free the decoder pDecoder->Release(&pDecoder); assert(pDecoder == NULL); return dib; } catch (const char *message) { // unload the dib FreeImage_Unload(dib); // free the decoder pDecoder->Release(&pDecoder); if(NULL != message) { FreeImage_OutputMessageProc(s_format_id, message); } } return NULL; }