1 /*
2 * PROJECT: ReactOS uxtheme.dll
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: Support for PNG images in visual styles
5 * COPYRIGHT: Copyright 2023 Ethan Rodensky <splitwirez@gmail.com>
6 */
7
8 #include "uxthemep.h"
9
10 #include <ole2.h>
11 #include <objidl.h>
12 #include <gdiplus.h>
13 #include <gdipluscolor.h>
14 #include <winreg.h>
15 #include <shlwapi.h>
16
17 BOOL
MSSTYLES_TryLoadPng(_In_ HINSTANCE hTheme,_In_ LPCWSTR szFile,_In_ LPCWSTR type,_Out_ HBITMAP * phBitmap)18 MSSTYLES_TryLoadPng(
19 _In_ HINSTANCE hTheme,
20 _In_ LPCWSTR szFile,
21 _In_ LPCWSTR type,
22 _Out_ HBITMAP *phBitmap)
23 {
24 BOOL ret = FALSE;
25
26 HRSRC hRes = FindResourceW(hTheme, szFile, type);
27 if (!hRes)
28 return FALSE;
29
30 HGLOBAL hAlloc = LoadResource(hTheme, hRes);
31 if (!hAlloc)
32 return FALSE;
33
34 DWORD dwSize = SizeofResource(hTheme, hRes);
35 LPVOID pData = LockResource(hAlloc);
36 if ((!pData) || (dwSize <= 0))
37 {
38 FreeResource(hAlloc);
39 return FALSE;
40 }
41
42 IStream* stream = SHCreateMemStream((BYTE*)pData, dwSize);
43 if (stream)
44 {
45 Gdiplus::Bitmap* gdipBitmap = Gdiplus::Bitmap::FromStream(stream, FALSE);
46 stream->Release();
47 if (gdipBitmap)
48 {
49 ret = gdipBitmap->GetHBITMAP(Gdiplus::Color(0, 0, 0, 0), phBitmap) == Gdiplus::Ok;
50 delete gdipBitmap;
51 }
52 }
53
54 UnlockResource(pData);
55 FreeResource(hAlloc);
56 return ret;
57 }
58
59 BOOL
prepare_png_alpha(_In_ HBITMAP png,_Out_ BOOL * hasAlpha)60 prepare_png_alpha(
61 _In_ HBITMAP png,
62 _Out_ BOOL* hasAlpha)
63 {
64 DIBSECTION dib;
65 int n;
66 BYTE* p;
67
68 *hasAlpha = FALSE;
69
70 if (!png || GetObjectW( png, sizeof(dib), &dib ) != sizeof(dib))
71 return FALSE;
72
73 if (dib.dsBm.bmBitsPixel != 32)
74 /* nothing to do */
75 return TRUE;
76
77 p = (BYTE*)dib.dsBm.bmBits;
78 n = dib.dsBmih.biHeight * dib.dsBmih.biWidth;
79 while (n-- > 0)
80 {
81 int a = p[3] + 1;
82 if (a < 256)
83 {
84 p[0] = MulDiv(p[0], 256, a);
85 p[1] = MulDiv(p[1], 256, a);
86 p[2] = MulDiv(p[2], 256, a);
87
88 *hasAlpha = TRUE;
89 }
90 p += 4;
91 }
92
93 return TRUE;
94 }
95