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 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 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