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.