From 7f19bda6ec10036f6202d7eeb64c3691082af847 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 27 May 2010 13:38:30 +0200 Subject: [PATCH] gdi32: Only 16 and 32 bpp DIB sections can have bitfields. --- dlls/gdi32/dib.c | 42 +++++++++++++++++++++++++----------- dlls/gdi32/tests/bitmap.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 12 deletions(-) diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c index 2725247de4a..ce5ab8b989e 100644 --- a/dlls/gdi32/dib.c +++ b/dlls/gdi32/dib.c @@ -647,18 +647,24 @@ INT WINAPI GetDIBits( DIB_GetDIBImageBytes( bmp->bitmap.bmWidth, bmp->bitmap.bmHeight, bmp->bitmap.bmBitsPixel ); - info->bmiHeader.biCompression = (bmp->bitmap.bmBitsPixel > 8) ? BI_BITFIELDS : BI_RGB; - switch(bmp->bitmap.bmBitsPixel) + if (bmp->dib) { - case 15: - info->bmiHeader.biBitCount = 16; - break; - case 24: - info->bmiHeader.biBitCount = 32; - break; - default: + info->bmiHeader.biBitCount = bmp->dib->dsBm.bmBitsPixel; + switch (bmp->dib->dsBm.bmBitsPixel) + { + case 16: + case 32: + info->bmiHeader.biCompression = BI_BITFIELDS; + break; + default: + info->bmiHeader.biCompression = BI_RGB; + break; + } + } + else + { + info->bmiHeader.biCompression = (bmp->bitmap.bmBitsPixel > 8) ? BI_BITFIELDS : BI_RGB; info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel; - break; } info->bmiHeader.biXPelsPerMeter = 0; info->bmiHeader.biYPelsPerMeter = 0; @@ -1244,10 +1250,22 @@ HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage, &planes, &bpp, &compression, &sizeImage )) == -1)) return 0; - if (compression != BI_RGB && compression != BI_BITFIELDS) + switch (bpp) { - TRACE("can't create a compressed (%u) dibsection\n", compression); + case 16: + case 32: + if (compression == BI_BITFIELDS) break; + /* fall through */ + case 1: + case 4: + case 8: + case 24: + if (compression == BI_RGB) break; + WARN( "invalid %u bpp compression %u\n", bpp, compression ); return 0; + default: + FIXME( "should fail %u bpp compression %u\n", bpp, compression ); + break; } if (!(dib = HeapAlloc( GetProcessHeap(), 0, sizeof(*dib) ))) return 0; diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c index b25cfd4ae1e..8e5ad2ea797 100644 --- a/dlls/gdi32/tests/bitmap.c +++ b/dlls/gdi32/tests/bitmap.c @@ -546,6 +546,18 @@ static void test_dibsections(void) ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n"); ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError()); + for (i = 0; i < 128; i++) + { + pbmi->bmiHeader.biBitCount = i; + pbmi->bmiHeader.biCompression = BI_RGB; + hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); + if (i == 1 || i == 4 || i == 8 || i == 16 || i == 24 || i == 32) + ok(hdib != NULL, "CreateDIBSection bpp %u\n", i); + else + todo_wine ok(hdib == NULL, "CreateDIBSection bpp %u succeeded\n", i); + if (hdib) DeleteObject( hdib ); + } + pbmi->bmiHeader.biBitCount = 16; pbmi->bmiHeader.biCompression = BI_BITFIELDS; ((PDWORD)pbmi->bmiColors)[0] = 0xf800; @@ -1978,6 +1990,49 @@ static void test_GetDIBits_BI_BITFIELDS(void) DeleteObject(hbm); } + /* 24-bpp DIB sections don't have bitfields */ + + dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + dibinfo->bmiHeader.biWidth = 1; + dibinfo->bmiHeader.biHeight = 1; + dibinfo->bmiHeader.biPlanes = 1; + dibinfo->bmiHeader.biBitCount = 24; + dibinfo->bmiHeader.biCompression = BI_BITFIELDS; + dibinfo->bmiHeader.biSizeImage = 0; + dibinfo->bmiHeader.biXPelsPerMeter = 0; + dibinfo->bmiHeader.biYPelsPerMeter = 0; + dibinfo->bmiHeader.biClrUsed = 0; + dibinfo->bmiHeader.biClrImportant = 0; + hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 ); + ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" ); + dibinfo->bmiHeader.biCompression = BI_RGB; + hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 ); + ok( hbm != 0, "failed to create bitmap\n" ); + + memset(dibinfo, 0, sizeof(dibinfo_buf)); + dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS); + ok(ret == 1, "GetDIBits failed\n"); + ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount ); + + ok( dibinfo->bmiHeader.biCompression == BI_RGB, + "compression is %u\n", dibinfo->bmiHeader.biCompression ); + ok( !bitmasks[0], "red mask is set\n" ); + ok( !bitmasks[1], "green mask is set\n" ); + ok( !bitmasks[2], "blue mask is set\n" ); + + dibinfo->bmiHeader.biSizeImage = 0xdeadbeef; + ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS); + ok(ret == 1, "GetDIBits failed\n"); + ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount ); + ok( !bitmasks[0], "red mask is set\n" ); + ok( !bitmasks[1], "green mask is set\n" ); + ok( !bitmasks[2], "blue mask is set\n" ); + ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef || + broken(dibinfo->bmiHeader.biSizeImage == 0xdeadbeef), /* win9x */ + "size image not set\n" ); + + DeleteObject(hbm); ReleaseDC(NULL, hdc); } -- 2.11.4.GIT