alignment and endianess fixes in x11drv/dib.c

Warren_Baird at cimmetry.com Warren_Baird at cimmetry.com
Wed Feb 5 17:21:31 CST 2003



ChangeLog:

     Fixes for memory alignment and endianess issues x11drv DIB functions.

Description:

     Introduced byte-swapping and safe memory access in various places
     in x11drv DIB related functions.
     Added FIXME messages in not yet big-endian safe functions.

Warren Baird : Warren_Baird at cimmetry.com

diff -ur clean/wine/graphics/x11drv/dib.c  wine/graphics/x11drv/dib.c
--- clean/wine/graphics/x11drv/dib.c     Wed Jan 29 15:31:02 2003
+++ wine/graphics/x11drv/dib.c     Fri Jan 31 10:07:55 2003
@@ -400,6 +400,10 @@
     DWORD* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     for (y=0; y<height; y++) {
         srcpixel=srcbits;
         dstpixel=dstbits;
@@ -432,6 +436,10 @@
     DWORD* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     for (y=0; y<height; y++) {
         srcpixel=srcbits;
         dstpixel=dstbits;
@@ -464,6 +472,10 @@
     DWORD* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     for (y=0; y<height; y++) {
         srcpixel=srcbits;
         dstpixel=dstbits;
@@ -498,6 +510,10 @@
     BYTE* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     for (y=0; y<height; y++) {
         srcpixel=srcbits;
         dstpixel=dstbits;
@@ -525,6 +541,10 @@
     BYTE* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     for (y=0; y<height; y++) {
         srcpixel=srcbits;
         dstpixel=dstbits;
@@ -552,6 +572,10 @@
     DWORD* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     for (y=0; y<height; y++) {
         srcpixel=srcbits;
         dstpixel=dstbits;
@@ -578,6 +602,10 @@
     DWORD* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     for (y=0; y<height; y++) {
         srcpixel=srcbits;
         dstpixel=dstbits;
@@ -610,6 +638,10 @@
     DWORD* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     /* Note, the source pixel value is shifted left by 16 bits so that
      * we know we will always have to shift right to extract the components.
      */
@@ -669,6 +701,10 @@
     DWORD* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     for (y=0; y<height; y++) {
         srcpixel=srcbits;
         dstpixel=dstbits;
@@ -701,6 +737,10 @@
     DWORD* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     for (y=0; y<height; y++) {
         srcpixel=srcbits;
         dstpixel=dstbits;
@@ -731,6 +771,10 @@
     DWORD* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     for (y=0; y<height; y++) {
         srcpixel=srcbits;
         dstpixel=dstbits;
@@ -763,6 +807,10 @@
     BYTE* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     for (y=0; y<height; y++) {
         srcpixel=srcbits;
         dstpixel=dstbits;
@@ -790,6 +838,10 @@
     BYTE* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     for (y=0; y<height; y++) {
         srcpixel=srcbits;
         dstpixel=dstbits;
@@ -817,6 +869,10 @@
     DWORD* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     for (y=0; y<height; y++) {
         srcpixel=srcbits;
         dstpixel=dstbits;
@@ -843,6 +899,10 @@
     DWORD* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     for (y=0; y<height; y++) {
         srcpixel=srcbits;
         dstpixel=dstbits;
@@ -873,6 +933,10 @@
     BYTE* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     for (y=0; y<height; y++) {
         srcpixel=srcbits;
         dstpixel=dstbits;
@@ -898,6 +962,10 @@
     int x,y;
     int oddwidth;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     oddwidth=width & 3;
     width=width/4;
     for (y=0; y<height; y++) {
@@ -949,6 +1017,10 @@
     int x,y;
     int oddwidth;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     oddwidth=width & 3;
     width=width/4;
     for (y=0; y<height; y++) {
@@ -1000,6 +1072,10 @@
     int x,y;
     int oddwidth;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     oddwidth=width & 3;
     width=width/4;
     for (y=0; y<height; y++) {
@@ -1051,6 +1127,10 @@
     int x,y;
     int oddwidth;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     oddwidth=width & 3;
     width=width/4;
     for (y=0; y<height; y++) {
@@ -1107,6 +1187,19 @@
         srcpixel=srcbits;
         dstpixel=dstbits;
         for (x=0; x<width; x++) {
+#ifdef WORDS_BIGENDIAN
+            /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
+            DWORD srcval1,srcval2;
+            srcval1=srcpixel[0];
+            dstpixel[0]=( srcval1 & 0xffffff00) ;         /* h1, g1, l1 */
+            srcval2=srcpixel[1];
+            dstpixel[1]=( srcval1 & 0xff) << 24 |         /* l2 */
+                        ( srcval2 & 0xffff0000) >> 8  ;   /* h2, g2 */
+            srcval1=srcpixel[2];
+            dstpixel[2]=( srcval2  & 0x0000ffff) << 16 |  /* g3, l3 */
+                        ( srcval1  & 0xff000000) >> 16;   /* h3 */
+            dstpixel[3]=( srcval1  & 0x00ffffff) << 8;    /* h4, g4, l4 */
+#else
             /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
             DWORD srcval1,srcval2;
             srcval1=srcpixel[0];
@@ -1118,16 +1211,31 @@
             dstpixel[2]=( srcval2 >> 16) |              /* g3, l3 */
                         ((srcval1 << 16) & 0x00ff0000); /* h3 */
             dstpixel[3]=( srcval1 >>  8);               /* h4, g4, l4 */
+#endif
             srcpixel+=3;
             dstpixel+=4;
         }
         /* And now up to 3 odd pixels */
+    /* There are alignment problems here - be careful on systems that
+       need alignment */
+
+#ifdef ALLOW_UNALIGNED_ACCESS
         for (x=0; x<oddwidth; x++) {
             DWORD srcval;
             srcval=*srcpixel;
             srcpixel=(LPDWORD)(((char*)srcpixel)+3);
             *dstpixel++=( srcval         & 0x00ffffff); /* h, g, l */
         }
+#else
+    if (oddwidth > 0) {
+        for (x=0; x<oddwidth; x++) {
+         DWORD srcval;
+         memcpy(&srcval,srcpixel,4);
+         srcpixel=(LPDWORD)(((char*)srcpixel)+3);
+         *dstpixel++ = (srcval  & 0xffffff00) ;
+        }
+    }
+#endif
         srcbits = (char*)srcbits + srclinebytes;
         dstbits = (char*)dstbits + dstlinebytes;
     }
@@ -1150,7 +1258,17 @@
         for (x=0; x<width; x++) {
             /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
             DWORD srcval1,srcval2;
-
+#ifdef WORDS_BIGENDIAN
+            srcval1=srcpixel[0];
+            dstpixel[0]=((srcval1 >>  8)  & 0xffffff) ; /* h1, g1, l1 */
+            srcval2=srcpixel[1];
+            dstpixel[1]=((srcval1 <<  16) & 0xff0000) | /* h2 */
+                        ((srcval2 >>  16) & 0x00ffff); /* g2,l2 */
+            srcval1=srcpixel[2];
+            dstpixel[2]=((srcval2 << 8)  & 0xffff00) | /* h3,g3 */
+                        ((srcval1 >> 24) & 0x0000ff);  /* h3 */
+            dstpixel[3]=( srcval1        & 0xffffff);  /* h4, g4, l4 */
+#else
             srcval1=srcpixel[0];
             dstpixel[0]=((srcval1 >> 16) & 0x0000ff) | /* h1 */
                         ( srcval1        & 0x00ff00) | /* g1 */
@@ -1166,10 +1284,12 @@
             dstpixel[3]=((srcval1 >> 24) & 0x0000ff) | /* h4 */
                         ((srcval1 >>  8) & 0x00ff00) | /* g4 */
                         ((srcval1 <<  8) & 0xff0000);  /* l4 */
+#endif
             srcpixel+=3;
             dstpixel+=4;
         }
         /* And now up to 3 odd pixels */
+#ifdef ALLOW_UNALIGNED_ACCESS
         for (x=0; x<oddwidth; x++) {
             DWORD srcval;
             srcval=*srcpixel;
@@ -1178,6 +1298,17 @@
                         ( srcval         & 0x00ff00) | /* g */
                         ((srcval  << 16) & 0xff0000);  /* l */
         }
+#else
+    if (oddwidth > 0) {
+        for (x=0; x<oddwidth; x++) {
+         DWORD srcval;
+         memcpy(&srcval,srcpixel,sizeof(DWORD));
+         srcpixel=(LPDWORD)(((char*)srcpixel)+3);
+         *dstpixel++ = ((srcval >>  8)  & 0xffffff) ;
+
+        }
+    }
+#endif
         srcbits = (char*)srcbits + srclinebytes;
         dstbits = (char*)dstbits + dstlinebytes;
     }
@@ -1193,6 +1324,10 @@
     DWORD* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     rLeftShift=X11DRV_DIB_MaskToShift(rdst);
     gLeftShift=X11DRV_DIB_MaskToShift(gdst);
     bLeftShift=X11DRV_DIB_MaskToShift(bdst);
@@ -1220,6 +1355,10 @@
     DWORD* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     rLeftShift=X11DRV_DIB_MaskToShift(rdst);
     gLeftShift=X11DRV_DIB_MaskToShift(gdst);
     bLeftShift=X11DRV_DIB_MaskToShift(bdst);
@@ -1249,6 +1388,10 @@
     DWORD* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     for (y=0; y<height; y++) {
         srcpixel=srcbits;
         dstpixel=dstbits;
@@ -1276,6 +1419,10 @@
     DWORD* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     rRightShift=X11DRV_DIB_MaskToShift(rsrc);
     gRightShift=X11DRV_DIB_MaskToShift(gsrc);
     bRightShift=X11DRV_DIB_MaskToShift(bsrc);
@@ -1305,6 +1452,10 @@
     WORD* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     for (y=0; y<height; y++) {
         srcpixel=srcbits;
         dstpixel=dstbits;
@@ -1328,6 +1479,10 @@
     WORD* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     for (y=0; y<height; y++) {
         srcpixel=srcbits;
         dstpixel=dstbits;
@@ -1351,6 +1506,10 @@
     WORD* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     for (y=0; y<height; y++) {
         srcpixel=srcbits;
         dstpixel=dstbits;
@@ -1374,6 +1533,10 @@
     WORD* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     for (y=0; y<height; y++) {
         srcpixel=srcbits;
         dstpixel=dstbits;
@@ -1401,6 +1564,10 @@
     WORD* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     /* Here is how we proceed. Assume we have rsrc=0x0000ff00 and our pixel
      * contains 0x11223344.
      * - first we shift 0x11223344 right by rRightShift to bring the most
@@ -1448,6 +1615,9 @@
     BYTE* dstbyte;
     int x,y;
     int oddwidth;
+#ifndef ALLOW_UNALIGNED_ACCESS
+    BYTE oddbytes[9]; /* space for bytes at end of row */
+#endif

     oddwidth=width & 3;
     width=width/4;
@@ -1455,6 +1625,18 @@
         srcpixel=srcbits;
         dstpixel=dstbits;
         for (x=0; x<width; x++) {
+#ifdef WORDS_BIGENDIAN
+            /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
+            DWORD srcval;
+              DWORD tmppixel;
+
+            srcval=((*srcpixel++)       & 0xffffff00);  /* h1, g1, l1*/
+            *dstpixel++=srcval | (*srcpixel & 0xff000000) >> 24; /* h2 */
+            srcval=(*srcpixel++ & 0x00ffff00) << 8;  /* g2, l2 */
+            *dstpixel++=srcval | ((*srcpixel & 0xffff0000) >> 16); /* h3, g3 */
+            srcval=(*srcpixel++ & 0x0000ff00) << 16;  /* l3 */
+            *dstpixel++=srcval | ((*srcpixel++ & 0xffffff00) >> 8);  /* h4, g4,
l4 */
+#else
             /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
             DWORD srcval;
             srcval=((*srcpixel++)       & 0x00ffffff);  /* h1, g1, l1*/
@@ -1463,8 +1645,14 @@
             *dstpixel++=srcval | ((*srcpixel)   << 16); /* h3, g3 */
             srcval=((*srcpixel++ >> 16) & 0x000000ff);  /* l3 */
             *dstpixel++=srcval | ((*srcpixel++) << 8);  /* h4, g4, l4 */
+#endif
         }
         /* And now up to 3 odd pixels */
+
+    /* There are alignment problems here - be careful on systems that
+       need alignment */
+
+#ifdef ALLOW_UNALIGNED_ACCESS
         dstbyte=(BYTE*)dstpixel;
         for (x=0; x<oddwidth; x++) {
             DWORD srcval;
@@ -1472,6 +1660,23 @@
             *((WORD*)dstbyte)++=srcval;                 /* h, g */
             *dstbyte++=srcval >> 16;                    /* l */
         }
+#else
+
+
+    /* fill in a temporary buffer with the pixels, and memcpy
+       it into the place we need it */
+
+        for (x=0; x<oddwidth; x++) {
+              srcpixel++;
+
+              oddbytes[x*3  ] = (*srcpixel & 0xff000000) >> 24;
+              oddbytes[x*3+1] = (*srcpixel & 0x00ff0000) >> 16;
+              oddbytes[x*3+2] = (*srcpixel & 0x0000ff00) >> 8;
+        }
+
+         memcpy((BYTE*)dstpixel,oddbytes,oddwidth*3);
+
+#endif
         srcbits = (char*)srcbits + srclinebytes;
         dstbits = (char*)dstbits + dstlinebytes;
     }
@@ -1486,6 +1691,9 @@
     BYTE* dstbyte;
     int x,y;
     int oddwidth;
+#ifndef ALLOW_UNALIGNED_ACCESS
+    BYTE oddbytes[9]; /* space for bytes at end of row */
+#endif

     oddwidth=width & 3;
     width=width/4;
@@ -1494,6 +1702,19 @@
         dstpixel=dstbits;
         for (x=0; x<width; x++) {
             /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
+#ifdef WORDS_BIGENDIAN
+            DWORD srcval;
+            srcval= (*srcpixel++ & 0xffffff) << 8;       /* h1, g1, l1 */
+            *dstpixel++=srcval |
+                        ((*srcpixel & 0xff0000) >> 16);  /* h2 */
+            srcval = (*srcpixel++ & 0x00ffff) << 16;     /* g2, l2 */
+            *dstpixel++=srcval |
+                        ((*srcpixel & 0x00ffff00) >> 8); /* h3, g3 */
+
+            srcval=    ((*srcpixel++ & 0x000000ff) << 24); /* l3 */
+            *dstpixel++=srcval |
+                        (*srcpixel++ & 0xffffff);        /* h4, g4, l4 */
+#else
             DWORD srcval1,srcval2;
             srcval1=*srcpixel++;
             srcval2=    ((srcval1 >> 16) & 0x000000ff) | /* h1 */
@@ -1514,8 +1735,13 @@
                         ((srcval1 >>  8) & 0x0000ff00) | /* h4 */
                         ((srcval1 <<  8) & 0x00ff0000) | /* g4 */
                         ( srcval1 << 24);                /* l4 */
+#endif
         }
         /* And now up to 3 odd pixels */
+    /* There are alignment problems here - be careful on systems that
+       need alignment */
+
+#ifdef ALLOW_UNALIGNED_ACCESS
         dstbyte=(BYTE*)dstpixel;
         for (x=0; x<oddwidth; x++) {
             DWORD srcval;
@@ -1524,6 +1750,22 @@
                                 (srcval         & 0xff00);  /* g */
             *dstbyte++=srcval;                              /* l */
         }
+#else
+    /* fill in a temporary buffer with the pixels, and memcpy
+       it into the place we need it */
+
+        for (x=0; x<oddwidth; x++) {
+            DWORD srcval;
+            srcval=*srcpixel++;
+
+        oddbytes[x*3  ] = (srcval & 0xff0000) >> 16; /* h */
+        oddbytes[x*3+1] = (srcval & 0x00ff00) >> 8;  /* g */
+        oddbytes[x*3+2] = (srcval & 0x0000ff);     /* l */
+        }
+
+    memcpy((BYTE*)dstpixel,oddbytes,oddwidth*3);
+
+#endif
         srcbits = (char*)srcbits + srclinebytes;
         dstbits = (char*)dstbits + dstlinebytes;
     }
@@ -1539,6 +1781,10 @@
     BYTE* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     rRightShift=X11DRV_DIB_MaskToShift(rsrc);
     gRightShift=X11DRV_DIB_MaskToShift(gsrc);
     bRightShift=X11DRV_DIB_MaskToShift(bsrc);
@@ -1568,6 +1814,10 @@
     BYTE* dstpixel;
     int x,y;

+#ifdef WORDS_BIGENDIAN
+    FIXME("This code is not yet big-endian safe - expect corrupt images\n");
+#endif
+
     rRightShift=X11DRV_DIB_MaskToShift(rsrc);
     gRightShift=X11DRV_DIB_MaskToShift(gsrc);
     bRightShift=X11DRV_DIB_MaskToShift(bsrc);
@@ -2812,9 +3062,15 @@
                     for (x=0; x<dstwidth; x++) {
                         *dstbyte++=X11DRV_DIB_GetNearestIndex
                             (colors, 256,
+#ifdef WORDS_BIGENDIAN
+                             srcbyte[3],
+                             srcbyte[2],
+                             srcbyte[1]);
+#else
                              srcbyte[0],
                              srcbyte[1],
                              srcbyte[2]);
+#endif
                         srcbyte+=bytes_per_pixel;
                     }
                     srcbits = (char*)srcbits - bmpImage->bytes_per_line;





More information about the wine-patches mailing list