git.y1.nz

SameBoy

Accurate GB/GBC emulator
download: https://git.y1.nz/archives/sameboy.tar.gz
README | Files | Log | Refs | LICENSE

SDL/save_png/windows.c

      1 #define COBJMACROS
      2 #include "save_png.h"
      3 #include <windows.h>
      4 #include <wincodec.h>
      5 
      6 static wchar_t *utf8_to_wide(const char *utf8)
      7 {
      8     int length = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
      9     if (length <= 0) {
     10         return NULL;
     11     }
     12     
     13     wchar_t *ret = malloc(length * sizeof(*ret));
     14     if (!ret) {
     15         return NULL;
     16     }
     17     
     18     if (!MultiByteToWideChar(CP_UTF8, 0, utf8, -1, ret, length)) {
     19         free(ret);
     20         return NULL;
     21     }
     22     
     23     return ret;
     24 }
     25 
     26 bool save_png(const char *filename, uint32_t width, uint32_t height, const void *pixels, SDL_PixelFormat *pixel_format)
     27 {
     28     bool success = false;
     29     wchar_t *wfilename = utf8_to_wide(filename);
     30     
     31     IWICImagingFactory *factory = NULL;
     32     IWICStream *stream = NULL;
     33     IWICBitmapEncoder *encoder = NULL;
     34     IWICBitmapFrameEncode *frame = NULL;
     35     uint8_t *row = malloc(width * 3);
     36 
     37     CoInitialize(NULL);
     38     
     39     
     40     if (CoCreateInstance(&CLSID_WICImagingFactory,
     41                          NULL,
     42                          CLSCTX_INPROC_SERVER,
     43                          &IID_IWICImagingFactory,
     44                          (void **)&factory)) {
     45         goto done;
     46     }
     47     
     48     if (IWICImagingFactory_CreateStream(factory, &stream)) goto done;
     49     if (IWICStream_InitializeFromFilename(stream, wfilename, GENERIC_WRITE)) goto done;
     50     if (IWICImagingFactory_CreateEncoder(factory, &GUID_ContainerFormatPng, NULL, &encoder)) goto done;
     51     if (IWICBitmapEncoder_Initialize(encoder, (IStream *)stream, WICBitmapEncoderNoCache)) goto done;
     52     if (IWICBitmapEncoder_CreateNewFrame(encoder, &frame, NULL)) goto done;
     53     if (IWICBitmapFrameEncode_Initialize(frame, NULL)) goto done;
     54     if (IWICBitmapFrameEncode_SetSize(frame, width, height)) goto done;
     55     
     56     WICPixelFormatGUID pixel_format_guid = GUID_WICPixelFormat24bppRGB;
     57     if (IWICBitmapFrameEncode_SetPixelFormat(frame, &pixel_format_guid)) goto done;
     58     
     59     for (uint32_t y = 0; y < height; y++) {
     60         const uint32_t *src = (uint32_t *)pixels + y * width;
     61         uint8_t *dest = row;
     62         
     63         for (uint32_t x = 0; x < width; x++) {
     64             uint8_t dummy;
     65             SDL_GetRGBA(*(src++), pixel_format, &dest[2], &dest[1], &dest[0], &dummy);
     66             dest += 3;
     67         }
     68         
     69         if (IWICBitmapFrameEncode_WritePixels(frame, 1, width * 3, width * 3, (void *)row)) goto done;
     70     }
     71     
     72     if (IWICBitmapFrameEncode_Commit(frame)) goto done;
     73     if (IWICBitmapEncoder_Commit(encoder)) goto done;
     74     
     75     success = true;
     76     
     77 done:
     78     if (frame) IWICBitmapFrameEncode_Release(frame);
     79     if (encoder) IWICBitmapEncoder_Release(encoder);
     80     if (stream) IWICStream_Release(stream);
     81     if (factory) IWICImagingFactory_Release(factory);
     82     
     83     CoUninitialize();
     84     free(wfilename);
     85     free(row);
     86     
     87     return success;
     88 }

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.