Rewrite IMG_WIC.c to work as a C file, use original IWICImagingFactory API default tip
authorEthan Lee <flibitijibibo@flibitijibibo.com>
Fri, 12 Apr 2019 16:29:43 -0400
changeset 64161f1bf992955
parent 640 db8eb5e7247c
Rewrite IMG_WIC.c to work as a C file, use original IWICImagingFactory API
IMG_WIC.c
     1.1 --- a/IMG_WIC.c	Sat Mar 16 18:57:27 2019 -0700
     1.2 +++ b/IMG_WIC.c	Fri Apr 12 16:29:43 2019 -0400
     1.3 @@ -22,19 +22,22 @@
     1.4  #if defined(SDL_IMAGE_USE_WIC_BACKEND)
     1.5  
     1.6  #include "SDL_image.h"
     1.7 +#define COBJMACROS
     1.8 +#include <initguid.h>
     1.9  #include <wincodec.h>
    1.10  
    1.11 -extern "C" {
    1.12 +static IWICImagingFactory* wicFactory = NULL;
    1.13  
    1.14 -#define SAFE_RELEASE(X) if ((X)) { (X)->Release(); }
    1.15 -#define DONE_IF_FAILED(X) if (FAILED((X))) { goto done; }
    1.16 -
    1.17 -IWICImagingFactory2* wicFactory = NULL;
    1.18 -
    1.19 -int WIC_Init()
    1.20 +static int WIC_Init()
    1.21  {
    1.22      if (wicFactory == NULL) {
    1.23 -        HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&wicFactory));
    1.24 +        HRESULT hr = CoCreateInstance(
    1.25 +            &CLSID_WICImagingFactory,
    1.26 +            NULL,
    1.27 +            CLSCTX_INPROC_SERVER,
    1.28 +            &IID_IWICImagingFactory,
    1.29 +            (void**)&wicFactory
    1.30 +        );
    1.31          if (FAILED(hr)) {
    1.32              return -1;
    1.33          }
    1.34 @@ -43,9 +46,11 @@
    1.35      return 0;
    1.36  }
    1.37  
    1.38 -void WIC_Quit()
    1.39 +static void WIC_Quit()
    1.40  {
    1.41 -    SAFE_RELEASE(wicFactory);
    1.42 +    if (wicFactory) {
    1.43 +        IWICImagingFactory_Release(wicFactory);
    1.44 +    }
    1.45  }
    1.46  
    1.47  int IMG_InitPNG()
    1.48 @@ -199,7 +204,7 @@
    1.49      return(is_TIF);
    1.50  }
    1.51  
    1.52 -SDL_Surface* WIC_LoadImage(SDL_RWops *src)
    1.53 +static SDL_Surface* WIC_LoadImage(SDL_RWops *src)
    1.54  {
    1.55      SDL_Surface* surface = NULL;
    1.56  
    1.57 @@ -207,6 +212,12 @@
    1.58      IWICBitmapDecoder* bitmapDecoder = NULL;
    1.59      IWICBitmapFrameDecode* bitmapFrame = NULL;
    1.60      IWICFormatConverter* formatConverter = NULL;
    1.61 +    UINT width, height;
    1.62 +
    1.63 +    if (wicFactory == NULL && (WIC_Init() < 0)) {
    1.64 +        IMG_SetError("WIC failed to initialize!");
    1.65 +        return NULL;
    1.66 +    }
    1.67      
    1.68      Sint64 fileSize = SDL_RWsize(src);
    1.69      Uint8* memoryBuffer = (Uint8*)SDL_malloc(fileSize);
    1.70 @@ -217,30 +228,61 @@
    1.71  
    1.72      SDL_RWread(src, memoryBuffer, 1, fileSize);
    1.73  
    1.74 -    DONE_IF_FAILED(wicFactory->CreateStream(&stream));
    1.75 -    DONE_IF_FAILED(stream->InitializeFromMemory(memoryBuffer, fileSize));
    1.76 -    DONE_IF_FAILED(wicFactory->CreateDecoderFromStream(stream, NULL, WICDecodeMetadataCacheOnDemand, &bitmapDecoder));
    1.77 -    DONE_IF_FAILED(bitmapDecoder->GetFrame(0, &bitmapFrame));
    1.78 -    DONE_IF_FAILED(wicFactory->CreateFormatConverter(&formatConverter));
    1.79 -    DONE_IF_FAILED(formatConverter->Initialize(bitmapFrame, GUID_WICPixelFormat32bppPRGBA, WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeCustom));
    1.80 -    
    1.81 -    UINT width, height;
    1.82 -    DONE_IF_FAILED(bitmapFrame->GetSize(&width, &height));
    1.83 -    
    1.84 -    Uint32 Amask = 0xFF000000;
    1.85 -    Uint32 Rmask = 0x00FF0000;
    1.86 -    Uint32 Gmask = 0x0000FF00;
    1.87 -    Uint32 Bmask = 0x000000FF;
    1.88 +#define DONE_IF_FAILED(X) if (FAILED((X))) { goto done; }
    1.89 +    DONE_IF_FAILED(IWICImagingFactory_CreateStream(wicFactory, &stream));
    1.90 +    DONE_IF_FAILED(IWICStream_InitializeFromMemory(stream, memoryBuffer, fileSize));
    1.91 +    DONE_IF_FAILED(IWICImagingFactory_CreateDecoderFromStream(
    1.92 +        wicFactory,
    1.93 +        (IStream*)stream,
    1.94 +        NULL,
    1.95 +        WICDecodeMetadataCacheOnDemand,
    1.96 +        &bitmapDecoder
    1.97 +    ));
    1.98 +    DONE_IF_FAILED(IWICBitmapDecoder_GetFrame(bitmapDecoder, 0, &bitmapFrame));
    1.99 +    DONE_IF_FAILED(IWICImagingFactory_CreateFormatConverter(wicFactory, &formatConverter));
   1.100 +    DONE_IF_FAILED(IWICFormatConverter_Initialize(
   1.101 +        formatConverter,
   1.102 +        (IWICBitmapSource*)bitmapFrame,
   1.103 +        &GUID_WICPixelFormat32bppPRGBA,
   1.104 +        WICBitmapDitherTypeNone,
   1.105 +        NULL,
   1.106 +        0.0,
   1.107 +        WICBitmapPaletteTypeCustom
   1.108 +    ));
   1.109 +    DONE_IF_FAILED(IWICBitmapFrameDecode_GetSize(bitmapFrame, &width, &height));
   1.110 +#undef DONE_IF_FAILED
   1.111  
   1.112 -    surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, Rmask, Gmask, Bmask, Amask);
   1.113 -
   1.114 -    formatConverter->CopyPixels(NULL, width * 4, width * height * 4, (BYTE*)surface->pixels);
   1.115 +    surface = SDL_CreateRGBSurface(
   1.116 +        0,
   1.117 +        width,
   1.118 +        height,
   1.119 +        32,
   1.120 +        0x000000FF,
   1.121 +        0x0000FF00,
   1.122 +        0x00FF0000,
   1.123 +        0xFF000000
   1.124 +    );
   1.125 +    IWICFormatConverter_CopyPixels(
   1.126 +        formatConverter,
   1.127 +        NULL,
   1.128 +        width * 4,
   1.129 +        width * height * 4,
   1.130 +        (BYTE*)surface->pixels
   1.131 +    );
   1.132  
   1.133  done:
   1.134 -    SAFE_RELEASE(formatConverter);
   1.135 -    SAFE_RELEASE(bitmapFrame);
   1.136 -    SAFE_RELEASE(bitmapDecoder);
   1.137 -    SAFE_RELEASE(stream);
   1.138 +    if (formatConverter) {
   1.139 +        IWICFormatConverter_Release(formatConverter);
   1.140 +    }
   1.141 +    if (bitmapFrame) {
   1.142 +        IWICBitmapFrameDecode_Release(bitmapFrame);
   1.143 +    }
   1.144 +    if (bitmapDecoder) {
   1.145 +        IWICBitmapDecoder_Release(bitmapDecoder);
   1.146 +    }
   1.147 +    if (stream) {
   1.148 +        IWICStream_Release(stream);
   1.149 +    }
   1.150  
   1.151   SDL_free(memoryBuffer);
   1.152