Dmitry Timoshkov : gdiplus: Avoid not necessary memory allocation in GdipCreateBitmapFromHICON.
Alexandre Julliard
julliard at winehq.org
Wed Jan 16 13:47:42 CST 2013
Module: wine
Branch: master
Commit: 0d0f05e523d37e9cc8d625455335868522b79aad
URL: http://source.winehq.org/git/wine.git/?a=commit;h=0d0f05e523d37e9cc8d625455335868522b79aad
Author: Dmitry Timoshkov <dmitry at baikal.ru>
Date: Wed Jan 16 17:18:30 2013 +0800
gdiplus: Avoid not necessary memory allocation in GdipCreateBitmapFromHICON.
---
dlls/gdiplus/image.c | 45 ++++++++++++---------------------------------
1 files changed, 12 insertions(+), 33 deletions(-)
diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
index b182405..bb555a8 100644
--- a/dlls/gdiplus/image.c
+++ b/dlls/gdiplus/image.c
@@ -1628,13 +1628,12 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHICON(HICON hicon, GpBitmap** bitmap)
ICONINFO iinfo;
BITMAP bm;
int ret;
- UINT width, height;
+ UINT width, height, stride;
GpRect rect;
BitmapData lockeddata;
HDC screendc;
BOOL has_alpha;
int x, y;
- BYTE *bits;
BITMAPINFOHEADER bih;
DWORD *src;
BYTE *dst_row;
@@ -1654,24 +1653,13 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHICON(HICON hicon, GpBitmap** bitmap)
}
width = bm.bmWidth;
+ height = iinfo.hbmColor ? abs(bm.bmHeight) : abs(bm.bmHeight) / 2;
+ stride = width * 4;
- if (iinfo.hbmColor)
- height = abs(bm.bmHeight);
- else /* combined bitmap + mask */
- height = abs(bm.bmHeight) / 2;
-
- bits = HeapAlloc(GetProcessHeap(), 0, 4*width*height);
- if (!bits) {
- DeleteObject(iinfo.hbmColor);
- DeleteObject(iinfo.hbmMask);
- return OutOfMemory;
- }
-
- stat = GdipCreateBitmapFromScan0(width, height, 0, PixelFormat32bppARGB, NULL, bitmap);
+ stat = GdipCreateBitmapFromScan0(width, height, stride, PixelFormat32bppARGB, NULL, bitmap);
if (stat != Ok) {
DeleteObject(iinfo.hbmColor);
DeleteObject(iinfo.hbmMask);
- HeapFree(GetProcessHeap(), 0, bits);
return stat;
}
@@ -1684,7 +1672,6 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHICON(HICON hicon, GpBitmap** bitmap)
if (stat != Ok) {
DeleteObject(iinfo.hbmColor);
DeleteObject(iinfo.hbmMask);
- HeapFree(GetProcessHeap(), 0, bits);
GdipDisposeImage((GpImage*)*bitmap);
return stat;
}
@@ -1704,14 +1691,14 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHICON(HICON hicon, GpBitmap** bitmap)
screendc = GetDC(0);
if (iinfo.hbmColor)
{
- GetDIBits(screendc, iinfo.hbmColor, 0, height, bits, (BITMAPINFO*)&bih, DIB_RGB_COLORS);
+ GetDIBits(screendc, iinfo.hbmColor, 0, height, lockeddata.Scan0, (BITMAPINFO*)&bih, DIB_RGB_COLORS);
if (bm.bmBitsPixel == 32)
{
has_alpha = FALSE;
/* If any pixel has a non-zero alpha, ignore hbmMask */
- src = (DWORD*)bits;
+ src = (DWORD*)lockeddata.Scan0;
for (x=0; x<width && !has_alpha; x++)
for (y=0; y<height && !has_alpha; y++)
if ((*src++ & 0xff000000) != 0)
@@ -1721,24 +1708,16 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHICON(HICON hicon, GpBitmap** bitmap)
}
else
{
- GetDIBits(screendc, iinfo.hbmMask, 0, height, bits, (BITMAPINFO*)&bih, DIB_RGB_COLORS);
+ GetDIBits(screendc, iinfo.hbmMask, 0, height, lockeddata.Scan0, (BITMAPINFO*)&bih, DIB_RGB_COLORS);
has_alpha = FALSE;
}
- /* copy the image data to the Bitmap */
- src = (DWORD*)bits;
- dst_row = lockeddata.Scan0;
- for (y=0; y<height; y++)
- {
- memcpy(dst_row, src, width*4);
- src += width;
- dst_row += lockeddata.Stride;
- }
-
if (!has_alpha)
{
if (iinfo.hbmMask)
{
+ BYTE *bits = HeapAlloc(GetProcessHeap(), 0, height * stride);
+
/* read alpha data from the mask */
if (iinfo.hbmColor)
GetDIBits(screendc, iinfo.hbmMask, 0, height, bits, (BITMAPINFO*)&bih, DIB_RGB_COLORS);
@@ -1760,11 +1739,13 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHICON(HICON hicon, GpBitmap** bitmap)
}
dst_row += lockeddata.Stride;
}
+
+ HeapFree(GetProcessHeap(), 0, bits);
}
else
{
/* set constant alpha of 255 */
- dst_row = bits;
+ dst_row = lockeddata.Scan0;
for (y=0; y<height; y++)
{
dst = (DWORD*)dst_row;
@@ -1782,8 +1763,6 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHICON(HICON hicon, GpBitmap** bitmap)
GdipBitmapUnlockBits(*bitmap, &lockeddata);
- HeapFree(GetProcessHeap(), 0, bits);
-
return Ok;
}
More information about the wine-cvs
mailing list