aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorinmarket <andrewh@inmarket.com.au>2015-11-12 18:33:12 +1000
committerinmarket <andrewh@inmarket.com.au>2015-11-12 18:33:12 +1000
commitd403294cb430c1dfb811880a3b8280a616c3d279 (patch)
tree502faabc1a5c63808075fd4efc44dabef6351905 /src
parent2928950e47903d09c418427f107d5854cea20638 (diff)
downloaduGFX-d403294cb430c1dfb811880a3b8280a616c3d279.tar.gz
uGFX-d403294cb430c1dfb811880a3b8280a616c3d279.tar.bz2
uGFX-d403294cb430c1dfb811880a3b8280a616c3d279.zip
More endian updates. Images should now work for any endian machine even strange ones.
Diffstat (limited to 'src')
-rw-r--r--src/gdisp/gdisp_image.c45
-rw-r--r--src/gdisp/gdisp_image_support.h52
2 files changed, 85 insertions, 12 deletions
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" {