Commit c8171e02 authored by Jeff Smith's avatar Jeff Smith Committed by Alexandre Julliard

gdiplus: Fix GdipCreateBitmapFromHICON bitmap data.

parent 9341798c
......@@ -1626,12 +1626,13 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHICON(HICON hicon, GpBitmap** bitmap)
GpRect rect;
BitmapData lockeddata;
HDC screendc;
BOOL has_alpha;
int x, y;
BITMAPINFOHEADER bih;
DWORD *src;
BYTE *dst_row;
DWORD *dst;
BYTE *bits;
int mask_scanlines = 0, color_scanlines = 0;
TRACE("%p, %p\n", hicon, bitmap);
......@@ -1682,52 +1683,55 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHICON(HICON hicon, GpBitmap** bitmap)
bih.biClrUsed = 0;
bih.biClrImportant = 0;
screendc = CreateCompatibleDC(0);
GetDIBits(screendc, iinfo.hbmColor, 0, height, lockeddata.Scan0, (BITMAPINFO*)&bih, DIB_RGB_COLORS);
if (bm.bmBitsPixel == 32)
bits = heap_alloc(height * stride);
if (!bits)
{
has_alpha = FALSE;
/* If any pixel has a non-zero alpha, ignore hbmMask */
src = (DWORD*)lockeddata.Scan0;
for (y=0; y<height && !has_alpha; y++)
for (x=0; x<width && !has_alpha; x++)
if ((*src++ & 0xff000000) != 0)
has_alpha = TRUE;
DeleteObject(iinfo.hbmColor);
DeleteObject(iinfo.hbmMask);
GdipBitmapUnlockBits(*bitmap, &lockeddata);
GdipDisposeImage(&(*bitmap)->image);
return OutOfMemory;
}
else has_alpha = FALSE;
if (!has_alpha)
screendc = CreateCompatibleDC(0);
if (screendc)
{
BYTE *bits = heap_alloc(height * stride);
/* read alpha data from the mask - the mask can safely be assumed to exist */
GetDIBits(screendc, iinfo.hbmMask, 0, height, bits, (BITMAPINFO*)&bih, DIB_RGB_COLORS);
color_scanlines = GetDIBits(screendc, iinfo.hbmColor, 0, height, lockeddata.Scan0,
(BITMAPINFO*)&bih, DIB_RGB_COLORS);
mask_scanlines = GetDIBits(screendc, iinfo.hbmMask, 0, height, bits,
(BITMAPINFO*)&bih, DIB_RGB_COLORS);
DeleteDC(screendc);
}
src = (DWORD*)bits;
dst_row = lockeddata.Scan0;
for (y=0; y<height; y++)
{
dst = (DWORD*)dst_row;
for (x=0; x<width; x++)
{
DWORD src_value = *src++;
if (src_value)
*dst++ = 0;
else
*dst++ |= 0xff000000;
}
dst_row += lockeddata.Stride;
}
DeleteObject(iinfo.hbmColor);
DeleteObject(iinfo.hbmMask);
if (!screendc || ((color_scanlines == 0 || mask_scanlines == 0) &&
GetLastError() == ERROR_INVALID_PARAMETER))
{
heap_free(bits);
GdipBitmapUnlockBits(*bitmap, &lockeddata);
GdipDisposeImage(&(*bitmap)->image);
return GenericError;
}
DeleteDC(screendc);
src = (DWORD*)bits;
dst_row = lockeddata.Scan0;
for (y=0; y<height; y++)
{
dst = (DWORD*)dst_row;
for (x=0; x<width; x++)
{
DWORD src_value = *src++;
if (src_value)
*dst++ = 0;
else
*dst++ |= 0xff000000;
}
dst_row += lockeddata.Stride;
}
DeleteObject(iinfo.hbmColor);
DeleteObject(iinfo.hbmMask);
heap_free(bits);
GdipBitmapUnlockBits(*bitmap, &lockeddata);
......
......@@ -120,7 +120,6 @@ static void expect_bitmap_locked_data(GpBitmap *bitmap, const BYTE *expect_bits,
ok_(__FILE__, line)(lockeddata.Stride == stride, "Expected %d, got %d\n", stride, lockeddata.Stride);
ok_(__FILE__, line)(lockeddata.PixelFormat == PixelFormat32bppARGB,
"Expected %d, got %d\n", PixelFormat32bppARGB, lockeddata.PixelFormat);
todo_wine
ok_(__FILE__, line)(!memcmp(expect_bits, lockeddata.Scan0, lockeddata.Height * lockeddata.Stride),
"data mismatch\n");
GdipBitmapUnlockBits(bitmap, &lockeddata);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment