1 /****************************************************************************
2 * Copyright (C) 2014-2015 Intel Corporation. All Rights Reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 * @brief Utilities used by SWR core.
27 ******************************************************************************/
31 // GDI Plus requires non-std min / max macros be defined :(
37 #include <Gdiplusheaders.h>
40 using namespace Gdiplus
;
42 int GetEncoderClsid(const WCHAR
* format
, CLSID
* pClsid
)
44 uint32_t num
= 0; // number of image encoders
45 uint32_t size
= 0; // size of the image encoder array in bytes
47 ImageCodecInfo
* pImageCodecInfo
= nullptr;
49 GetImageEncodersSize(&num
, &size
);
53 pImageCodecInfo
= (ImageCodecInfo
*)(malloc(size
));
54 if(pImageCodecInfo
== nullptr)
57 GetImageEncoders(num
, size
, pImageCodecInfo
);
59 for(uint32_t j
= 0; j
< num
; ++j
)
61 if( wcscmp(pImageCodecInfo
[j
].MimeType
, format
) == 0 )
63 *pClsid
= pImageCodecInfo
[j
].Clsid
;
64 free(pImageCodecInfo
);
69 free(pImageCodecInfo
);
73 void SaveImageToPNGFile(
74 const WCHAR
*pFilename
,
78 bool broadcastRed
= false)
80 // dump pixels to a png
82 GdiplusStartupInput gdiplusStartupInput
;
83 ULONG_PTR gdiplusToken
;
84 GdiplusStartup(&gdiplusToken
, &gdiplusStartupInput
, nullptr);
86 Bitmap
*bitmap
= new Bitmap(width
, height
);
87 BYTE
*pBytes
= (BYTE
*)pBuffer
;
88 const uint32_t bytesPerPixel
= (broadcastRed
? 1 : 4);
89 for (uint32_t y
= 0; y
< height
; ++y
)
90 for (uint32_t x
= 0; x
< width
; ++x
)
95 pixel
= *(uint8_t*)pBytes
;
96 pixel
= pixel
| (pixel
<< 8) | (pixel
<< 16) | 0xFF000000;
100 pixel
= *(uint32_t*)pBytes
;
101 if (pixel
== 0xcdcdcdcd)
105 else if (pixel
== 0xdddddddd)
116 bitmap
->SetPixel(x
, y
, color
);
117 pBytes
+= bytesPerPixel
;
122 GetEncoderClsid(L
"image/png", &pngClsid
);
123 bitmap
->Save(pFilename
, &pngClsid
, nullptr);
127 GdiplusShutdown(gdiplusToken
);
130 void OpenBitmapFromFile(
131 const WCHAR
*pFilename
,
136 GdiplusStartupInput gdiplusStartupInput
;
137 ULONG_PTR gdiplusToken
;
138 GdiplusStartup(&gdiplusToken
, &gdiplusStartupInput
, nullptr);
140 Bitmap
*bitmap
= new Bitmap(pFilename
);
142 *width
= bitmap
->GetWidth();
143 *height
= bitmap
->GetHeight();
144 *pBuffer
= new BYTE
[*width
* *height
* 4]; // width * height * |RGBA|
146 // The folder 'stb_image' contains a PNG open/close module which
147 // is far less painful than this is, yo.
149 for (uint32_t y
= 0, idx
= 0; y
< *height
; ++y
)
151 for (uint32_t x
= 0; x
< *width
; ++x
, idx
+= 4)
153 bitmap
->GetPixel(x
, *height
- y
- 1, &clr
);
154 ((BYTE
*)*pBuffer
)[idx
+ 0] = clr
.GetBlue();
155 ((BYTE
*)*pBuffer
)[idx
+ 1] = clr
.GetGreen();
156 ((BYTE
*)*pBuffer
)[idx
+ 2] = clr
.GetRed();
157 ((BYTE
*)*pBuffer
)[idx
+ 3] = clr
.GetAlpha();