Author: tkreuzer
Date: Sat May 5 21:39:35 2012
New Revision: 56518
URL:
http://svn.reactos.org/svn/reactos?rev=56518&view=rev
Log:
[WIN32K]
Implement CreateDIBPalette(), replacing BuildDIBPalette.
It creates a palette without a handle and handles DIB_PAL_COLORS as well as
DIB_RGB_COLORS. Additionally it now handles DIB_PAL_BRUSHHACK, which is used for DIB
brushes, when DIB_PAL_COLORS is passed to CreateDIBPatternBrush(). The palette is not
created directly, but instead the indices into the DC palette are put into the palette and
the real palette is created, when the brush is realized. The latter is not yet handled.
Modified:
trunk/reactos/win32ss/gdi/ntgdi/brush.h
trunk/reactos/win32ss/gdi/ntgdi/dib.h
trunk/reactos/win32ss/gdi/ntgdi/dibobj.c
trunk/reactos/win32ss/gdi/ntgdi/palette.c
trunk/reactos/win32ss/gdi/ntgdi/palette.h
Modified: trunk/reactos/win32ss/gdi/ntgdi/brush.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/brush.h?…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/brush.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/brush.h [iso-8859-1] Sat May 5 21:39:35 2012
@@ -56,8 +56,8 @@
// DWORD dwUnknown30;
SURFACE * psurfTrg;
struct _PALETTE * ppalSurf;
-// PALETTE * ppalDC;
-// PALETTE * ppal3;
+ struct _PALETTE * ppalDC;
+ struct _PALETTE * ppalDIB;
// DWORD dwUnknown44;
BRUSH * pbrush;
FLONG flattrs;
Modified: trunk/reactos/win32ss/gdi/ntgdi/dib.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/dib.h?re…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/dib.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/dib.h [iso-8859-1] Sat May 5 21:39:35 2012
@@ -9,3 +9,5 @@
HPALETTE FASTCALL BuildDIBPalette (CONST BITMAPINFO *bmi);
BITMAPINFO* FASTCALL DIB_ConvertBitmapInfo(CONST BITMAPINFO* bmi, DWORD Usage);
VOID FASTCALL DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig);
+
+#define DIB_PAL_BRUSHHACK 3
Modified: trunk/reactos/win32ss/gdi/ntgdi/dibobj.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/dibobj.c…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/dibobj.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/dibobj.c [iso-8859-1] Sat May 5 21:39:35 2012
@@ -103,6 +103,157 @@
{ 0xff, 0xff, 0xff }
};
+PPALETTE
+NTAPI
+CreateDIBPalette(
+ _In_ const BITMAPINFO *pbmi,
+ _In_ PDC pdc,
+ _In_ ULONG iUsage)
+{
+ PPALETTE ppal;
+ ULONG i, cColors;
+
+ /* Check if the colors are indexed */
+ if (pbmi->bmiHeader.biBitCount <= 8)
+ {
+ /* We create a "full" palette */
+ cColors = 1 << pbmi->bmiHeader.biBitCount;
+
+ /* Allocate the palette */
+ ppal = PALETTE_AllocPalette(PAL_INDEXED,
+ cColors,
+ NULL,
+ 0,
+ 0,
+ 0);
+
+ /* Check if the BITMAPINFO specifies how many colors to use */
+ if (pbmi->bmiHeader.biClrUsed != 0)
+ {
+ /* This is how many colors we can actually process */
+ cColors = min(cColors, pbmi->bmiHeader.biClrUsed);
+ }
+
+ /* Check how to use the colors */
+ if (iUsage == DIB_PAL_COLORS)
+ {
+ COLORREF crColor;
+
+ /* The colors are an array of WORD indices into the DC palette */
+ PWORD pwColors = (PWORD)((PCHAR)pbmi + pbmi->bmiHeader.biSize);
+
+ /* Use the DCs palette or, if no DC is given, the default one */
+ PPALETTE ppalDC = pdc ? pdc->dclevel.ppal : gppalDefault;
+
+ /* Loop all color indices in the DIB */
+ for (i = 0; i < cColors; i++)
+ {
+ /* Get the RGB value from the DC palette, indexed by the DIB
+ color table value */
+ crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, pwColors[i]);
+ PALETTE_vSetRGBColorForIndex(ppal, i, crColor);
+ }
+ }
+ else if (iUsage == DIB_PAL_BRUSHHACK)
+ {
+ /* The colors are an array of WORD indices into the DC palette */
+ PWORD pwColors = (PWORD)((PCHAR)pbmi + pbmi->bmiHeader.biSize);
+
+ /* Loop all color indices in the DIB */
+ for (i = 0; i < cColors; i++)
+ {
+ /* Set the index directly as the RGB color, the real palette
+ containing RGB values will be calculated when the brush is
+ realized */
+ PALETTE_vSetRGBColorForIndex(ppal, i, pwColors[i]);
+ }
+
+ /* Mark the palette as a brush hack palette */
+ ppal->flFlags |= PAL_BRUSHHACK;
+ }
+ else if (iUsage == 2)
+ {
+ // FIXME: this one is undocumented
+ ASSERT(FALSE);
+ }
+ else // if (iUsage == DIB_RGB_COLORS)
+ {
+ /* The colors are an array of RGBQUAD values */
+ RGBQUAD *prgb = (RGBQUAD*)((PCHAR)pbmi + pbmi->bmiHeader.biSize);
+
+ // FIXME: do we need to handle PALETTEINDEX / PALETTERGB macro?
+
+ /* Loop all color indices in the DIB */
+ for (i = 0; i < cColors; i++)
+ {
+ /* Get the color value and translate it to a COLORREF */
+ RGBQUAD rgb = prgb[i];
+ COLORREF crColor = RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue);
+
+ /* Set the RGB value in the palette */
+ PALETTE_vSetRGBColorForIndex(ppal, i, crColor);
+ }
+ }
+ }
+ else
+ {
+ /* This is a bitfield / RGB palette */
+ ULONG flRedMask, flGreenMask, flBlueMask;
+
+ /* Check if the DIB contains bitfield values */
+ if (pbmi->bmiHeader.biCompression == BI_BITFIELDS)
+ {
+ /* Check if we have a v4/v5 header */
+ if (pbmi->bmiHeader.biSize >= sizeof(BITMAPV4HEADER))
+ {
+ /* The masks are dedicated fields in the header */
+ PBITMAPV4HEADER pbmV4Header = (PBITMAPV4HEADER)&pbmi->bmiHeader;
+ flRedMask = pbmV4Header->bV4RedMask;
+ flGreenMask = pbmV4Header->bV4GreenMask;
+ flBlueMask = pbmV4Header->bV4BlueMask;
+ }
+ else
+ {
+ /* The masks are the first 3 values in the DIB color table */
+ PDWORD pdwColors = (PVOID)((PCHAR)pbmi + pbmi->bmiHeader.biSize);
+ flRedMask = pdwColors[0];
+ flGreenMask = pdwColors[1];
+ flBlueMask = pdwColors[2];
+ }
+ }
+ else
+ {
+ /* Check what bit depth we have. Note: optimization flags are
+ calculated in PALETTE_AllocPalette() */
+ if (pbmi->bmiHeader.biBitCount == 16)
+ {
+ /* This is an RGB 555 palette */
+ flRedMask = 0x7C00;
+ flGreenMask = 0x03E0;
+ flBlueMask = 0x001F;
+ }
+ else
+ {
+ /* This is an RGB 888 palette */
+ flRedMask = 0xFF0000;
+ flGreenMask = 0x00FF00;
+ flBlueMask = 0x0000FF;
+ }
+ }
+
+ /* Allocate the bitfield palette */
+ ppal = PALETTE_AllocPalette(PAL_BITFIELDS,
+ 0,
+ NULL,
+ flRedMask,
+ flGreenMask,
+ flBlueMask);
+ }
+
+ /* We're done, return the palette */
+ return ppal;
+}
+
UINT
APIENTRY
@@ -251,7 +402,6 @@
RECT rcDst;
POINTL ptSrc;
EXLATEOBJ exlo;
- HPALETTE hpalDIB = 0;
PPALETTE ppalDIB = 0;
SourceBitmap = GreCreateBitmapEx(bmi->bmiHeader.biWidth,
@@ -280,18 +430,10 @@
}
/* Create a palette for the DIB */
- hpalDIB = BuildDIBPalette(bmi);
- if (!hpalDIB)
+ ppalDIB = CreateDIBPalette(bmi, DC, ColorUse);
+ if (!ppalDIB)
{
EngSetLastError(ERROR_NO_SYSTEM_RESOURCES);
- goto cleanup;
- }
-
- /* Lock the DIB palette */
- ppalDIB = PALETTE_ShareLockPalette(hpalDIB);
- if (!ppalDIB)
- {
- EngSetLastError(ERROR_INVALID_HANDLE);
goto cleanup;
}
@@ -323,7 +465,6 @@
cleanup:
if (ppalDIB) PALETTE_ShareUnlockPalette(ppalDIB);
- if (hpalDIB) GreDeleteObject(hpalDIB);
if(psurfSrc) SURFACE_ShareUnlockSurface(psurfSrc);
if(psurfDst) SURFACE_ShareUnlockSurface(psurfDst);
GreDeleteObject(SourceBitmap);
@@ -364,7 +505,6 @@
SIZEL SourceSize;
EXLATEOBJ exlo;
PPALETTE ppalDIB = NULL;
- HPALETTE hpalDIB = NULL;
LPBITMAPINFO pbmiSafe;
if (!Bits) return 0;
@@ -455,20 +595,11 @@
ASSERT(pSurf->ppal);
/* Create a palette for the DIB */
- hpalDIB = BuildDIBPalette(bmi);
- if (!hpalDIB)
+ ppalDIB = CreateDIBPalette(bmi, pDC, ColorUse);
+ if (!ppalDIB)
{
EngSetLastError(ERROR_NO_SYSTEM_RESOURCES);
Status = STATUS_NO_MEMORY;
- goto Exit;
- }
-
- /* Lock the DIB palette */
- ppalDIB = PALETTE_ShareLockPalette(hpalDIB);
- if (!ppalDIB)
- {
- EngSetLastError(ERROR_INVALID_HANDLE);
- Status = STATUS_UNSUCCESSFUL;
goto Exit;
}
@@ -509,7 +640,6 @@
if (pSourceSurf) EngUnlockSurface(pSourceSurf);
if (hSourceBitmap) EngDeleteSurface((HSURF)hSourceBitmap);
- if (hpalDIB) GreDeleteObject(hpalDIB);
DC_UnlockDc(pDC);
Exit2:
ExFreePool(pbmiSafe);
@@ -1118,15 +1248,7 @@
}
/* Create a palette for the DIB */
- hpalDIB = BuildDIBPalette(pbmi);
- if (!hpalDIB)
- {
- bResult = FALSE;
- goto cleanup;
- }
-
- /* Lock the DIB palette */
- ppalDIB = PALETTE_ShareLockPalette(hpalDIB);
+ ppalDIB = CreateDIBPalette(pbmi, pdc, dwUsage);
if (!ppalDIB)
{
bResult = FALSE;
@@ -1162,7 +1284,6 @@
EXLATEOBJ_vCleanup(&exlo);
cleanup:
if (ppalDIB) PALETTE_ShareUnlockPalette(ppalDIB);
- if (hpalDIB) GreDeleteObject(hpalDIB);
if (psurfTmp) SURFACE_ShareUnlockSurface(psurfTmp);
if (hbmTmp) GreDeleteObject(hbmTmp);
if (pdc) DC_UnlockDc(pdc);
@@ -1439,7 +1560,7 @@
HBITMAP res = 0;
SURFACE *bmp = NULL;
void *mapBits = NULL;
- HPALETTE hpal ;
+ PPALETTE ppalDIB;
// Fill BITMAP32 structure with DIB data
CONST BITMAPINFOHEADER *bi = &bmi->bmiHeader;
@@ -1534,33 +1655,6 @@
// hSecure = MmSecureVirtualMemory(bm.bmBits, totalSize, PAGE_READWRITE);
hSecure = (HANDLE)0x1; // HACK OF UNIMPLEMENTED KERNEL STUFF !!!!
- if (usage == DIB_PAL_COLORS)
- {
- if(dc)
- {
- PPALETTE ppalDc;
- ppalDc = PALETTE_ShareLockPalette(dc->dclevel.hpal);
- hpal = DIB_MapPaletteColors(ppalDc, bmi);
- PALETTE_ShareUnlockPalette(ppalDc);
- }
- else
- {
- /* For DIB Brushes */
- DPRINT1("FIXME: Unsupported DIB_PAL_COLORS without a DC to map
colors.\n");
- /* HACK */
- hpal = (HPALETTE) 0xFFFFFFFF;
- }
- }
- else
- {
- hpal = BuildDIBPalette(bmi);
- }
-
- if(!hpal)
- {
- DPRINT1("Error: Could not create a palette for the DIB.\n");
- goto cleanup;
- }
// Create Device Dependent Bitmap and add DIB pointer
//Size.cx = bm.bmWidth;
@@ -1598,19 +1692,12 @@
bmp->flags = API_BITMAP;
bmp->biClrImportant = bi->biClrImportant;
- /* HACK */
- if(hpal != (HPALETTE)0xFFFFFFFF)
- {
- PPALETTE ppal = PALETTE_ShareLockPalette(hpal);
-
- if (ppal)
- {
- if (bmp->ppal) PALETTE_ShareUnlockPalette(bmp->ppal);
- bmp->ppal = ppal;
- }
-
- /* Lazy delete hpal, it will be freed at surface release */
- GreDeleteObject(hpal);
+ /* Create a palette for the DIB */
+ ppalDIB = CreateDIBPalette(bmi, dc, usage);
+ if (ppalDIB)
+ {
+ if (bmp->ppal) PALETTE_ShareUnlockPalette(bmp->ppal);
+ bmp->ppal = ppalDIB;
}
// Clean up in case of errors
@@ -1774,112 +1861,6 @@
return hpal;
}
-HPALETTE
-FASTCALL
-BuildDIBPalette(CONST BITMAPINFO *bmi)
-{
- WORD bits;
- ULONG ColorCount;
- HPALETTE hpal;
- PPALETTE ppal;
- ULONG RedMask = 0, GreenMask = 0, BlueMask = 0;
- PDWORD pdwColors = (PDWORD)((PBYTE)bmi + bmi->bmiHeader.biSize);
- ULONG paletteType, i;
-
- // Determine Bits Per Pixel
- bits = bmi->bmiHeader.biBitCount;
-
- // Determine paletteType from Bits Per Pixel
- if (bits <= 8)
- {
- paletteType = PAL_INDEXED;
- RedMask = GreenMask = BlueMask = 0;
- }
- else if (bmi->bmiHeader.biCompression == BI_BITFIELDS)
- {
- paletteType = PAL_BITFIELDS;
- if (bmi->bmiHeader.biSize >= sizeof(BITMAPV4HEADER))
- {
- PBITMAPV4HEADER pV4Header = (PBITMAPV4HEADER)&bmi->bmiHeader;
- RedMask = pV4Header->bV4RedMask;
- GreenMask = pV4Header->bV4GreenMask;
- BlueMask = pV4Header->bV4BlueMask;
- }
- else
- {
- RedMask = pdwColors[0];
- GreenMask = pdwColors[1];
- BlueMask = pdwColors[2];
- }
- }
- else
- {
- paletteType = PAL_BITFIELDS;
- switch (bits)
- {
- case 16:
- paletteType |= PAL_RGB16_555;
- RedMask = 0x7C00;
- GreenMask = 0x03E0;
- BlueMask = 0x001F;
- break;
-
- case 24:
- case 32:
- paletteType |= PAL_BGR;
- RedMask = 0xFF0000;
- GreenMask = 0x00FF00;
- BlueMask = 0x0000FF;
- break;
- }
- }
-
- if (bmi->bmiHeader.biClrUsed == 0)
- {
- ColorCount = 1 << bmi->bmiHeader.biBitCount;
- }
- else
- {
- ColorCount = bmi->bmiHeader.biClrUsed;
- }
-
- if (paletteType == PAL_INDEXED)
- {
- RGBQUAD* pColors = (RGBQUAD*)((PBYTE)bmi + bmi->bmiHeader.biSize);
-
- /* Allocate a palette */
- ppal = PALETTE_AllocPalWithHandle(PAL_INDEXED,
- ColorCount,
- NULL,
- 0, 0, 0);
- if (!ppal) return NULL;
-
- /* Copy all colors */
- for (i = 0; i < ColorCount; i++)
- {
- ppal->IndexedColors[i].peRed = pColors[i].rgbRed;
- ppal->IndexedColors[i].peGreen = pColors[i].rgbGreen;
- ppal->IndexedColors[i].peBlue = pColors[i].rgbBlue;
- ppal->IndexedColors[i].peFlags = 0;
- }
-
- /* Get palette handle and unlock the palette */
- hpal = ppal->BaseObject.hHmgr;
- PALETTE_UnlockPalette(ppal);
- }
- else
- {
- ppal = PALETTE_AllocPalWithHandle(paletteType, 0,
- NULL,
- RedMask, GreenMask, BlueMask);
-
- hpal = ppal->BaseObject.hHmgr;
- PALETTE_UnlockPalette(ppal);
- }
-
- return hpal;
-}
-
/* Converts a BITMAPCOREINFO to a BITMAPINFO structure,
* or does nothing if it's already a BITMAPINFO (or V4 or V5) */
BITMAPINFO*
Modified: trunk/reactos/win32ss/gdi/ntgdi/palette.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/palette.…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/palette.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/palette.c [iso-8859-1] Sat May 5 21:39:35 2012
@@ -151,7 +151,7 @@
PALETTE_AllocPalette(
_In_ ULONG iMode,
_In_ ULONG cColors,
- _In_ PULONG pulColors,
+ _In_opt_ PULONG pulColors,
_In_ FLONG flRed,
_In_ FLONG flGreen,
_In_ FLONG flBlue)
Modified: trunk/reactos/win32ss/gdi/ntgdi/palette.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/palette.…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/palette.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/palette.h [iso-8859-1] Sat May 5 21:39:35 2012
@@ -62,7 +62,7 @@
PALETTE_AllocPalette(
_In_ ULONG iMode,
_In_ ULONG cColors,
- _In_ PULONG pulColors,
+ _In_opt_ PULONG pulColors,
_In_ FLONG flRed,
_In_ FLONG flGreen,
_In_ FLONG flBlue);
@@ -140,6 +140,16 @@
ppal->IndexedColors[ulIndex].peBlue);
}
+FORCEINLINE
+VOID
+PALETTE_vSetRGBColorForIndex(PPALETTE ppal, ULONG ulIndex, COLORREF crColor)
+{
+ if (ulIndex >= ppal->NumColors) return;
+ ppal->IndexedColors[ulIndex].peRed = GetRValue(crColor);
+ ppal->IndexedColors[ulIndex].peGreen = GetGValue(crColor);
+ ppal->IndexedColors[ulIndex].peBlue = GetBValue(crColor);
+}
+
HPALETTE
NTAPI
GreCreatePaletteInternal(