gdi32: Fixed GetDIBits for top-down bitmaps.

This commit is contained in:
John Edmonds 2011-02-20 22:31:26 -05:00 committed by Alexandre Julliard
parent d2e1478db0
commit 3c239fa0cd
2 changed files with 19 additions and 14 deletions

View File

@ -871,18 +871,23 @@ INT WINAPI GetDIBits(
if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && bpp >= 15)
{
/*FIXME: Only RGB dibs supported for now */
unsigned int srcwidth = bmp->dib->dsBm.bmWidth, srcwidthb = bmp->dib->dsBm.bmWidthBytes;
unsigned int srcwidth = bmp->dib->dsBm.bmWidth;
int srcwidthb = bmp->dib->dsBm.bmWidthBytes;
unsigned int dstwidth = width;
int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
unsigned 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) - 2 * startscan - 1));
srcwidthb = -srcwidthb;
}
switch( bpp ) {
case 15:
@ -897,7 +902,7 @@ INT WINAPI GetDIBits(
case 16: /* 16 bpp srcDIB -> 16 bpp dstDIB */
{
widthb = min(srcwidthb, abs(dstwidthb));
widthb = min(abs(srcwidthb), dstwidthb);
/* FIXME: BI_BITFIELDS not supported yet */
for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
memcpy(dbits, sbits, widthb);
@ -975,7 +980,7 @@ INT WINAPI GetDIBits(
case 24: /* 24 bpp srcDIB -> 24 bpp dstDIB */
{
widthb = min(srcwidthb, abs(dstwidthb));
widthb = min(abs(srcwidthb), dstwidthb);
for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
memcpy(dbits, sbits, widthb);
}
@ -1051,7 +1056,7 @@ INT WINAPI GetDIBits(
case 32: /* 32 bpp srcDIB -> 32 bpp dstDIB */
{
widthb = min(srcwidthb, abs(dstwidthb));
widthb = min(abs(srcwidthb), dstwidthb);
/* FIXME: BI_BITFIELDS not supported yet */
for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb) {
memcpy(dbits, sbits, widthb);

View File

@ -3116,27 +3116,27 @@ static void test_GetDIBits_single_pixel_destination(int bpp)
ok((char)pixelOut == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pixelOut);
statusCode = GetDIBits(hdc, bmptb, 0, 1, &pixelOut, &bi, DIB_RGB_COLORS);
ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
todo_wine ok((char)pixelOut == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pixelOut);
ok((char)pixelOut == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pixelOut);
/*Check second scanline.*/
statusCode = GetDIBits(hdc, bmptb, 1, 1, &pixelOut, &bi, DIB_RGB_COLORS);
ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
todo_wine ok((char)pixelOut == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pixelOut);
ok((char)pixelOut == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pixelOut);
statusCode = GetDIBits(hdc, bmpbt, 1, 1, &pixelOut, &bi, DIB_RGB_COLORS);
ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
ok((char)pixelOut == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pixelOut);
/*Make destination bitmap top-down. Windows (and soon, Wine) will ignore this.*/
/*Make destination bitmap top-down. This should be ignored by GetDIBits.*/
bi.bmiHeader.biHeight = -2;
statusCode = GetDIBits(hdc, bmpbt, 0, 1, &pixelOut, &bi, DIB_RGB_COLORS);
ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
ok((char)pixelOut == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pixelOut);
statusCode = GetDIBits(hdc, bmptb, 0, 1, &pixelOut, &bi, DIB_RGB_COLORS);
ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
todo_wine ok((char)pixelOut == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pixelOut);
ok((char)pixelOut == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pixelOut);
/*Check second scanline.*/
statusCode = GetDIBits(hdc, bmptb, 1, 1, &pixelOut, &bi, DIB_RGB_COLORS);
ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
todo_wine ok((char)pixelOut == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pixelOut);
ok((char)pixelOut == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pixelOut);
statusCode = GetDIBits(hdc, bmpbt, 1, 1, &pixelOut, &bi, DIB_RGB_COLORS);
ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
ok((char)pixelOut == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pixelOut);