gdiplus: Avoid not necessary memory allocation in GdipCreateBitmapFromHICON.

Dmitry Timoshkov dmitry at baikal.ru
Wed Jan 16 03:18:30 CST 2013


---
 dlls/gdiplus/image.c | 45 ++++++++++++---------------------------------
 1 file 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;
 }
 
-- 
1.8.0.2




More information about the wine-patches mailing list