github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/image/jxr/temp/load-jxr.c (about) 1 #include "mupdf/fitz.h" 2 3 /* SumatraPDF: support JPEG-XR images */ 4 5 #ifdef _WIN32 6 #define COBJMACROS 7 #include <wincodec.h> 8 #endif 9 10 static fz_pixmap * 11 fz_load_jxr_or_info(fz_context *ctx, unsigned char *data, int size, int *wp, int *hp, int *xresp, int *yresp, fz_colorspace **cspacep) 12 { 13 #ifdef _WIN32 14 int info_only = wp && hp && xresp && yresp && cspacep; 15 fz_pixmap *pix = NULL; 16 IStream *stream = NULL; 17 IWICImagingFactory *factory = NULL; 18 IWICBitmapDecoder *decoder = NULL; 19 IWICFormatConverter *converter = NULL; 20 IWICBitmapFrameDecode *src_frame = NULL; 21 IWICBitmapSource *src_bitmap = NULL; 22 int codec_available = 0; 23 LARGE_INTEGER zero = { 0 }; 24 UINT width, height; 25 double xres, yres; 26 ULONG written; 27 HRESULT hr; 28 29 hr = CoInitialize(NULL); 30 if (FAILED(hr)) 31 fz_throw(ctx, FZ_ERROR_GENERIC, "JPEG-XR codec is not available"); 32 #define Check(hr) if (FAILED(hr)) goto CleanUp 33 Check(CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_ALL, &IID_IWICImagingFactory, (void **)&factory)); 34 Check(CreateStreamOnHGlobal(NULL, TRUE, &stream)); 35 Check(IStream_Write(stream, data, (ULONG)size, &written)); 36 Check(IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL)); 37 Check(IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, WICDecodeMetadataCacheOnDemand, &decoder)); 38 Check(IWICImagingFactory_CreateFormatConverter(factory, &converter)); 39 Check(IWICBitmapDecoder_GetFrame(decoder, 0, &src_frame)); 40 Check(IUnknown_QueryInterface(src_frame, &IID_IWICBitmapSource, &src_bitmap)); 41 Check(IWICFormatConverter_Initialize(converter, src_bitmap, &GUID_WICPixelFormat32bppBGRA, WICBitmapDitherTypeNone, NULL, 0.f, WICBitmapPaletteTypeCustom)); 42 Check(IWICFormatConverter_GetSize(converter, &width, &height)); 43 Check(IWICFormatConverter_GetResolution(converter, &xres, &yres)); 44 #undef Check 45 codec_available = 1; 46 47 if (info_only) 48 { 49 *cspacep = fz_device_bgr(ctx); 50 *wp = width; 51 *hp = height; 52 *xresp = (int)(xres + 0.5); 53 *yresp = (int)(yres + 0.5); 54 } 55 else 56 { 57 fz_try(ctx) 58 { 59 pix = fz_new_pixmap(ctx, fz_device_bgr(ctx), width, height); 60 } 61 fz_catch(ctx) 62 { 63 pix = NULL; 64 goto CleanUp; 65 } 66 hr = IWICFormatConverter_CopyPixels(converter, NULL, pix->w * pix->n, pix->w * pix->h * pix->n, pix->samples); 67 if (FAILED(hr)) 68 { 69 fz_drop_pixmap(ctx, pix); 70 pix = NULL; 71 goto CleanUp; 72 } 73 pix->xres = (int)(xres + 0.5); 74 pix->yres = (int)(yres + 0.5); 75 } 76 77 CleanUp: 78 #define Release(unk) if (unk) IUnknown_Release(unk) 79 Release(src_bitmap); 80 Release(converter); 81 Release(src_frame); 82 Release(decoder); 83 Release(factory); 84 Release(stream); 85 #undef Release 86 CoUninitialize(); 87 88 if (codec_available) 89 { 90 if (!pix && !info_only) 91 fz_throw(ctx, FZ_ERROR_GENERIC, "JPEG-XR codec failed to decode the image"); 92 return pix; 93 } 94 #endif 95 fz_throw(ctx, FZ_ERROR_GENERIC, "JPEG-XR codec is not available"); 96 } 97 98 fz_pixmap * 99 fz_load_jxr(fz_context *ctx, unsigned char *data, int size) 100 { 101 return fz_load_jxr_or_info(ctx, data, size, NULL, NULL, NULL, NULL, NULL); 102 } 103 104 void 105 fz_load_jxr_info(fz_context *ctx, unsigned char *data, int size, int *wp, int *hp, int *xresp, int *yresp, fz_colorspace **cspacep) 106 { 107 fz_load_jxr_or_info(ctx, data, size, wp, hp, xresp, yresp, cspacep); 108 }