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  }