[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