gdi32: Fixed GetDIBits for top-down bitmaps (try 2).
Jack Edmonds
pocketcookies2 at gmail.com
Sat Feb 12 12:24:26 CST 2011
gdi32/dib.c: Reversed source bitmap pointer instead of destination bitmap pointer.
Removed check for destination bitmap height when determining whether to copy the source bitmap upside down.
gdi32/tests/bitmap.c: Added a test for copying between top-down bitmaps.
---
dlls/gdi32/dib.c | 12 +++++++---
dlls/gdi32/tests/bitmap.c | 52 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 60 insertions(+), 4 deletions(-)
diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c
index 5067e49..9004b2c 100644
--- a/dlls/gdi32/dib.c
+++ b/dlls/gdi32/dib.c
@@ -876,11 +876,15 @@ INT WINAPI GetDIBits(
int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
unsigned int x, y, width, widthb;
-
- if ((height < 0) ^ (bmp->dib->dsBmih.biHeight < 0))
+ /*
+ * If copying from a top-down source bitmap, move the source
+ * pointer to the end of the source bitmap and negate the width
+ * so that we copy the bits upside-down.
+ */
+ if (bmp->dib->dsBmih.biHeight < 0)
{
- dbits = (LPBYTE)bits + (dstwidthb * (lines-1));
- dstwidthb = -dstwidthb;
+ sbits += (srcwidthb * (abs(bmp->dib->dsBmih.biHeight) - startscan - 1));
+ srcwidthb = -srcwidthb;
}
switch( bpp ) {
diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c
index d0d7a9c..ffdb2a4 100644
--- a/dlls/gdi32/tests/bitmap.c
+++ b/dlls/gdi32/tests/bitmap.c
@@ -3050,6 +3050,57 @@ static void test_32bit_bitmap_blt(void)
DeleteDC(hdcScreen);
}
+static void test_GetDIBits_single_pixel_destination(void)
+{
+ BITMAPINFO bi;
+ HBITMAP bmptb, bmpbt;
+ HDC hdc;
+ int pixelOut;
+ int *picture;
+ bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
+ bi.bmiHeader.biWidth=2;
+ bi.bmiHeader.biHeight=2;
+ bi.bmiHeader.biPlanes=1;
+ bi.bmiHeader.biBitCount=32;
+ bi.bmiHeader.biCompression=BI_RGB;
+
+ /*Get the device context for the screen.*/
+ hdc=GetDC(NULL);
+
+ /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
+ bmpbt=CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
+ /*Now that we have a pointer to the pixels, we write to them.*/
+ picture[0]=1;
+ picture[1]=2;
+ picture[2]=3;
+ picture[3]=4;
+ /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
+ bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
+ bmptb=CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
+ /*Write to this top to bottom bitmap.*/
+ picture[0]=1;
+ picture[1]=2;
+ picture[2]=3;
+ picture[3]=4;
+
+ bi.bmiHeader.biWidth=1;
+
+ bi.bmiHeader.biHeight=2;
+ GetDIBits(hdc, bmpbt, 0, 1, &pixelOut, &bi, DIB_RGB_COLORS);
+ ok(pixelOut==1, "Bottom-up -> bottom-up should have first scanline.\n");
+ GetDIBits(hdc, bmptb, 0, 1, &pixelOut, &bi, DIB_RGB_COLORS);
+ ok(pixelOut==3, "Top-down -> bottom-up should have last scanline.\n");
+
+ bi.bmiHeader.biHeight=-2;
+ GetDIBits(hdc, bmpbt, 0, 1, &pixelOut, &bi, DIB_RGB_COLORS);
+ ok(pixelOut==1, "Bottom-up -> top-down should have first scanline.\n");
+ GetDIBits(hdc, bmptb, 0, 1, &pixelOut, &bi, DIB_RGB_COLORS);
+ ok(pixelOut==3, "Top-down -> top-down should have last scanline.\n");
+
+ DeleteObject(bmpbt);
+ DeleteObject(bmptb);
+}
+
START_TEST(bitmap)
{
HMODULE hdll;
@@ -3080,4 +3131,5 @@ START_TEST(bitmap)
test_bitmapinfoheadersize();
test_get16dibits();
test_clipping();
+ test_GetDIBits_single_pixel_destination();
}
--
1.7.1
More information about the wine-patches
mailing list