xc/programs/Xserver/Xprint/Init.c
authorRoland Mainz <roland.mainz@nrubsig.org>
Fri, 1 Apr 2005 21:45:20 +0000 (21:45 +0000)
committerRoland Mainz <roland.mainz@nrubsig.org>
Fri, 1 Apr 2005 21:45:20 +0000 (21:45 +0000)
xc/programs/Xserver/Xprint/ps/Imakefile
xc/programs/Xserver/Xprint/ps/Ps.h
xc/programs/Xserver/Xprint/ps/PsArea.c
xc/programs/Xserver/Xprint/ps/PsColor.c
xc/programs/Xserver/Xprint/ps/PsImageUtil.c
xc/programs/Xserver/Xprint/ps/PsInit.c
//bugs.freedesktop.org/show_bug.cgi?id=2879) attachment #2287
    (https://bugs.freedesktop.org/attachment.cgi?id=2287) Follow-up to
    bugzilla #1299: Add new visuals in the Postscript DDX (including
    TrueColor 16bit, PseudoColor 15bit/12bpg(12 bits per R-, G-, B-channel
    as in PostScript Level 2 (and above) colors can have 12 bits per
    component (36 bit for RGB)), PseudoColor+GrayScale+StaticGray
12bit/12bpg) and switch the default visual from PseudoColor 8bit/8bpg to
    PseudoColor 12bit/12bpg.

Xprint/Init.c
Xprint/ps/Ps.h
Xprint/ps/PsArea.c
Xprint/ps/PsColor.c
Xprint/ps/PsImageUtil.c [new file with mode: 0644]
Xprint/ps/PsInit.c
Xprint/ps/psout.h

index e9cd8a2..3bfc62e 100644 (file)
@@ -164,6 +164,8 @@ PixmapFormatRec     PSPixmapFormats[] = {
     {  1,  1, BITMAP_SCANLINE_PAD },
     {  8,  8, BITMAP_SCANLINE_PAD },
     { 12, 16, BITMAP_SCANLINE_PAD },
+    { 15, 16, BITMAP_SCANLINE_PAD },
+    { 16, 16, BITMAP_SCANLINE_PAD },
     { 24, 32, BITMAP_SCANLINE_PAD }
 };
 
index f8a0736..2f68304 100644 (file)
@@ -575,4 +575,12 @@ extern PsElmPtr PsCreateFillElementList(PixmapPtr pix, int *nElms);
 extern PsElmPtr PsCloneFillElementList(int nElms, PsElmPtr elms);
 extern void PsDestroyFillElementList(int nElms, PsElmPtr elms);
 
+/*
+ *  Functions in PsImageUtil.c
+ */
+
+extern unsigned long
+PsGetImagePixel(char *pImage, int depth, int w, int h, int leftPad, int format,
+                int px, int py);
+
 #endif  /* _PS_H_ */
index d01ccd2..7850da0 100644 (file)
@@ -78,6 +78,7 @@ in this Software without prior written authorization from The Open Group.
 #include "gcstruct.h"
 #include "windowstr.h"
 
+
 void
 PsPutScaledImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
            int w, int h, int leftPad, int format, int imageRes, char *pImage)
@@ -113,7 +114,6 @@ PsPutScaledImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
   {
     int          i, j;
     int          r, c;
-    int          swap;
     char        *pt;
     PsOutPtr     psOut;
     ColormapPtr  cMap;
@@ -129,139 +129,66 @@ PsPutScaledImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
        sh = (float)h * (float)pageRes / (float)imageRes + 0.5;
     }
     PsOut_Offset(psOut, pDrawable->x, pDrawable->y);
-    pt = (char *)(&i); i = 1; if( pt[0]=='\001' ) swap = 1; else swap = 0;
 
-#ifdef PSOUT_USE_DEEPCOLOR
-    if( depth==30 )
-    {
-      ErrorF("PsPutScaledImage: Not implemented yet for 30bit\m");
-    }
-    else
-#endif /* PSOUT_USE_DEEPCOLOR */
-    if( depth==24 )
-    {
-      PsOut_BeginImage(psOut, 0, 0, x, y, w, h, sw, sh, 3);
-      if( format==XYPixmap )
-      {
-        int   rowsiz = PixmapBytePad(w, depth);
-        char *planes[3];
-        planes[0] = pImage;
-        planes[1] = &pImage[rowsiz*h];
-        planes[2] = &pImage[rowsiz*h*2];
-        for( r=0 ; r<h ; r++ )
-        {
-          char *pt[3];
-          for( i=0 ; i<3 ;  i++ ) pt[i] = &planes[i][rowsiz*r];
-          for( c=0 ; c<w ; c++ )
-          {
-            for( i=0 ; i<3 ; i++ )
-              { PsOut_OutImageBytes(psOut, 1, &pt[i][c]); pt[i]++; }
-          }
-        }
-      }
-      else if( format==ZPixmap )
-      {
-        int  rowsiz = PixmapBytePad(w, depth);
-        for( r=0 ; r<h ; r++ )
-        {
-          char *pt = &pImage[rowsiz*r];
-          for( c=0 ; c<w ; c++,pt+=4 )
-          {
-            if( swap )
-            {
-              char tmp[4];
-              tmp[0] = pt[3]; tmp[1] = pt[2]; tmp[2] = pt[1]; tmp[3] = pt[0];
-              PsOut_OutImageBytes(psOut, 3, &tmp[1]);
-            }
-            else
-              PsOut_OutImageBytes(psOut, 3, &pt[1]);
-          }
-        }
-      }
-      else goto error;
-      PsOut_EndImage(psOut);
-    }
-#ifdef PSOUT_USE_DEEPCOLOR
-    else if( (depth > 8) && (depth < 16) )
+    if( depth!=1 )
     {
-      int  rowsiz = PixmapBytePad(w, depth);
       PsOut_BeginImage(psOut, 0, 0, x, y, w, h, sw, sh, 3);
+
       for( r=0 ; r<h ; r++ )
       {
-        short *pt = (short *)&pImage[rowsiz*r];
-        for( c=0 ; c<w ; c++,pt++ )
-        {
-          PsOutColor clr = PsGetPixelColor(cMap, (int)(*pt)&0xFFFF);
+        for( c=0 ; c<w ; c++ )
+        {         
+          unsigned long pv = PsGetImagePixel(pImage, depth, w, h, leftPad, format, c, r);
+          PsOutColor clr = PsGetPixelColor(cMap, pv);
           /* XXX: This needs to be fixed for endian swapping and to support
            * depths deeper than 8bit per R-,G-,B-gun... */
-          int        val = PSOUTCOLOR_TO_RGB24BIT(clr);
+          unsigned long val = PSOUTCOLOR_TO_RGB24BIT(clr);
           char      *ipt = (char *)&val;
-          if( swap )
+/* XXX: Is this the right way to detect the platform endianess ? */
+#if IMAGE_BYTE_ORDER == LSBFirst
           {
-            char tmp[4];
-            tmp[0] = ipt[3]; tmp[1] = ipt[2]; tmp[2] = ipt[1]; tmp[3] = ipt[0];
-            PsOut_OutImageBytes(psOut, 3, &tmp[1]);
+            long l;
+            swapl(&val, l);
           }
-          else
-            PsOut_OutImageBytes(psOut, 3, &ipt[1]);
+#elif IMAGE_BYTE_ORDER == MSBFirst
+#else
+#error Unsupported byte order
+#endif
+          PsOut_OutImageBytes(psOut, 3, &ipt[1]);
         }
       }
+
       PsOut_EndImage(psOut);
     }
-#endif /* PSOUT_USE_DEEPCOLOR */
-    else if( depth==8 )
+    else
     {
-      int  rowsiz = PixmapBytePad(w, depth);
-      PsOut_BeginImage(psOut, 0, 0, x, y, w, h, sw, sh, 3);
+      int  rowsiz = BitmapBytePad(w);
+      int  psrsiz = (w+7)/8;
+      PsOut_BeginImage(psOut, PsGetPixelColor(cMap, pGC->bgPixel),
+                       PsGetPixelColor(cMap, pGC->fgPixel),
+                       x, y, w, h, sw, sh, 1);
       for( r=0 ; r<h ; r++ )
       {
         char *pt = &pImage[rowsiz*r];
-        for( c=0 ; c<w ; c++,pt++ )
+        for( i=0 ; i<psrsiz ; i++ )
         {
-          PsOutColor clr = PsGetPixelColor(cMap, (int)(*pt)&0xFF);
-          int        val = PSOUTCOLOR_TO_RGB24BIT(clr);
-          char      *ipt = (char *)&val;
-          if( swap )
-          {
-            char tmp[4];
-            tmp[0] = ipt[3]; tmp[1] = ipt[2]; tmp[2] = ipt[1]; tmp[3] = ipt[0];
-            PsOut_OutImageBytes(psOut, 3, &tmp[1]);
-          }
-          else
-            PsOut_OutImageBytes(psOut, 3, &ipt[1]);
+          int  iv_, iv = (int)pt[i]&0xFF;
+          char c;
+/* XXX: Is this the right way to detect the platform endianess ? */
+#if IMAGE_BYTE_ORDER == LSBFirst
+          { for( j=0,iv_=0 ; j<8 ; j++ ) iv_ |= (((iv>>j)&1)<<(7-j)); }
+#elif IMAGE_BYTE_ORDER == MSBFirst
+          iv_ = iv;
+#else
+#error Unsupported byte order
+#endif
+          c = iv_;
+          PsOut_OutImageBytes(psOut, 1, &c);
         }
       }
       PsOut_EndImage(psOut);
     }
-    else if( depth==1 )
-    {
-      {
-        int  rowsiz = BitmapBytePad(w);
-        int  psrsiz = (w+7)/8;
-        PsOut_BeginImage(psOut, PsGetPixelColor(cMap, pGC->bgPixel),
-                         PsGetPixelColor(cMap, pGC->fgPixel),
-                        x, y, w, h, sw, sh, 1);
-        for( r=0 ; r<h ; r++ )
-        {
-          char *pt = &pImage[rowsiz*r];
-          for( i=0 ; i<psrsiz ; i++ )
-          {
-            int  iv_, iv = (int)pt[i]&0xFF;
-            char c;
-            if( swap )
-              { for( j=0,iv_=0 ; j<8 ; j++ ) iv_ |= (((iv>>j)&1)<<(7-j)); }
-            else
-              iv_ = iv;
-            c = iv_;
-            PsOut_OutImageBytes(psOut, 1, &c);
-          }
-        }
-        PsOut_EndImage(psOut);
-      }
-    }
   }
-error:
-  return;
 }
 
 void
@@ -299,7 +226,6 @@ PsPutScaledImageIM(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
   {
     int          i, j;
     int          r, c;
-    int          swap;
     char        *pt;
     PsOutPtr     psOut;
     ColormapPtr  cMap;
@@ -318,7 +244,6 @@ PsPutScaledImageIM(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
         sh = (float)h * (float)pageRes / (float)imageRes + 0.5;
     }
     PsOut_Offset(psOut, pDrawable->x, pDrawable->y);
-    pt = (char *)(&i); i = 1; if( pt[0]=='\001' ) swap = 1; else swap = 0;
 
 #ifdef BM_CACHE
     cache_id = PsBmIsImageCached(w, h, pImage);
@@ -332,134 +257,63 @@ PsPutScaledImageIM(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
 
       PsOut_BeginImageCache(psOut, cache_id);
 #endif
-
-#ifdef PSOUT_USE_DEEPCOLOR
-      if( depth==30 )
-      {
-        ErrorF("PsPutScaledImageIM: Not implemented yet for 30bit\m");
-      }
-      else
-#endif /* PSOUT_USE_DEEPCOLOR */
-      if( depth==24 )
-      {
-        PsOut_BeginImageIM(psOut, 0, 0, x, y, w, h, sw, sh, 3);
-        if( format==XYPixmap )
-        {
-          int   rowsiz = PixmapBytePad(w, depth);
-          char *planes[3];
-          planes[0] = pImage;
-          planes[1] = &pImage[rowsiz*h];
-          planes[2] = &pImage[rowsiz*h*2];
-          for( r=0 ; r<h ; r++ )
-          {
-            char *pt[3];
-            for( i=0 ; i<3 ;  i++ ) pt[i] = &planes[i][rowsiz*r];
-            for( c=0 ; c<w ; c++ )
-            {
-              for( i=0 ; i<3 ; i++ )
-                { PsOut_OutImageBytes(psOut, 1, &pt[i][c]); pt[i]++; }
-            }
-          }
-        }
-        else if( format==ZPixmap )
-        {
-          int  rowsiz = PixmapBytePad(w, depth);
-          for( r=0 ; r<h ; r++ )
-          {
-            char *pt = &pImage[rowsiz*r];
-            for( c=0 ; c<w ; c++,pt+=4 )
-            {
-              if( swap )
-              {
-                char tmp[4];
-                tmp[0] = pt[3]; tmp[1] = pt[2]; tmp[2] = pt[1]; tmp[3] = pt[0];
-                PsOut_OutImageBytes(psOut, 3, &tmp[1]);
-              }
-              else
-                PsOut_OutImageBytes(psOut, 3, &pt[1]);
-            }
-          }
-        }
-        else goto error;
-        PsOut_EndImage(psOut);
-      }
-#ifdef PSOUT_USE_DEEPCOLOR
-      else if( (depth > 8) && (depth < 16) )
+      if( depth!=1 )
       {
-        int  rowsiz = PixmapBytePad(w, depth);
-        PsOut_BeginImageIM(psOut, 0, 0, x, y, w, h, sw, sh, 3);
-        for( r=0 ; r<h ; r++ )
-        {
-          short *pt = (short *)&pImage[rowsiz*r];
-          for( c=0 ; c<w ; c++,pt++ )
-          {
-            PsOutColor clr = PsGetPixelColor(cMap, (int)(*pt)&0xFFFF);
-            int        val = PSOUTCOLOR_TO_RGB24BIT(clr);
-            char      *ipt = (char *)&val;
-            if( swap )
-            {
-              char tmp[4];
-              tmp[0] = ipt[3]; tmp[1] = ipt[2]; tmp[2] = ipt[1]; tmp[3] = ipt[0];
-              PsOut_OutImageBytes(psOut, 3, &tmp[1]);
-            }
-            else
-              PsOut_OutImageBytes(psOut, 3, &ipt[1]);
-          }
-        }
-        PsOut_EndImage(psOut);
-      }
-#endif /* PSOUT_USE_DEEPCOLOR */
-      else if( depth==8 )
-      {
-        int  rowsiz = PixmapBytePad(w, depth);
         PsOut_BeginImageIM(psOut, 0, 0, x, y, w, h, sw, sh, 3);
+
         for( r=0 ; r<h ; r++ )
         {
-          char *pt = &pImage[rowsiz*r];
-          for( c=0 ; c<w ; c++,pt++ )
-          {
-            PsOutColor clr = PsGetPixelColor(cMap, (int)(*pt)&0xFF);
+          for( c=0 ; c<w ; c++ )
+          {         
+            unsigned long pv = PsGetImagePixel(pImage, depth, w, h, leftPad, format, c, r);
+            PsOutColor clr = PsGetPixelColor(cMap, pv);
             /* XXX: This needs to be fixed for endian swapping and to support
              * depths deeper than 8bit per R-,G-,B-gun... */
-            int        val = PSOUTCOLOR_TO_RGB24BIT(clr);
+            unsigned long val = PSOUTCOLOR_TO_RGB24BIT(clr);
             char      *ipt = (char *)&val;
-            if( swap )
-            {
-              char tmp[4];
-              tmp[0] = ipt[3]; tmp[1] = ipt[2]; tmp[2] = ipt[1]; tmp[3] = ipt[0];
-              PsOut_OutImageBytes(psOut, 3, &tmp[1]);
-            }
-            else
-              PsOut_OutImageBytes(psOut, 3, &ipt[1]);
+/* XXX: Is this the right way to detect the platform endianess ? */
+#if IMAGE_BYTE_ORDER == LSBFirst
+          {
+            long l;
+            swapl(&val, l);
+          }
+#elif IMAGE_BYTE_ORDER == MSBFirst
+#else
+#error Unsupported byte order
+#endif
+            PsOut_OutImageBytes(psOut, 3, &ipt[1]);
           }
         }
+
         PsOut_EndImage(psOut);
       }
-      else if( depth==1 )
+      else
       {
-        {
-          int  rowsiz = BitmapBytePad(w);
-          int  psrsiz = (w+7)/8;
-          PsOut_BeginImageIM(psOut, PsGetPixelColor(cMap, pGC->bgPixel),
+        int  rowsiz = BitmapBytePad(w);
+        int  psrsiz = (w+7)/8;
+        PsOut_BeginImageIM(psOut, PsGetPixelColor(cMap, pGC->bgPixel),
                            PsGetPixelColor(cMap, pGC->fgPixel),
                            x, y, w, h, sw, sh, 1);
-          for( r=0 ; r<h ; r++ )
+        for( r=0 ; r<h ; r++ )
+        {
+          char *pt = &pImage[rowsiz*r];
+          for( i=0 ; i<psrsiz ; i++ )
           {
-            char *pt = &pImage[rowsiz*r];
-            for( i=0 ; i<psrsiz ; i++ )
-            {
-              int  iv_, iv = (int)pt[i]&0xFF;
-              char c;
-              if( swap )
-                { for( j=0,iv_=0 ; j<8 ; j++ ) iv_ |= (((iv>>j)&1)<<(7-j)); }
-              else
-                iv_ = iv;
-              c = iv_;
-              PsOut_OutImageBytes(psOut, 1, &c);
-            }
+            int  iv_, iv = (int)pt[i]&0xFF;
+            char c;
+/* XXX: Is this the right way to detect the platform endianess ? */
+#if IMAGE_BYTE_ORDER == LSBFirst
+            { for( j=0,iv_=0 ; j<8 ; j++ ) iv_ |= (((iv>>j)&1)<<(7-j)); }
+#elif IMAGE_BYTE_ORDER == MSBFirst
+            iv_ = iv;
+#else
+#error Unsupported byte order
+#endif
+            c = iv_;
+            PsOut_OutImageBytes(psOut, 1, &c);
           }
-          PsOut_EndImage(psOut);
         }
+        PsOut_EndImage(psOut);
       }
 #ifdef BM_CACHE
       PsOut_EndImageCache(psOut);
@@ -468,8 +322,6 @@ PsPutScaledImageIM(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
                            PsGetPixelColor(cMap, pGC->fgPixel));
 #endif
   }
-error:
-  return;
 }
 void
 PsPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
index 1f98424..3586a77 100644 (file)
@@ -151,19 +151,22 @@ PsGetPixelColor(ColormapPtr cMap, int pixval)
     {
         PsOutColor p = pixval;       
         PsOutColor r, g, b;
-#ifdef PSOUT_USE_DEEPCOLOR
-        int shift = 16 - v->bitsPerRGBValue;
-#else
-        int shift =  8 - v->bitsPerRGBValue;
-#endif /* PSOUT_USE_DEEPCOLOR */
 
-        r = ((p & v->redMask)   >> v->offsetRed)   << shift;
-        g = ((p & v->greenMask) >> v->offsetGreen) << shift;
-        b = ((p & v->blueMask)  >> v->offsetBlue)  << shift;
+        r = (p & v->redMask)   >> v->offsetRed;
+        g = (p & v->greenMask) >> v->offsetGreen;
+        b = (p & v->blueMask)  >> v->offsetBlue;
 
+        r = cMap->red[r].co.local.red;
+        g = cMap->green[g].co.local.green;
+        b = cMap->blue[b].co.local.blue;
+                
 #ifdef PSOUT_USE_DEEPCOLOR
         return((r<<32)|(g<<16)|b);
 #else
+        r >>= 8;
+        g >>= 8;
+        b >>= 8;
+
         return((r<<16)|(g<<8)|b);
 #endif /* PSOUT_USE_DEEPCOLOR */
     }
diff --git a/Xprint/ps/PsImageUtil.c b/Xprint/ps/PsImageUtil.c
new file mode 100644 (file)
index 0000000..c32cb54
--- /dev/null
@@ -0,0 +1,325 @@
+
+/* $Xorg: PsImageUtil.c,v 1.1 2005/03/25 1:19:56 gisburn Exp $ */
+/*
+Copyright (c) 2005 Roland Mainz <roland.mainz@nrubsig.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+
+/* Please do not beat me for this ugly code - most of it has been stolen from
+ * xc/lib/X11/ImUtil.c */
+
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "attributes.h"
+
+static unsigned char const _reverse_byte[0x100] = {
+        0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+        0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+        0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+        0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+        0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+        0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+        0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+        0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+        0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+        0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+        0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+        0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+        0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+        0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+        0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+        0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+        0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+        0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+        0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+        0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+        0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+        0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+        0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+        0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+        0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+        0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+        0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+        0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+        0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+        0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+        0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+        0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+};
+
+static
+int XReverse_Bytes(
+    register unsigned char *bpt,
+    register int nb)
+{
+    do {
+        *bpt = _reverse_byte[*bpt];
+        bpt++;
+    } while (--nb > 0);
+    return 0;
+}
+
+/*
+ * Data structure for "image" data, used by image manipulation routines.
+ */
+typedef struct {
+    int width, height;          /* size of image */
+    int xoffset;                /* number of pixels offset in X direction */
+    int format;                 /* XYBitmap, XYPixmap, ZPixmap */
+    char *data;                 /* pointer to image data */
+    int byte_order;             /* data byte order, LSBFirst, MSBFirst */
+    int bitmap_unit;            /* quant. of scanline 8, 16, 32 */
+    int bitmap_bit_order;       /* LSBFirst, MSBFirst */
+    int depth;                  /* depth of image */
+    int bytes_per_line;         /* accelarator to next line */
+    int bits_per_pixel;         /* bits per pixel (ZPixmap) */
+} TmpImage;
+
+
+static void xynormalizeimagebits (
+    register unsigned char *bp,
+    register TmpImage *img)
+{
+       register unsigned char c;
+
+       if (img->byte_order != img->bitmap_bit_order) {
+           switch (img->bitmap_unit) {
+
+               case 16:
+                   c = *bp;
+                   *bp = *(bp + 1);
+                   *(bp + 1) = c;
+                   break;
+
+               case 32:
+                   c = *(bp + 3);
+                   *(bp + 3) = *bp;
+                   *bp = c;
+                   c = *(bp + 2);
+                   *(bp + 2) = *(bp + 1);
+                   *(bp + 1) = c;
+                   break;
+           }
+       }
+       if (img->bitmap_bit_order == MSBFirst)
+           XReverse_Bytes (bp, img->bitmap_unit >> 3);
+}
+
+static void znormalizeimagebits (
+    register unsigned char *bp,
+    register TmpImage *img)
+{
+       register unsigned char c;
+       switch (img->bits_per_pixel) {
+
+           case 4:
+               *bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF);
+               break;
+
+           case 16:
+               c = *bp;
+               *bp = *(bp + 1);
+               *(bp + 1) = c;
+               break;
+
+           case 24:
+               c = *(bp + 2);
+               *(bp + 2) = *bp;
+               *bp = c;
+               break;
+
+           case 32:
+               c = *(bp + 3);
+               *(bp + 3) = *bp;
+               *bp = c;
+               c = *(bp + 2);
+               *(bp + 2) = *(bp + 1);
+               *(bp + 1) = c;
+               break;
+       }
+}
+
+/*
+ * Macros
+ * 
+ * The ROUNDUP macro rounds up a quantity to the specified boundary,
+ * then truncates to bytes.
+ *
+ * The XYNORMALIZE macro determines whether XY format data requires 
+ * normalization and calls a routine to do so if needed. The logic in
+ * this module is designed for LSBFirst byte and bit order, so 
+ * normalization is done as required to present the data in this order.
+ *
+ * The ZNORMALIZE macro performs byte and nibble order normalization if 
+ * required for Z format data.
+ *
+ * The XYINDEX macro computes the index to the starting byte (char) boundary
+ * for a bitmap_unit containing a pixel with coordinates x and y for image
+ * data in XY format.
+ * 
+ * The ZINDEX macro computes the index to the starting byte (char) boundary 
+ * for a pixel with coordinates x and y for image data in ZPixmap format.
+ * 
+ */
+
+#if defined(Lynx) && defined(ROUNDUP)
+#undef ROUNDUP
+#endif
+
+#define ROUNDUP(nbytes, pad) ((((nbytes) + ((pad)-1)) / (pad)) * ((pad)>>3))
+
+#define XYNORMALIZE(bp, img) \
+    if ((img->byte_order == MSBFirst) || (img->bitmap_bit_order == MSBFirst)) \
+       xynormalizeimagebits((unsigned char *)(bp), img)
+
+#define ZNORMALIZE(bp, img) \
+    if (img->byte_order == MSBFirst) \
+       znormalizeimagebits((unsigned char *)(bp), img)
+
+#define XYINDEX(x, y, img) \
+    ((y) * img->bytes_per_line) + \
+    (((x) + img->xoffset) / img->bitmap_unit) * (img->bitmap_unit >> 3)
+
+#define ZINDEX(x, y, img) ((y) * img->bytes_per_line) + \
+    (((x) * img->bits_per_pixel) >> 3)
+
+/*
+ * GetPixel
+ * 
+ * Returns the specified pixel.  The X and Y coordinates are relative to 
+ * the origin (upper left [0,0]) of the image.  The pixel value is returned
+ * in normalized format, i.e. the LSB of the long is the LSB of the pixel.
+ * The algorithm used is:
+ *
+ *     copy the source bitmap_unit or Zpixel into temp
+ *     normalize temp if needed
+ *     extract the pixel bits into return value
+ *
+ */
+
+static unsigned long const low_bits_table[] = {
+    0x00000000, 0x00000001, 0x00000003, 0x00000007,
+    0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
+    0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
+    0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
+    0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
+    0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
+    0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
+    0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
+    0xffffffff
+};
+
+static unsigned long XGetPixel (TmpImage *ximage, int x, int y)
+{
+       unsigned long pixel, px;
+       register char *src;
+       register char *dst;
+       register int i, j;
+       int bits, nbytes;
+       long plane;
+     
+       if ((ximage->bits_per_pixel | ximage->depth) == 1) {
+               src = &ximage->data[XYINDEX(x, y, ximage)];
+               dst = (char *)&pixel;
+               pixel = 0;
+               for (i = ximage->bitmap_unit >> 3; --i >= 0; ) *dst++ = *src++;
+               XYNORMALIZE(&pixel, ximage);
+               bits = (x + ximage->xoffset) % ximage->bitmap_unit;
+               pixel = ((((char *)&pixel)[bits>>3])>>(bits&7)) & 1;
+       } else if (ximage->format == XYPixmap) {
+               pixel = 0;
+               plane = 0;
+               nbytes = ximage->bitmap_unit >> 3;
+               for (i = ximage->depth; --i >= 0; ) {
+                   src = &ximage->data[XYINDEX(x, y, ximage)+ plane];
+                   dst = (char *)&px;
+                   px = 0;
+                   for (j = nbytes; --j >= 0; ) *dst++ = *src++;
+                   XYNORMALIZE(&px, ximage);
+                   bits = (x + ximage->xoffset) % ximage->bitmap_unit;
+                   pixel = (pixel << 1) |
+                           (((((char *)&px)[bits>>3])>>(bits&7)) & 1);
+                   plane = plane + (ximage->bytes_per_line * ximage->height);
+               }
+       } else if (ximage->format == ZPixmap) {
+               src = &ximage->data[ZINDEX(x, y, ximage)];
+               dst = (char *)&px;
+               px = 0;
+               for (i = (ximage->bits_per_pixel + 7) >> 3; --i >= 0; )
+                   *dst++ = *src++;            
+               ZNORMALIZE(&px, ximage);
+               pixel = 0;
+               for (i=sizeof(unsigned long); --i >= 0; )
+                   pixel = (pixel << 8) | ((unsigned char *)&px)[i];
+               if (ximage->bits_per_pixel == 4) {
+                   if (x & 1)
+                       pixel >>= 4;
+                   else
+                       pixel &= 0xf;
+               }
+       } else {
+               return 0; /* bad image */
+       }
+       if (ximage->bits_per_pixel == ximage->depth)
+         return pixel;
+       else
+         return (pixel & low_bits_table[ximage->depth]);
+}
+
+unsigned long
+PsGetImagePixel(char *pImage, int depth, int w, int h, int leftPad, int format,
+                int px, int py)
+{
+  TmpImage xi = {0};
+  
+  xi.width            = w;
+  xi.height           = h;
+  xi.xoffset          = 0/*leftPad*/;
+  xi.format           = format;
+  xi.data             = pImage;
+  xi.byte_order       = IMAGE_BYTE_ORDER;
+  xi.bitmap_bit_order = BITMAP_BIT_ORDER;
+  xi.bitmap_unit      = ((depth > 16)?(32):
+                        ((depth >  8)?(16):
+                        ((depth >  1)? (8):
+                                  (1))));
+  xi.depth            = depth;
+  xi.bits_per_pixel   = xi.bitmap_unit;
+
+  /*
+   * compute per line accelerator.
+   */
+  if (format == ZPixmap)
+      xi.bytes_per_line = 
+          ROUNDUP((xi.bits_per_pixel * xi.width), 32);
+  else
+      xi.bytes_per_line =
+          ROUNDUP((xi.width + xi.xoffset), 32); 
+
+  return XGetPixel(&xi, px, py);
+}
+
+
+
index a5f7a8a..8da6e0d 100644 (file)
@@ -121,12 +121,17 @@ InitializePsDriver(ndx, pScreen, argc, argv)
                     nv_1bit,  /* number of 8bit visuals */
                     nv_8bit,  /* number of 8bit visuals */
                     nv_12bit, /* number of 12bit visuals */
+                    nv_15bit, /* number of 15bit visuals */
+                    nv_16bit, /* number of 16bit visuals */
                     nv_24bit, /* number of 24bit visuals*/
                     nv_30bit; /* number of 30bit visuals*/
   int               nd;       /* number of depths */
+  int               defaultVisualIndex = -1;
   VisualID         *vids_1bit,
                    *vids_8bit,
                    *vids_12bit,
+                   *vids_15bit,
+                   *vids_16bit,
                    *vids_24bit,
                    *vids_30bit;
   VisualPtr         visuals;
@@ -187,15 +192,40 @@ InitializePsDriver(ndx, pScreen, argc, argv)
     /* Will BitmapToRegion make any difference at all? */
   pScreen->BitmapToRegion         = mfbPixmapToRegion;
 
-  visuals    = (VisualPtr) xalloc(8*sizeof(VisualRec));
-  depths     = (DepthPtr)  xalloc(8*sizeof(DepthRec));
-  vids_1bit  = (VisualID *)xalloc(8*sizeof(VisualID));
-  vids_8bit  = (VisualID *)xalloc(8*sizeof(VisualID));
-  vids_12bit = (VisualID *)xalloc(8*sizeof(VisualID));
-  vids_24bit = (VisualID *)xalloc(8*sizeof(VisualID));
-  vids_30bit = (VisualID *)xalloc(8*sizeof(VisualID));
+  visuals    = (VisualPtr) xalloc(16*sizeof(VisualRec));
+  depths     = (DepthPtr)  xalloc(16*sizeof(DepthRec));
+  vids_1bit  = (VisualID *)xalloc(16*sizeof(VisualID));
+  vids_8bit  = (VisualID *)xalloc(16*sizeof(VisualID));
+  vids_12bit = (VisualID *)xalloc(16*sizeof(VisualID));
+  vids_15bit = (VisualID *)xalloc(16*sizeof(VisualID));
+  vids_16bit = (VisualID *)xalloc(16*sizeof(VisualID));
+  vids_24bit = (VisualID *)xalloc(16*sizeof(VisualID));
+  vids_30bit = (VisualID *)xalloc(16*sizeof(VisualID));
 
-  nv = nv_1bit = nv_8bit = nv_12bit = nv_24bit = nv_30bit = nd = 0;
+  nv = nv_1bit = nv_8bit = nv_12bit = nv_15bit = nv_16bit = nv_24bit = nv_30bit = nd = 0;
+
+#ifdef PSOUT_USE_DEEPCOLOR
+/* gisburn: 30bit TrueColor has been disabled for now since it causes problems
+ * with GLX - see https://bugs.freedesktop.org/show_bug.cgi?id=2868 ("Mesa
+ * seems to be unable to handle 30bit TrueColor visuals") for details... 
+ */
+#ifdef DISABLED_FOR_NOW
+  /* TrueColor, 30bit, 10bit per R-,G-,B-gun */
+  visuals[nv].vid             = FakeClientID(0);
+  visuals[nv].class           = TrueColor;
+  visuals[nv].bitsPerRGBValue = 10;
+  visuals[nv].ColormapEntries = 1024;
+  visuals[nv].nplanes         = 30;
+  visuals[nv].redMask         = 0X3FF00000;
+  visuals[nv].greenMask       = 0X000FFC00;
+  visuals[nv].blueMask        = 0X000003FF;
+  visuals[nv].offsetRed       = 20;
+  visuals[nv].offsetGreen     = 10;
+  visuals[nv].offsetBlue      = 0;
+  vids_30bit[nv_30bit] = visuals[nv].vid;
+  nv++; nv_30bit++;
+#endif /* DISABLED_FOR_NOW */
+#endif /* PSOUT_USE_DEEPCOLOR */
 
   /* TrueColor, 24bit */
   visuals[nv].vid             = FakeClientID(0);
@@ -212,6 +242,86 @@ InitializePsDriver(ndx, pScreen, argc, argv)
   vids_24bit[nv_24bit] = visuals[nv].vid;
   nv++; nv_24bit++;
 
+  /* TrueColor, 16bit */
+  visuals[nv].vid             = FakeClientID(0);
+  visuals[nv].class           = TrueColor;
+  visuals[nv].bitsPerRGBValue = 6;
+  visuals[nv].ColormapEntries = 64;
+  visuals[nv].nplanes         = 16;
+  visuals[nv].redMask         = 0x0000f800;
+  visuals[nv].greenMask       = 0x000007e0;
+  visuals[nv].blueMask        = 0x0000001f;
+  visuals[nv].offsetRed       = 11;
+  visuals[nv].offsetGreen     = 5;
+  visuals[nv].offsetBlue      = 0;
+  vids_16bit[nv_16bit] = visuals[nv].vid;
+  nv++; nv_16bit++;
+  
+#ifdef PSOUT_USE_DEEPCOLOR
+  /* PostScript Level 2 and above, colors can have 12 bits per component
+   * (36 bit for RGB) */
+  /* PseudoColor, 15bit */
+  visuals[nv].vid             = FakeClientID(0);
+  visuals[nv].class           = PseudoColor;
+  visuals[nv].bitsPerRGBValue = 12;
+  visuals[nv].ColormapEntries = 32768;
+  visuals[nv].nplanes         = 15;
+  visuals[nv].redMask         = 0x0;
+  visuals[nv].greenMask       = 0x0;
+  visuals[nv].blueMask        = 0x0;
+  visuals[nv].offsetRed       = 0x0;
+  visuals[nv].offsetGreen     = 0x0;
+  visuals[nv].offsetBlue      = 0x0;
+  vids_15bit[nv_15bit] = visuals[nv].vid;
+  nv++; nv_15bit++;
+
+  /* PseudoColor, 12bit */
+  visuals[nv].vid             = FakeClientID(0);
+  visuals[nv].class           = PseudoColor;
+  visuals[nv].bitsPerRGBValue = 12;
+  visuals[nv].ColormapEntries = 4096;
+  visuals[nv].nplanes         = 12;
+  visuals[nv].redMask         = 0x0;
+  visuals[nv].greenMask       = 0x0;
+  visuals[nv].blueMask        = 0x0;
+  visuals[nv].offsetRed       = 0x0;
+  visuals[nv].offsetGreen     = 0x0;
+  visuals[nv].offsetBlue      = 0x0;
+  vids_12bit[nv_12bit] = visuals[nv].vid;
+  defaultVisualIndex = nv;
+  nv++; nv_12bit++;
+
+  /* GrayScale, 12bit, 12bit per R-,G-,B-gun */
+  visuals[nv].vid             = FakeClientID(0);
+  visuals[nv].class           = GrayScale;
+  visuals[nv].bitsPerRGBValue = 12;
+  visuals[nv].ColormapEntries = 4096;
+  visuals[nv].nplanes         = 12;
+  visuals[nv].redMask         = 0x0;
+  visuals[nv].greenMask       = 0x0;
+  visuals[nv].blueMask        = 0x0;
+  visuals[nv].offsetRed       = 0x0;
+  visuals[nv].offsetGreen     = 0x0;
+  visuals[nv].offsetBlue      = 0x0;
+  vids_12bit[nv_12bit] = visuals[nv].vid;
+  nv++; nv_12bit++;
+
+  /* StaticGray, 12bit, 12bit per R-,G-,B-gun */
+  visuals[nv].vid             = FakeClientID(0);
+  visuals[nv].class           = StaticGray;
+  visuals[nv].bitsPerRGBValue = 12;
+  visuals[nv].ColormapEntries = 4096;
+  visuals[nv].nplanes         = 12;
+  visuals[nv].redMask         = 0x0;
+  visuals[nv].greenMask       = 0x0;
+  visuals[nv].blueMask        = 0x0;
+  visuals[nv].offsetRed       = 0x0;
+  visuals[nv].offsetGreen     = 0x0;
+  visuals[nv].offsetBlue      = 0x0;
+  vids_12bit[nv_12bit] = visuals[nv].vid;
+  nv++; nv_12bit++;
+#endif /* PSOUT_USE_DEEPCOLOR */
+
   /* PseudoColor, 8bit */
   visuals[nv].vid             = FakeClientID(0);
   visuals[nv].class           = PseudoColor;
@@ -225,6 +335,9 @@ InitializePsDriver(ndx, pScreen, argc, argv)
   visuals[nv].offsetGreen     = 0x0;
   visuals[nv].offsetBlue      = 0x0;
   vids_8bit[nv_8bit] = visuals[nv].vid;
+#ifndef PSOUT_USE_DEEPCOLOR
+  defaultVisualIndex = nv;
+#endif /* !PSOUT_USE_DEEPCOLOR */
   nv++; nv_8bit++;
 
   /* GrayScale, 8bit */
@@ -272,56 +385,6 @@ InitializePsDriver(ndx, pScreen, argc, argv)
   vids_1bit[nv_1bit] = visuals[nv].vid;
   nv++; nv_1bit++;
 
-#ifdef PSOUT_USE_DEEPCOLOR
-  /* TrueColor, 30bit, 10bit per R-,G-,B-gun */
-  visuals[nv].vid             = FakeClientID(0);
-  visuals[nv].class           = TrueColor;
-  visuals[nv].bitsPerRGBValue = 10;
-  visuals[nv].ColormapEntries = 1024;
-  visuals[nv].nplanes         = 30;
-  visuals[nv].redMask         = 0X3FF00000;
-  visuals[nv].greenMask       = 0X000FFC00;
-  visuals[nv].blueMask        = 0X000003FF;
-  visuals[nv].offsetRed       = 20;
-  visuals[nv].offsetGreen     = 10;
-  visuals[nv].offsetBlue      = 0;
-  vids_30bit[nv_30bit] = visuals[nv].vid;
-  nv++; nv_30bit++;
-
-  /* PostScript Level 2 and above, colors can have 12 bits per component
-   * (36 bit for RGB) */
-
-  /* GrayScale, 12bit, 12bit per R-,G-,B-gun */
-  visuals[nv].vid             = FakeClientID(0);
-  visuals[nv].class           = GrayScale;
-  visuals[nv].bitsPerRGBValue = 12;
-  visuals[nv].ColormapEntries = 4096;
-  visuals[nv].nplanes         = 12;
-  visuals[nv].redMask         = 0x0;
-  visuals[nv].greenMask       = 0x0;
-  visuals[nv].blueMask        = 0x0;
-  visuals[nv].offsetRed       = 0x0;
-  visuals[nv].offsetGreen     = 0x0;
-  visuals[nv].offsetBlue      = 0x0;
-  vids_12bit[nv_12bit] = visuals[nv].vid;
-  nv++; nv_12bit++;
-
-  /* StaticGray, 12bit, 12bit per R-,G-,B-gun */
-  visuals[nv].vid             = FakeClientID(0);
-  visuals[nv].class           = StaticGray;
-  visuals[nv].bitsPerRGBValue = 12;
-  visuals[nv].ColormapEntries = 4096;
-  visuals[nv].nplanes         = 12;
-  visuals[nv].redMask         = 0x0;
-  visuals[nv].greenMask       = 0x0;
-  visuals[nv].blueMask        = 0x0;
-  visuals[nv].offsetRed       = 0x0;
-  visuals[nv].offsetGreen     = 0x0;
-  visuals[nv].offsetBlue      = 0x0;
-  vids_12bit[nv_12bit] = visuals[nv].vid;
-  nv++; nv_12bit++;
-#endif /* PSOUT_USE_DEEPCOLOR */
-
   if( nv_30bit > 0 )
   {
     depths[nd].depth   = 30;
@@ -338,6 +401,22 @@ InitializePsDriver(ndx, pScreen, argc, argv)
     nd++;
   }
 
+  if( nv_16bit > 0 )
+  {
+    depths[nd].depth   = 16;
+    depths[nd].numVids = nv_16bit;
+    depths[nd].vids    = vids_16bit;
+    nd++;
+  }
+
+  if( nv_15bit > 0 )
+  {
+    depths[nd].depth   = 15;
+    depths[nd].numVids = nv_15bit;
+    depths[nd].vids    = vids_15bit;
+    nd++;
+  }
+  
   if( nv_12bit > 0 )
   {
     depths[nd].depth   = 12;
@@ -362,9 +441,9 @@ InitializePsDriver(ndx, pScreen, argc, argv)
     nd++;
   }
 
-  /* Defaul visual is 8bit PseudoColor */
-  defaultVisual = visuals[1].vid;
-  rootDepth = visuals[1].nplanes;
+  /* Defaul visual is 12bit PseudoColor */
+  defaultVisual = visuals[defaultVisualIndex].vid;
+  rootDepth = visuals[defaultVisualIndex].nplanes;
 
 #ifdef GLXEXT
   {
index a9c7d4a..d60717b 100644 (file)
@@ -153,8 +153,28 @@ typedef enum PsFTDownloadFontType_
   PsFontType3
 } PsFTDownloadFontType;
 
+/* Define |PsOutColor| color type which can hold one RGB value
+ * (note: this needs to be |signed| long/long long to represent
+ * special values such as |PSOUTCOLOR_NOCOLOR|)
+ */
 #ifdef PSOUT_USE_DEEPCOLOR
-typedef long long PsOutColor;
+/* 64bit |PsOutColor| which can hold 16bit R-,G-,B-values */
+#ifdef WIN32
+typedef signed __int64    PsOutColor;
+#else
+# if defined(__alpha__) || defined(__alpha) || \
+     defined(ia64) || defined(__ia64__) || \
+     defined(__sparc64__) || defined(_LP64) || \
+     defined(__s390x__) || \
+     defined(amd64) || defined (__amd64__) || \
+     defined (__powerpc64__) || \
+     (defined(sgi) && (_MIPS_SZLONG == 64))
+typedef signed long       PsOutColor;
+# else
+typedef signed long long  PsOutColor;
+# endif /* native 64bit platform */
+#endif /* WIN32 */
+
 #define PSOUTCOLOR_TO_REDBITS(clr)    ((clr) >> 32)
 #define PSOUTCOLOR_TO_GREENBITS(clr)  (((clr) >> 16) & 0xFFFF)
 #define PSOUTCOLOR_TO_BLUEBITS(clr)   ((clr) & 0xFFFF)
@@ -165,7 +185,8 @@ typedef long long PsOutColor;
                                        ((PSOUTCOLOR_TO_GREENBITS(clr) >> 8) << 8)  | \
                                        ((PSOUTCOLOR_TO_BLUEBITS(clr)  >> 8) << 0))
 #else
-typedef long PsOutColor;
+/* 32bit |PsOutColor| which can hold 8bit R-,G-,B-values */
+typedef signed long PsOutColor;
 #define PSOUTCOLOR_TO_REDBITS(clr)    ((clr) >> 16)
 #define PSOUTCOLOR_TO_GREENBITS(clr)  (((clr) >> 8) & 0xFF)
 #define PSOUTCOLOR_TO_BLUEBITS(clr)   ((clr) & 0xFF)