[1/2] gdi32/dib: Respect DIB_PAL_COLORS in every case
Michael Karcher
wine at mkarcher.dialup.fu-berlin.de
Sat Jun 7 18:44:10 CDT 2008
If the exported bitmap had less colors than the DDB to export from,
the default palette was always stored in RGB format. This is a buffer
overrun as RGB format palettes are twice as big than index palettes.
Testcase tested on patched wine and Windows XP (with 8, 16, 24, 32bpp;
only an already-present failure on 24 bpp has been observed)
---
This is patch one of a three patch series to close bug 6519. The third
one is based on the patch by Eric Pouech, who I am going to talk to
about it first, so only the first two get submitted now.
dlls/gdi32/dib.c | 33 +++++++++++++++++----------------
dlls/gdi32/tests/bitmap.c | 42 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 59 insertions(+), 16 deletions(-)
diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c
index ffd6f31..46be0f0 100644
--- a/dlls/gdi32/dib.c
+++ b/dlls/gdi32/dib.c
@@ -701,7 +701,11 @@ INT WINAPI GetDIBits(
}
}
else {
- if(bpp >= bmp->bitmap.bmBitsPixel) {
+ if (coloruse == DIB_PAL_COLORS) {
+ for (i = 0; i < (1 << bpp); i++)
+ ((WORD *)colorPtr)[i] = (WORD)i;
+ }
+ else if(bpp >= bmp->bitmap.bmBitsPixel) {
/* Generate the color map from the selected palette */
PALETTEENTRY palEntry[256];
@@ -713,22 +717,19 @@ INT WINAPI GetDIBits(
return 0;
}
for (i = 0; i < (1 << bmp->bitmap.bmBitsPixel); i++) {
- if (coloruse == DIB_RGB_COLORS) {
- if (core_header)
- {
- rgbTriples[i].rgbtRed = palEntry[i].peRed;
- rgbTriples[i].rgbtGreen = palEntry[i].peGreen;
- rgbTriples[i].rgbtBlue = palEntry[i].peBlue;
- }
- else
- {
- rgbQuads[i].rgbRed = palEntry[i].peRed;
- rgbQuads[i].rgbGreen = palEntry[i].peGreen;
- rgbQuads[i].rgbBlue = palEntry[i].peBlue;
- rgbQuads[i].rgbReserved = 0;
- }
+ if (core_header)
+ {
+ rgbTriples[i].rgbtRed = palEntry[i].peRed;
+ rgbTriples[i].rgbtGreen = palEntry[i].peGreen;
+ rgbTriples[i].rgbtBlue = palEntry[i].peBlue;
+ }
+ else
+ {
+ rgbQuads[i].rgbRed = palEntry[i].peRed;
+ rgbQuads[i].rgbGreen = palEntry[i].peGreen;
+ rgbQuads[i].rgbBlue = palEntry[i].peBlue;
+ rgbQuads[i].rgbReserved = 0;
}
- else ((WORD *)colorPtr)[i] = (WORD)i;
}
} else {
switch (bpp) {
diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c
index 06b1672..6685ae6 100644
--- a/dlls/gdi32/tests/bitmap.c
+++ b/dlls/gdi32/tests/bitmap.c
@@ -1301,6 +1301,28 @@ static void test_GetDIBits_selected_DDB(BOOL monochrome)
}
ok(equalContents, "GetDIBits with DDB selected in DC: Got different DIB bits\n");
+ /* Test the palette */
+ equalContents = TRUE;
+ if (info2->bmiHeader.biBitCount <= 8)
+ {
+ WORD *colors = (WORD*)info2->bmiColors;
+
+ /* Get the palette indices */
+ res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
+ ok(res, "GetDIBits failed\n");
+
+ for (i=0;i < 1 << info->bmiHeader.biSizeImage; i++)
+ {
+ if (colors[i] != i)
+ {
+ equalContents = FALSE;
+ break;
+ }
+ }
+ }
+
+ ok(equalContents, "GetDIBits with DDB selected in DC: non 1:1 palette indices\n");
+
HeapFree(GetProcessHeap(), 0, bits2);
HeapFree(GetProcessHeap(), 0, bits);
DeleteDC(dc);
@@ -1482,6 +1504,16 @@ todo_wine
todo_wine
ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
+ /* Test the palette indices */
+ memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
+ SetLastError(0xdeadbeef);
+ lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
+
+ ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
+ ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
+ for (i = 2; i < 256; i++)
+ ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]);
+
/* retrieve 24-bit DIB data */
memset(bi, 0, sizeof(*bi));
bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
@@ -1582,6 +1614,16 @@ todo_wine
todo_wine
ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
+ /* Test the palette indices */
+ memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
+ SetLastError(0xdeadbeef);
+ lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
+
+ ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
+ ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
+ for (i = 2; i < 256; i++)
+ ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]);
+
/* retrieve 24-bit DIB data */
memset(bi, 0, sizeof(*bi));
bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
--
1.5.5.1
More information about the wine-patches
mailing list