Module: wine Branch: master Commit: 3f051d3b1e6d654b00825e00e3a488e79d03e70f URL: https://gitlab.winehq.org/wine/wine/-/commit/3f051d3b1e6d654b00825e00e3a488e...
Author: Piotr Caban piotr@codeweavers.com Date: Thu Mar 30 19:50:20 2023 +0200
win32u: Add support for undocummented DIB_PAL_INDICES color usage in SetDIBits.
---
dlls/gdi32/tests/bitmap.c | 8 +++++++- dlls/win32u/dib.c | 20 ++++++++++++++++++-- dlls/win32u/ntgdi_private.h | 3 +++ 3 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c index d3074286ee6..e9b93d15fce 100644 --- a/dlls/gdi32/tests/bitmap.c +++ b/dlls/gdi32/tests/bitmap.c @@ -915,7 +915,7 @@ static void test_dib_formats(void) char data[2048]; /* 2 x 2 pixels, max 64 bits-per-pixel, max 64 planes */ void *bits; int planes, bpp, compr, format; - HBITMAP hdib, hbmp; + HBITMAP hdib, hbmp, hbmp_mono; HDC hdc, memdc; UINT ret; BOOL format_ok, expect_ok; @@ -924,6 +924,7 @@ static void test_dib_formats(void) hdc = GetDC( 0 ); memdc = CreateCompatibleDC( 0 ); hbmp = CreateCompatibleBitmap( hdc, 10, 10 ); + hbmp_mono = CreateBitmap( 10, 10, 1, 1, NULL );
memset( data, 0xaa, sizeof(data) );
@@ -1203,6 +1204,8 @@ static void test_dib_formats(void) DeleteObject( hdib ); ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_PAL_COLORS+1); ok( !ret, "SetDIBits succeeded with DIB_PAL_COLORS+1\n" ); + ret = SetDIBits(hdc, hbmp_mono, 0, 1, data, bi, DIB_PAL_COLORS+1); + ok( ret, "SetDIBits failed with DIB_PAL_COLORS+1\n" ); ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_PAL_COLORS+1 ); ok( ret, "SetDIBitsToDevice failed with DIB_PAL_COLORS+1\n" ); ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_PAL_COLORS+1, SRCCOPY ); @@ -1227,6 +1230,8 @@ static void test_dib_formats(void) DeleteObject( hdib ); ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_PAL_COLORS+2); ok( !ret, "SetDIBits succeeded with DIB_PAL_COLORS+2\n" ); + ret = SetDIBits(hdc, hbmp_mono, 0, 1, data, bi, DIB_PAL_COLORS+2); + ok( !ret, "SetDIBits succeeded with DIB_PAL_COLORS+2\n" ); ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_PAL_COLORS+2 ); ok( !ret, "SetDIBitsToDevice succeeded with DIB_PAL_COLORS+2\n" ); ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_PAL_COLORS+2, SRCCOPY ); @@ -1285,6 +1290,7 @@ static void test_dib_formats(void)
DeleteDC( memdc ); DeleteObject( hbmp ); + DeleteObject( hbmp_mono ); ReleaseDC( 0, hdc ); HeapFree( GetProcessHeap(), 0, bi ); } diff --git a/dlls/win32u/dib.c b/dlls/win32u/dib.c index ccbb7d6db33..64f96b268c9 100644 --- a/dlls/win32u/dib.c +++ b/dlls/win32u/dib.c @@ -205,9 +205,11 @@ static BOOL bitmapinfo_from_user_bitmapinfo( BITMAPINFO *dst, const BITMAPINFO * { void *src_colors;
- if (coloruse > DIB_PAL_COLORS + 1) return FALSE; /* FIXME: handle DIB_PAL_COLORS+1 format */ + if (coloruse > DIB_PAL_INDICES) return FALSE; if (!bitmapinfoheader_from_user_bitmapinfo( &dst->bmiHeader, &info->bmiHeader )) return FALSE; if (!is_valid_dib_format( &dst->bmiHeader, allow_compression )) return FALSE; + if (coloruse == DIB_PAL_INDICES && (dst->bmiHeader.biBitCount != 1 || + dst->bmiHeader.biCompression != BI_RGB)) return FALSE;
src_colors = (char *)info + info->bmiHeader.biSize;
@@ -230,6 +232,18 @@ static BOOL bitmapinfo_from_user_bitmapinfo( BITMAPINFO *dst, const BITMAPINFO * memcpy( dst->bmiColors, src_colors, colors * sizeof(WORD) ); max_colors = colors; } + else if (coloruse == DIB_PAL_INDICES) + { + dst->bmiColors[0].rgbRed = 0; + dst->bmiColors[0].rgbGreen = 0; + dst->bmiColors[0].rgbBlue = 0; + dst->bmiColors[0].rgbReserved = 0; + dst->bmiColors[1].rgbRed = 0xff; + dst->bmiColors[1].rgbGreen = 0xff; + dst->bmiColors[1].rgbBlue = 0xff; + dst->bmiColors[1].rgbReserved = 0; + colors = max_colors; + } else if (info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) { memcpy( dst->bmiColors, src_colors, colors * sizeof(RGBQUAD) ); @@ -675,7 +689,7 @@ INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan, INT src_to_dst_offset; HRGN clip = 0;
- if (!bitmapinfo_from_user_bitmapinfo( src_info, info, coloruse, TRUE ) || coloruse > DIB_PAL_COLORS) + if (!bitmapinfo_from_user_bitmapinfo( src_info, info, coloruse, TRUE )) { RtlSetLastWin32Error( ERROR_INVALID_PARAMETER ); return 0; @@ -699,6 +713,8 @@ INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan,
if (!(bitmap = GDI_GetObjPtr( hbitmap, NTGDI_OBJ_BITMAP ))) return 0;
+ if (coloruse == DIB_PAL_INDICES && bitmap->dib.dsBm.bmBitsPixel != 1) return 0; + if (src_info->bmiHeader.biCompression == BI_RLE4 || src_info->bmiHeader.biCompression == BI_RLE8) { if (lines == 0) goto done; diff --git a/dlls/win32u/ntgdi_private.h b/dlls/win32u/ntgdi_private.h index 93be59c9d7e..cd714f8ec0d 100644 --- a/dlls/win32u/ntgdi_private.h +++ b/dlls/win32u/ntgdi_private.h @@ -28,6 +28,9 @@ /* extra stock object: default 1x1 bitmap for memory DCs */ #define DEFAULT_BITMAP (STOCK_LAST+1)
+/* Undocumented value for DIB's color use: indicates a mono DIB w/o pal entries */ +#define DIB_PAL_INDICES 2 + struct gdi_obj_funcs { INT (*pGetObjectW)( HGDIOBJ handle, INT count, LPVOID buffer );