Author: khornicek
Date: Wed Apr 28 14:39:22 2010
New Revision: 47054
URL:
http://svn.reactos.org/svn/reactos?rev=47054&view=rev
Log:
[WIN32K]
- Bring support from RLE compressed bitmaps from trunk.
- Merge the 4bpp and 8bpp decompress functions to one generic function to avoid code
duplication and to reduce code complexity.
- Fixes missing icons in Wordpad toolbars, missing reactos logo bitmap in shell about
dialog and more.
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/win3…
==============================================================================
--- 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 Apr 28
14:39:22 2010
@@ -13,6 +13,13 @@
#include <debug.h>
/* PRIVATE FUNCTIONS *********************************************************/
+
+enum Rle_EscapeCodes
+{
+ RLE_EOL = 0, /* End of line */
+ RLE_END = 1, /* End of bitmap */
+ RLE_DELTA = 2 /* Delta */
+};
ULONG
NTAPI
@@ -118,6 +125,83 @@
return ((bmWidth * bpp + 15) & ~15) >> 3;
}
+VOID DecompressBitmap(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG
Delta, ULONG Format)
+{
+ INT x = 0;
+ INT y = Size.cy - 1;
+ INT c;
+ INT length;
+ INT width;
+ INT height = Size.cy - 1;
+ BYTE *begin = CompressedBits;
+ BYTE *bits = CompressedBits;
+ BYTE *temp;
+ INT shift;
+
+ switch (Format)
+ {
+ case BMF_4RLE:
+ shift = 1;
+ break;
+ case BMF_8RLE:
+ shift = 0;
+ break;
+ default:
+ DPRINT1("Unsupported RLE format 0x%x\n", Format);
+ return;
+ }
+
+ width = ((Size.cx + shift) >> shift);
+
+ while (y >= 0)
+ {
+ length = (*bits++) >> shift;
+ if (length)
+ {
+ c = *bits++;
+ while (length--)
+ {
+ if (x >= width) break;
+ temp = UncompressedBits + (((height - y) * Delta) + x);
+ x++;
+ *temp = c;
+ }
+ }
+ else
+ {
+ length = *bits++;
+ switch (length)
+ {
+ case RLE_EOL:
+ x = 0;
+ y--;
+ break;
+ case RLE_END:
+ return;
+ case RLE_DELTA:
+ x += (*bits++) >> shift;
+ y -= (*bits++) >> shift;
+ break;
+ default:
+ length = length >> shift;
+ while (length--)
+ {
+ c = *bits++;
+ if (x < width)
+ {
+ temp = UncompressedBits + (((height - y) * Delta) + x);
+ x++;
+ *temp = c;
+ }
+ }
+ if ((bits - begin) & 1)
+ {
+ bits++;
+ }
+ }
+ }
+ }
+}
/* PUBLIC FUNCTIONS **********************************************************/
@@ -142,16 +226,6 @@
/* Save a handle to it */
hSurface = pSurface->BaseObject.hHmgr;
- /* Check the format */
- if (Format == BMF_4RLE || Format == BMF_8RLE)
- {
- DPRINT1("Bitmaps with format 0x%x aren't supported yet!\n",
Format);
-
- /* Cleanup and exit */
- GDIOBJ_FreeObjByHandle(hSurface, GDI_OBJECT_TYPE_BITMAP);
- return 0;
- }
-
/* Initialize SURFOBJ */
pSurfObj = &pSurface->SurfObj;
@@ -160,32 +234,57 @@
pSurfObj->iType = STYPE_BITMAP;
pSurfObj->fjBitmap = Flags & (BMF_TOPDOWN | BMF_NOZEROINIT);
- /* Calculate byte width automatically if it was not provided */
- if (Width == 0)
- Width = BITMAP_GetWidthBytes(Size.cx, BitsPerFormat(Format));
-
- pSurfObj->lDelta = abs(Width);
- pSurfObj->cjBits = pSurfObj->lDelta * Size.cy;
-
- if (!Bits)
- {
- /* Allocate memory for bitmap bits */
- pSurfObj->pvBits = EngAllocMem(0 != (Flags & BMF_NOZEROINIT) ? 0 :
FL_ZERO_MEMORY,
- pSurfObj->cjBits,
- TAG_DIB);
- if (!pSurfObj->pvBits)
+ /* Check the format */
+ if (Format == BMF_4RLE || Format == BMF_8RLE)
+ {
+ PVOID UncompressedBits;
+ pSurfObj->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format));
+ pSurfObj->cjBits = pSurfObj->lDelta * Size.cy;
+
+ UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pSurfObj->cjBits, TAG_DIB);
+ if(!UncompressedBits)
{
/* Cleanup and exit */
GDIOBJ_FreeObjByHandle(hSurface, GDI_OBJECT_TYPE_BITMAP);
return 0;
}
-
+ if(Bits)
+ {
+ DecompressBitmap(Size, (BYTE *)Bits, (BYTE *)UncompressedBits,
pSurfObj->lDelta, Format);
+ }
+ pSurfObj->pvBits = UncompressedBits;
+ Format = (Format == BMF_4RLE)? BMF_4BPP : BMF_8BPP;
/* Indicate we allocated memory ourselves */
pSurface->ulFlags |= SRF_BITSALLOCD;
}
else
{
- pSurfObj->pvBits = Bits;
+ /* Calculate byte width automatically if it was not provided */
+ if (Width == 0)
+ Width = BITMAP_GetWidthBytes(Size.cx, BitsPerFormat(Format));
+ pSurfObj->lDelta = abs(Width);
+ pSurfObj->cjBits = pSurfObj->lDelta * Size.cy;
+
+ if (!Bits)
+ {
+ /* Allocate memory for bitmap bits */
+ pSurfObj->pvBits = EngAllocMem(0 != (Flags & BMF_NOZEROINIT) ? 0 :
FL_ZERO_MEMORY,
+ pSurfObj->cjBits,
+ TAG_DIB);
+ if (!pSurfObj->pvBits)
+ {
+ /* Cleanup and exit */
+ GDIOBJ_FreeObjByHandle(hSurface, GDI_OBJECT_TYPE_BITMAP);
+ return 0;
+ }
+
+ /* Indicate we allocated memory ourselves */
+ pSurface->ulFlags |= SRF_BITSALLOCD;
+ }
+ else
+ {
+ pSurfObj->pvBits = Bits;
+ }
}
pSurfObj->pvScan0 = pSurfObj->pvBits;