Author: hbelusca
Date: Tue Dec 15 02:54:24 2015
New Revision: 70349

URL: http://svn.reactos.org/svn/reactos?rev=70349&view=rev
Log:
[CLIPBRD]
Fix the computation of where bitmap pixels start, depending on whether we are 
dealing with DIBs or DIBs version 5+ (depending on the header BITMAPINFOHEADER 
or BITMAPV5HEADER etc...).
I also noticed a bug in Windows that few other people already discovered, 
related to the automatic conversion of CF_DIBV5/CF_BITMAP to CF_DIB clipboard 
format. See the comment in the code.
CORE-10679

Modified:
    trunk/reactos/base/applications/clipbrd/winutils.c

Modified: trunk/reactos/base/applications/clipbrd/winutils.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/clipbrd/winutils.c?rev=70349&r1=70348&r2=70349&view=diff
==============================================================================
--- trunk/reactos/base/applications/clipbrd/winutils.c  [iso-8859-1] (original)
+++ trunk/reactos/base/applications/clipbrd/winutils.c  [iso-8859-1] Tue Dec 15 
02:54:24 2015
@@ -16,7 +16,7 @@
     dwError = GetLastError();
 
     FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
-                   NULL, dwError, 0, (LPWSTR)&lpMsgBuf, 0,  NULL);
+                   NULL, dwError, 0, (LPWSTR)&lpMsgBuf, 0, NULL);
     MessageBoxW(hwndParent, lpMsgBuf, NULL, MB_OK | MB_ICONERROR);
     LocalFree(lpMsgBuf);
 }
@@ -102,8 +102,9 @@
 {
     LPBITMAPINFOHEADER lpInfoHeader;
     LPBYTE lpBits;
+    LONG bmWidth, bmHeight;
+    DWORD dwPalSize = 0;
     HGLOBAL hGlobal;
-    INT iPalSize;
 
     hGlobal = GetClipboardData(uFormat);
     if (!hGlobal)
@@ -113,18 +114,96 @@
     if (!lpInfoHeader)
         return;
 
-    if (lpInfoHeader->biBitCount < 16)
-    {
-        iPalSize = (1 << lpInfoHeader->biBitCount) * 4;
+    if (lpInfoHeader->biSize == sizeof(BITMAPCOREHEADER))
+    {
+        LPBITMAPCOREHEADER lpCoreHeader = (LPBITMAPCOREHEADER)lpInfoHeader;
+
+        dwPalSize = 0;
+
+        if (lpCoreHeader->bcBitCount <= 8)
+        {
+            dwPalSize = (1 << lpCoreHeader->bcBitCount);
+
+            if (fuColorUse == DIB_RGB_COLORS)
+                dwPalSize *= sizeof(RGBTRIPLE);
+            else
+                dwPalSize *= sizeof(WORD);
+        }
+
+        bmWidth  = lpCoreHeader->bcWidth;
+        bmHeight = lpCoreHeader->bcHeight;
+    }
+    else if ((lpInfoHeader->biSize == sizeof(BITMAPINFOHEADER)) ||
+             (lpInfoHeader->biSize == sizeof(BITMAPV4HEADER))   ||
+             (lpInfoHeader->biSize == sizeof(BITMAPV5HEADER)))
+    {
+        dwPalSize = lpInfoHeader->biClrUsed;
+
+        if ((dwPalSize == 0) && (lpInfoHeader->biBitCount <= 8))
+            dwPalSize = (1 << lpInfoHeader->biBitCount);
+
+        if (fuColorUse == DIB_RGB_COLORS)
+            dwPalSize *= sizeof(RGBQUAD);
+        else
+            dwPalSize *= sizeof(WORD);
+
+        if (/*(lpInfoHeader->biSize == sizeof(BITMAPINFOHEADER)) &&*/
+            (lpInfoHeader->biCompression == BI_BITFIELDS))
+        {
+            dwPalSize += 3 * sizeof(DWORD);
+        }
+
+        /*
+         * This is a (disabled) hack for Windows, when uFormat == CF_DIB
+         * it needs yet another extra 3 DWORDs, in addition to the
+         * ones already taken into account in via the compression.
+         * This problem doesn't happen when uFormat == CF_DIBV5
+         * (in that case, when compression is taken into account,
+         * everything is nice).
+         *
+         * NOTE 1: This fix is only for us, because when one pastes DIBs
+         * directly in apps, the bitmap offset problem is still present.
+         *
+         * NOTE 2: The problem can be seen with Windows' clipbrd.exe if
+         * one copies a CF_DIB image in the clipboard. By default Windows'
+         * clipbrd.exe works with CF_DIBV5 and CF_BITMAP, so the problem
+         * is unseen, and the clipboard doesn't have to convert to CF_DIB.
+         *
+         * FIXME: investigate!!
+         * ANSWER: this is a Windows bug; part of the answer is there:
+         * 
http://go4answers.webhost4life.com/Help/bug-clipboard-format-conversions-28724.aspx
+         * May be related:
+         * http://blog.talosintel.com/2015/10/dangerous-clipboard.html
+         */
+#if 0
+        if ((lpInfoHeader->biSize == sizeof(BITMAPINFOHEADER)) &&
+            (lpInfoHeader->biCompression == BI_BITFIELDS))
+        {
+            dwPalSize += 3 * sizeof(DWORD);
+        }
+#endif
+
+        bmWidth  = lpInfoHeader->biWidth;
+        bmHeight = lpInfoHeader->biHeight;
     }
     else
     {
-        iPalSize = 0;
-    }
-
-    lpBits = (LPBYTE)lpInfoHeader + lpInfoHeader->biSize + iPalSize;
-
-    SetDIBitsToDevice(hdc, XDest, YDest, lpInfoHeader->biWidth, 
lpInfoHeader->biHeight, XSrc, YSrc, uStartScan, lpInfoHeader->biHeight, lpBits, 
(LPBITMAPINFO)lpInfoHeader, fuColorUse);
+        /* Invalid format */
+        GlobalUnlock(hGlobal);
+        return;
+    }
+
+    lpBits = (LPBYTE)lpInfoHeader + lpInfoHeader->biSize + dwPalSize;
+
+    SetDIBitsToDevice(hdc,
+                      XDest, YDest,
+                      bmWidth, bmHeight,
+                      XSrc, YSrc,
+                      uStartScan,
+                      bmHeight,
+                      lpBits,
+                      (LPBITMAPINFO)lpInfoHeader,
+                      fuColorUse);
 
     GlobalUnlock(hGlobal);
 }


Reply via email to