[PATCH] Fix for monochrome device independent bitmaps with inverted colors

Oldřich Jedlička <[email protected]> Thu, 3 Nov 2005 18:01:09 +0100
Newsgroups gmane.comp.emulators.winex.devel
Organization CorteNico
Message-ID <[email protected]>
--Boundary-00=_VJkaDd4PiFPBYwA
Content-Type: text/plain;
  charset="us-ascii"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

Hi,

I found a problem in translating XImage into DIB created by CreateDIBSection. 
All problems are in graphics/x11drv/dib.c only.

1. When update XImage->DIB (monochrome images) is made, function 
X11DRV_DIB_GetImageBits_1 falls back into "notsupported" branch. The palette 
of the DIB was ignored in this case. If the colors are inverted, also image 
is inverted for updating DIB. Update DIB->XImage is not affected as it uses  
palette.

2. Used XImage (bmpImage parameter) has RGB mask corresponding to current  
visual, so it is not zero. The RGB mask was checked for zero when copying 
BMP->DIB, so new static inline function X11DRV_DIB_CheckMask has been 
created.

3. Parameter colorMap was set to identity color map for every monochrome 
bitmap. Changed to check if colorMap is NULL or has the same colors.

ChangeLog:

Oldrich Jedlicka <[email protected]>

* Check for inverted colors in "notsupported" branch of 
X11DRV_DIB_GetImageBits_1
* Check for non-zero RGB mask corresponding to current visual
* Fix for setting identity colorMap for every monochrome bitmap

--Boundary-00=_VJkaDd4PiFPBYwA
Content-Type: text/x-diff;
  charset="us-ascii";
  name="dib.c.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
	filename="dib.c.patch"

Index: graphics/x11drv/dib.c
===================================================================
RCS file: /cvsroot/winex/graphics/x11drv/dib.c,v
retrieving revision 1.90
diff -u -r1.90 graphics/x11drv/dib.c
--- graphics/x11drv/dib.c	21 Jan 2005 22:05:40 -0000	1.90
+++ graphics/x11drv/dib.c	15 Aug 2005 06:59:10 -0000
@@ -1725,6 +1725,17 @@
 }
 
 /***********************************************************************
+ *           X11DRV_DIB_CheckMask
+ *
+ * Check RGB mask if it is either 0 or matches visual's mask.
+ */
+static inline int X11DRV_DIB_CheckMask( int red_mask, int green_mask, int blue_mask ) {
+    return ( red_mask == 0 && green_mask == 0 && blue_mask == 0 ) ||
+           ( red_mask == visual->red_mask && green_mask == visual->green_mask &&
+             blue_mask == visual->blue_mask );
+}
+
+/***********************************************************************
  *           X11DRV_DIB_SetImageBits_1
  *
  * SetDIBits for a 1-bit deep DIB.
@@ -1810,7 +1821,8 @@
     {
     case 1:
     case 4:
-        if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
+        if (X11DRV_DIB_CheckMask(bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask)
+            && srccolors) {
             /* ==== pal 1 or 4 bmp -> pal 1 dib ==== */
             BYTE* dstbyte;
 
@@ -1842,7 +1854,8 @@
         break;
 
     case 8:
-        if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
+        if (X11DRV_DIB_CheckMask(bmpImage->red_mask, bmpImage->green_mask, bmpImage->blue_mask )
+            && srccolors) {
             /* ==== pal 8 bmp -> pal 1 dib ==== */
             const void* srcbits;
             const BYTE* srcpixel;
@@ -2090,19 +2103,30 @@
     notsupported:
         {
             BYTE* dstbyte;
+            BYTE neg = 0;
             unsigned long white = (1 << bmpImage->bits_per_pixel) - 1;
 
             /* ==== any bmp format -> pal 1 dib ==== */
-            WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 1 bit DIB\n",
-                  bmpImage->bits_per_pixel, bmpImage->red_mask,
-                  bmpImage->green_mask, bmpImage->blue_mask );
+            if ( (unsigned)colors[0].rgbRed+colors[0].rgbGreen+
+            	 	   colors[0].rgbBlue >= 
+            	 (unsigned)colors[1].rgbRed+colors[1].rgbGreen+
+            	 	   colors[1].rgbBlue ) {
+            	neg = 1;
+            }
 
+            WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 1 bit DIB, "
+            	 "%s color mapping\n",
+                  bmpImage->bits_per_pixel, bmpImage->red_mask,
+                  bmpImage->green_mask, bmpImage->blue_mask,
+                  neg?"negative":"direct" );
+                  
             for (h=lines-1; h>=0; h--) {
                 BYTE dstval;
                 dstbyte=dstbits;
                 dstval=0;
                 for (x=0; x<dstwidth; x++) {
-                    dstval|=(XGetPixel( bmpImage, x, h) >= white) << (7 - (x&7));
+                    dstval|=((XGetPixel(bmpImage, x, h) >= white) ^ neg) << 
+                            (7 - (x&7));
                     if ((x&7)==7) {
                         *dstbyte++=dstval;
                         dstval=0;
@@ -2185,7 +2209,8 @@
     switch (bmpImage->depth) {
     case 1:
     case 4:
-        if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
+        if (X11DRV_DIB_CheckMask(bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask)
+            && srccolors) {
             /* ==== pal 1 or 4 bmp -> pal 4 dib ==== */
             BYTE* dstbyte;
 
@@ -2217,7 +2242,8 @@
         break;
 
     case 8:
-        if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
+        if (X11DRV_DIB_CheckMask(bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask)
+            && srccolors) {
             /* ==== pal 8 bmp -> pal 4 dib ==== */
             const void* srcbits;
             const BYTE *srcpixel;
@@ -2770,7 +2796,8 @@
     switch (bmpImage->depth) {
     case 1:
     case 4:
-        if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
+        if (X11DRV_DIB_CheckMask(bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask)
+            && srccolors) {
 
             /* ==== pal 1 bmp -> pal 8 dib ==== */
             /* ==== pal 4 bmp -> pal 8 dib ==== */
@@ -2792,7 +2819,8 @@
         break;
 
     case 8:
-       if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
+       if (X11DRV_DIB_CheckMask(bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask)
+           && srccolors) {
             /* ==== pal 8 bmp -> pal 8 dib ==== */
            const void* srcbits;
            const BYTE* srcpixel;
@@ -3464,7 +3492,8 @@
 
     case 1:
     case 4:
-        if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
+        if (X11DRV_DIB_CheckMask(bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask)
+            && srccolors) {
             /* ==== pal 1 or 4 bmp -> rgb or bgr 555 or 565 dib ==== */
             int rShift,gShift,bShift;
             WORD* dstpixel;
@@ -3502,7 +3531,8 @@
         break;
 
     case 8:
-        if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
+        if (X11DRV_DIB_CheckMask(bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask)
+            && srccolors) {
             /* ==== pal 8 bmp -> rgb or bgr 555 or 565 dib ==== */
             int rShift,gShift,bShift;
             const BYTE* srcbits;
@@ -3888,7 +3918,8 @@
 
     case 1:
     case 4:
-        if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
+        if (X11DRV_DIB_CheckMask(bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask)
+            && srccolors) {
             /* ==== pal 1 or 4 bmp -> rgb 888 dib ==== */
             BYTE* dstbyte;
 
@@ -3911,7 +3942,8 @@
         break;
 
     case 8:
-        if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask == 0 && srccolors) {
+        if (X11DRV_DIB_CheckMask(bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask)
+            && srccolors) {
             /* ==== pal 8 bmp -> rgb 888 dib ==== */
             const void* srcbits;
             const BYTE* srcpixel;
@@ -4462,7 +4494,8 @@
 
     case 1:
     case 4:
-        if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
+        if (X11DRV_DIB_CheckMask(bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask)
+            && srccolors) {
             /* ==== pal 1 or 4 bmp -> any 0888 dib ==== */
             int rShift,gShift,bShift;
             DWORD* dstpixel;
@@ -4487,7 +4520,8 @@
         break;
 
     case 8:
-        if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
+        if (X11DRV_DIB_CheckMask(bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask)
+            && srccolors) {
             /* ==== pal 8 bmp -> any 0888 dib ==== */
             int rShift,gShift,bShift;
             const void* srcbits;
@@ -6171,7 +6205,7 @@
 	{
 	    ; /* Created Image */
 	} else {
-	   dib->image = X11DRV_DIB_CreateXImage( aligned_width, height, bpp );
+	   dib->image = X11DRV_DIB_CreateXImage( aligned_width, height, DEPTH_FROM_BPP(bpp) );
 	   dib->shminfo.shmid = -1;
 	}
 #else

--Boundary-00=_VJkaDd4PiFPBYwA--