update for HEAD-2003091401
[reactos.git] / subsys / win32k / eng / xlate.c
index 00a4f63..e797b34 100644 (file)
@@ -1,4 +1,23 @@
 /*
+ *  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
@@ -15,6 +34,7 @@
 #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;
 
@@ -61,15 +81,17 @@ static ULONG ShiftAndMask(XLATEGDI *XlateGDI, ULONG Color)
 // 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
@@ -79,24 +101,20 @@ ULONG ClosestColorMatch(XLATEGDI *XlateGDI, ULONG SourceColor, ULONG *DestColors
     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];
@@ -123,18 +141,27 @@ ULONG ClosestColorMatch(XLATEGDI *XlateGDI, ULONG SourceColor, ULONG *DestColors
   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)
@@ -161,9 +188,9 @@ static VOID BitMasksFromPal(USHORT PalType, PPALGDI Palette,
  * 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))
@@ -175,7 +202,7 @@ static INT CalculateShift(ULONG Mask)
    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
@@ -190,8 +217,8 @@ XLATEOBJ *IntEngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
   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 );
@@ -200,11 +227,15 @@ XLATEOBJ *IntEngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
 
   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;
@@ -239,6 +270,14 @@ XLATEOBJ *IntEngCreateXlate(USHORT DestPalType, USHORT 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;
   }
 
@@ -253,11 +292,19 @@ XLATEOBJ *IntEngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
       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))
@@ -289,9 +336,7 @@ XLATEOBJ *IntEngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
 
         // 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++)
@@ -305,25 +350,34 @@ XLATEOBJ *IntEngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
   }
 
   // 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)
@@ -334,6 +388,9 @@ VOID EngDeleteXlate(XLATEOBJ *XlateObj)
   FreeGDIHandle((ULONG)HXlate);
 }
 
+/*
+ * @implemented
+ */
 ULONG * STDCALL
 XLATEOBJ_piVector(XLATEOBJ *XlateObj)
 {
@@ -347,12 +404,16 @@ 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;
@@ -365,16 +426,19 @@ XLATEOBJ_iXlate(XLATEOBJ *XlateObj,
   {
     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)
   {
@@ -384,6 +448,9 @@ XLATEOBJ_iXlate(XLATEOBJ *XlateObj,
   return 0;
 }
 
+/*
+ * @implemented
+ */
 ULONG STDCALL
 XLATEOBJ_cGetPalette(XLATEOBJ *XlateObj,
                     ULONG PalOutType,
@@ -406,8 +473,11 @@ XLATEOBJ_cGetPalette(XLATEOBJ *XlateObj,
     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 */