diff --git a/reactos/win32ss/gdi/ntgdi/dib.h b/reactos/win32ss/gdi/ntgdi/dib.h index 2c679598750..1e93edc4e45 100644 --- a/reactos/win32ss/gdi/ntgdi/dib.h +++ b/reactos/win32ss/gdi/ntgdi/dib.h @@ -26,4 +26,11 @@ GreGetDIBitsInternal( UINT MaxBits, UINT MaxInfo); +HBITMAP +NTAPI +GreCreateDIBitmapFromPackedDIB( + _In_reads_(cjPackedDIB )PVOID pvPackedDIB, + _In_ UINT cjPackedDIB, + _In_ ULONG uUsage); + #define DIB_PAL_BRUSHHACK 3 diff --git a/reactos/win32ss/gdi/ntgdi/dibobj.c b/reactos/win32ss/gdi/ntgdi/dibobj.c index 63558c6604f..fa81db9183e 100644 --- a/reactos/win32ss/gdi/ntgdi/dibobj.c +++ b/reactos/win32ss/gdi/ntgdi/dibobj.c @@ -1539,6 +1539,56 @@ GreCreateDIBitmapInternal( return Bmp; } +HBITMAP +NTAPI +GreCreateDIBitmapFromPackedDIB( + _In_reads_(cjPackedDIB )PVOID pvPackedDIB, + _In_ UINT cjPackedDIB, + _In_ ULONG uUsage) +{ + PBITMAPINFO pbmi; + PBYTE pjBits; + UINT cjInfo, cjBits; + HBITMAP hbm; + + /* We only support BITMAPINFOHEADER, make sure the size is ok */ + if (cjPackedDIB < sizeof(BITMAPINFOHEADER)) + { + return NULL; + } + + /* The packed DIB starts with the BITMAPINFOHEADER */ + pbmi = pvPackedDIB; + + if (cjPackedDIB < pbmi->bmiHeader.biSize) + { + return NULL; + } + + /* Calculate the info size and make sure the packed DIB is large enough */ + cjInfo = DIB_BitmapInfoSize(pbmi, uUsage); + if (cjPackedDIB <= cjInfo) + { + return NULL; + } + + /* The bitmap bits start after the header */ + pjBits = (PBYTE)pvPackedDIB + cjInfo; + cjBits = cjPackedDIB - cjInfo; + + hbm = GreCreateDIBitmapInternal(NULL, + pbmi->bmiHeader.biWidth, + abs(pbmi->bmiHeader.biHeight), + CBM_INIT | CBM_CREATDIB, + pjBits, + pbmi, + uUsage, + 0, + cjBits, + NULL); + + return hbm; +} HBITMAP APIENTRY