diff options
Diffstat (limited to 'src/gdisp/gdisp_image_bmp.c')
-rw-r--r-- | src/gdisp/gdisp_image_bmp.c | 84 |
1 files changed, 20 insertions, 64 deletions
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 |