From f48b492303d87349d054c80727000d9a66c9f094 Mon Sep 17 00:00:00 2001 From: inmarket Date: Wed, 11 Nov 2015 19:20:10 +1000 Subject: Clean up endian support for images based on new system defines Remove deprecated image functions --- src/gdisp/gdisp_image.c | 39 +++----------- src/gdisp/gdisp_image.h | 59 ---------------------- src/gdisp/gdisp_image_bmp.c | 84 ++++++++----------------------- src/gdisp/gdisp_image_gif.c | 60 ++++------------------ src/gdisp/gdisp_image_jpg.c | 2 + src/gdisp/gdisp_image_native.c | 2 + src/gdisp/gdisp_image_png.c | 2 + src/gdisp/gdisp_image_support.h | 109 ++++++++++++++++++++++++++++++++++++++++ 8 files changed, 150 insertions(+), 207 deletions(-) create mode 100644 src/gdisp/gdisp_image_support.h (limited to 'src') diff --git a/src/gdisp/gdisp_image.c b/src/gdisp/gdisp_image.c index 35020634..7da3d90e 100644 --- a/src/gdisp/gdisp_image.c +++ b/src/gdisp/gdisp_image.c @@ -9,6 +9,8 @@ #if GFX_USE_GDISP && GDISP_NEED_IMAGE +#include "gdisp_image_support.h" + #if GDISP_NEED_IMAGE_NATIVE extern gdispImageError gdispImageOpen_NATIVE(gdispImage *img); extern void gdispImageClose_NATIVE(gdispImage *img); @@ -90,39 +92,6 @@ static gdispImageHandlers ImageHandlers[] = { #endif }; -gdispImageError - DEPRECATED("Use gdispImageOpenGFile() instead") - gdispImageOpen(gdispImage *img) { - return gdispImageOpenGFile(img, img->f); -} - -#if GFILE_NEED_MEMFS - bool_t - DEPRECATED("Use gdispImageOpenMemory() instead") - gdispImageSetMemoryReader(gdispImage *img, const void *memimage) { - img->f = gfileOpenMemory((void *)memimage, "rb"); - return img->f != 0; - } -#endif - -#if defined(WIN32) || GFX_USE_OS_WIN32 || GFX_USE_OS_LINUX || GFX_USE_OS_OSX - bool_t - DEPRECATED("Use gdispImageOpenFile() instead") - gdispImageSetFileReader(gdispImage *img, const char *filename) { - img->f = gfileOpen(filename, "rb"); - return img->f != 0; - } -#endif - -#if GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS - bool_t - DEPRECATED("Use gdispImageOpenBaseFileStream() instead") - gdispImageSetBaseFileStreamReader(gdispImage *img, void *BaseFileStreamPtr) { - img->f = gfileOpenBaseFileStream(BaseFileStreamPtr, "rb"); - return img->f != 0; - } -#endif - void gdispImageInit(gdispImage *img) { img->type = GDISP_IMAGE_TYPE_UNKNOWN; } @@ -222,4 +191,8 @@ 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 }; +#endif + #endif /* GFX_USE_GDISP && GDISP_NEED_IMAGE */ diff --git a/src/gdisp/gdisp_image.h b/src/gdisp/gdisp_image.h index 1ab320e4..4613bea7 100644 --- a/src/gdisp/gdisp_image.h +++ b/src/gdisp/gdisp_image.h @@ -52,52 +52,6 @@ typedef uint16_t gdispImageFlags; #define GDISP_IMAGE_FLG_ANIMATED 0x0002 /* The image has animation */ #define GDISP_IMAGE_FLG_MULTIPAGE 0x0004 /* The image has multiple pages */ -struct gdispImageIO; - -/** - * @brief An image IO close function - * - * @param[in] pio Pointer to the io structure - * @param[in] desc The descriptor. A filename or an image structure pointer. - * - */ -typedef void (*gdispImageIOCloseFn)(struct gdispImageIO *pio); - -/** - * @brief An image IO read function - * @returns The number of bytes actually read or 0 on error - * - * @param[in] pio Pointer to the io structure - * @param[in] buf Where the results should be placed - * @param[in] len The number of bytes to read - * - */ -typedef size_t (*gdispImageIOReadFn)(struct gdispImageIO *pio, void *buf, size_t len); - -/** - * @brief An image IO seek function - * - * @param[in] pio Pointer to the io structure - * @param[in] pos Which byte to seek to relative to the start of the "file". - * - */ -typedef void (*gdispImageIOSeekFn)(struct gdispImageIO *pio, size_t pos); - -typedef struct gdispImageIOFunctions { - gdispImageIOReadFn read; /* @< The function to read input */ - gdispImageIOSeekFn seek; /* @< The function to seek input */ - gdispImageIOCloseFn close; /* @< The function to close input */ - } gdispImageIOFunctions; - -/** - * @brief The structure defining the IO routines for image handling - */ -typedef struct gdispImageIO { - const void * fd; /* @< The "file" descriptor */ - size_t pos; /* @< The current "file" position */ - const gdispImageIOFunctions *fns; /* @< The current "file" functions */ -} gdispImageIO; - /** * @brief The structure for an image */ @@ -119,19 +73,6 @@ typedef struct gdispImage { extern "C" { #endif - /* - * Deprecated Functions. - */ - gdispImageError DEPRECATED("Use gdispImageOpenGFile() instead") gdispImageOpen(gdispImage *img); - bool_t DEPRECATED("Use gdispImageOpenMemory() instead") gdispImageSetMemoryReader(gdispImage *img, const void *memimage); - #if GFX_USE_OS_CHIBIOS - bool_t DEPRECATED("Use gdispImageOpenBaseFileStream() instead") gdispImageSetBaseFileStreamReader(gdispImage *img, void *BaseFileStreamPtr); - #endif - #if defined(WIN32) || GFX_USE_OS_WIN32 || GFX_USE_OS_LINUX || GFX_USE_OS_OSX - bool_t DEPRECATED("Please use gdispImageOpenFile() instead") gdispImageSetFileReader(gdispImage *img, const char *filename); - #define gdispImageSetSimulFileReader(img, fname) gdispImageSetFileReader(img, fname) - #endif - /** * @brief Initialise a gdispImage object * diff --git a/src/gdisp/gdisp_image_bmp.c b/src/gdisp/gdisp_image_bmp.c index 9fc0e13a..dd45081a 100644 --- a/src/gdisp/gdisp_image_bmp.c +++ b/src/gdisp/gdisp_image_bmp.c @@ -9,11 +9,7 @@ #if GFX_USE_GDISP && GDISP_NEED_IMAGE && GDISP_NEED_IMAGE_BMP -/** - * Helper Routines Needed - */ -void *gdispImageAlloc(gdispImage *img, size_t sz); -void gdispImageFree(gdispImage *img, void *ptr, size_t sz); +#include "gdisp_image_support.h" /** * How big a pixel array to allocate for blitting (in pixels) @@ -22,36 +18,6 @@ void gdispImageFree(gdispImage *img, void *ptr, size_t sz); */ #define BLIT_BUFFER_SIZE 32 -/* - * Determining endianness as at compile time is not guaranteed or compiler portable. - * We use the best test we can. If we can't guarantee little endianness we do things the - * hard way. - */ -#define GUARANTEED_LITTLE_ENDIAN (!defined(SAFE_ENDIAN) && !defined(SAFE_ALIGNMENT) && (\ - (defined(__BYTE_ORDER__)&&(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) \ - || defined(__LITTLE_ENDIAN__) \ - || defined(__LITTLE_ENDIAN) \ - || defined(_LITTLE_ENDIAN) \ -/* || (1 == *(unsigned char *)&(const int){1})*/ \ - )) - - -/* This is a runtime test */ -static const uint8_t dwordOrder[4] = { 1, 2, 3, 4 }; - -#define isWordLittleEndian() (*(uint16_t *)&dwordOrder == 0x0201) -#define isDWordLittleEndian() (*(uint32_t *)&dwordOrder == 0x04030201) - -#if GUARANTEED_LITTLE_ENDIAN - /* These are fast routines for guaranteed little endian machines */ - #define CONVERT_FROM_WORD_LE(w) - #define CONVERT_FROM_DWORD_LE(dw) -#else - /* These are slower routines for when little endianness cannot be guaranteed at compile time */ - #define CONVERT_FROM_WORD_LE(w) { if (!isWordLittleEndian()) w = ((((uint16_t)(w))>>8)|(((uint16_t)(w))<<8)); } - #define CONVERT_FROM_DWORD_LE(dw) { if (!isDWordLittleEndian()) dw = (((uint32_t)(((const uint8_t *)(&dw))[0]))|(((uint32_t)(((const uint8_t *)(&dw))[1]))<<8)|(((uint32_t)(((const uint8_t *)(&dw))[2]))<<16)|(((uint32_t)(((const uint8_t *)(&dw))[3]))<<24)); } -#endif - typedef struct gdispImagePrivate { uint8_t bmpflags; #define BMP_V2 0x01 // Version 2 (old) header format @@ -141,14 +107,14 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) { /* Get the offset to the bitmap data */ if (gfileRead(img->f, &priv->frame0pos, 4) != 4) goto baddatacleanup; - CONVERT_FROM_DWORD_LE(priv->frame0pos); + gdispImageMakeLE32(priv->frame0pos); /* Process the BITMAPCOREHEADER structure */ /* Get the offset to the colour data */ if (gfileRead(img->f, &offsetColorTable, 4) != 4) goto baddatacleanup; - CONVERT_FROM_DWORD_LE(offsetColorTable); + gdispImageMakeLE32(offsetColorTable); offsetColorTable += 14; // Add the size of the BITMAPFILEHEADER // Detect our bitmap version @@ -159,23 +125,19 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) { if (gfileRead(img->f, priv->buf, 12-4) != 12-4) goto baddatacleanup; // Get the width - img->width = *(uint16_t *)(((uint8_t *)priv->buf)+0); - CONVERT_FROM_WORD_LE(img->width); + img->width = gdispImageGetAlignedLE16(priv->buf, 0); // Get the height - img->height = *(uint16_t *)(((uint8_t *)priv->buf)+2); - CONVERT_FROM_WORD_LE(img->height); + img->height = gdispImageGetAlignedLE16(priv->buf, 2); if (img->height < 0) { img->priv->bmpflags |= BMP_TOP_TO_BOTTOM; img->height = -img->height; } // Get the planes - aword = *(uint16_t *)(((uint8_t *)priv->buf)+4); - CONVERT_FROM_WORD_LE(aword); + aword = gdispImageGetAlignedLE16(priv->buf, 4); if (aword != 1) goto unsupportedcleanup; // Get the bits per pixel - aword = *(uint16_t *)(((uint8_t *)priv->buf)+6); - CONVERT_FROM_WORD_LE(aword); + aword = gdispImageGetAlignedLE16(priv->buf, 6); switch(aword) { #if GDISP_NEED_IMAGE_BMP_1 case 1: @@ -208,14 +170,12 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) { if (gfileRead(img->f, priv->buf, 40-4) != 40-4) goto baddatacleanup; // Get the width - adword = *(uint32_t *)(((uint8_t *)priv->buf)+0); - CONVERT_FROM_DWORD_LE(adword); + adword = gdispImageGetAlignedLE32(priv->buf, 0); if (adword > 32768) // This also picks up negative values goto unsupportedcleanup; img->width = adword; // Get the height - adword = *(uint32_t *)(((uint8_t *)priv->buf)+4); - CONVERT_FROM_DWORD_LE(adword); + adword = gdispImageGetAlignedLE32(priv->buf, 4); if ((int32_t)adword < 0) { // Negative test priv->bmpflags |= BMP_TOP_TO_BOTTOM; adword = -adword; @@ -224,13 +184,11 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) { goto unsupportedcleanup; img->height = adword; // Get the planes - aword = *(uint16_t *)(((uint8_t *)priv->buf)+8); - CONVERT_FROM_WORD_LE(aword); + aword = gdispImageGetAlignedLE16(priv->buf, 8); if (aword != 1) goto unsupportedcleanup; // Get the bits per pixel - aword = *(uint16_t *)(((uint8_t *)priv->buf)+10); - CONVERT_FROM_WORD_LE(aword); + aword = gdispImageGetAlignedLE16(priv->buf, 10); switch(aword) { #if GDISP_NEED_IMAGE_BMP_1 case 1: @@ -263,8 +221,7 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) { } priv->bitsperpixel = aword; // Get the compression - adword = *(uint32_t *)(((uint8_t *)priv->buf)+12); - CONVERT_FROM_DWORD_LE(adword); + adword = gdispImageGetAlignedLE32(priv->buf, 12); switch(adword) { case 0: // BI_RGB - uncompressed break; @@ -297,8 +254,7 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) { priv->bitsperpixel = aword; #if GDISP_NEED_IMAGE_BMP_1 || GDISP_NEED_IMAGE_BMP_4 || GDISP_NEED_IMAGE_BMP_4_RLE || GDISP_NEED_IMAGE_BMP_8 || GDISP_NEED_IMAGE_BMP_8_RLE // Get the actual colors used - adword = *(uint32_t *)(((uint8_t *)priv->buf)+28); - CONVERT_FROM_DWORD_LE(adword); + adword = gdispImageGetAlignedLE32(priv->buf, 28); if (adword && adword < priv->palsize) priv->palsize = adword; #endif @@ -332,14 +288,14 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) { if (priv->bmpflags & BMP_COMP_MASK) { gfileSetPos(img->f, offsetColorTable); if (gfileRead(img->f, &priv->maskred, 4) != 4) goto baddatacleanup; - CONVERT_FROM_DWORD_LE(priv->maskred); + gdispImageMakeLE32(priv->maskred); if (gfileRead(img->f, &priv->maskgreen, 4) != 4) goto baddatacleanup; - CONVERT_FROM_DWORD_LE(priv->maskgreen); + gdispImageMakeLE32(priv->maskgreen); if (gfileRead(img->f, &priv->maskblue, 4) != 4) goto baddatacleanup; - CONVERT_FROM_DWORD_LE(priv->maskblue); + gdispImageMakeLE32(priv->maskblue); if (priv->bmpflags & BMP_V4) { if (gfileRead(img->f, &priv->maskalpha, 4) != 4) goto baddatacleanup; - CONVERT_FROM_DWORD_LE(priv->maskalpha); + gdispImageMakeLE32(priv->maskalpha); } else priv->maskalpha = 0; } else if (priv->bitsperpixel == 16) { @@ -644,8 +600,8 @@ static coord_t getPixels(gdispImage *img, coord_t x) { while(x < img->width && len <= BLIT_BUFFER_SIZE-2) { if (gfileRead(img->f, &w, 4) != 4) return 0; - CONVERT_FROM_WORD_LE(w[0]); - CONVERT_FROM_WORD_LE(w[1]); + gdispImageMakeLE16(w[0]); + gdispImageMakeLE16(w[1]); if (priv->shiftred < 0) r = (color_t)((w[0] & priv->maskred) << -priv->shiftred); else @@ -712,7 +668,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { while(x < img->width && len < BLIT_BUFFER_SIZE) { if (gfileRead(img->f, &dw, 4) != 4) return 0; - CONVERT_FROM_DWORD_LE(dw); + gdispImageMakeLE32(dw); if (priv->shiftred < 0) r = (color_t)((dw & priv->maskred) << -priv->shiftred); else diff --git a/src/gdisp/gdisp_image_gif.c b/src/gdisp/gdisp_image_gif.c index 88dac4c8..515d67e8 100644 --- a/src/gdisp/gdisp_image_gif.c +++ b/src/gdisp/gdisp_image_gif.c @@ -9,11 +9,7 @@ #if GFX_USE_GDISP && GDISP_NEED_IMAGE && GDISP_NEED_IMAGE_GIF -/** - * Helper Routines Needed - */ -void *gdispImageAlloc(gdispImage *img, size_t sz); -void gdispImageFree(gdispImage *img, void *ptr, size_t sz); +#include "gdisp_image_support.h" /** * How big an array to allocate for blitting (in pixels) @@ -21,36 +17,6 @@ void gdispImageFree(gdispImage *img, void *ptr, size_t sz); */ #define BLIT_BUFFER_SIZE 32 -/* - * Determining endianness as at compile time is not guaranteed or compiler portable. - * We use the best test we can. If we can't guarantee little endianness we do things the - * hard way. - */ -#define GUARANTEED_LITTLE_ENDIAN (!defined(SAFE_ENDIAN) && !defined(SAFE_ALIGNMENT) && (\ - (defined(__BYTE_ORDER__)&&(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) \ - || defined(__LITTLE_ENDIAN__) \ - || defined(__LITTLE_ENDIAN) \ - || defined(_LITTLE_ENDIAN) \ -/* || (1 == *(unsigned char *)&(const int){1})*/ \ - )) - - -/* This is a runtime test */ -static const uint8_t dwordOrder[4] = { 1, 2, 3, 4 }; - -#define isWordLittleEndian() (*(uint16_t *)&dwordOrder == 0x0201) -#define isDWordLittleEndian() (*(uint32_t *)&dwordOrder == 0x04030201) - -#if GUARANTEED_LITTLE_ENDIAN - /* These are fast routines for guaranteed little endian machines */ - #define CONVERT_FROM_WORD_LE(w) - #define CONVERT_FROM_DWORD_LE(dw) -#else - /* These are slower routines for when little endianness cannot be guaranteed at compile time */ - #define CONVERT_FROM_WORD_LE(w) { if (!isWordLittleEndian()) w = ((((uint16_t)(w))>>8)|(((uint16_t)(w))<<8)); } - #define CONVERT_FROM_DWORD_LE(dw) { if (!isDWordLittleEndian()) dw = (((uint32_t)(((const uint8_t *)(&dw))[0]))|(((uint32_t)(((const uint8_t *)(&dw))[1]))<<8)|(((uint32_t)(((const uint8_t *)(&dw))[2]))<<16)|(((uint32_t)(((const uint8_t *)(&dw))[3]))<<24)); } -#endif - // We need a special error to indicate the end of file (which may not actually be an error) #define GDISP_IMAGE_EOF ((gdispImageError)-1) #define GDISP_IMAGE_LOOP ((gdispImageError)-2) @@ -416,14 +382,10 @@ static gdispImageError initFrame(gdispImage *img) { // Read the Image Descriptor if (gfileRead(img->f, priv->buf, 9) != 9) return GDISP_IMAGE_ERR_BADDATA; - priv->frame.x = *(uint16_t *)(((uint8_t *)priv->buf)+0); - CONVERT_FROM_WORD_LE(priv->frame.x); - priv->frame.y = *(uint16_t *)(((uint8_t *)priv->buf)+2); - CONVERT_FROM_WORD_LE(priv->frame.y); - priv->frame.width = *(uint16_t *)(((uint8_t *)priv->buf)+4); - CONVERT_FROM_WORD_LE(priv->frame.width); - priv->frame.height = *(uint16_t *)(((uint8_t *)priv->buf)+6); - CONVERT_FROM_WORD_LE(priv->frame.height); + priv->frame.x = gdispImageGetAlignedLE16(priv->buf, 0); + priv->frame.y = gdispImageGetAlignedLE16(priv->buf, 2); + priv->frame.width = gdispImageGetAlignedLE16(priv->buf, 4); + priv->frame.height = gdispImageGetAlignedLE16(priv->buf, 6); if (((uint8_t *)priv->buf)[8] & 0x80) // Local color table? priv->frame.palsize = 2 << (((uint8_t *)priv->buf)[8] & 0x07); if (((uint8_t *)priv->buf)[8] & 0x40) // Interlaced? @@ -468,8 +430,7 @@ static gdispImageError initFrame(gdispImage *img) { else img->flags &= ~GDISP_IMAGE_FLG_MULTIPAGE; // Process frame delay and the transparent color (if any) - priv->frame.delay = *(uint16_t *)(((uint8_t *)priv->buf)+2); - CONVERT_FROM_WORD_LE(priv->frame.delay); + priv->frame.delay = gdispImageGetAlignedLE16(priv->buf, 2); priv->frame.paltrans = ((uint8_t *)priv->buf)[4]; break; @@ -489,8 +450,7 @@ static gdispImageError initFrame(gdispImage *img) { && ((uint8_t *)priv->buf)[7] == 'P' && ((uint8_t *)priv->buf)[8] == 'E' && ((uint8_t *)priv->buf)[9] == '2' && ((uint8_t *)priv->buf)[10] == '.' && ((uint8_t *)priv->buf)[11] == '0') { if (((uint8_t *)priv->buf)[13] == 1) { - priv->loops = *(uint16_t *)(((uint8_t *)priv->buf)+14); - CONVERT_FROM_WORD_LE(priv->loops); + priv->loops = gdispImageGetAlignedLE16(priv->buf, 14); priv->flags |= GIF_LOOP; if (!priv->loops) priv->flags |= GIF_LOOPFOREVER; @@ -597,11 +557,9 @@ gdispImageError gdispImageOpen_GIF(gdispImage *img) { if (gfileRead(img->f, priv->buf, 7) != 7) goto baddatacleanup; // Get the width - img->width = *(uint16_t *)(((uint8_t *)priv->buf)+0); - CONVERT_FROM_WORD_LE(img->width); + img->width = gdispImageGetAlignedLE16(priv->buf, 0); // Get the height - img->height = *(uint16_t *)(((uint8_t *)priv->buf)+2); - CONVERT_FROM_WORD_LE(img->height); + img->height = gdispImageGetAlignedLE16(priv->buf, 2); if (((uint8_t *)priv->buf)[4] & 0x80) { // Global color table priv->palsize = 2 << (((uint8_t *)priv->buf)[4] & 0x07); diff --git a/src/gdisp/gdisp_image_jpg.c b/src/gdisp/gdisp_image_jpg.c index 02ec9a8f..0f856e2c 100644 --- a/src/gdisp/gdisp_image_jpg.c +++ b/src/gdisp/gdisp_image_jpg.c @@ -9,6 +9,8 @@ #if GFX_USE_GDISP && GDISP_NEED_IMAGE && GDISP_NEED_IMAGE_JPG +#include "gdisp_image_support.h" + #error "JPG support not implemented yet" #endif /* GFX_USE_GDISP && GDISP_NEED_IMAGE && GDISP_NEED_IMAGE_JPG */ diff --git a/src/gdisp/gdisp_image_native.c b/src/gdisp/gdisp_image_native.c index ec22f386..347738bd 100644 --- a/src/gdisp/gdisp_image_native.c +++ b/src/gdisp/gdisp_image_native.c @@ -9,6 +9,8 @@ #if GFX_USE_GDISP && GDISP_NEED_IMAGE && GDISP_NEED_IMAGE_NATIVE +#include "gdisp_image_support.h" + /** * How big a pixel array to allocate for blitting * Bigger is faster but uses more RAM. diff --git a/src/gdisp/gdisp_image_png.c b/src/gdisp/gdisp_image_png.c index 6538b2ff..b6e70d91 100644 --- a/src/gdisp/gdisp_image_png.c +++ b/src/gdisp/gdisp_image_png.c @@ -9,6 +9,8 @@ #if GFX_USE_GDISP && GDISP_NEED_IMAGE && GDISP_NEED_IMAGE_PNG +#include "gdisp_image_support.h" + #error "PNG support not implemented yet" #endif /* GFX_USE_GDISP && GDISP_NEED_IMAGE && GDISP_NEED_IMAGE_PNG */ diff --git a/src/gdisp/gdisp_image_support.h b/src/gdisp/gdisp_image_support.h new file mode 100644 index 00000000..a853f9e4 --- /dev/null +++ b/src/gdisp/gdisp_image_support.h @@ -0,0 +1,109 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * @file src/gdisp/gdisp_image_support.h + * @brief GDISP image support routines header file. + * + * @defgroup Image Image + * @ingroup GDISP + * @{ + */ + +#ifndef _GDISP_IMAGE_SUPPORT_H +#define _GDISP_IMAGE_SUPPORT_H + +/* Base endian handling routines */ +#define gdispImageGetVar(type, p, idx) (*(type *)(((uint8_t *)(p))+(idx))) +#define gdispImageGetByte(type, p, idx, shift) (((type)gdispImageGetVar(uint8_t, p, idx))<<(shift)) +#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)) + +/* + * Get a uint16_t/uint32_t from memory in the required endianness. + * There is no alignment requirement. + */ +#if GFX_CPU_ENDIAN == GFX_CPU_ENDIAN_LITTLE && GFX_CPU_NO_ALIGNMENT_FAULTS + #define gidspImageGetLE16(p, idx) gdispImageGetVar(uint16_t, (p), (idx)) + #define gidspImageGetLE32(p, idx) gdispImageGetVar(uint32_t, (p), (idx)) +#else + #define gdispImageGetLE16(p, idx) ( gdispImageGetByte(uint16_t, (p), (idx) , 0) | gdispImageGetByte(uint16_t, (p), (idx)+1, 8)) + #define gdispImageGetLE32(p, idx) ( gdispImageGetByte(uint32_t, (p), (idx) , 0) | gdispImageGetByte(uint32_t, (p), (idx)+1, 8)\ + |gdispImageGetByte(uint32_t, (p), (idx)+2, 16) | gdispImageGetByte(uint32_t, (p), (idx)+3, 24)) +#endif +#if GFX_CPU_ENDIAN == GFX_CPU_ENDIAN_BIG && GFX_CPU_NO_ALIGNMENT_FAULTS + #define gidspImageGetBE16(p, idx) gdispImageGetVar(uint16_t, (p), (idx)) + #define gidspImageGetBE32(p, idx) gdispImageGetVar(uint32_t, (p), (idx)) +#else + #define gdispImageGetBE16(p, idx) ( gdispImageGetByte(uint16_t, (p), (idx) , 8) | gdispImageGetByte(uint16_t, (p), (idx)+1, 0)) + #define gdispImageGetBE32(p, idx) ( gdispImageGetByte(uint32_t, (p), (idx) , 24) | gdispImageGetByte(uint32_t, (p), (idx)+1, 16)\ + |gdispImageGetByte(uint32_t, (p), (idx)+2, 8) | gdispImageGetByte(uint32_t, (p), (idx)+3, 0)) +#endif + +/* + * Get a uint16_t/uint32_t from memory in the required endianness. + * These are optimised routines but the memory must be word/dword aligned. + */ +#if GFX_CPU_ENDIAN == GFX_CPU_ENDIAN_LITTLE + #define gdispImageGetAlignedLE16(p, idx) gdispImageGetVar(uint16_t, (p), (idx)) + #define gdispImageGetAlignedBE16(p, idx) gidspImageGetBE16(p, (idx)) + #define gdispImageGetAlignedLE32(p, idx) gdispImageGetVar(uint32_t, (p), (idx)) + #define gdispImageGetAlignedBE32(p, idx) gidspImageGetBE32(p, (idx)) +#elif GFX_CPU_ENDIAN == GFX_CPU_ENDIAN_BIG + #define gdispImageGetAlignedLE16(p, idx) gidspImageGetLE16(p, (idx)) + #define gdispImageGetAlignedBE16(p, idx) gdispImageGetVar(uint16_t, (p), (idx)) + #define gdispImageGetAlignedLE32(p, idx) gidspImageGetLE32(p, (idx)) + #define gdispImageGetAlignedBE32(p, idx) gdispImageGetVar(uint32_t, (p), (idx)) +#else + #define gdispImageGetAlignedLE16(p, idx) gidspImageGetLE16(p, (idx)) + #define gdispImageGetAlignedBE16(p, idx) gidspImageGetBE16(p, (idx)) + #define gdispImageGetAlignedLE32(p, idx) gidspImageGetLE32(p, (idx)) + #define gdispImageGetAlignedBE32(p, idx) gidspImageGetBE32(p, (idx)) +#endif + +/* + * Change a uint16 or uint32 already in a register to the required endianness. + */ +#if GFX_CPU_ENDIAN == GFX_CPU_ENDIAN_LITTLE + #define gdispImageMakeLE16(w) + #define gdispImageMakeLE32(dw) + #define gdispImageMakeBE16(w) { w = gdispImageSwap16(w); } + #define gdispImageMakeBE32(dw) { dw = gdispImageSwap32(dw); } +#elif GFX_CPU_ENDIAN == GFX_CPU_ENDIAN_BIG + #define gdispImageMakeLE16(w) { w = gdispImageSwap16(w); } + #define gdispImageMakeLE32(dw) { dw = gdispImageSwap32(dw); } + #define gdispImageMakeBE16(w) + #define gdispImageMakeBE32(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); } +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + void *gdispImageAlloc(gdispImage *img, size_t sz); + void gdispImageFree(gdispImage *img, void *ptr, size_t sz); + + #if GFX_CPU_ENDIAN == GFX_CPU_ENDIAN_UNKNOWN + extern const uint8_t gdispImageEndianArray[4]; + #endif + +#ifdef __cplusplus +} +#endif + +#endif /* _GDISP_IMAGE_SUPPORT_H */ +/** @} */ + -- cgit v1.2.3