user32: Honor bfOffBits in BITMAP_Load.

This commit is contained in:
Wolfram Sang 2010-05-10 03:36:27 +02:00 committed by Alexandre Julliard
parent 8ea1f3385a
commit f76a3b965c
2 changed files with 47 additions and 19 deletions

View File

@ -2394,7 +2394,7 @@ static HBITMAP BITMAP_Load( HINSTANCE instance, LPCWSTR name,
char *bits; char *bits;
LONG width, height, new_width, new_height; LONG width, height, new_width, new_height;
WORD bpp_dummy; WORD bpp_dummy;
DWORD compr_dummy; DWORD compr_dummy, offbits = 0;
INT bm_type; INT bm_type;
HDC screen_mem_dc = NULL; HDC screen_mem_dc = NULL;
@ -2424,6 +2424,7 @@ static HBITMAP BITMAP_Load( HINSTANCE instance, LPCWSTR name,
UnmapViewOfFile( ptr ); UnmapViewOfFile( ptr );
return 0; return 0;
} }
offbits = bmfh->bfOffBits - sizeof(BITMAPFILEHEADER);
} }
size = bitmap_info_size(info, DIB_RGB_COLORS); size = bitmap_info_size(info, DIB_RGB_COLORS);
@ -2466,7 +2467,7 @@ static HBITMAP BITMAP_Load( HINSTANCE instance, LPCWSTR name,
if (!screen_dc) screen_dc = CreateDCW( DISPLAYW, NULL, NULL, NULL ); if (!screen_dc) screen_dc = CreateDCW( DISPLAYW, NULL, NULL, NULL );
if (!(screen_mem_dc = CreateCompatibleDC( screen_dc ))) goto end; if (!(screen_mem_dc = CreateCompatibleDC( screen_dc ))) goto end;
bits = (char *)info + size; bits = (char *)info + (offbits ? offbits : size);
if (loadflags & LR_CREATEDIBSECTION) if (loadflags & LR_CREATEDIBSECTION)
{ {

View File

@ -225,6 +225,14 @@ static void test_child_process(void)
SendMessage(child, WM_USER+1, 0, (LPARAM) cursor); SendMessage(child, WM_USER+1, 0, (LPARAM) cursor);
} }
static BOOL color_match(COLORREF a, COLORREF b)
{
/* 5-bit accuracy is a sufficient test. This will match as long as
* colors are never truncated to less that 3x5-bit accuracy i.e.
* palettized. */
return (a & 0x00F8F8F8) == (b & 0x00F8F8F8);
}
static void test_CopyImage_Check(HBITMAP bitmap, UINT flags, INT copyWidth, INT copyHeight, static void test_CopyImage_Check(HBITMAP bitmap, UINT flags, INT copyWidth, INT copyHeight,
INT expectedWidth, INT expectedHeight, WORD expectedDepth, BOOL dibExpected) INT expectedWidth, INT expectedHeight, WORD expectedDepth, BOOL dibExpected)
{ {
@ -698,13 +706,14 @@ static const unsigned char pngimage[285] = {
0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
}; };
/* 1x1 pixel bmp */ /* 1x1 pixel bmp with gap between palette and bitmap. Correct bitmap contains only
static const unsigned char bmpimage[66] = { zeroes, gap is 0xFF. */
0x42,0x4d,0x42,0x00,0x00,0x00,0xDE,0xAD,0xBE,0xEF,0x3e,0x00,0x00,0x00,0x28,0x00, static const unsigned char bmpimage[70] = {
0x42,0x4d,0x46,0x00,0x00,0x00,0xDE,0xAD,0xBE,0xEF,0x42,0x00,0x00,0x00,0x28,0x00,
0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00, 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00, 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00, 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0x55,0x55,0x55,0x00,0xFF,0xFF,
0x00,0x00 0xFF,0xFF,0x00,0x00,0x00,0x00
}; };
/* 2x2 pixel gif */ /* 2x2 pixel gif */
@ -714,6 +723,29 @@ static const unsigned char gif4pixel[42] = {
0x02,0x00,0x00,0x02,0x03,0x14,0x16,0x05,0x00,0x3b 0x02,0x00,0x00,0x02,0x03,0x14,0x16,0x05,0x00,0x3b
}; };
static void test_LoadImageBitmap(HBITMAP hbm)
{
BITMAP bm;
BITMAPINFO bmi;
DWORD ret, pixel = 0;
HDC hdc = GetDC(NULL);
ret = GetObject(hbm, sizeof(bm), &bm);
ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
memset(&bmi, 0, sizeof(bmi));
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
bmi.bmiHeader.biWidth = bm.bmWidth;
bmi.bmiHeader.biHeight = bm.bmHeight;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount= 24;
bmi.bmiHeader.biCompression= BI_RGB;
ret = GetDIBits(hdc, hbm, 0, bm.bmHeight, &pixel, &bmi, DIB_RGB_COLORS);
ok(ret == bm.bmHeight, "%d lines were converted, not %d\n", ret, bm.bmHeight);
ok(color_match(pixel, 0x00ffffff), "Pixel is 0x%08x\n", pixel);
}
static void test_LoadImageFile(const unsigned char * image_data, static void test_LoadImageFile(const unsigned char * image_data,
unsigned int image_size, const char * ext, BOOL expect_success) unsigned int image_size, const char * ext, BOOL expect_success)
{ {
@ -758,15 +790,18 @@ static void test_LoadImageFile(const unsigned char * image_data,
/* Load as bitmap. Should succeed if bmp, fail for everything else */ /* Load as bitmap. Should succeed if bmp, fail for everything else */
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
handle = LoadImageA(NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); handle = LoadImageA(NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
if (expect_success)
ok(handle != NULL, "LoadImage(%s) as IMAGE_BITMAP failed.\n", ext);
else ok(handle == NULL, "LoadImage(%s) as IMAGE_BITMAP succeeded incorrectly.\n", ext);
error = GetLastError(); error = GetLastError();
ok(error == 0 || ok(error == 0 ||
error == 0xdeadbeef, /* Win9x, WinMe */ error == 0xdeadbeef, /* Win9x, WinMe */
"Last error: %u\n", error); "Last error: %u\n", error);
if (handle != NULL) DeleteObject(handle);
if (expect_success) {
ok(handle != NULL, "LoadImage(%s) as IMAGE_BITMAP failed.\n", ext);
if (handle != NULL) test_LoadImageBitmap(handle);
}
else ok(handle == NULL, "LoadImage(%s) as IMAGE_BITMAP succeeded incorrectly.\n", ext);
if (handle != NULL) DeleteObject(handle);
DeleteFileA(filename); DeleteFileA(filename);
} }
@ -994,14 +1029,6 @@ static HICON create_test_icon(HDC hdc, int width, int height, int bpp,
return CreateIconIndirect(&iconInfo); return CreateIconIndirect(&iconInfo);
} }
static BOOL color_match(COLORREF a, COLORREF b)
{
/* 5-bit accuracy is a sufficient test. This will match, so long as
* colors are never truncated to less that 3x5-bit accuracy i.e.
* paletized. */
return (a & 0x00F8F8F8) == (b & 0x00F8F8F8);
}
static void check_alpha_draw(HDC hdc, BOOL drawiconex, BOOL alpha, int bpp, int line) static void check_alpha_draw(HDC hdc, BOOL drawiconex, BOOL alpha, int bpp, int line)
{ {
HICON hicon; HICON hicon;