frontend: Fix colorspace conversion routines on big-endian
authorPaul Cercueil <paul@crapouillou.net>
Sat, 21 May 2022 17:58:14 +0000 (18:58 +0100)
committernotaz <notasas@gmail.com>
Fri, 29 Jul 2022 20:48:40 +0000 (23:48 +0300)
The bgr555_to_rgb565() and bgr888_to_rgb565() functions were only
working correctly on little-endian systems.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
frontend/cspace.c

index 33a981d..f60026c 100644 (file)
  * in favor of NEON version or platform-specific conversion
  */
 
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#define SWAP16(x) __builtin_bswap16(x)
+#define LE16TOHx2(x) ((SWAP16((x) >> 16) << 16) | SWAP16(x))
+#else
+#define LE16TOHx2(x) (x)
+#endif
+
 #ifndef __arm__
 
 void bgr555_to_rgb565(void *dst_, const void *src_, int bytes)
 {
        const unsigned int *src = src_;
        unsigned int *dst = dst_;
-       unsigned int p;
-       int x;
+       unsigned int x, p, r, g, b;
 
        for (x = 0; x < bytes / 4; x++) {
-               p = src[x];
-               p = ((p & 0x7c007c00) >> 10) | ((p & 0x03e003e0) << 1)
-                       | ((p & 0x001f001f) << 11);
-               dst[x] = p;
+               p = LE16TOHx2(src[x]);
+
+               r = (p & 0x001f001f) << 11;
+               g = (p & 0x03e003e0) << 1;
+               b = (p & 0x7c007c00) >> 10;
+
+               dst[x] = r | g | b;
        }
 }
 
@@ -49,8 +58,13 @@ void bgr888_to_rgb565(void *dst_, const void *src_, int bytes)
                r2 = src[3] & 0xf8;
                g2 = src[4] & 0xfc;
                b2 = src[5] & 0xf8;
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+               *dst = (r1 << 24) | (g1 << 19) | (b1 << 13) |
+                       (r2 << 8) | (g2 << 3) | (b2 >> 3);
+#else
                *dst = (r2 << 24) | (g2 << 19) | (b2 << 13) |
                        (r1 << 8) | (g1 << 3) | (b1 >> 3);
+#endif
        }
 }