Commit 3424dac3 authored by Vincent Povirk's avatar Vincent Povirk Committed by Alexandre Julliard

gdiplus: Explicitly copy the bits from dib sections to new bitmaps.

On Windows, GdipCreateBitmapFromHBITMAP creates a copy of the bitmap, not a reference. Currently, we match this behavior, but this is only because we cannot yet create bitmap objects that reference existing memory. If GdipCreateBitmapFromScan0 were fixed to do this, FromHBITMAP would break. Therefore, we always pass NULL to FromScan0 so that it allocates new memory for the bitmap.
parent 9823c239
......@@ -2659,7 +2659,8 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHBITMAP(HBITMAP hbm, HPALETTE hpal, GpBi
BITMAP bm;
GpStatus retval;
PixelFormat format;
BYTE* bits;
BitmapData lockeddata;
INT y;
TRACE("%p %p %p\n", hbm, hpal, bitmap);
......@@ -2700,16 +2701,32 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHBITMAP(HBITMAP hbm, HPALETTE hpal, GpBi
return InvalidParameter;
}
if (bm.bmBits)
bits = (BYTE*)bm.bmBits + (bm.bmHeight - 1) * bm.bmWidthBytes;
else
retval = GdipCreateBitmapFromScan0(bm.bmWidth, bm.bmHeight, 0,
format, NULL, bitmap);
if (retval == Ok)
{
FIXME("can only get image data from DIB sections\n");
bits = NULL;
}
retval = GdipBitmapLockBits(*bitmap, NULL, ImageLockModeWrite,
format, &lockeddata);
if (retval == Ok)
{
if (bm.bmBits)
{
for (y=0; y<bm.bmHeight; y++)
{
memcpy((BYTE*)lockeddata.Scan0+lockeddata.Stride*y,
(BYTE*)bm.bmBits+bm.bmWidthBytes*(bm.bmHeight-1-y),
bm.bmWidthBytes);
}
}
else
{
FIXME("can only get image data from DIB sections\n");
}
retval = GdipCreateBitmapFromScan0(bm.bmWidth, bm.bmHeight, -bm.bmWidthBytes,
format, bits, bitmap);
GdipBitmapUnlockBits(*bitmap, &lockeddata);
}
}
return retval;
}
......
......@@ -465,6 +465,7 @@ static void test_GdipCreateBitmapFromHBITMAP(void)
const REAL HEIGHT2 = 20;
HDC hdc;
BITMAPINFO bmi;
BYTE *bits;
stat = GdipCreateBitmapFromHBITMAP(NULL, NULL, NULL);
expect(InvalidParameter, stat);
......@@ -504,16 +505,26 @@ static void test_GdipCreateBitmapFromHBITMAP(void)
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biCompression = BI_RGB;
hbm = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, NULL, NULL, 0);
hbm = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
ok(hbm != NULL, "CreateDIBSection failed\n");
bits[0] = 0;
stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
expect(Ok, stat);
expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
expectf(WIDTH1, width);
expectf(HEIGHT1, height);
if (stat == Ok)
{
/* test whether writing to the bitmap affects the original */
stat = GdipBitmapSetPixel(gpbm, 0, 0, 0xffffffff);
expect(Ok, stat);
expect(0, bits[0]);
GdipDisposeImage((GpImage*)gpbm);
}
LogPal = GdipAlloc(sizeof(LOGPALETTE));
ok(LogPal != NULL, "unable to allocate LOGPALETTE\n");
......
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