gdi32/dib.c: Write true bitmap height into info and copy scanlines in the correct order.

Jack Edmonds pocketcookies2 at gmail.com
Sun Feb 13 15:21:43 CST 2011


Sorry about that. I added the newlines in my latest patch. Thanks for
telling me.
On Feb 8, 2011 4:22 AM, "Nicolas Le Cam" <niko.lecam at gmail.com> wrote:
> 2011/2/8 Jack Edmonds <jack at jack-desktop.>
>
>> Fixes bug 25698 and addresses one of the test cases in bug 24278
(possibly
>> resolves bug 24278 but more testing is required to be sure).
>>
>> dib.c: Fills BITMAPINFOHEADER with correct width and height when bits ==
>> NULL and copying from a top-to-bottom bitmap.
>> For top-to-bottom bitmaps, reverses the source pointer rather than the
>> destination pointer.
>> Ignoring the case when both source and destination are top-to-bottom
>> bitmaps and treating this as if the destination is only a top-to-bottom
>> bitmap.
>> ---
>> dlls/gdi32/dib.c | 113
>> ++++++++++++++++++++++++---------------------
>> dlls/gdi32/tests/bitmap.c | 112
>> ++++++++++++++++++++++++++++++++++++++++++++
>> 2 files changed, 173 insertions(+), 52 deletions(-)
>>
>> diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c
>> index 5067e49..bf7a525 100644
>> --- a/dlls/gdi32/dib.c
>> +++ b/dlls/gdi32/dib.c
>> @@ -636,54 +636,6 @@ INT WINAPI GetDIBits(
>>
>> switch (bpp)
>> {
>> - case 0: /* query bitmap info only */
>> - if (core_header)
>> - {
>> - BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) info;
>> - coreheader->bcWidth = bmp->bitmap.bmWidth;
>> - coreheader->bcHeight = bmp->bitmap.bmHeight;
>> - coreheader->bcPlanes = 1;
>> - coreheader->bcBitCount = bmp->bitmap.bmBitsPixel;
>> - }
>> - else
>> - {
>> - info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
>> - info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
>> - info->bmiHeader.biPlanes = 1;
>> - info->bmiHeader.biSizeImage =
>> - DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
>> - bmp->bitmap.bmHeight,
>> - bmp->bitmap.bmBitsPixel );
>> - if (bmp->dib)
>> - {
>> - 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;
>> - }
>> - info->bmiHeader.biXPelsPerMeter = 0;
>> - info->bmiHeader.biYPelsPerMeter = 0;
>> - info->bmiHeader.biClrUsed = 0;
>> - info->bmiHeader.biClrImportant = 0;
>> -
>> - /* Windows 2000 doesn't touch the additional struct members if
>> - it's a BITMAPV4HEADER or a BITMAPV5HEADER */
>> - }
>> - lines = abs(bmp->bitmap.bmHeight);
>> - goto done;
>> -
>> case 1:
>> case 4:
>> case 8:
>> @@ -877,10 +829,10 @@ INT WINAPI GetDIBits(
>> 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 (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 ) {
>> @@ -1086,7 +1038,64 @@ INT WINAPI GetDIBits(
>> }
>> }
>> }
>> - else lines = abs(height);
>> + else /* query bitmap info only */
>> + {
>> + if (core_header)
>> + {
>> + BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) info;
>> + if (bmp->dib)
>> + {
>> + coreheader->bcWidth = bmp->dib->dsBmih.biWidth;
>> + coreheader->bcHeight = bmp->dib->dsBmih.biHeight;
>> + }
>> + else
>> + {
>> + coreheader->bcWidth = bmp->bitmap.bmWidth;
>> + coreheader->bcHeight = bmp->bitmap.bmHeight;
>> + }
>> + coreheader->bcPlanes = 1;
>> + coreheader->bcBitCount = bmp->bitmap.bmBitsPixel;
>> + }
>> + else
>> + {
>> + if (bmp->dib)
>> + {
>> + info->bmiHeader.biHeight = bmp->dib->dsBmih.biHeight;
>> + info->bmiHeader.biWidth = bmp->dib->dsBmih.biWidth;
>> + 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.biWidth = bmp->bitmap.bmWidth;
>> + info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
>> + info->bmiHeader.biCompression = (bmp->bitmap.bmBitsPixel >
>> 8) ? BI_BITFIELDS : BI_RGB;
>> + info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
>> + }
>> + info->bmiHeader.biPlanes = 1;
>> + info->bmiHeader.biSizeImage =
>> + DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
>> + bmp->bitmap.bmHeight,
>> + bmp->bitmap.bmBitsPixel );
>> + info->bmiHeader.biXPelsPerMeter = 0;
>> + info->bmiHeader.biYPelsPerMeter = 0;
>> + info->bmiHeader.biClrUsed = 0;
>> + info->bmiHeader.biClrImportant = 0;
>> +
>> + /* Windows 2000 doesn't touch the additional struct members if
>> + it's a BITMAPV4HEADER or a BITMAPV5HEADER */
>> + }
>> + lines = abs(bmp->bitmap.bmHeight);
>> + }
>>
>> /* The knowledge base article Q81498 ("DIBs and Their Uses") states
>> that
>> if bits == NULL and bpp != 0, only biSizeImage and the color table
>> are
>> diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c
>> index d0d7a9c..a76d437 100644
>> --- a/dlls/gdi32/tests/bitmap.c
>> +++ b/dlls/gdi32/tests/bitmap.c
>> @@ -3050,6 +3050,116 @@ static void test_32bit_bitmap_blt(void)
>> DeleteDC(hdcScreen);
>> }
>>
>> +static void test_GetDIBits_info_query(void)
>> +{
>> + BITMAPINFO bi;
>> + HBITMAP bmp;
>> + HDC hdc;
>> + int *picture;
>> +
>> + hdc = GetDC(NULL);
>> +
>> + 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;
>> + bmp = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture,
>> NULL, 0);
>> + /*Clear the structure to make sure that we really are testing that the
>> structure is being written to.*/
>> + memset(&bi, 0, sizeof(bi));
>> + /*Test with a BITMAPINFOHEADER.*/
>> + bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
>> + GetDIBits(hdc, bmp, 0, 0, NULL, &bi, DIB_RGB_COLORS);
>> + ok(bi.bmiHeader.biHeight == 2, "Height should be 2.");
>> + ok(bi.bmiHeader.biWidth == 2, "Width should be 2.");
>> + /*Clear the structure to make sure that we really are testing that the
>> structure is being written to.*/
>> + memset(&bi, 0, sizeof(bi));
>> + /*Now test with a BITMAPCOREHEADER.*/
>> + bi.bmiHeader.biSize=sizeof(BITMAPCOREHEADER);
>> + GetDIBits(hdc, bmp, 0, 0, NULL, &bi, DIB_RGB_COLORS);
>> + ok(((BITMAPCOREHEADER*)&bi)->bcHeight == 2, "Height should be 2.");
>> + ok(((BITMAPCOREHEADER*)&bi)->bcWidth == 2, "Width should be 2.");
>> + /*Clean up.*/
>> + DeleteObject(bmp);
>> +
>> + /*Test top to bottom bitmap.*/
>> + 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;
>> + bmp = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture,
>> NULL, 0);
>> + /*Clear the structure to make sure that we really are testing that the
>> structure is being written to.*/
>> + memset(&bi, 0, sizeof(bi));
>> + /*Test with a BITMAPINFOHEADER.*/
>> + bi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
>> + GetDIBits(hdc, bmp, 0, 0, NULL, &bi, DIB_RGB_COLORS);
>> + ok(bi.bmiHeader.biHeight == -2, "Height should be -2.");
>> + ok(bi.bmiHeader.biWidth == 2, "Width should be 2.");
>> + /*Clear the structure to make sure that we really are testing that the
>> structure is being written to.*/
>> + memset(&bi, 0, sizeof(bi));
>> + /*Now test with a BITMAPCOREHEADER.*/
>> + bi.bmiHeader.biSize=sizeof(BITMAPCOREHEADER);
>> + GetDIBits(hdc, bmp, 0, 0, NULL, &bi, DIB_RGB_COLORS);
>> + ok(((BITMAPCOREHEADER*)&bi)->bcHeight == (WORD)-2, "Height should be
>> -2.");
>> + ok(((BITMAPCOREHEADER*)&bi)->bcWidth == (WORD)2, "Width should be
>> 2.");
>> + /*Clean up.*/
>> + DeleteObject(bmp);
>> +}
>> +
>> +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.");
>> + GetDIBits(hdc, bmptb, 0, 1, &pixelOut, &bi, DIB_RGB_COLORS);
>> + ok(pixelOut==3, "Top-down -> bottom-up should have last scanline.");
>> +
>> + 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.");
>> + GetDIBits(hdc, bmptb, 0, 1, &pixelOut, &bi, DIB_RGB_COLORS);
>> + ok(pixelOut==3, "Top-down -> top-down should have last scanline.");
>> +
>> + DeleteObject(bmpbt);
>> + DeleteObject(bmptb);
>> +}
>> +
>> START_TEST(bitmap)
>> {
>> HMODULE hdll;
>> @@ -3080,4 +3190,6 @@ START_TEST(bitmap)
>> test_bitmapinfoheadersize();
>> test_get16dibits();
>> test_clipping();
>> + test_GetDIBits_single_pixel_destination();
>> + test_GetDIBits_info_query();
>> }
>> --
>> 1.7.1
>>
>>
>>
>>
> Hi Jack,
>
> You forgot trailing \n in the ok() calls.
>
> --
> Nicolas Le Cam
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20110213/222c681f/attachment-0001.htm>


More information about the wine-devel mailing list