gdi32: Only 16 and 32 bpp DIB sections can have bitfields.
diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c
index 2725247..ce5ab8b 100644
--- a/dlls/gdi32/dib.c
+++ b/dlls/gdi32/dib.c
@@ -647,18 +647,24 @@
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 @@
&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 b25cfd4..8e5ad2e 100644
--- a/dlls/gdi32/tests/bitmap.c
+++ b/dlls/gdi32/tests/bitmap.c
@@ -546,6 +546,18 @@
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 @@
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);
}