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.
This commit is contained in:
Vincent Povirk 2009-12-12 17:13:39 -06:00 committed by Alexandre Julliard
parent 9823c23927
commit 3424dac386
2 changed files with 39 additions and 11 deletions

View File

@ -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;
}
retval = GdipCreateBitmapFromScan0(bm.bmWidth, bm.bmHeight, 0,
format, NULL, bitmap);
if (retval == Ok)
{
retval = GdipBitmapLockBits(*bitmap, NULL, ImageLockModeWrite,
format, &lockeddata);
if (retval == Ok)
{
if (bm.bmBits)
bits = (BYTE*)bm.bmBits + (bm.bmHeight - 1) * bm.bmWidthBytes;
{
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");
bits = NULL;
}
retval = GdipCreateBitmapFromScan0(bm.bmWidth, bm.bmHeight, -bm.bmWidthBytes,
format, bits, bitmap);
GdipBitmapUnlockBits(*bitmap, &lockeddata);
}
}
return retval;
}

View File

@ -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");