From d403294cb430c1dfb811880a3b8280a616c3d279 Mon Sep 17 00:00:00 2001 From: inmarket Date: Thu, 12 Nov 2015 18:33:12 +1000 Subject: [PATCH] More endian updates. Images should now work for any endian machine even strange ones. --- gfx.h | 22 +++++++++----- src/gdisp/gdisp_image.c | 45 ++++++++++++++++++++++++++-- src/gdisp/gdisp_image_support.h | 52 ++++++++++++++++++++++++++------- 3 files changed, 99 insertions(+), 20 deletions(-) diff --git a/gfx.h b/gfx.h index a6eb9cf7..aeced09e 100644 --- a/gfx.h +++ b/gfx.h @@ -269,8 +269,10 @@ #define GFX_CPU_ENDIAN GFX_CPU_ENDIAN_UNKNOWN #endif #define GFX_CPU_ENDIAN_UNKNOWN 0 //**< Unknown endianness - #define GFX_CPU_ENDIAN_LITTLE 0x04030201 //**< Little Endian - #define GFX_CPU_ENDIAN_BIG 0x01020304 //**< Big Endian + #define GFX_CPU_ENDIAN_LITTLE 0x03020100 //**< Little endian + #define GFX_CPU_ENDIAN_BIG 0x00010203 //**< Big endian + #define GFX_CPU_ENDIAN_WBDWL 0x02030001 //**< Words are big endian, DWords are little endian eg. Honeywell 316 + #define GFX_CPU_ENDIAN_WLDWB 0x01000302 //**< Words are little endian, DWords are big endian eg PDP-11 /** @} */ /** @} */ @@ -369,14 +371,18 @@ #if GFX_CPU_ENDIAN == GFX_CPU_ENDIAN_UNKNOWN #undef GFX_CPU_ENDIAN #if (defined(__BYTE_ORDER__)&&(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) \ - || defined(__LITTLE_ENDIAN__) \ - || defined(__LITTLE_ENDIAN) \ - || defined(_LITTLE_ENDIAN) + || defined(__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN) \ + || defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) \ + || defined(__THUMBEL__) \ + || defined(__AARCH64EL__) \ + || defined(__ARMEL__) #define GFX_CPU_ENDIAN GFX_CPU_ENDIAN_LITTLE #elif (defined(__BYTE_ORDER__)&&(__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) \ - || defined(__BIG_ENDIAN__) \ - || defined(__BIG_ENDIAN) \ - || defined(_BIG_ENDIAN) + || defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN) \ + || defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) \ + || defined(__THUMBEB__) \ + || defined(__AARCH64EB__) \ + || defined(__ARMEB__) #define GFX_CPU_ENDIAN GFX_CPU_ENDIAN_BIG #else #define GFX_CPU_ENDIAN GFX_CPU_ENDIAN_UNKNOWN diff --git a/src/gdisp/gdisp_image.c b/src/gdisp/gdisp_image.c index 7da3d90e..87d11065 100644 --- a/src/gdisp/gdisp_image.c +++ b/src/gdisp/gdisp_image.c @@ -191,8 +191,49 @@ void gdispImageFree(gdispImage *img, void *ptr, size_t sz) { #endif } -#if GFX_CPU_ENDIAN != GFX_CPU_ENDIAN_LITTLE && GFX_CPU_ENDIAN != GFX_CPU_ENDIAN_BIG - const uint8_t gdispImageEndianArray[4] = { 1, 2, 3, 4 }; +#if GFX_CPU_ENDIAN != GFX_CPU_ENDIAN_LITTLE && GFX_CPU_ENDIAN != GFX_CPU_ENDIAN_BIG \ + && GFX_CPU_ENDIAN != GFX_CPU_ENDIAN_WBDWL && GFX_CPU_ENDIAN != GFX_CPU_ENDIAN_WLDWB + + union wbyteorder_u { + uint8_t b[2]; + uint32_t w; + }; + union dwbyteorder_u { + uint8_t b[4]; + uint32_t l; + }; + + uint16_t gdispImageH16toLE16(uint16_t w) { + union wbyteorder_u we; + + we.w = w; + return (((uint16_t)we.b[0]))|(((uint16_t)we.b[1]) << 8); + } + uint16_t gdispImageH16toBE16(uint16_t dw) { + union wbyteorder_u we; + + we.w = w; + return (((uint16_t)we.b[0]) << 8)|(((uint16_t)we.b[1])); + } + + uint32_t gdispImageH32toLE32(uint32_t dw) { + union dwbyteorder_u we; + + we.l = dw; + return (((uint32_t)we.b[0])) + |(((uint32_t)we.b[1]) << 8) + |(((uint32_t)we.b[2]) << 16) + |(((uint32_t)we.b[3]) << 24); + } + uint32_t gdispImageH32toBE32(uint32_t dw) { + union dwbyteorder_u we; + + we.l = dw; + return (((uint32_t)we.b[0]) << 24) + |(((uint32_t)we.b[1]) << 16) + |(((uint32_t)we.b[2]) << 8) + |(((uint32_t)we.b[3])); + } #endif #endif /* GFX_USE_GDISP && GDISP_NEED_IMAGE */ diff --git a/src/gdisp/gdisp_image_support.h b/src/gdisp/gdisp_image_support.h index a853f9e4..fee07e3b 100644 --- a/src/gdisp/gdisp_image_support.h +++ b/src/gdisp/gdisp_image_support.h @@ -23,6 +23,9 @@ #define gdispImageSwap16(w) ((((uint16_t)(w))>>8)|(((uint16_t)(w))<<8)) #define gdispImageSwap32(dw) ((((uint32_t)(w))>>24)|((((uint32_t)(w))&0x00FF0000)>>8)\ |((((uint32_t)(w))&0x0000FF00)<<8)|(((uint32_t)(w))<<24)) +#define gdispImageSwapWords32(dw) ((((uint32_t)(w))>>16)|(((uint32_t)(w))<<16)) +#define gdispImageSwapBytes32(dw) (((((uint32_t)(w))&0xFF000000)>>8)|((((uint32_t)(w))&0x00FF0000)<<8)\ + |((((uint32_t)(w))&0x0000FF00)>>8)|(((uint32_t)(w))<<8)) /* * Get a uint16_t/uint32_t from memory in the required endianness. @@ -70,24 +73,53 @@ * Change a uint16 or uint32 already in a register to the required endianness. */ #if GFX_CPU_ENDIAN == GFX_CPU_ENDIAN_LITTLE + #define gdispImageH16toLE16(w) (w) + #define gdispImageH16toBE16(w) gdispImageSwap16(w) + #define gdispImageH32toLE32(dw) (dw) + #define gdispImageH32toBE32(dw) gdispImageSwap32(dw) #define gdispImageMakeLE16(w) + #define gdispImageMakeBE16(w) { w = gdispImageH16toBE16(w); } #define gdispImageMakeLE32(dw) - #define gdispImageMakeBE16(w) { w = gdispImageSwap16(w); } - #define gdispImageMakeBE32(dw) { dw = gdispImageSwap32(dw); } + #define gdispImageMakeBE32(dw) { dw = gdispImageH32toBE32(dw); } #elif GFX_CPU_ENDIAN == GFX_CPU_ENDIAN_BIG - #define gdispImageMakeLE16(w) { w = gdispImageSwap16(w); } - #define gdispImageMakeLE32(dw) { dw = gdispImageSwap32(dw); } + #define gdispImageH16toLE16(w) gdispImageSwap16(w) + #define gdispImageH16toBE16(w) (w) + #define gdispImageH32toLE32(dw) gdispImageSwap32(dw) + #define gdispImageH32toBE32(dw) (dw) + #define gdispImageMakeLE16(w) { w = gdispImageH16toLE16(w); } #define gdispImageMakeBE16(w) + #define gdispImageMakeLE32(dw) { dw = gdispImageH32toLE32(dw); } #define gdispImageMakeBE32(dw) +#elif GFX_CPU_ENDIAN == GFX_CPU_ENDIAN_WBDWL + #define gdispImageH16toLE16(w) gdispImageSwap16(w) + #define gdispImageH16toBE16(w) (w) + #define gdispImageH32toLE32(dw) gdispImageSwapBytes32(dw) + #define gdispImageH32toBE32(dw) gdispImageSwapWords32(dw) + #define gdispImageMakeLE16(w) { w = gdispImageH16toLE16(w); } + #define gdispImageMakeBE16(w) + #define gdispImageMakeLE32(dw) { dw = gdispImageH32toLE32(dw); } + #define gdispImageMakeBE32(dw) { dw = gdispImageH32toBE32(dw); } +#elif GFX_CPU_ENDIAN == GFX_CPU_ENDIAN_WLDWB + #define gdispImageH16toLE16(w) (w) + #define gdispImageH16toBE16(w) gdispImageSwap16(w) + #define gdispImageH32toLE32(dw) gdispImageSwapWords32(dw) + #define gdispImageH32toBE32(dw) gdispImageSwapBytes32(dw) + #define gdispImageMakeLE16(w) + #define gdispImageMakeBE16(w) { w = gdispImageH16toBE16(w); } + #define gdispImageMakeLE32(dw) { dw = gdispImageH32toLE32(dw); } + #define gdispImageMakeBE32(dw) { dw = gdispImageH32toBE32(dw); } #else - #define gdispImageEndianness() (*(uint32_t *)&gdispImageEndianArray) - - #define gdispImageMakeLE16(w) { if (gdispImageEndianness() != GFX_CPU_ENDIAN_LITTLE) w = gdispImageSwap16(w); } - #define gdispImageMakeLE32(dw) { if (gdispImageEndianness() != GFX_CPU_ENDIAN_LITTLE) dw = gdispImageSwap32(dw); } - #define gdispImageMakeBE16(w) { if (gdispImageEndianness() != GFX_CPU_ENDIAN_BIG) w = gdispImageSwap16(w); } - #define gdispImageMakeBE32(dw) { if (gdispImageEndianness() != GFX_CPU_ENDIAN_BIG) dw = gdispImageSwap32(dw); } + uint16_t gdispImageH16toLE16(uint16_t w); + uint16_t gdispImageH16toBE16(uint16_t w); + uint32_t gdispImageH32toLE32(uint32_t dw); + uint32_t gdispImageH32toBE32(uint32_t dw); + #define gdispImageMakeLE16(w) { w = gdispImageH16toLE16(w); } + #define gdispImageMakeBE16(w) { w = gdispImageH16toBE16(w); } + #define gdispImageMakeLE32(dw) { dw = gdispImageH32toLE32(dw); } + #define gdispImageMakeBE32(dw) { dw = gdispImageH32toBE32(dw); } #endif + #ifdef __cplusplus extern "C" {