Clean up endian support for images based on new system defines
Remove deprecated image functions
This commit is contained in:
parent
1fa5677d44
commit
f48b492303
8 changed files with 150 additions and 207 deletions
|
@ -9,6 +9,8 @@
|
||||||
|
|
||||||
#if GFX_USE_GDISP && GDISP_NEED_IMAGE
|
#if GFX_USE_GDISP && GDISP_NEED_IMAGE
|
||||||
|
|
||||||
|
#include "gdisp_image_support.h"
|
||||||
|
|
||||||
#if GDISP_NEED_IMAGE_NATIVE
|
#if GDISP_NEED_IMAGE_NATIVE
|
||||||
extern gdispImageError gdispImageOpen_NATIVE(gdispImage *img);
|
extern gdispImageError gdispImageOpen_NATIVE(gdispImage *img);
|
||||||
extern void gdispImageClose_NATIVE(gdispImage *img);
|
extern void gdispImageClose_NATIVE(gdispImage *img);
|
||||||
|
@ -90,39 +92,6 @@ static gdispImageHandlers ImageHandlers[] = {
|
||||||
#endif
|
#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) {
|
void gdispImageInit(gdispImage *img) {
|
||||||
img->type = GDISP_IMAGE_TYPE_UNKNOWN;
|
img->type = GDISP_IMAGE_TYPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
@ -222,4 +191,8 @@ void gdispImageFree(gdispImage *img, void *ptr, size_t sz) {
|
||||||
#endif
|
#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 */
|
#endif /* GFX_USE_GDISP && GDISP_NEED_IMAGE */
|
||||||
|
|
|
@ -52,52 +52,6 @@ typedef uint16_t gdispImageFlags;
|
||||||
#define GDISP_IMAGE_FLG_ANIMATED 0x0002 /* The image has animation */
|
#define GDISP_IMAGE_FLG_ANIMATED 0x0002 /* The image has animation */
|
||||||
#define GDISP_IMAGE_FLG_MULTIPAGE 0x0004 /* The image has multiple pages */
|
#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
|
* @brief The structure for an image
|
||||||
*/
|
*/
|
||||||
|
@ -119,19 +73,6 @@ typedef struct gdispImage {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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
|
* @brief Initialise a gdispImage object
|
||||||
*
|
*
|
||||||
|
|
|
@ -9,11 +9,7 @@
|
||||||
|
|
||||||
#if GFX_USE_GDISP && GDISP_NEED_IMAGE && GDISP_NEED_IMAGE_BMP
|
#if GFX_USE_GDISP && GDISP_NEED_IMAGE && GDISP_NEED_IMAGE_BMP
|
||||||
|
|
||||||
/**
|
#include "gdisp_image_support.h"
|
||||||
* Helper Routines Needed
|
|
||||||
*/
|
|
||||||
void *gdispImageAlloc(gdispImage *img, size_t sz);
|
|
||||||
void gdispImageFree(gdispImage *img, void *ptr, size_t sz);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How big a pixel array to allocate for blitting (in pixels)
|
* 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
|
#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 {
|
typedef struct gdispImagePrivate {
|
||||||
uint8_t bmpflags;
|
uint8_t bmpflags;
|
||||||
#define BMP_V2 0x01 // Version 2 (old) header format
|
#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 */
|
/* Get the offset to the bitmap data */
|
||||||
if (gfileRead(img->f, &priv->frame0pos, 4) != 4)
|
if (gfileRead(img->f, &priv->frame0pos, 4) != 4)
|
||||||
goto baddatacleanup;
|
goto baddatacleanup;
|
||||||
CONVERT_FROM_DWORD_LE(priv->frame0pos);
|
gdispImageMakeLE32(priv->frame0pos);
|
||||||
|
|
||||||
/* Process the BITMAPCOREHEADER structure */
|
/* Process the BITMAPCOREHEADER structure */
|
||||||
|
|
||||||
/* Get the offset to the colour data */
|
/* Get the offset to the colour data */
|
||||||
if (gfileRead(img->f, &offsetColorTable, 4) != 4)
|
if (gfileRead(img->f, &offsetColorTable, 4) != 4)
|
||||||
goto baddatacleanup;
|
goto baddatacleanup;
|
||||||
CONVERT_FROM_DWORD_LE(offsetColorTable);
|
gdispImageMakeLE32(offsetColorTable);
|
||||||
offsetColorTable += 14; // Add the size of the BITMAPFILEHEADER
|
offsetColorTable += 14; // Add the size of the BITMAPFILEHEADER
|
||||||
|
|
||||||
// Detect our bitmap version
|
// Detect our bitmap version
|
||||||
|
@ -159,23 +125,19 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) {
|
||||||
if (gfileRead(img->f, priv->buf, 12-4) != 12-4)
|
if (gfileRead(img->f, priv->buf, 12-4) != 12-4)
|
||||||
goto baddatacleanup;
|
goto baddatacleanup;
|
||||||
// Get the width
|
// Get the width
|
||||||
img->width = *(uint16_t *)(((uint8_t *)priv->buf)+0);
|
img->width = gdispImageGetAlignedLE16(priv->buf, 0);
|
||||||
CONVERT_FROM_WORD_LE(img->width);
|
|
||||||
// Get the height
|
// Get the height
|
||||||
img->height = *(uint16_t *)(((uint8_t *)priv->buf)+2);
|
img->height = gdispImageGetAlignedLE16(priv->buf, 2);
|
||||||
CONVERT_FROM_WORD_LE(img->height);
|
|
||||||
if (img->height < 0) {
|
if (img->height < 0) {
|
||||||
img->priv->bmpflags |= BMP_TOP_TO_BOTTOM;
|
img->priv->bmpflags |= BMP_TOP_TO_BOTTOM;
|
||||||
img->height = -img->height;
|
img->height = -img->height;
|
||||||
}
|
}
|
||||||
// Get the planes
|
// Get the planes
|
||||||
aword = *(uint16_t *)(((uint8_t *)priv->buf)+4);
|
aword = gdispImageGetAlignedLE16(priv->buf, 4);
|
||||||
CONVERT_FROM_WORD_LE(aword);
|
|
||||||
if (aword != 1)
|
if (aword != 1)
|
||||||
goto unsupportedcleanup;
|
goto unsupportedcleanup;
|
||||||
// Get the bits per pixel
|
// Get the bits per pixel
|
||||||
aword = *(uint16_t *)(((uint8_t *)priv->buf)+6);
|
aword = gdispImageGetAlignedLE16(priv->buf, 6);
|
||||||
CONVERT_FROM_WORD_LE(aword);
|
|
||||||
switch(aword) {
|
switch(aword) {
|
||||||
#if GDISP_NEED_IMAGE_BMP_1
|
#if GDISP_NEED_IMAGE_BMP_1
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -208,14 +170,12 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) {
|
||||||
if (gfileRead(img->f, priv->buf, 40-4) != 40-4)
|
if (gfileRead(img->f, priv->buf, 40-4) != 40-4)
|
||||||
goto baddatacleanup;
|
goto baddatacleanup;
|
||||||
// Get the width
|
// Get the width
|
||||||
adword = *(uint32_t *)(((uint8_t *)priv->buf)+0);
|
adword = gdispImageGetAlignedLE32(priv->buf, 0);
|
||||||
CONVERT_FROM_DWORD_LE(adword);
|
|
||||||
if (adword > 32768) // This also picks up negative values
|
if (adword > 32768) // This also picks up negative values
|
||||||
goto unsupportedcleanup;
|
goto unsupportedcleanup;
|
||||||
img->width = adword;
|
img->width = adword;
|
||||||
// Get the height
|
// Get the height
|
||||||
adword = *(uint32_t *)(((uint8_t *)priv->buf)+4);
|
adword = gdispImageGetAlignedLE32(priv->buf, 4);
|
||||||
CONVERT_FROM_DWORD_LE(adword);
|
|
||||||
if ((int32_t)adword < 0) { // Negative test
|
if ((int32_t)adword < 0) { // Negative test
|
||||||
priv->bmpflags |= BMP_TOP_TO_BOTTOM;
|
priv->bmpflags |= BMP_TOP_TO_BOTTOM;
|
||||||
adword = -adword;
|
adword = -adword;
|
||||||
|
@ -224,13 +184,11 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) {
|
||||||
goto unsupportedcleanup;
|
goto unsupportedcleanup;
|
||||||
img->height = adword;
|
img->height = adword;
|
||||||
// Get the planes
|
// Get the planes
|
||||||
aword = *(uint16_t *)(((uint8_t *)priv->buf)+8);
|
aword = gdispImageGetAlignedLE16(priv->buf, 8);
|
||||||
CONVERT_FROM_WORD_LE(aword);
|
|
||||||
if (aword != 1)
|
if (aword != 1)
|
||||||
goto unsupportedcleanup;
|
goto unsupportedcleanup;
|
||||||
// Get the bits per pixel
|
// Get the bits per pixel
|
||||||
aword = *(uint16_t *)(((uint8_t *)priv->buf)+10);
|
aword = gdispImageGetAlignedLE16(priv->buf, 10);
|
||||||
CONVERT_FROM_WORD_LE(aword);
|
|
||||||
switch(aword) {
|
switch(aword) {
|
||||||
#if GDISP_NEED_IMAGE_BMP_1
|
#if GDISP_NEED_IMAGE_BMP_1
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -263,8 +221,7 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) {
|
||||||
}
|
}
|
||||||
priv->bitsperpixel = aword;
|
priv->bitsperpixel = aword;
|
||||||
// Get the compression
|
// Get the compression
|
||||||
adword = *(uint32_t *)(((uint8_t *)priv->buf)+12);
|
adword = gdispImageGetAlignedLE32(priv->buf, 12);
|
||||||
CONVERT_FROM_DWORD_LE(adword);
|
|
||||||
switch(adword) {
|
switch(adword) {
|
||||||
case 0: // BI_RGB - uncompressed
|
case 0: // BI_RGB - uncompressed
|
||||||
break;
|
break;
|
||||||
|
@ -297,8 +254,7 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) {
|
||||||
priv->bitsperpixel = aword;
|
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
|
#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
|
// Get the actual colors used
|
||||||
adword = *(uint32_t *)(((uint8_t *)priv->buf)+28);
|
adword = gdispImageGetAlignedLE32(priv->buf, 28);
|
||||||
CONVERT_FROM_DWORD_LE(adword);
|
|
||||||
if (adword && adword < priv->palsize)
|
if (adword && adword < priv->palsize)
|
||||||
priv->palsize = adword;
|
priv->palsize = adword;
|
||||||
#endif
|
#endif
|
||||||
|
@ -332,14 +288,14 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) {
|
||||||
if (priv->bmpflags & BMP_COMP_MASK) {
|
if (priv->bmpflags & BMP_COMP_MASK) {
|
||||||
gfileSetPos(img->f, offsetColorTable);
|
gfileSetPos(img->f, offsetColorTable);
|
||||||
if (gfileRead(img->f, &priv->maskred, 4) != 4) goto baddatacleanup;
|
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;
|
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;
|
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 (priv->bmpflags & BMP_V4) {
|
||||||
if (gfileRead(img->f, &priv->maskalpha, 4) != 4) goto baddatacleanup;
|
if (gfileRead(img->f, &priv->maskalpha, 4) != 4) goto baddatacleanup;
|
||||||
CONVERT_FROM_DWORD_LE(priv->maskalpha);
|
gdispImageMakeLE32(priv->maskalpha);
|
||||||
} else
|
} else
|
||||||
priv->maskalpha = 0;
|
priv->maskalpha = 0;
|
||||||
} else if (priv->bitsperpixel == 16) {
|
} 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) {
|
while(x < img->width && len <= BLIT_BUFFER_SIZE-2) {
|
||||||
if (gfileRead(img->f, &w, 4) != 4)
|
if (gfileRead(img->f, &w, 4) != 4)
|
||||||
return 0;
|
return 0;
|
||||||
CONVERT_FROM_WORD_LE(w[0]);
|
gdispImageMakeLE16(w[0]);
|
||||||
CONVERT_FROM_WORD_LE(w[1]);
|
gdispImageMakeLE16(w[1]);
|
||||||
if (priv->shiftred < 0)
|
if (priv->shiftred < 0)
|
||||||
r = (color_t)((w[0] & priv->maskred) << -priv->shiftred);
|
r = (color_t)((w[0] & priv->maskred) << -priv->shiftred);
|
||||||
else
|
else
|
||||||
|
@ -712,7 +668,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) {
|
||||||
while(x < img->width && len < BLIT_BUFFER_SIZE) {
|
while(x < img->width && len < BLIT_BUFFER_SIZE) {
|
||||||
if (gfileRead(img->f, &dw, 4) != 4)
|
if (gfileRead(img->f, &dw, 4) != 4)
|
||||||
return 0;
|
return 0;
|
||||||
CONVERT_FROM_DWORD_LE(dw);
|
gdispImageMakeLE32(dw);
|
||||||
if (priv->shiftred < 0)
|
if (priv->shiftred < 0)
|
||||||
r = (color_t)((dw & priv->maskred) << -priv->shiftred);
|
r = (color_t)((dw & priv->maskred) << -priv->shiftred);
|
||||||
else
|
else
|
||||||
|
|
|
@ -9,11 +9,7 @@
|
||||||
|
|
||||||
#if GFX_USE_GDISP && GDISP_NEED_IMAGE && GDISP_NEED_IMAGE_GIF
|
#if GFX_USE_GDISP && GDISP_NEED_IMAGE && GDISP_NEED_IMAGE_GIF
|
||||||
|
|
||||||
/**
|
#include "gdisp_image_support.h"
|
||||||
* Helper Routines Needed
|
|
||||||
*/
|
|
||||||
void *gdispImageAlloc(gdispImage *img, size_t sz);
|
|
||||||
void gdispImageFree(gdispImage *img, void *ptr, size_t sz);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How big an array to allocate for blitting (in pixels)
|
* 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
|
#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)
|
// 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_EOF ((gdispImageError)-1)
|
||||||
#define GDISP_IMAGE_LOOP ((gdispImageError)-2)
|
#define GDISP_IMAGE_LOOP ((gdispImageError)-2)
|
||||||
|
@ -416,14 +382,10 @@ static gdispImageError initFrame(gdispImage *img) {
|
||||||
// Read the Image Descriptor
|
// Read the Image Descriptor
|
||||||
if (gfileRead(img->f, priv->buf, 9) != 9)
|
if (gfileRead(img->f, priv->buf, 9) != 9)
|
||||||
return GDISP_IMAGE_ERR_BADDATA;
|
return GDISP_IMAGE_ERR_BADDATA;
|
||||||
priv->frame.x = *(uint16_t *)(((uint8_t *)priv->buf)+0);
|
priv->frame.x = gdispImageGetAlignedLE16(priv->buf, 0);
|
||||||
CONVERT_FROM_WORD_LE(priv->frame.x);
|
priv->frame.y = gdispImageGetAlignedLE16(priv->buf, 2);
|
||||||
priv->frame.y = *(uint16_t *)(((uint8_t *)priv->buf)+2);
|
priv->frame.width = gdispImageGetAlignedLE16(priv->buf, 4);
|
||||||
CONVERT_FROM_WORD_LE(priv->frame.y);
|
priv->frame.height = gdispImageGetAlignedLE16(priv->buf, 6);
|
||||||
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);
|
|
||||||
if (((uint8_t *)priv->buf)[8] & 0x80) // Local color table?
|
if (((uint8_t *)priv->buf)[8] & 0x80) // Local color table?
|
||||||
priv->frame.palsize = 2 << (((uint8_t *)priv->buf)[8] & 0x07);
|
priv->frame.palsize = 2 << (((uint8_t *)priv->buf)[8] & 0x07);
|
||||||
if (((uint8_t *)priv->buf)[8] & 0x40) // Interlaced?
|
if (((uint8_t *)priv->buf)[8] & 0x40) // Interlaced?
|
||||||
|
@ -468,8 +430,7 @@ static gdispImageError initFrame(gdispImage *img) {
|
||||||
else
|
else
|
||||||
img->flags &= ~GDISP_IMAGE_FLG_MULTIPAGE;
|
img->flags &= ~GDISP_IMAGE_FLG_MULTIPAGE;
|
||||||
// Process frame delay and the transparent color (if any)
|
// Process frame delay and the transparent color (if any)
|
||||||
priv->frame.delay = *(uint16_t *)(((uint8_t *)priv->buf)+2);
|
priv->frame.delay = gdispImageGetAlignedLE16(priv->buf, 2);
|
||||||
CONVERT_FROM_WORD_LE(priv->frame.delay);
|
|
||||||
priv->frame.paltrans = ((uint8_t *)priv->buf)[4];
|
priv->frame.paltrans = ((uint8_t *)priv->buf)[4];
|
||||||
break;
|
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)[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') {
|
&& ((uint8_t *)priv->buf)[10] == '.' && ((uint8_t *)priv->buf)[11] == '0') {
|
||||||
if (((uint8_t *)priv->buf)[13] == 1) {
|
if (((uint8_t *)priv->buf)[13] == 1) {
|
||||||
priv->loops = *(uint16_t *)(((uint8_t *)priv->buf)+14);
|
priv->loops = gdispImageGetAlignedLE16(priv->buf, 14);
|
||||||
CONVERT_FROM_WORD_LE(priv->loops);
|
|
||||||
priv->flags |= GIF_LOOP;
|
priv->flags |= GIF_LOOP;
|
||||||
if (!priv->loops)
|
if (!priv->loops)
|
||||||
priv->flags |= GIF_LOOPFOREVER;
|
priv->flags |= GIF_LOOPFOREVER;
|
||||||
|
@ -597,11 +557,9 @@ gdispImageError gdispImageOpen_GIF(gdispImage *img) {
|
||||||
if (gfileRead(img->f, priv->buf, 7) != 7)
|
if (gfileRead(img->f, priv->buf, 7) != 7)
|
||||||
goto baddatacleanup;
|
goto baddatacleanup;
|
||||||
// Get the width
|
// Get the width
|
||||||
img->width = *(uint16_t *)(((uint8_t *)priv->buf)+0);
|
img->width = gdispImageGetAlignedLE16(priv->buf, 0);
|
||||||
CONVERT_FROM_WORD_LE(img->width);
|
|
||||||
// Get the height
|
// Get the height
|
||||||
img->height = *(uint16_t *)(((uint8_t *)priv->buf)+2);
|
img->height = gdispImageGetAlignedLE16(priv->buf, 2);
|
||||||
CONVERT_FROM_WORD_LE(img->height);
|
|
||||||
if (((uint8_t *)priv->buf)[4] & 0x80) {
|
if (((uint8_t *)priv->buf)[4] & 0x80) {
|
||||||
// Global color table
|
// Global color table
|
||||||
priv->palsize = 2 << (((uint8_t *)priv->buf)[4] & 0x07);
|
priv->palsize = 2 << (((uint8_t *)priv->buf)[4] & 0x07);
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
|
|
||||||
#if GFX_USE_GDISP && GDISP_NEED_IMAGE && GDISP_NEED_IMAGE_JPG
|
#if GFX_USE_GDISP && GDISP_NEED_IMAGE && GDISP_NEED_IMAGE_JPG
|
||||||
|
|
||||||
|
#include "gdisp_image_support.h"
|
||||||
|
|
||||||
#error "JPG support not implemented yet"
|
#error "JPG support not implemented yet"
|
||||||
|
|
||||||
#endif /* GFX_USE_GDISP && GDISP_NEED_IMAGE && GDISP_NEED_IMAGE_JPG */
|
#endif /* GFX_USE_GDISP && GDISP_NEED_IMAGE && GDISP_NEED_IMAGE_JPG */
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
|
|
||||||
#if GFX_USE_GDISP && GDISP_NEED_IMAGE && GDISP_NEED_IMAGE_NATIVE
|
#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
|
* How big a pixel array to allocate for blitting
|
||||||
* Bigger is faster but uses more RAM.
|
* Bigger is faster but uses more RAM.
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
|
|
||||||
#if GFX_USE_GDISP && GDISP_NEED_IMAGE && GDISP_NEED_IMAGE_PNG
|
#if GFX_USE_GDISP && GDISP_NEED_IMAGE && GDISP_NEED_IMAGE_PNG
|
||||||
|
|
||||||
|
#include "gdisp_image_support.h"
|
||||||
|
|
||||||
#error "PNG support not implemented yet"
|
#error "PNG support not implemented yet"
|
||||||
|
|
||||||
#endif /* GFX_USE_GDISP && GDISP_NEED_IMAGE && GDISP_NEED_IMAGE_PNG */
|
#endif /* GFX_USE_GDISP && GDISP_NEED_IMAGE && GDISP_NEED_IMAGE_PNG */
|
||||||
|
|
109
src/gdisp/gdisp_image_support.h
Normal file
109
src/gdisp/gdisp_image_support.h
Normal file
|
@ -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 */
|
||||||
|
/** @} */
|
||||||
|
|
Loading…
Add table
Reference in a new issue