[WIN32K]
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Sun, 3 Jan 2016 16:16:04 +0000 (16:16 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Sun, 3 Jan 2016 16:16:04 +0000 (16:16 +0000)
NtGdiCreateDIBitmapInternal: clear CBM_INIT flag, if no bits are given.
IntSetDIBits: Always calculate the bitmap size for uncompressed bitmaps, do not pass uncompressed bits to GreCreateBitmapEx, since they don't have the required alignment (the width in bytes for DIB is 16 bit aligned, bitmaps 32).
Remove a broken ASSERT.

svn path=/trunk/; revision=70482

reactos/win32ss/gdi/ntgdi/bitmaps.c
reactos/win32ss/gdi/ntgdi/bitmaps.h
reactos/win32ss/gdi/ntgdi/dibobj.c

index e4c8a22..13d5a78 100644 (file)
@@ -42,15 +42,15 @@ GreSetBitmapOwner(
     return GreSetObjectOwner(hbmp, ulOwner);
 }
 
-static
-int
+BOOL
 NTAPI
 UnsafeSetBitmapBits(
-    PSURFACE psurf,
-    IN ULONG cjBits,
-    IN PVOID pvBits)
+    _Inout_ PSURFACE psurf,
+    _In_ ULONG cjBits,
+    _In_ const VOID *pvBits)
 {
-    PUCHAR pjDst, pjSrc;
+    PUCHAR pjDst;
+    const UCHAR *pjSrc;
     LONG lDeltaDst, lDeltaSrc;
     ULONG nWidth, nHeight, cBitsPixel;
     NT_ASSERT(psurf->flags & API_BITMAP);
@@ -69,7 +69,7 @@ UnsafeSetBitmapBits(
 
     /* Make sure the buffer is large enough*/
     if (cjBits < (lDeltaSrc * nHeight))
-        return 0;
+        return FALSE;
 
     while (nHeight--)
     {
@@ -79,7 +79,7 @@ UnsafeSetBitmapBits(
         pjDst += lDeltaDst;
     }
 
-    return 1;
+    return TRUE;
 }
 
 HBITMAP
index 96c2611..3ef00c2 100644 (file)
@@ -43,3 +43,10 @@ GreCreateDIBitmapInternal(
     IN FLONG fl,
     IN UINT cjMaxBits,
     IN HANDLE hcmXform);
+
+BOOL
+NTAPI
+UnsafeSetBitmapBits(
+    _Inout_ PSURFACE psurf,
+    _In_ ULONG cjBits,
+    _In_ const VOID *pvBits);
index 36bfa4d..bd7999a 100644 (file)
@@ -260,23 +260,26 @@ IntSetDIBits(
     EXLATEOBJ  exlo;
     PPALETTE    ppalDIB = 0;
     ULONG cjSizeImage;
+    BOOL bCompressed;
 
-    if (!bmi) return 0;
+    if (!bmi || !Bits) return 0;
 
-    /* Check if the header provided an image size */
-    if (bmi->bmiHeader.biSizeImage != 0)
-    {
-        /* Use the given size */
-        cjSizeImage = bmi->bmiHeader.biSizeImage;
-    }
-    /* Otherwise check for uncompressed formats */
-    else if ((bmi->bmiHeader.biCompression == BI_RGB) ||
+    /* Check for uncompressed formats */
+    if ((bmi->bmiHeader.biCompression == BI_RGB) ||
              (bmi->bmiHeader.biCompression == BI_BITFIELDS))
     {
         /* Calculate the image size */
         cjSizeImage = DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth,
                                            ScanLines,
                                            bmi->bmiHeader.biBitCount);
+        bCompressed = FALSE;
+    }
+    /* Check if the header provided an image size */
+    else if (bmi->bmiHeader.biSizeImage != 0)
+    {
+        /* Use the given size */
+        cjSizeImage = bmi->bmiHeader.biSizeImage;
+        bCompressed = TRUE;
     }
     else
     {
@@ -293,6 +296,8 @@ IntSetDIBits(
         return 0;
     }
 
+    /* We cannot use the provided buffer for uncompressed bits, since they
+       might not be aligned correctly! */
     SourceBitmap = GreCreateBitmapEx(bmi->bmiHeader.biWidth,
                                      ScanLines,
                                      0,
@@ -300,7 +305,7 @@ IntSetDIBits(
                                                   bmi->bmiHeader.biCompression),
                                      bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
                                      cjSizeImage,
-                                     (PVOID)Bits,
+                                     bCompressed ? (PVOID)Bits : NULL,
                                      0);
     if (!SourceBitmap)
     {
@@ -318,6 +323,17 @@ IntSetDIBits(
         goto cleanup;
     }
 
+    /* Check for uncompressed bits */
+    if (!bCompressed)
+    {
+        /* Copy the bitmap bits */
+        if (!UnsafeSetBitmapBits(psurfSrc, cjMaxBits, Bits))
+        {
+            DPRINT1("Error: Could not set bitmap bits\n");
+            goto cleanup;
+        }
+    }
+
     /* Create a palette for the DIB */
     ppalDIB = CreateDIBPalette(bmi, DC, ColorUse);
     if (!ppalDIB)
@@ -341,8 +357,6 @@ IntSetDIBits(
     ptSrc.x = 0;
     ptSrc.y = 0;
 
-    NT_ASSERT(psurfSrc->SurfObj.cjBits <= cjMaxBits);
-
     result = IntEngCopyBits(&psurfDst->SurfObj,
                             &psurfSrc->SurfObj,
                             NULL,
@@ -1456,6 +1470,11 @@ NtGdiCreateDIBitmapInternal(
     PBYTE safeBits = NULL;
     HBITMAP hbmResult = NULL;
 
+    if (pjInit == NULL)
+    {
+        fInit &= ~CBM_INIT;
+    }
+
     if(pjInit && (fInit & CBM_INIT))
     {
         if (cjMaxBits == 0) return NULL;