From 0d0d4f394fd9e3f66f6a8ca6855cb31f4c741272 Mon Sep 17 00:00:00 2001 From: John Edmonds Date: Tue, 1 Mar 2011 22:29:51 -0500 Subject: [PATCH] gdi32: Fixes GetDIBits for top-down destination bitmaps. --- dlls/gdi32/dib.c | 14 ++++++++++---- dlls/gdi32/tests/bitmap.c | 8 ++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c index eae7f35676c..0abd8334fcd 100644 --- a/dlls/gdi32/dib.c +++ b/dlls/gdi32/dib.c @@ -874,7 +874,7 @@ INT WINAPI GetDIBits( unsigned int srcwidth = bmp->dib->dsBm.bmWidth; int srcwidthb = bmp->dib->dsBm.bmWidthBytes; unsigned int dstwidth = width; - unsigned int dstwidthb = DIB_GetDIBWidthBytes( width, bpp ); + int dstwidthb = DIB_GetDIBWidthBytes( width, bpp ); LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb); unsigned int x, y, width, widthb; @@ -888,6 +888,12 @@ INT WINAPI GetDIBits( sbits += (srcwidthb * (int)(abs(bmp->dib->dsBmih.biHeight) - 2 * startscan - 1)); srcwidthb = -srcwidthb; } + /*Same for the destination.*/ + if (height < 0) + { + dbits = (LPBYTE)bits + (dstwidthb * (lines - 1)); + dstwidthb = -dstwidthb; + } switch( bpp ) { case 15: @@ -902,7 +908,7 @@ INT WINAPI GetDIBits( case 16: /* 16 bpp srcDIB -> 16 bpp dstDIB */ { - widthb = min(abs(srcwidthb), dstwidthb); + widthb = min(abs(srcwidthb), abs(dstwidthb)); /* FIXME: BI_BITFIELDS not supported yet */ for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb) memcpy(dbits, sbits, widthb); @@ -980,7 +986,7 @@ INT WINAPI GetDIBits( case 24: /* 24 bpp srcDIB -> 24 bpp dstDIB */ { - widthb = min(abs(srcwidthb), dstwidthb); + widthb = min(abs(srcwidthb), abs(dstwidthb)); for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb) memcpy(dbits, sbits, widthb); } @@ -1056,7 +1062,7 @@ INT WINAPI GetDIBits( case 32: /* 32 bpp srcDIB -> 32 bpp dstDIB */ { - widthb = min(abs(srcwidthb), dstwidthb); + widthb = min(abs(srcwidthb), abs(dstwidthb)); /* FIXME: BI_BITFIELDS not supported yet */ for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb) { memcpy(dbits, sbits, widthb); diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c index 01ac758556a..adef0359fb6 100644 --- a/dlls/gdi32/tests/bitmap.c +++ b/dlls/gdi32/tests/bitmap.c @@ -3057,12 +3057,12 @@ static void test_GetDIBits_top_down(int bpp) /*Check both scanlines.*/ statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS); ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode); - todo_wine ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]); - todo_wine ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]); + ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]); + ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]); statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS); ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode); - todo_wine ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]); - todo_wine ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]); + ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]); + ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]); DeleteObject(bmpbt); DeleteObject(bmptb);