aboutsummaryrefslogtreecommitdiffstats
path: root/src/gdisp/gdisp_image_bmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gdisp/gdisp_image_bmp.c')
-rw-r--r--src/gdisp/gdisp_image_bmp.c84
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