[ros-diffs] [fireball] 45810: - GetBitmapBits and SetBitmapBits should get/set bitmaps bits in a particular format described in MSDN, not in the format they are stored in internally. Reimplement them based on winex11.drv implementation. Could use some optimisation, but they are deprecated non time-critical functions. Thanks to Maarten Kroese for finding this problem. Fixes issue #28 in Arwinss wiki.

fireball at svn.reactos.org fireball at svn.reactos.org
Wed Mar 3 23:33:50 CET 2010


Author: fireball
Date: Wed Mar  3 23:33:50 2010
New Revision: 45810

URL: http://svn.reactos.org/svn/reactos?rev=45810&view=rev
Log:
- GetBitmapBits and SetBitmapBits should get/set bitmaps bits in a particular format described in MSDN, not in the format they are stored in internally. Reimplement them based on winex11.drv implementation. Could use some optimisation, but they are deprecated non time-critical functions. Thanks to Maarten Kroese for finding this problem. Fixes issue #28 in Arwinss wiki.

Modified:
    branches/arwinss/reactos/subsystems/win32/win32k/gre/surfobj.c

Modified: branches/arwinss/reactos/subsystems/win32/win32k/gre/surfobj.c
URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/gre/surfobj.c?rev=45810&r1=45809&r2=45810&view=diff
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/gre/surfobj.c [iso-8859-1] (original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/gre/surfobj.c [iso-8859-1] Wed Mar  3 23:33:50 2010
@@ -257,27 +257,224 @@
 LONG FASTCALL
 GreGetBitmapBits(PSURFACE pSurf, ULONG ulBytes, PVOID pBits)
 {
-    /* Don't copy more bytes than the buffer has */
-    ulBytes = min(ulBytes, pSurf->SurfObj.cjBits);
-
-    /* Copy actual bits */
-    RtlCopyMemory(pBits, pSurf->SurfObj.pvBits, ulBytes);
-
-    /* Return amount copied */
+    LONG height, width, bytewidth;
+    LPBYTE tbuf, startline;
+    int h, w;
+    COLORREF cr;
+    PFN_DIB_GetPixel DibGetPixel;
+
+    DPRINT("(bmp=%p, buffer=%p, count=0x%x)\n", pSurf, pBits, ulBytes);
+
+    /* Check ulBytes */
+    if (!ulBytes) return 0;
+
+    bytewidth = pSurf->SurfObj.lDelta;
+    if (bytewidth < 0) bytewidth = -bytewidth;
+
+    height = ulBytes / bytewidth;
+    width = pSurf->SurfObj.sizlBitmap.cx;
+
+    /* Get getpixel routine address */
+    DibGetPixel = DibFunctionsForBitmapFormat[pSurf->SurfObj.iBitmapFormat].DIB_GetPixel;
+
+    /* copy bitmap to 16 bit padded image buffer with real bitsperpixel */
+    startline = pBits;
+    switch (BitsPerFormat(pSurf->SurfObj.iBitmapFormat))
+    {
+    case 1:
+        for (h=0;h<height;h++)
+        {
+            tbuf = startline;
+            *tbuf = 0;
+            for (w=0;w<width;w++)
+            {
+                if ((w%8) == 0)
+                    *tbuf = 0;
+                cr = DibGetPixel(&pSurf->SurfObj, w, h);
+                *tbuf |= cr<<(7-(w&7));
+                if ((w&7) == 7) ++tbuf;
+            }
+            startline += bytewidth;
+        }
+        break;
+    case 4:
+        for (h=0;h<height;h++)
+        {
+            tbuf = startline;
+            for (w=0;w<width;w++)
+            {
+                if (!(w & 1))
+                    *tbuf = DibGetPixel(&pSurf->SurfObj, w, h) << 4;
+                else
+                    *tbuf++ |= DibGetPixel(&pSurf->SurfObj, w, h) & 0x0f;
+            }
+            startline += bytewidth;
+        }
+        break;
+    case 8:
+        for (h=0;h<height;h++)
+        {
+            tbuf = startline;
+            for (w=0;w<width;w++)
+                *tbuf++ = DibGetPixel(&pSurf->SurfObj, w, h);
+            startline += bytewidth;
+        }
+        break;
+    case 15:
+    case 16:
+        for (h=0;h<height;h++)
+        {
+            tbuf = startline;
+            for (w=0;w<width;w++)
+            {
+            long pixel = DibGetPixel(&pSurf->SurfObj, w, h);
+
+            *tbuf++ = pixel & 0xff;
+            *tbuf++ = (pixel>>8) & 0xff;
+            }
+            startline += bytewidth;
+        }
+        break;
+    case 24:
+        for (h=0;h<height;h++)
+        {
+            tbuf = startline;
+            for (w=0;w<width;w++)
+            {
+                long pixel = DibGetPixel(&pSurf->SurfObj, w, h);
+
+                *tbuf++ = pixel & 0xff;
+                *tbuf++ = (pixel>> 8) & 0xff;
+                *tbuf++ = (pixel>>16) & 0xff;
+            }
+            startline += bytewidth;
+        }
+        break;
+
+    case 32:
+        for (h=0;h<height;h++)
+        {
+            tbuf = startline;
+            for (w=0;w<width;w++)
+            {
+                long pixel = DibGetPixel(&pSurf->SurfObj, w, h);
+
+                *tbuf++ = pixel & 0xff;
+                *tbuf++ = (pixel>> 8) & 0xff;
+                *tbuf++ = (pixel>>16) & 0xff;
+                *tbuf++ = (pixel>>24) & 0xff;
+            }
+            startline += bytewidth;
+        }
+        break;
+    default:
+        DPRINT1("Unhandled bits:%d\n", BitsPerFormat(pSurf->SurfObj.iBitmapFormat));
+    }
     return ulBytes;
 }
 
 LONG FASTCALL
 GreSetBitmapBits(PSURFACE pSurf, ULONG ulBytes, PVOID pBits)
 {
+    LONG height, width, bytewidth;
+    const BYTE *sbuf, *startline;
+    int h, w;
+    PFN_DIB_PutPixel DibPutPixel;
+
     /* Check ulBytes */
     if (!ulBytes) return 0;
 
-    /* Don't copy more bytes than the surface has */
-    ulBytes = min(ulBytes, pSurf->SurfObj.cjBits);
-
-    /* Copy actual bits */
-    RtlCopyMemory(pSurf->SurfObj.pvBits, pBits, ulBytes);
+    DPRINT("(bmp=%p, buffer=%p, count=0x%x)\n", pSurf, pBits, ulBytes);
+
+    bytewidth = pSurf->SurfObj.lDelta;
+    if (bytewidth < 0) bytewidth = -bytewidth;
+
+    height = ulBytes / bytewidth;
+    width = pSurf->SurfObj.sizlBitmap.cx;
+
+    /* Get getpixel routine address */
+    DibPutPixel = DibFunctionsForBitmapFormat[pSurf->SurfObj.iBitmapFormat].DIB_PutPixel;
+
+    /* copy bitmap to 16 bit padded image buffer with real bitsperpixel */
+    startline = pBits;
+    switch (BitsPerFormat(pSurf->SurfObj.iBitmapFormat))
+    {
+    case 1:
+        for (h=0;h<height;h++)
+        {
+            sbuf = startline;
+            for (w=0;w<width;w++)
+            {
+                DibPutPixel(&pSurf->SurfObj, w, h, (sbuf[0]>>(7-(w&7))) & 1);
+                if ((w&7) == 7)
+                    sbuf++;
+            }
+            startline += bytewidth;
+        }
+        break;
+    case 4:
+        for (h=0;h<height;h++)
+        {
+            sbuf = startline;
+            for (w=0;w<width;w++)
+            {
+                if (!(w & 1))
+                    DibPutPixel(&pSurf->SurfObj, w, h, *sbuf >> 4);
+                else
+                    DibPutPixel(&pSurf->SurfObj, w, h, *sbuf++ & 0xf);
+            }
+            startline += bytewidth;
+        }
+        break;
+    case 8:
+        for (h=0;h<height;h++)
+        {
+            sbuf = startline;
+            for (w=0;w<width;w++)
+                DibPutPixel(&pSurf->SurfObj, w, h, *sbuf++);
+            startline += bytewidth;
+        }
+        break;
+    case 15:
+    case 16:
+        for (h=0;h<height;h++)
+        {
+            sbuf = startline;
+            for (w=0;w<width;w++)
+            {
+                DibPutPixel(&pSurf->SurfObj, w, h, sbuf[1]*256+sbuf[0]);
+                sbuf+=2;
+            }
+            startline += bytewidth;
+        }
+        break;
+    case 24:
+        for (h=0;h<height;h++)
+        {
+            sbuf = startline;
+            for (w=0;w<width;w++)
+            {
+                DibPutPixel(&pSurf->SurfObj, w, h, (sbuf[2]<<16)+(sbuf[1]<<8)+sbuf[0]);
+                sbuf += 3;
+            }
+            startline += bytewidth;
+        }
+        break;
+    case 32:
+        for (h=0;h<height;h++)
+        {
+            sbuf = startline;
+            for (w=0;w<width;w++)
+            {
+                DibPutPixel(&pSurf->SurfObj, w, h, (sbuf[3]<<24)+(sbuf[2]<<16)+(sbuf[1]<<8)+sbuf[0]);
+                sbuf += 4;
+            }
+            startline += bytewidth;
+        }
+        break;
+    default:
+      DPRINT1("Unhandled bits:%d\n", BitsPerFormat(pSurf->SurfObj.iBitmapFormat));
+    }
 
     /* Return amount copied */
     return ulBytes;




More information about the Ros-diffs mailing list