[GDI32]
authorJérôme Gardou <jerome.gardou@reactos.org>
Fri, 24 Dec 2010 20:29:25 +0000 (20:29 +0000)
committerJérôme Gardou <jerome.gardou@reactos.org>
Fri, 24 Dec 2010 20:29:25 +0000 (20:29 +0000)
  - remove useless memory reallocation : the buffer size must be dword aligned, we have no way to guarantee the buffer location will be.
  - pass BITMAPINFO pointer size to NtGdiGetDIBitsInternal
[WIN32K]
  - Improve "not enough memory" check when creating a bitmap
  - use correct function to set the last error.

svn path=/trunk/; revision=50133

reactos/dll/win32/gdi32/objects/bitmap.c
reactos/subsystems/win32/win32k/objects/bitmaps.c

index 8d93036..18db05f 100644 (file)
@@ -3,6 +3,36 @@
 #define NDEBUG
 #include <debug.h>
 
+/*
+ *           DIB_BitmapInfoSize
+ *
+ * Return the size of the bitmap info structure including color table.
+ * 11/16/1999 (RJJ) lifted from wine
+ */
+
+INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO * info, WORD coloruse)
+{
+    unsigned int colors, size, masks = 0;
+
+    if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+    {
+        const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
+        colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
+        return sizeof(BITMAPCOREHEADER) + colors *
+             ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
+    }
+    else  /* assume BITMAPINFOHEADER */
+    {
+        colors = info->bmiHeader.biClrUsed;
+        if (colors > 256) colors = 256;
+        if (!colors && (info->bmiHeader.biBitCount <= 8))
+            colors = 1 << info->bmiHeader.biBitCount;
+        if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
+        size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
+        return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
+    }
+}
+
 /*
  * Return the full scan size for a bitmap.
  *
@@ -391,59 +421,40 @@ GetDIBits(
     LPBITMAPINFO lpbmi,
     UINT uUsage)
 {
-  INT Ret = 0;
-  UINT cjBmpScanSize;
-  PVOID pvSafeBits = lpvBits;
+    UINT cjBmpScanSize;
+    UINT cjInfoSize;
 
-  if (!hDC || !GdiIsHandleValid((HGDIOBJ)hDC))
-  {
-     GdiSetLastError(ERROR_INVALID_PARAMETER);
-     return Ret;
-  }
+    if (!hDC || !GdiIsHandleValid((HGDIOBJ)hDC) || !lpbmi)
+    {
+        GdiSetLastError(ERROR_INVALID_PARAMETER);
+        return 0;
+    }
 
-  cjBmpScanSize = DIB_BitmapMaxBitsSize(lpbmi, cScanLines);
+    cjBmpScanSize = DIB_BitmapMaxBitsSize(lpbmi, cScanLines);
+    cjInfoSize = DIB_BitmapInfoSize(lpbmi, uUsage);
 
-  if ( lpvBits )
-  {
-     if ( lpbmi )
-     {
+    if ( lpvBits )
+    {
         if ( lpbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
         {
-           if ( lpbmi->bmiHeader.biCompression == BI_JPEG ||
-                lpbmi->bmiHeader.biCompression == BI_PNG )
-           {
-              SetLastError(ERROR_INVALID_PARAMETER);
-              return Ret;
-           }
+            if ( lpbmi->bmiHeader.biCompression == BI_JPEG ||
+                 lpbmi->bmiHeader.biCompression == BI_PNG )
+            {
+                SetLastError(ERROR_INVALID_PARAMETER);
+                return 0;
+            }
         }
-     }
-
-     if ((ULONG)lpvBits & (sizeof(DWORD) - 1))
-     {
-         pvSafeBits = RtlAllocateHeap(RtlGetProcessHeap(), 0, cjBmpScanSize);
-         if (!pvSafeBits)
-            return Ret;
-     }
-  }
+    }
 
-  Ret = NtGdiGetDIBitsInternal(hDC,
+  return NtGdiGetDIBitsInternal(hDC,
                                hbmp,
                                uStartScan,
                                cScanLines,
-                               pvSafeBits,
+                               lpvBits,
                                lpbmi,
                                uUsage,
                                cjBmpScanSize,
-                               0);
-  if (lpvBits != pvSafeBits)
-  {
-     if (Ret)
-     {
-        RtlCopyMemory(lpvBits, pvSafeBits, cjBmpScanSize);
-     }
-     RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits);
-  }
-  return Ret;
+                               cjInfoSize);
 }
 
 /*
index c3b7e8f..8f75277 100644 (file)
@@ -170,11 +170,18 @@ NtGdiCreateBitmap(
     iFormat = BitmapFormat(cBitsPixel, BI_RGB);
 
     /* Check parameters */
-    if (iFormat == 0 || nWidth <= 0 || nWidth >= 0x8000000 || nHeight <= 0)
+    if (iFormat == 0 || nWidth <= 0 || nHeight <= 0)
     {
         DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
                 nWidth, nHeight, cBitsPixel);
-        EngSetLastError(ERROR_INVALID_PARAMETER);
+        SetLastWin32Error(ERROR_INVALID_PARAMETER);
+        return NULL;
+    }
+
+    if(WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel)*nHeight >= 0x8000000)
+    {
+        /* I just can't get enough, I just can't get enough */
+        SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
         return NULL;
     }