/*
+ * ReactOS W32 Subsystem
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id$
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: GDI Color Translation Functions
#include <ddk/ntddvid.h>
#include <include/object.h>
+#include <include/palette.h>
#include "handle.h"
#define NDEBUG
ULONG CCMLastSourceColor = 0, CCMLastColorMatch = 0;
-ULONG RGBtoULONG(BYTE Red, BYTE Green, BYTE Blue)
+ULONG STDCALL RGBtoULONG(BYTE Red, BYTE Green, BYTE Blue)
{
return ((Red & 0xff) << 16) | ((Green & 0xff) << 8) | (Blue & 0xff);
}
-ULONG BGRtoULONG(BYTE Blue, BYTE Green, BYTE Red)
+ULONG STDCALL BGRtoULONG(BYTE Blue, BYTE Green, BYTE Red)
{
return ((Blue & 0xff) << 16) | ((Green & 0xff) << 8) | (Red & 0xff);
}
-static ULONG ShiftAndMask(XLATEGDI *XlateGDI, ULONG Color)
+static ULONG FASTCALL ShiftAndMask(XLATEGDI *XlateGDI, ULONG Color)
{
ULONG TranslatedColor;
// then we should cache more than one value. Same with the source.
// Takes indexed palette and a
-ULONG ClosestColorMatch(XLATEGDI *XlateGDI, ULONG SourceColor, ULONG *DestColors,
+ULONG STDCALL
+ClosestColorMatch(XLATEGDI *XlateGDI, ULONG SourceColor, ULONG *DestColors,
ULONG NumColors)
{
PVIDEO_CLUTDATA cSourceColor;
PVIDEO_CLUTDATA cDestColors;
- LONG idx = 0, i, rt;
+ LONG idx = 0;
+ ULONG i;
ULONG SourceRGB;
ULONG SourceRed, SourceGreen, SourceBlue;
- ULONG cxRed, cxGreen, cxBlue, BestMatch = 16777215;
+ ULONG cxRed, cxGreen, cxBlue, rt, BestMatch = 16777215;
// Simple cache -- only one value because we don't want to waste time
// if the colors aren't very sequential
return CCMLastColorMatch;
}
- if (PAL_BITFIELDS == XlateGDI->XlateObj.iSrcType)
+ if (PAL_BITFIELDS == XlateGDI->XlateObj.iSrcType || PAL_BGR == XlateGDI->XlateObj.iSrcType)
{
- /* FIXME: must use bitfields */
- SourceRGB = ShiftAndMask(XlateGDI, SourceColor);
- cSourceColor = (PVIDEO_CLUTDATA) &SourceRGB;
-/*
- SourceRed = (SourceColor >> 7) & 0xff;
- SourceGreen = (SourceColor >> 2) & 0xff;
- SourceBlue = (SourceColor << 3) & 0xff;
-*/
+ /* FIXME: must use bitfields */
+ SourceRGB = ShiftAndMask(XlateGDI, SourceColor);
+ cSourceColor = (PVIDEO_CLUTDATA) &SourceRGB;
}
else
{
- cSourceColor = (PVIDEO_CLUTDATA)&SourceColor;
+ cSourceColor = (PVIDEO_CLUTDATA)&SourceColor;
}
SourceRed = cSourceColor->Red;
SourceGreen = cSourceColor->Green;
SourceBlue = cSourceColor->Blue;
+
for (i=0; i<NumColors; i++)
{
cDestColors = (PVIDEO_CLUTDATA)&DestColors[i];
return idx;
}
-VOID IndexedToIndexedTranslationTable(XLATEGDI *XlateGDI, ULONG *TranslationTable,
+VOID STDCALL
+IndexedToIndexedTranslationTable(XLATEGDI *XlateGDI, ULONG *TranslationTable,
PALGDI *PalDest, PALGDI *PalSource)
{
ULONG i;
+ WINBOOL Trivial;
+ Trivial = TRUE;
for(i=0; i<PalSource->NumColors; i++)
- {
- TranslationTable[i] = ClosestColorMatch(XlateGDI, PalSource->IndexedColors[i], PalDest->IndexedColors, PalDest->NumColors);
- }
+ {
+ TranslationTable[i] = ClosestColorMatch(XlateGDI, PalSource->IndexedColors[i], PalDest->IndexedColors, PalDest->NumColors);
+ Trivial = Trivial && (TranslationTable[i] == i);
+ }
+ if (Trivial)
+ {
+ XlateGDI->XlateObj.flXlate |= XO_TRIVIAL;
+ }
}
-static VOID BitMasksFromPal(USHORT PalType, PPALGDI Palette,
+static VOID STDCALL
+BitMasksFromPal(USHORT PalType, PPALGDI Palette,
PULONG RedMask, PULONG BlueMask, PULONG GreenMask)
{
switch(PalType)
* Calculate the number of bits Mask must be shift to the left to get a
* 1 in the most significant bit position
*/
-static INT CalculateShift(ULONG Mask)
+static INT FASTCALL CalculateShift(ULONG Mask)
{
- INT Shift = 0;
+ ULONG Shift = 0;
ULONG LeftmostBit = 1 << (8 * sizeof(ULONG) - 1);
while (0 == (Mask & LeftmostBit) && Shift < 8 * sizeof(ULONG))
return Shift;
}
-XLATEOBJ *IntEngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
+XLATEOBJ * STDCALL IntEngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
HPALETTE PaletteDest, HPALETTE PaletteSource)
{
// FIXME: Add support for BGR conversions
UINT i;
NewXlate = (HPALETTE)CreateGDIHandle(sizeof( XLATEGDI ), sizeof( XLATEOBJ ));
- if( !ValidEngHandle( NewXlate ) )
- return NULL;
+ if ( !ValidEngHandle ( NewXlate ) )
+ return NULL;
XlateObj = (XLATEOBJ*) AccessUserObject( (ULONG) NewXlate );
XlateGDI = (XLATEGDI*) AccessInternalObject( (ULONG) NewXlate );
if (NULL != PaletteSource)
{
- SourcePalGDI = (PALGDI*)AccessInternalObject((ULONG)PaletteSource);
+ SourcePalGDI = PALETTE_LockPalette(PaletteSource);
+ }
+ if (PaletteDest == PaletteSource)
+ {
+ DestPalGDI = SourcePalGDI;
}
- if (NULL != PaletteDest)
+ else if (NULL != PaletteDest)
{
- DestPalGDI = (PALGDI*)AccessInternalObject((ULONG)PaletteDest);
+ DestPalGDI = PALETTE_LockPalette(PaletteDest);
}
XlateObj->iSrcType = SourcePalType;
((DestPalType == PAL_BGR) && (SourcePalType == PAL_BGR)) )
{
XlateObj->flXlate |= XO_TRIVIAL;
+ if (NULL != PaletteSource)
+ {
+ PALETTE_UnlockPalette(PaletteSource);
+ }
+ if (NULL != PaletteDest && PaletteDest != PaletteSource)
+ {
+ PALETTE_UnlockPalette(PaletteDest);
+ }
return XlateObj;
}
XlateObj->flXlate |= XO_TRIVIAL;
}
XlateGDI->UseShiftAndMask = TRUE;
+ if (NULL != PaletteSource)
+ {
+ PALETTE_UnlockPalette(PaletteSource);
+ }
+ if (NULL != PaletteDest && PaletteDest != PaletteSource)
+ {
+ PALETTE_UnlockPalette(PaletteDest);
+ }
return XlateObj;
}
// Prepare the translation table
- if( (SourcePalType == PAL_INDEXED) || (SourcePalType == PAL_RGB) )
+ if (PAL_INDEXED == SourcePalType || PAL_RGB == SourcePalType || PAL_BGR == SourcePalType)
{
XlateObj->flXlate |= XO_TABLE;
if ((SourcePalType == PAL_INDEXED) && (DestPalType == PAL_INDEXED))
// Converting from indexed to RGB
- XLATEOBJ_cGetPalette(XlateObj, XO_SRCPALETTE,
- SourcePalGDI->NumColors,
- XlateGDI->translationTable);
+ RtlCopyMemory(XlateGDI->translationTable, SourcePalGDI->IndexedColors, sizeof(ULONG) * SourcePalGDI->NumColors);
if (PAL_BITFIELDS == XlateObj->iDstType)
{
for (i = 0; i < SourcePalGDI->NumColors; i++)
}
// Source palette is RGB
- if(XlateObj->iSrcType == PAL_RGB)
+ if (PAL_RGB == XlateObj->iSrcType || PAL_BGR == XlateObj->iSrcType)
{
- if(XlateObj->iDstType == PAL_INDEXED)
+ if(PAL_INDEXED == XlateObj->iDstType)
{
// FIXME: Is this necessary? I think the driver has to call this
// function anyways if pulXlate is NULL and Dest is PAL_INDEXED
// Converting from RGB to indexed
- XLATEOBJ_cGetPalette(XlateObj, XO_DESTPALETTE, DestPalGDI->NumColors, XlateGDI->translationTable);
+ RtlCopyMemory(XlateGDI->translationTable, DestPalGDI->IndexedColors, sizeof(ULONG) * DestPalGDI->NumColors);
}
}
// FIXME: Add support for XO_TO_MONO
+ if (NULL != PaletteSource)
+ {
+ PALETTE_UnlockPalette(PaletteSource);
+ }
+ if (NULL != PaletteDest && PaletteDest != PaletteSource)
+ {
+ PALETTE_UnlockPalette(PaletteDest);
+ }
+
return XlateObj;
}
-VOID EngDeleteXlate(XLATEOBJ *XlateObj)
+VOID FASTCALL EngDeleteXlate(XLATEOBJ *XlateObj)
{
- HPALETTE HXlate = (HPALETTE)AccessHandleFromUserObject(XlateObj);
+ HANDLE HXlate = (HANDLE)AccessHandleFromUserObject(XlateObj);
XLATEGDI *XlateGDI = (XLATEGDI*)AccessInternalObject((ULONG)HXlate);
if(XlateGDI->translationTable!=NULL)
FreeGDIHandle((ULONG)HXlate);
}
+/*
+ * @implemented
+ */
ULONG * STDCALL
XLATEOBJ_piVector(XLATEOBJ *XlateObj)
{
return NULL;
}
+/*
+ * @unimplemented
+ */
ULONG STDCALL
XLATEOBJ_iXlate(XLATEOBJ *XlateObj,
ULONG Color)
{
PALGDI *PalGDI;
XLATEGDI *XlateGDI = (XLATEGDI*)AccessInternalObjectFromUserObject(XlateObj);
+ ULONG Closest;
// Return the original color if there's no color translation object
if(!XlateObj) return Color;
{
return ShiftAndMask(XlateGDI, Color);
} else
- if(PAL_RGB == XlateObj->iSrcType || PAL_BITFIELDS == XlateObj->iSrcType)
+ if (PAL_RGB == XlateObj->iSrcType || PAL_BGR == XlateObj->iSrcType
+ || PAL_BITFIELDS == XlateObj->iSrcType)
{
// FIXME: should we cache colors used often?
// FIXME: won't work if destination isn't indexed
// Extract the destination palette
- PalGDI = (PALGDI*)AccessInternalObject((ULONG)XlateGDI->DestPal);
+ PalGDI = PALETTE_LockPalette(XlateGDI->DestPal);
// Return closest match for the given color
- return ClosestColorMatch(XlateGDI, Color, PalGDI->IndexedColors, PalGDI->NumColors);
+ Closest = ClosestColorMatch(XlateGDI, Color, PalGDI->IndexedColors, PalGDI->NumColors);
+ PALETTE_UnlockPalette(XlateGDI->DestPal);
+ return Closest;
} else
if(XlateObj->iSrcType == PAL_INDEXED)
{
return 0;
}
+/*
+ * @implemented
+ */
ULONG STDCALL
XLATEOBJ_cGetPalette(XLATEOBJ *XlateObj,
ULONG PalOutType,
HPal = XlateGDI->DestPal;
}
- PalGDI = (PALGDI*)AccessInternalObject((ULONG)HPal);
+ PalGDI = PALETTE_LockPalette(HPal);
RtlCopyMemory(OutPal, PalGDI->IndexedColors, sizeof(ULONG)*cPal);
+ PALETTE_UnlockPalette(HPal);
return i;
}
+
+/* EOF */