winex11: Fix the color conversions from paletted DIBs to TrueColor pixmaps and back. Fixes the gdi32/bitmap.c test on 16bpp displays.

Francois Gouget fgouget at free.fr
Fri Nov 9 08:17:21 CST 2007


---

The core issue is that the code built a map from the DIB indices to the 
X11 colors, but then reused these X11 colors as if they were RGBQUADs. 
Obviously the two are not equivalent: for instance in 15bpp the X11 
color for white is 0x7fff and the RGBQUAD is {0xff, 0xff, 0xff, 0}.

So the code now keeps two pieces of information for each color in the 
DIB palette:
 * the X11 color
   This is used for the XPutPixel() or similar in the SetImageBits_*() 
functions.

 * an RGBQUAD representing the _X11 color_
   This is used in the GetImageBits_*() functions to match an X11 color 
(after it has been decomposed into its red, green and blue components) 
back to a DIB color index in X11DRV_DIB_GetNearestIndex().

Note that the RGBQUAD contains the color components of the actual X11 
color, not the color components of the original DIB color. The 
distinction is very important for 16bpp displays (and also for the 
uncommon RGB233 or BGR 233 displays). Here's an example that shows why. 
Let's take the following DIB color palette mapping to 16bpp X11 colors:

    Index | DIB RGB  | X11
      0   | 00,00,00 | 0000
      1   | 01,01,01 | 0000
      2   | 02,02,02 | 0000
      3   | 03,03,03 | 0000
      4   | 04,04,04 | 0020
      5   | 08,08,08 | 0841
      6   | 09,09,09 | 0841
      7   | 0c,0c,0c | 0861
 
Note that for color 4 we've lost the red and blue components because in 
16bpp mode there's only 5bits for these, while green gets blessed with 6 
bits.

So let's these pixmap pixels back to a DIB index by choosing the one 
with the closest color. Here closeness is defined as the distance 
between the two RGB triplets in three dimensional space. Here are see 
how it gets mapped back to a DIB color index. Here are the results:

   X11  | X11 RGB  | Index of Best Match
   0000 | 00,00,00 | 0
   0020 | 00,04,00 | 1 not 4!
   0841 | 08,08,08 | 5
   0061 | 08,0c,08 | 6 not 7!

Notice how (00,04,00) is closer to (01,01,01), the distance square is 11 
(1+3*3+1), than to (04,04,04) for which the distance square is 32 
(4*4+0+4*4). This leads to the paradox that although DIB color 4 is the 
only one that gets mapped to the X11 color 0020, that X11 color gets 
mapped back to another index.

This is why the code stores the X11 RGB components in the color map 
rather than the DIB ones.


The code also removes X11DRV_DIB_MapColor() because we cannot assume 
that every pixmap pixel will match one of the colors of the original DIB 
and failing with a 'Strange color' message is not good enough. It had 
one interesting optimisation though: if the DIB color still mapped to 
the current pixmap color it skipped the search. This should be extended 
to all X11DRV_DIB_GetNearestIndex() calls, except the monochrome cases 
(because whenever the pixmap is paletted we'd be better off maintaining 
a reverse color map that maps each pixmap color index to a DIB color).



 dlls/winex11.drv/dib.c    |  488 ++++++++++++++++++++++-----------------------
 dlls/winex11.drv/x11drv.h |   10 +-
 2 files changed, 245 insertions(+), 253 deletions(-)

diff --git a/dlls/winex11.drv/dib.c b/dlls/winex11.drv/dib.c
index 8fb61dd..1f4409c 100644
--- a/dlls/winex11.drv/dib.c
+++ b/dlls/winex11.drv/dib.c
@@ -70,8 +70,8 @@ typedef struct
     WORD            depth;
     WORD            infoBpp;
     WORD            compression;
-    RGBQUAD        *colorMap;
-    int             nColorMap;
+    unsigned int    nColorMap;
+    X11DRV_COLOR   *colorMap;
     Drawable        drawable;
     GC              gc;
     int             xSrc;
@@ -255,6 +255,27 @@ static int DIB_GetBitmapInfoEx( const BITMAPINFOHEADER *header, LONG *width,
     return -1;
 }
 
+/***********************************************************************
+ *           DIB_GetBitmapInfo
+ *
+ * Get the info from a bitmap header.
+ * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
+ */
+static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
+                              LONG *height, WORD *bpp, WORD *compr )
+{
+    WORD planes;
+    DWORD size;
+    
+    return DIB_GetBitmapInfoEx( header, width, height, &planes, bpp, compr, &size);    
+}
+
+
+static inline BOOL colour_is_brighter(RGBQUAD c1, RGBQUAD c2)
+{
+    return (c1.rgbRed * c1.rgbRed + c1.rgbGreen * c1.rgbGreen + c1.rgbBlue * c1.rgbBlue) > 
+        (c2.rgbRed * c2.rgbRed + c2.rgbGreen * c2.rgbGreen + c2.rgbBlue * c2.rgbBlue);
+}
 
 /***********************************************************************
  *           X11DRV_DIB_GetColorCount
@@ -285,36 +306,16 @@ static unsigned int X11DRV_DIB_GetColorCount(const BITMAPINFO *info)
 }
 
 /***********************************************************************
- *           DIB_GetBitmapInfo
+ *           X11DRV_DIB_SetColorMap
  *
- * Get the info from a bitmap header.
- * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
- */
-static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
-                              LONG *height, WORD *bpp, WORD *compr )
-{
-    WORD planes;
-    DWORD size;
-    
-    return DIB_GetBitmapInfoEx( header, width, height, &planes, bpp, compr, &size);    
-}
-
-
-static inline BOOL colour_is_brighter(RGBQUAD c1, RGBQUAD c2)
-{
-    return (c1.rgbRed * c1.rgbRed + c1.rgbGreen * c1.rgbGreen + c1.rgbBlue * c1.rgbBlue) > 
-        (c2.rgbRed * c2.rgbRed + c2.rgbGreen * c2.rgbGreen + c2.rgbBlue * c2.rgbBlue);
-}
-
-/***********************************************************************
- *           X11DRV_DIB_GenColorMap
- *
- * Fills the color map of a bitmap palette. Should not be called
- * for a >8-bit deep bitmap.
+ * Set the table mapping from DIB palette indices to X11 colors,
+ * and to the corresponding X11 RGB components.
+ * Should not be called for a non-paletted DIB.
  */
-static int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE *physDev, int *colorMapping,
-                             WORD coloruse, WORD depth, BOOL quads,
-                             const void *colorPtr, int start, int end )
+static void X11DRV_DIB_SetColorMap(X11DRV_PDEVICE *physDev, WORD pixmap_depth,
+                                   X11DRV_COLOR* colorMap, WORD coloruse,
+                                   BOOL quads, const void* srcColorMap,
+                                   int start, int end)
 {
     int i;
 
@@ -322,9 +323,8 @@ static int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE *physDev, int *colorMapping,
     {
         if (quads)
         {
-            const RGBQUAD * rgb = (const RGBQUAD *)colorPtr;
-
-            if (depth == 1)  /* Monochrome */
+            const RGBQUAD* rgb = (const RGBQUAD*)srcColorMap;
+            if (pixmap_depth == 1)  /* Monochrome */
             {
                 BOOL invert = FALSE;
                 RGBQUAD table[2];
@@ -332,23 +332,30 @@ static int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE *physDev, int *colorMapping,
                 if (GetDIBColorTable( physDev->hdc, 0, 2, table ) == 2)
                     invert = !colour_is_brighter(table[1], table[0]);
 
-                for (i = start; i < end; i++, rgb++) 
-                    colorMapping[i] = ((rgb->rgbRed + rgb->rgbGreen +
+                for (i = start; i < end; i++, rgb++)
+                {
+                    colorMap[i].x11 = ((rgb->rgbRed + rgb->rgbGreen +
                                         rgb->rgbBlue > 255*3/2 && !invert) ||
                                        (rgb->rgbRed + rgb->rgbGreen +
                                         rgb->rgbBlue <= 255*3/2 && invert));
+                    colorMap[i].c = X11DRV_PALETTE_ToLogical(colorMap[i].x11);
+                }
             }
             else
+            {
                 for (i = start; i < end; i++, rgb++)
-                    colorMapping[i] = X11DRV_PALETTE_ToPhysical( NULL, RGB(rgb->rgbRed,
-                                                                rgb->rgbGreen,
-                                                                rgb->rgbBlue));
+                {
+                    colorMap[i].x11 = X11DRV_PALETTE_ToPhysical( NULL,
+                        RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue));
+                    colorMap[i].c = X11DRV_PALETTE_ToLogical(colorMap[i].x11);
+                }
+            }
         }
         else
         {
-            const RGBTRIPLE * rgb = (const RGBTRIPLE *)colorPtr;
+            const RGBTRIPLE* rgb = (const RGBTRIPLE*)srcColorMap;
 
-            if (depth == 1)  /* Monochrome */
+            if (pixmap_depth == 1)  /* Monochrome */
             {
                 BOOL invert = FALSE;
                 RGBQUAD table[2];
@@ -357,74 +364,37 @@ static int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE *physDev, int *colorMapping,
                     invert = !colour_is_brighter(table[1], table[0]);
 
                 for (i = start; i < end; i++, rgb++)
-                    colorMapping[i] = ((rgb->rgbtRed + rgb->rgbtGreen +
+                {
+                    colorMap[i].x11 = ((rgb->rgbtRed + rgb->rgbtGreen +
                                         rgb->rgbtBlue > 255*3/2 && !invert) ||
                                        (rgb->rgbtRed + rgb->rgbtGreen +
                                         rgb->rgbtBlue <= 255*3/2 && invert));
+                    colorMap[i].c = X11DRV_PALETTE_ToLogical(colorMap[i].x11);
+                }
             }
             else
+	      {
                 for (i = start; i < end; i++, rgb++)
-                    colorMapping[i] = X11DRV_PALETTE_ToPhysical( NULL, RGB(rgb->rgbtRed,
-                                                               rgb->rgbtGreen,
-                                                               rgb->rgbtBlue));
+                {
+                    colorMap[i].x11 = X11DRV_PALETTE_ToPhysical( NULL,
+                        RGB(rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue));
+                    colorMap[i].c = X11DRV_PALETTE_ToLogical(colorMap[i].x11);
+                }
+	      }
         }
     }
-    else  /* DIB_PAL_COLORS */
+    else /* DIB_PAL_COLORS */
     {
-        const WORD * index = (const WORD *)colorPtr;
+        const WORD* index = (const WORD*)srcColorMap;
 
         for (i = start; i < end; i++, index++)
-            colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, PALETTEINDEX(*index) );
+        {
+            colorMap[i].x11 = X11DRV_PALETTE_ToPhysical( physDev, PALETTEINDEX(*index) );
+            colorMap[i].c = X11DRV_PALETTE_ToLogical(colorMap[i].x11);
+        }
     }
-
-    return colorMapping;
-}
-
-/***********************************************************************
- *           X11DRV_DIB_BuildColorMap
- *
- * Build the color map from the bitmap palette. Should not be called
- * for a >8-bit deep bitmap.
- */
-static int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE *physDev, WORD coloruse, WORD depth,
-                                      const BITMAPINFO *info, int *nColors )
-{
-    BOOL isInfo;
-    const void *colorPtr;
-    int *colorMapping;
-
-
-    *nColors = X11DRV_DIB_GetColorCount(info);
-    if (!*nColors) return NULL;
-
-    isInfo = info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER);
-    colorPtr = (const BYTE*)info + (WORD)info->bmiHeader.biSize;
-    if (!(colorMapping = HeapAlloc(GetProcessHeap(), 0, *nColors * sizeof(int) )))
-        return NULL;
-
-    return X11DRV_DIB_GenColorMap( physDev, colorMapping, coloruse, depth,
-                                   isInfo, colorPtr, 0, *nColors);
 }
 
-/***********************************************************************
- *           X11DRV_DIB_MapColor
- */
-static int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol )
-{
-    unsigned int color;
-
-    if ((oldcol < nPhysMap) && (physMap[oldcol] == phys))
-        return oldcol;
-
-    for (color = 0; color < nPhysMap; color++)
-        if (physMap[color] == phys)
-            return color;
-
-    WARN("Strange color %08x\n", phys);
-    return 0;
-}
-
-
 /*********************************************************************
  *         X11DRV_DIB_GetNearestIndex
  *
@@ -432,18 +402,20 @@ static int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol
  * Returns the nearest colour table index for a given RGB.
  * Nearest is defined by minimizing the sum of the squares.
  */
-static INT X11DRV_DIB_GetNearestIndex(RGBQUAD *colormap, int numColors, BYTE r, BYTE g, BYTE b)
+static INT X11DRV_DIB_GetNearestIndex(const X11DRV_COLOR* colormap, int numColors, BYTE r, BYTE g, BYTE b)
 {
-    INT i, best = -1, diff, bestdiff = -1;
-    RGBQUAD *color;
+    INT i, best = 0, diff;
+    unsigned int bestdiff = 0xffffffff;
+    const X11DRV_COLOR* color;
 
     for(color = colormap, i = 0; i < numColors; color++, i++) {
-        diff = (r - color->rgbRed) * (r - color->rgbRed) +
-	       (g - color->rgbGreen) * (g - color->rgbGreen) +
-	       (b - color->rgbBlue) * (b - color->rgbBlue);
-	if(diff == 0)
+	diff = (r - GetRValue(color->c)) * (r - GetRValue(color->c)) +
+	       (g - GetGValue(color->c)) * (g - GetGValue(color->c)) +
+	       (b - GetBValue(color->c)) * (b - GetBValue(color->c));
+	if (diff == 0)
 	    return i;
-	if(best == -1 || diff < bestdiff) {
+	if (diff < bestdiff)
+	{
 	    best = i;
 	    bestdiff = diff;
 	}
@@ -489,9 +461,10 @@ static inline int X11DRV_DIB_CheckMask(int red_mask, int green_mask, int blue_ma
  *
  * SetDIBits for a 1-bit deep DIB.
  */
-static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
-                                DWORD srcwidth, DWORD dstwidth, int left,
-                                int *colors, XImage *bmpImage, DWORD linebytes)
+static void X11DRV_DIB_SetImageBits_1(int lines, const BYTE* srcbits,
+                                      DWORD srcwidth, DWORD dstwidth, int left,
+                                      const X11DRV_COLOR* colors,
+                                      XImage* bmpImage, DWORD linebytes)
 {
     int h, width;
     const BYTE* srcbyte;
@@ -516,26 +489,26 @@ static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
         srcbyte=srcbits;
         for (i = width/8, x = left; i > 0; i--) {
             srcval=*srcbyte++;
-            XPutPixel( bmpImage, x++, h, colors[ srcval >> 7] );
-            XPutPixel( bmpImage, x++, h, colors[(srcval >> 6) & 1] );
-            XPutPixel( bmpImage, x++, h, colors[(srcval >> 5) & 1] );
-            XPutPixel( bmpImage, x++, h, colors[(srcval >> 4) & 1] );
-            XPutPixel( bmpImage, x++, h, colors[(srcval >> 3) & 1] );
-            XPutPixel( bmpImage, x++, h, colors[(srcval >> 2) & 1] );
-            XPutPixel( bmpImage, x++, h, colors[(srcval >> 1) & 1] );
-            XPutPixel( bmpImage, x++, h, colors[ srcval       & 1] );
+            XPutPixel( bmpImage, x++, h, colors[ srcval >> 7].x11 );
+            XPutPixel( bmpImage, x++, h, colors[(srcval >> 6) & 1].x11 );
+            XPutPixel( bmpImage, x++, h, colors[(srcval >> 5) & 1].x11 );
+            XPutPixel( bmpImage, x++, h, colors[(srcval >> 4) & 1].x11 );
+            XPutPixel( bmpImage, x++, h, colors[(srcval >> 3) & 1].x11 );
+            XPutPixel( bmpImage, x++, h, colors[(srcval >> 2) & 1].x11 );
+            XPutPixel( bmpImage, x++, h, colors[(srcval >> 1) & 1].x11 );
+            XPutPixel( bmpImage, x++, h, colors[ srcval       & 1].x11 );
         }
         if (width % 8){
             srcval=*srcbyte;
             switch (width & 7)
             {
-            case 7: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
-            case 6: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
-            case 5: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
-            case 4: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
-            case 3: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
-            case 2: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
-            case 1: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]);
+            case 7: XPutPixel(bmpImage, x++, h, colors[srcval >> 7].x11); srcval<<=1;
+            case 6: XPutPixel(bmpImage, x++, h, colors[srcval >> 7].x11); srcval<<=1;
+            case 5: XPutPixel(bmpImage, x++, h, colors[srcval >> 7].x11); srcval<<=1;
+            case 4: XPutPixel(bmpImage, x++, h, colors[srcval >> 7].x11); srcval<<=1;
+            case 3: XPutPixel(bmpImage, x++, h, colors[srcval >> 7].x11); srcval<<=1;
+            case 2: XPutPixel(bmpImage, x++, h, colors[srcval >> 7].x11); srcval<<=1;
+            case 1: XPutPixel(bmpImage, x++, h, colors[srcval >> 7].x11);
             }
         }
         srcbits += linebytes;
@@ -547,10 +520,11 @@ static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
  *
  * GetDIBits for a 1-bit deep DIB.
  */
-static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits,
-				       DWORD dstwidth, DWORD srcwidth,
-				       RGBQUAD *colors, PALETTEENTRY *srccolors,
-                                XImage *bmpImage, DWORD linebytes )
+static void X11DRV_DIB_GetImageBits_1(int lines, BYTE* dstbits,
+                                      DWORD dstwidth, DWORD srcwidth,
+                                      const X11DRV_COLOR* colors,
+                                      const PALETTEENTRY* srccolors,
+                                      XImage* bmpImage, DWORD linebytes)
 {
     DWORD x;
     int h, width = min(dstwidth, srcwidth);
@@ -851,8 +825,8 @@ static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits,
             unsigned long white = (1 << bmpImage->bits_per_pixel) - 1;
 
             /* ==== any bmp format -> pal 1 dib ==== */
-            if ((unsigned)colors[0].rgbRed+colors[0].rgbGreen+colors[0].rgbBlue >=
-                (unsigned)colors[1].rgbRed+colors[1].rgbGreen+colors[1].rgbBlue )
+            if ((unsigned)GetRValue(colors[0].c)+GetGValue(colors[0].c)+GetBValue(colors[0].c) >=
+                (unsigned)GetRValue(colors[1].c)+GetGValue(colors[1].c)+GetBValue(colors[1].c))
                 neg = 1;
 
             WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 1 bit DIB, "
@@ -887,9 +861,10 @@ static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits,
  *
  * SetDIBits for a 4-bit deep DIB.
  */
-static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
-                                DWORD srcwidth, DWORD dstwidth, int left,
-                                int *colors, XImage *bmpImage, DWORD linebytes)
+static void X11DRV_DIB_SetImageBits_4(int lines, const BYTE* srcbits,
+                                      DWORD srcwidth, DWORD dstwidth, int left,
+                                      const X11DRV_COLOR* colors,
+                                      XImage* bmpImage, DWORD linebytes)
 {
     int h, width;
     const BYTE* srcbyte;
@@ -913,11 +888,11 @@ static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
         srcbyte=srcbits;
         for (i = width/2, x = left; i > 0; i--) {
             BYTE srcval=*srcbyte++;
-            XPutPixel( bmpImage, x++, h, colors[srcval >> 4] );
-            XPutPixel( bmpImage, x++, h, colors[srcval & 0x0f] );
+            XPutPixel( bmpImage, x++, h, colors[srcval >> 4].x11 );
+            XPutPixel( bmpImage, x++, h, colors[srcval & 0x0f].x11 );
         }
         if (width & 1)
-            XPutPixel( bmpImage, x, h, colors[*srcbyte >> 4] );
+            XPutPixel( bmpImage, x, h, colors[*srcbyte >> 4].x11 );
         srcbits += linebytes;
     }
 }
@@ -929,10 +904,11 @@ static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
  *
  * GetDIBits for a 4-bit deep DIB.
  */
-static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits,
-				       DWORD srcwidth, DWORD dstwidth,
-				       RGBQUAD *colors, PALETTEENTRY *srccolors,
-				       XImage *bmpImage, DWORD linebytes )
+static void X11DRV_DIB_GetImageBits_4(int lines, BYTE* dstbits,
+                                      DWORD srcwidth, DWORD dstwidth,
+                                      const X11DRV_COLOR* colors,
+                                      const PALETTEENTRY* srccolors,
+                                      XImage* bmpImage, DWORD linebytes)
 {
     DWORD x;
     int h, width = min(srcwidth, dstwidth);
@@ -1322,11 +1298,16 @@ static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits,
             for (h=lines-1; h>=0; h--) {
                 dstbyte=dstbits;
                 for (x=0; x<(width & ~1); x+=2) {
-                    *dstbyte++=(X11DRV_DIB_MapColor((int*)colors, 16, XGetPixel(bmpImage, x, h), 0) << 4) |
-                        X11DRV_DIB_MapColor((int*)colors, 16, XGetPixel(bmpImage, x+1, h), 0);
+                    COLORREF srcval1, srcval2;
+                    srcval1=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x, h));
+                    srcval2=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x+1, h));
+                    *dstbyte++=(X11DRV_DIB_GetNearestIndex(colors, 16, GetRValue(srcval1), GetGValue(srcval1), GetBValue(srcval1)) << 4) |
+                        X11DRV_DIB_GetNearestIndex(colors, 16, GetRValue(srcval2), GetGValue(srcval2), GetBValue(srcval2));
                 }
                 if (width & 1) {
-                    *dstbyte=(X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel(bmpImage, x, h), 0) << 4);
+                    COLORREF srcval;
+                    srcval=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x, h));
+                    *dstbyte=(X11DRV_DIB_GetNearestIndex(colors, 16, GetRValue(srcval), GetGValue(srcval), GetBValue(srcval)) << 4);
                 }
                 dstbits += linebytes;
             }
@@ -1340,10 +1321,10 @@ static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits,
  *
  * SetDIBits for a 4-bit deep compressed DIB.
  */
-static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
-					  DWORD srcwidth, DWORD dstwidth,
-					  int left, int *colors,
-					  XImage *bmpImage )
+static void X11DRV_DIB_SetImageBits_RLE4(int lines, const BYTE* bits,
+                                         DWORD srcwidth, DWORD dstwidth,
+                                         int left, const X11DRV_COLOR* colors,
+                                         XImage* bmpImage)
 {
     unsigned int x = 0, width = min(srcwidth, dstwidth);
     int y = lines - 1, c, length;
@@ -1356,11 +1337,11 @@ static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
 	    c = *bits++;
 	    while (length--) {
                 if (x >= (left + width)) break;
-                if( x >= left) XPutPixel(bmpImage, x, y, colors[c >> 4]);
+                if( x >= left) XPutPixel(bmpImage, x, y, colors[c >> 4].x11);
                 x++;
                 if (!length--) break;
                 if (x >= (left + width)) break;
-                if( x >= left) XPutPixel(bmpImage, x, y, colors[c & 0xf]);
+                if( x >= left) XPutPixel(bmpImage, x, y, colors[c & 0xf].x11);
                 x++;
 	    }
 	} else {
@@ -1384,11 +1365,11 @@ static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
 	        while (length--) {
 		    c = *bits++;
                     if (x >= left && x < (left + width))
-                        XPutPixel(bmpImage, x, y, colors[c >> 4]);
+                        XPutPixel(bmpImage, x, y, colors[c >> 4].x11);
                     x++;
                     if (!length--) break;
                     if (x >= left && x < (left + width))
-                        XPutPixel(bmpImage, x, y, colors[c & 0xf]);
+                        XPutPixel(bmpImage, x, y, colors[c & 0xf].x11);
                     x++;
 		}
 		if ((bits - begin) & 1)
@@ -1405,10 +1386,10 @@ static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
  *
  * SetDIBits for an 8-bit deep DIB.
  */
-static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
-				DWORD srcwidth, DWORD dstwidth, int left,
-                                const int *colors, XImage *bmpImage,
-				DWORD linebytes )
+static void X11DRV_DIB_SetImageBits_8(int lines, const BYTE* srcbits,
+                                      DWORD srcwidth, DWORD dstwidth, int left,
+                                      const X11DRV_COLOR* colors,
+                                      XImage* bmpImage, DWORD linebytes)
 {
     DWORD x;
     int h, width = min(srcwidth, dstwidth);
@@ -1442,7 +1423,7 @@ static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
 		"cld\n"
 		"1:\n"
 		"    lodsb\n"
-		"    movw (%%edx,%%eax,4),%%ax\n"
+		"    movw (%%edx,%%eax,8),%%ax\n"
 		"    stosw\n"
 		"      xor %%eax,%%eax\n"
 		"    loop 1b\n"
@@ -1457,12 +1438,12 @@ static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
 		DWORD* dstpixel=(DWORD*)dstbits;
 		for (x=0; x<width/2; x++) {
 		    /* Do 2 pixels at a time */
-		    *dstpixel++=(colors[srcbyte[1]] << 16) | colors[srcbyte[0]];
+		    *dstpixel++=(colors[srcbyte[1]].x11 << 16) | colors[srcbyte[0]].x11;
 		    srcbyte+=2;
 		}
 		if (width&1) {
 		    /* And then the odd pixel */
-		    *((WORD*)dstpixel)=colors[srcbyte[0]];
+		    *((WORD*)dstpixel)=colors[srcbyte[0]].x11;
 		}
 #endif
 		srcbyte = (srcbits += linebytes);
@@ -1487,7 +1468,7 @@ static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
 		"cld\n"
 		"1:\n"
 		"    lodsb\n"
-		"    movl (%%edx,%%eax,4),%%eax\n"
+		"    movl (%%edx,%%eax,8),%%eax\n"
 		"    stosl\n"
 		"      xor %%eax,%%eax\n"
 		"    loop 1b\n"
@@ -1501,7 +1482,7 @@ static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
 #else
 		DWORD* dstpixel=(DWORD*)dstbits;
 		for (x=0; x<width; x++) {
-		    *dstpixel++=colors[*srcbyte++];
+		    *dstpixel++=colors[*srcbyte++].x11;
 		}
 #endif
 		srcbyte = (srcbits += linebytes);
@@ -1517,7 +1498,7 @@ static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
     /* ==== pal 8 dib -> any bmp format ==== */
     for (h=lines-1; h>=0; h--) {
         for (x=left; x<width+left; x++) {
-            XPutPixel(bmpImage, x, h, colors[*srcbyte++]);
+            XPutPixel(bmpImage, x, h, colors[*srcbyte++].x11);
         }
         srcbyte = (srcbits += linebytes);
     }
@@ -1528,10 +1509,11 @@ static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
  *
  * GetDIBits for an 8-bit deep DIB.
  */
-static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
-				       DWORD srcwidth, DWORD dstwidth,
-				       RGBQUAD *colors, PALETTEENTRY *srccolors,
-				       XImage *bmpImage, DWORD linebytes )
+static void X11DRV_DIB_GetImageBits_8(int lines, BYTE* dstbits,
+                                      DWORD srcwidth, DWORD dstwidth,
+                                      const X11DRV_COLOR* colors,
+                                      const PALETTEENTRY* srccolors,
+                                      XImage* bmpImage, DWORD linebytes)
 {
     DWORD x;
     int h, width = min(srcwidth, dstwidth);
@@ -1768,9 +1750,10 @@ static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
         for (h=lines-1; h>=0; h--) {
             dstbyte=dstbits;
             for (x=0; x<width; x++) {
-                *dstbyte=X11DRV_DIB_MapColor
-                    ((int*)colors, 256,
-                     XGetPixel(bmpImage, x, h), *dstbyte);
+                COLORREF srcval;
+                srcval=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x, h));
+                *dstbyte=X11DRV_DIB_GetNearestIndex(colors, 256,
+                     GetRValue(srcval), GetGValue(srcval), GetBValue(srcval));
                 dstbyte++;
             }
             dstbits += linebytes;
@@ -1799,10 +1782,10 @@ static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
  *			James A. Youngman <mbcstjy at afs.man.ac.uk>
  *						[JAY]
  */
-static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
-					  DWORD srcwidth, DWORD dstwidth,
-					  int left, int *colors,
-					  XImage *bmpImage )
+static void X11DRV_DIB_SetImageBits_RLE8(int lines, const BYTE* bits,
+                                         DWORD srcwidth, DWORD dstwidth,
+                                         int left, const X11DRV_COLOR* colors,
+                                         XImage* bmpImage)
 {
     unsigned int x;		/* X-position on each line.  Increases. */
     int y;			/* Line #.  Starts at lines-1, decreases */
@@ -1836,7 +1819,7 @@ static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
             /*
              * [Run-Length] Encoded mode
              */
-            int color = colors[*pIn++];
+            int color = colors[*pIn++].x11;
             while (length-- && x < (left + dstwidth)) {
                 if( x >= left) XPutPixel(bmpImage, x, y, color);
                 x++;
@@ -1872,7 +1855,7 @@ static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
                 length = escape_code;
                 while (length--)
                 {
-                    int color = colors[*pIn++];
+                    int color = colors[*pIn++].x11;
                     if (x >= (left + dstwidth))
                     {
                         pIn += length;
@@ -2167,11 +2150,11 @@ static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits,
  *
  * GetDIBits for an 16-bit deep DIB.
  */
-static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *dstbits,
-					DWORD dstwidth, DWORD srcwidth,
-					PALETTEENTRY *srccolors,
-					DWORD rDst, DWORD gDst, DWORD bDst,
-					XImage *bmpImage, DWORD dibpitch )
+static void X11DRV_DIB_GetImageBits_16(int lines, BYTE* dstbits,
+                                       DWORD dstwidth, DWORD srcwidth,
+                                       const PALETTEENTRY* srccolors,
+                                       DWORD rDst, DWORD gDst, DWORD bDst,
+                                       XImage* bmpImage, DWORD dibpitch)
 {
     DWORD x;
     int h, width = min(srcwidth, dstwidth);
@@ -2662,11 +2645,11 @@ static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits,
  *
  * GetDIBits for an 24-bit deep DIB.
  */
-static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *dstbits,
-					DWORD dstwidth, DWORD srcwidth,
-					PALETTEENTRY *srccolors,
-                                        DWORD rDst, DWORD gDst, DWORD bDst,
-					XImage *bmpImage, DWORD linebytes )
+static void X11DRV_DIB_GetImageBits_24(int lines, BYTE* dstbits,
+                                       DWORD dstwidth, DWORD srcwidth,
+                                       const PALETTEENTRY* srccolors,
+                                       DWORD rDst, DWORD gDst, DWORD bDst,
+                                       XImage* bmpImage, DWORD linebytes)
 {
     DWORD x;
     int h, width = min(srcwidth, dstwidth);
@@ -3147,11 +3130,11 @@ static void X11DRV_DIB_SetImageBits_32(int lines, const BYTE *srcbits,
  *
  * GetDIBits for an 32-bit deep DIB.
  */
-static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *dstbits,
-					DWORD dstwidth, DWORD srcwidth,
-					PALETTEENTRY *srccolors,
-					DWORD rDst, DWORD gDst, DWORD bDst,
-					XImage *bmpImage, DWORD linebytes )
+static void X11DRV_DIB_GetImageBits_32(int lines, BYTE* dstbits,
+                                       DWORD dstwidth, DWORD srcwidth,
+                                       const PALETTEENTRY* srccolors,
+                                       DWORD rDst, DWORD gDst, DWORD bDst,
+                                       XImage* bmpImage, DWORD linebytes)
 {
     DWORD x;
     int h, width = min(srcwidth, dstwidth);
@@ -3531,7 +3514,7 @@ static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
     {
     case 1:
 	X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
-				   descr->width, descr->xSrc, (int *)(descr->colorMap),
+				   descr->width, descr->xSrc, descr->colorMap,
 				   bmpImage, descr->dibpitch );
 	break;
     case 4:
@@ -3539,12 +3522,12 @@ static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
             X11DRV_DIB_SetImageBits_GetSubImage( descr, bmpImage);
 	    X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits,
 					  descr->infoWidth, descr->width,
-					  descr->xSrc, (int *)(descr->colorMap),
+					  descr->xSrc, descr->colorMap,
 					  bmpImage );
 	} else
 	    X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits,
 				       descr->infoWidth, descr->width,
-				       descr->xSrc, (int*)(descr->colorMap),
+				       descr->xSrc, descr->colorMap,
 				       bmpImage, descr->dibpitch );
 	break;
     case 8:
@@ -3552,12 +3535,12 @@ static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
             X11DRV_DIB_SetImageBits_GetSubImage( descr, bmpImage);
 	    X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits,
 					  descr->infoWidth, descr->width,
-					  descr->xSrc, (int *)(descr->colorMap),
+					  descr->xSrc, descr->colorMap,
 					  bmpImage );
 	} else
 	    X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits,
 				       descr->infoWidth, descr->width,
-				       descr->xSrc, (int *)(descr->colorMap),
+				       descr->xSrc, descr->colorMap,
 				       bmpImage, descr->dibpitch );
 	break;
     case 15:
@@ -3829,10 +3812,14 @@ INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest, INT yDest, DWO
        case 1:
        case 4:
        case 8:
-               descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
-                                            physDev, coloruse,
-                                            physDev->depth, info, &descr.nColorMap );
+               descr.nColorMap = X11DRV_DIB_GetColorCount(info);
+               descr.colorMap = HeapAlloc(GetProcessHeap(), 0, descr.nColorMap * sizeof(*descr.colorMap));
                if (!descr.colorMap) return 0;
+               X11DRV_DIB_SetColorMap(physDev, physDev->depth,
+                                         descr.colorMap, coloruse,
+                                         (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER) ? FALSE : TRUE),
+                                         (const BYTE*)info+info->bmiHeader.biSize,
+                                         0, descr.nColorMap);
                descr.rMask = descr.gMask = descr.bMask = 0;
                break;
        case 15:
@@ -3840,7 +3827,7 @@ INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest, INT yDest, DWO
                descr.rMask = (descr.compression == BI_BITFIELDS) ? *(const DWORD *)info->bmiColors       : 0x7c00;
                descr.gMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)info->bmiColors + 1) : 0x03e0;
                descr.bMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)info->bmiColors + 2) : 0x001f;
-               descr.colorMap = 0;
+               descr.colorMap = NULL;
                break;
 
        case 24:
@@ -3848,7 +3835,7 @@ INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest, INT yDest, DWO
                descr.rMask = (descr.compression == BI_BITFIELDS) ? *(const DWORD *)info->bmiColors       : 0xff0000;
                descr.gMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)info->bmiColors + 1) : 0x00ff00;
                descr.bMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)info->bmiColors + 2) : 0x0000ff;
-               descr.colorMap = 0;
+               descr.colorMap = NULL;
                break;
     }
 
@@ -3872,8 +3859,7 @@ INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest, INT yDest, DWO
 
     result = X11DRV_DIB_SetImageBits( &descr );
 
-    if (descr.infoBpp <= 8)
-       HeapFree(GetProcessHeap(), 0, descr.colorMap);
+    HeapFree(GetProcessHeap(), 0, descr.colorMap);
 
     /* Update the DIBSection of the pixmap */
     X11DRV_UnlockDIBSection(physDev, TRUE);
@@ -3915,11 +3901,15 @@ INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
        case 1:
        case 4:
        case 8:
-	       descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
-                                                          descr.physDev, coloruse,
-                                                          physBitmap->pixmap_depth,
-                                                          info, &descr.nColorMap );
+               descr.nColorMap = X11DRV_DIB_GetColorCount(info);
+               descr.colorMap = HeapAlloc(GetProcessHeap(), 0, descr.nColorMap * sizeof(*descr.colorMap));
                if (!descr.colorMap) return 0;
+               X11DRV_DIB_SetColorMap(descr.physDev,
+                                      physBitmap->pixmap_depth,
+                                      descr.colorMap, coloruse,
+                                      (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER) ? FALSE : TRUE),
+                                      (const BYTE*)info+info->bmiHeader.biSize,
+                                      0, descr.nColorMap);
                descr.rMask = descr.gMask = descr.bMask = 0;
                break;
        case 15:
@@ -3927,7 +3917,7 @@ INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
                descr.rMask = (descr.compression == BI_BITFIELDS) ? *(const DWORD *)info->bmiColors       : 0x7c00;
                descr.gMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)info->bmiColors + 1) : 0x03e0;
                descr.bMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)info->bmiColors + 2) : 0x001f;
-               descr.colorMap = 0;
+               descr.colorMap = NULL;
                break;
 
        case 24:
@@ -3935,7 +3925,7 @@ INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
                descr.rMask = (descr.compression == BI_BITFIELDS) ? *(const DWORD *)info->bmiColors       : 0xff0000;
                descr.gMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)info->bmiColors + 1) : 0x00ff00;
                descr.bMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)info->bmiColors + 2) : 0x0000ff;
-               descr.colorMap = 0;
+               descr.colorMap = NULL;
                break;
 
        default: break;
@@ -3981,7 +3971,6 @@ INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
   LONG width, tempHeight;
   int bitmap_type;
   BOOL core_header;
-  void* colorPtr;
 
   GetPaletteEntries( GetCurrentObject( physDev->hdc, OBJ_PAL ), 0, 256, palette );
 
@@ -3996,7 +3985,6 @@ INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
       return 0;
   }
   core_header = (bitmap_type == 0);
-  colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
 
   TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
         lines, dib.dsBm.bmWidth, dib.dsBm.bmHeight, width, descr.lines, startscan);
@@ -4016,42 +4004,33 @@ INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
 
   if( startscan >= dib.dsBm.bmHeight ) return 0;
 
-  descr.colorMap = NULL;
-
   switch (descr.infoBpp)
   {
       case 1:
       case 4:
       case 8:
+          descr.nColorMap = X11DRV_DIB_GetColorCount(info);
+          descr.colorMap = HeapAlloc(GetProcessHeap(), 0, descr.nColorMap * sizeof(*descr.colorMap));
+          X11DRV_DIB_SetColorMap(physDev, physBitmap->pixmap_depth,
+                                 descr.colorMap, coloruse,
+                                 (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER) ? FALSE : TRUE),
+                                 (const BYTE*)info+info->bmiHeader.biSize,
+                                 0, descr.nColorMap);
           descr.rMask= descr.gMask = descr.bMask = 0;
-          if(coloruse == DIB_RGB_COLORS)
-              descr.colorMap = colorPtr;
-          else {
-              int num_colors = 1 << descr.infoBpp, i;
-              RGBQUAD *rgb;
-              COLORREF colref;
-              WORD *index = (WORD*)colorPtr;
-              descr.colorMap = rgb = HeapAlloc(GetProcessHeap(), 0, num_colors * sizeof(RGBQUAD));
-              for(i = 0; i < num_colors; i++, rgb++, index++) {
-                  colref = X11DRV_PALETTE_ToLogical(X11DRV_PALETTE_ToPhysical(physDev, PALETTEINDEX(*index)));
-                  rgb->rgbRed = GetRValue(colref);
-                  rgb->rgbGreen = GetGValue(colref);
-                  rgb->rgbBlue = GetBValue(colref);
-                  rgb->rgbReserved = 0;
-              }
-          }
           break;
       case 15:
       case 16:
           descr.rMask = (descr.compression == BI_BITFIELDS) ? *(const DWORD *)info->bmiColors       : 0x7c00;
           descr.gMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)info->bmiColors + 1) : 0x03e0;
           descr.bMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)info->bmiColors + 2) : 0x001f;
+          descr.colorMap = NULL;
           break;
       case 24:
       case 32:
           descr.rMask = (descr.compression == BI_BITFIELDS) ? *(const DWORD *)info->bmiColors       : 0xff0000;
           descr.gMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)info->bmiColors + 1) : 0x00ff00;
           descr.bMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)info->bmiColors + 2) : 0x0000ff;
+          descr.colorMap = NULL;
           break;
   }
 
@@ -4109,8 +4088,7 @@ INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
     info->bmiHeader.biCompression = 0;
   }
 
-  if(descr.colorMap != colorPtr)
-      HeapFree(GetProcessHeap(), 0, descr.colorMap);
+  HeapFree(GetProcessHeap(), 0, descr.colorMap);
   return lines;
 }
 
@@ -4129,7 +4107,7 @@ static void X11DRV_DIB_DoProtectDIBSection( X_PHYSBITMAP *physBitmap, DWORD new_
  *           X11DRV_DIB_DoCopyDIBSection
  */
 static void X11DRV_DIB_DoCopyDIBSection(X_PHYSBITMAP *physBitmap, BOOL toDIB,
-					void *colorMap, int nColorMap,
+					int nColorMap, X11DRV_COLOR* colorMap,
 					Drawable dest, GC gc,
 					DWORD xSrc, DWORD ySrc,
 					DWORD xDest, DWORD yDest,
@@ -4137,7 +4115,7 @@ static void X11DRV_DIB_DoCopyDIBSection(X_PHYSBITMAP *physBitmap, BOOL toDIB,
 {
   DIBSECTION dibSection;
   X11DRV_DIB_IMAGEBITS_DESCR descr;
-  int identity[2] = {0,1};
+  X11DRV_COLOR identity[2] = {{0,0}, {1,1}};
 
   if (!GetObjectW( physBitmap->hbitmap, sizeof(dibSection), &dibSection )) return;
 
@@ -4147,14 +4125,14 @@ static void X11DRV_DIB_DoCopyDIBSection(X_PHYSBITMAP *physBitmap, BOOL toDIB,
   descr.infoBpp   = dibSection.dsBmih.biBitCount;
   descr.lines     = dibSection.dsBmih.biHeight;
   descr.image     = physBitmap->image;
-  descr.colorMap  = colorMap;
   descr.nColorMap = nColorMap;
+  descr.colorMap  = colorMap;
   descr.bits      = dibSection.dsBm.bmBits;
   descr.depth     = physBitmap->pixmap_depth;
   descr.compression = dibSection.dsBmih.biCompression;
 
   if(descr.infoBpp == 1)
-      descr.colorMap = (void*)identity;
+      descr.colorMap = identity;
 
   switch (descr.infoBpp)
   {
@@ -4218,7 +4196,7 @@ void X11DRV_DIB_CopyDIBSection(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physD
   DIBSECTION dib;
   X_PHYSBITMAP *physBitmap;
   unsigned int nColorMap;
-  int* x11ColorMap;
+  X11DRV_COLOR* colorMap;
   int freeColorMap;
 
   TRACE("(%p,%p,%d,%d,%d,%d,%d,%d)\n", physDevSrc->hdc, physDevDst->hdc,
@@ -4248,34 +4226,37 @@ void X11DRV_DIB_CopyDIBSection(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physD
 	 * use the DIB colormap instead - this is necessary in some
 	 * cases since we need to do depth conversion in some places
 	 * where real Windows can just copy data straight over */
-	x11ColorMap = physBitmap->colorMap;
 	nColorMap = physBitmap->nColorMap;
-        freeColorMap = FALSE;
+	colorMap = physBitmap->colorMap;
+	freeColorMap = FALSE;
       } else {
-	  const BITMAPINFO* info = (BITMAPINFO*)&dib.dsBmih;
-	  int i;
-
-	  nColorMap = X11DRV_DIB_GetColorCount(info);
-	  x11ColorMap = HeapAlloc(GetProcessHeap(), 0, nColorMap * sizeof(int));
-	  for (i = 0; i < nColorMap; i++)
-	      x11ColorMap[i] = X11DRV_PALETTE_ToPhysical(physDevSrc, PALETTEINDEX(i));
-	  freeColorMap = TRUE;
+	const BITMAPINFO* info = (BITMAPINFO*)&dib.dsBmih;
+	int i;
+
+	nColorMap = X11DRV_DIB_GetColorCount(info);
+	colorMap = HeapAlloc(GetProcessHeap(), 0, nColorMap * sizeof(*colorMap));
+	for (i = 0; i < nColorMap; i++)
+	{
+	    colorMap[i].x11 = X11DRV_PALETTE_ToPhysical( physDevSrc, PALETTEINDEX(i) );
+	    colorMap[i].c = X11DRV_PALETTE_ToLogical(colorMap[i].x11);
+	}
+	freeColorMap = TRUE;
       }
     }
     else
     {
         nColorMap = 0;
-        x11ColorMap = NULL;
+        colorMap = NULL;
         freeColorMap = FALSE;
     }
     /* perform the copy */
-    X11DRV_DIB_DoCopyDIBSection(physBitmap, FALSE, x11ColorMap, nColorMap,
+    X11DRV_DIB_DoCopyDIBSection(physBitmap, FALSE, nColorMap, colorMap,
 				physDevDst->drawable, physDevDst->gc, xSrc, ySrc,
                                 physDevDst->dc_rect.left + xDest, physDevDst->dc_rect.top + yDest,
 				width, height);
     /* free color mapping */
     if (freeColorMap)
-      HeapFree(GetProcessHeap(), 0, x11ColorMap);
+        HeapFree(GetProcessHeap(), 0, colorMap);
   }
 }
 
@@ -4288,7 +4269,7 @@ static void X11DRV_DIB_DoUpdateDIBSection(X_PHYSBITMAP *physBitmap, BOOL toDIB)
 
     GetObjectW( physBitmap->hbitmap, sizeof(bitmap), &bitmap );
     X11DRV_DIB_DoCopyDIBSection(physBitmap, toDIB,
-                                physBitmap->colorMap, physBitmap->nColorMap,
+                                physBitmap->nColorMap, physBitmap->colorMap,
                                 physBitmap->pixmap, BITMAP_GC(physBitmap),
                                 0, 0, 0, 0, bitmap.bmWidth, bitmap.bmHeight);
 }
@@ -4619,18 +4600,23 @@ HBITMAP X11DRV_CreateDIBSection( X11DRV_PDEVICE *physDev, HBITMAP hbitmap,
     physBitmap->status = DIB_Status_None;
 
     GetObjectW( hbitmap, sizeof(dib), &dib );
+    physBitmap->pixmap_depth = (dib.dsBm.bmBitsPixel == 1) ? 1 : screen_depth;
 
     /* create color map */
     if (dib.dsBm.bmBitsPixel <= 8)
     {
-        physBitmap->colorMap = X11DRV_DIB_BuildColorMap( physDev,
-                                                         usage, dib.dsBm.bmBitsPixel, bmi,
-                                                         &physBitmap->nColorMap );
+        physBitmap->nColorMap = X11DRV_DIB_GetColorCount(bmi);
+        physBitmap->colorMap = HeapAlloc(GetProcessHeap(), 0, physBitmap->nColorMap * sizeof(*physBitmap->colorMap));
+        X11DRV_DIB_SetColorMap(physDev, physBitmap->pixmap_depth,
+
+                               physBitmap->colorMap, usage,
+                               (bmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER) ? FALSE : TRUE),
+                               (const BYTE*)bmi+bmi->bmiHeader.biSize,
+                               0, physBitmap->nColorMap);
     }
 
     /* create pixmap and X image */
     wine_tsx11_lock();
-    physBitmap->pixmap_depth = (dib.dsBm.bmBitsPixel == 1) ? 1 : screen_depth;
     physBitmap->pixmap = XCreatePixmap( gdi_display, root_window, dib.dsBm.bmWidth,
                                         dib.dsBm.bmHeight, physBitmap->pixmap_depth );
 #ifdef HAVE_LIBXXSHM
@@ -4731,9 +4717,9 @@ UINT X11DRV_SetDIBColorTable( X11DRV_PDEVICE *physDev, UINT start, UINT count, c
          * at least for a 1 bpp dibsection
          */
         X11DRV_DIB_Lock( physBitmap, DIB_Status_AppMod );
-        X11DRV_DIB_GenColorMap( physDev, physBitmap->colorMap, DIB_RGB_COLORS,
-                                dib.dsBm.bmBitsPixel,
-                                TRUE, colors, start, end );
+        X11DRV_DIB_SetColorMap( physDev, dib.dsBm.bmBitsPixel,
+                                physBitmap->colorMap,
+                                DIB_RGB_COLORS, TRUE, colors, start, end );
         X11DRV_DIB_Unlock( physBitmap, TRUE );
         ret = end - start;
     }
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 445badc..a3f1f0d 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -93,6 +93,12 @@ typedef struct
     Pixmap       pixmap;
 } X_PHYSBRUSH;
 
+typedef struct
+{
+    int      x11;
+    COLORREF c;
+} X11DRV_COLOR;
+
   /* X physical bitmap */
 typedef struct
 {
@@ -103,8 +109,8 @@ typedef struct
     /* the following fields are only used for DIB section bitmaps */
     int          status, p_status;  /* mapping status */
     XImage      *image;             /* cached XImage */
-    int         *colorMap;          /* color map info */
-    int          nColorMap;
+    unsigned int nColorMap;
+    X11DRV_COLOR *colorMap;         /* color map info */
     CRITICAL_SECTION lock;          /* GDI access lock */
 #ifdef HAVE_LIBXXSHM
     XShmSegmentInfo shminfo;        /* shared memory segment info */
-- 
1.5.3.4




More information about the wine-patches mailing list