]> source.dussan.org Git - tigervnc.git/commitdiff
Make sure we handle endian problems in the conversion code.
authorPierre Ossman <ossman@cendio.se>
Tue, 21 Apr 2009 17:30:45 +0000 (17:30 +0000)
committerPierre Ossman <ossman@cendio.se>
Tue, 21 Apr 2009 17:30:45 +0000 (17:30 +0000)
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@3784 3789f03b-4d11-0410-bbf8-ca57d06f2519

common/rfb/PixelFormat.cxx
common/rfb/PixelFormat.h
common/rfb/PixelFormat.inl

index a106cf36e26d6e5cd50646c2e19b1b4ad4362559..afcf4295e4bdd9766eb4f6a4d982d5b847abbc66 100644 (file)
@@ -42,7 +42,7 @@ PixelFormat::PixelFormat(int b, int d, bool e, bool t,
   assert((greenMax & (greenMax + 1)) == 0);
   assert((blueMax & (blueMax + 1)) == 0);
 
-  updateShifts();
+  updateState();
 }
 
 PixelFormat::PixelFormat()
@@ -50,7 +50,7 @@ PixelFormat::PixelFormat()
     redMax(7), greenMax(7), blueMax(3),
     redShift(0), greenShift(3), blueShift(6)
 {
-  updateShifts();
+  updateState();
 }
 
 bool PixelFormat::equal(const PixelFormat& other) const
@@ -81,7 +81,7 @@ void PixelFormat::read(rdr::InStream* is)
   blueShift = is->readU8();
   is->skip(3);
 
-  updateShifts();
+  updateState();
 }
 
 void PixelFormat::write(rdr::OutStream* os) const
@@ -387,7 +387,7 @@ bool PixelFormat::parse(const char* str)
     return false;
   }
 
-  updateShifts();
+  updateState();
 
   return true;
 }
@@ -419,9 +419,10 @@ static int bits(rdr::U16 value)
   return bits;
 }
 
-void PixelFormat::updateShifts(void)
+void PixelFormat::updateState(void)
 {
   int redBits, greenBits, blueBits;
+  int endianTest = 1;
 
   redBits = bits(redMax);
   greenBits = bits(greenMax);
@@ -430,4 +431,9 @@ void PixelFormat::updateShifts(void)
   redConvShift = 16 - redBits;
   greenConvShift = 16 - greenBits;
   blueConvShift = 16 - blueBits;
+
+  if (((*(char*)&endianTest) == 0) != bigEndian)
+    endianMismatch = true;
+  else
+    endianMismatch = false;
 }
index 8adbf911052b179542666c822a34352c52c6f0ee..c1de09a98bfbee014d2eb14c7dd8519ba198f3d6 100644 (file)
@@ -64,7 +64,7 @@ namespace rfb {
     bool parse(const char* str);
 
   protected:
-    void updateShifts(void);
+    void updateState(void);
 
   public:
     int bpp;
@@ -85,6 +85,7 @@ namespace rfb {
     int redConvShift;
     int greenConvShift;
     int blueConvShift;
+    bool endianMismatch;
   };
 }
 
index 90d8e6da9de7b25112c696cd369e7435f7e7ee85..ca83a30572ab666d1ff058d5c3888244acf61f19 100644 (file)
@@ -75,9 +75,16 @@ inline void PixelFormat::bufferFromPixel(rdr::U8* buffer, Pixel p) const
 }
 
 
+#define _rfb_bswap_32(x) \
+        ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) | \
+         (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
+
+
 inline void PixelFormat::rgbFromPixel(Pixel p, ColourMap* cm, rdr::U16 *r, rdr::U16 *g, rdr::U16 *b) const
 {
   if (trueColour) {
+    if (endianMismatch)
+      p = _rfb_bswap_32(p);
     /* We don't need to mask since we shift out unwanted bits */
     *r = (p >> redShift) << redConvShift;
     *g = (p >> greenShift) << greenConvShift;
@@ -100,6 +107,8 @@ inline void PixelFormat::rgbFromPixel(Pixel p, ColourMap* cm, rdr::U16 *r, rdr::
 inline void PixelFormat::rgbFromPixel(Pixel p, ColourMap* cm, rdr::U8 *r, rdr::U8 *g, rdr::U8 *b) const
 {
   if (trueColour) {
+    if (endianMismatch)
+      p = _rfb_bswap_32(p);
     *r = (p >> redShift) << (redConvShift - 8);
     *g = (p >> greenShift) << (greenConvShift - 8);
     *b = (p >> blueShift) << (blueConvShift - 8);