Fork of David Smart's RA8875 library for the purpose of adding touch screen support
Fork of RA8875 by
Diff: GraphicsDisplay.cpp
- Revision:
- 42:7cbdfd2bbfc5
- Parent:
- 41:2956a0a221e5
--- a/GraphicsDisplay.cpp Sat Feb 08 17:35:45 2014 +0000 +++ b/GraphicsDisplay.cpp Sun Feb 23 17:58:39 2014 +0000 @@ -7,8 +7,9 @@ #include "GraphicsDisplay.h" #include "Bitmap.h" +#include "string.h" -#define DEBUG "GD" +//#define DEBUG "GD" // ... // INFO("Stuff to show %d", var); // new-line is automatically appended // @@ -145,6 +146,40 @@ }; #endif // LOCALFONT +char mytolower(char a) { + if (a >= 'A' && a <= 'Z') + return (a - 'A' + 'a'); + else + return a; +} +/// mystrnicmp exists because not all compiler libraries have this function. +/// +/// Some have strnicmp, others _strnicmp, and others have C++ methods, which +/// is outside the scope of this C-portable set of functions. +/// +/// @param l is a pointer to the string on the left +/// @param r is a pointer to the string on the right +/// @param n is the number of characters to compare +/// @returns -1 if l < r +/// @returns 0 if l == r +/// @returns +1 if l > r +/// +int mystrnicmp(const char *l, const char *r, size_t n) { + int result = 0; + + if (n != 0) { + do { + result = mytolower(*l++) - mytolower(*r++); + } while ((result == 0) && (*l != '\0') && (--n > 0)); + } + if (result < -1) + result = -1; + else if (result > 1) + result = 1; + return result; +} + + GraphicsDisplay::GraphicsDisplay(const char *name) : TextDisplay(name) { @@ -412,40 +447,19 @@ } } - -RetCode_t GraphicsDisplay::RenderBitmapFile(loc_t x, loc_t y, const char *Name_BMP) +RetCode_t GraphicsDisplay::_RenderBitmap(loc_t x, loc_t y, uint32_t fileOffset, FILE * Image) { - #define OffsetPixelWidth 18 - #define OffsetPixelHeight 22 - #define OffsetFileSize 34 - #define OffsetPixData 10 - #define OffsetBPP 28 - - BITMAPFILEHEADER BMP_Header; BITMAPINFOHEADER BMP_Info; RGBQUAD * colorPalette = NULL; int colorCount; uint8_t * lineBuffer = NULL; uint16_t BPP_t; uint32_t PixelWidth, PixelHeight; - uint32_t start_data; + //uint32_t start_data; unsigned int i, offset; int padd,j; - INFO("Opening {%s}", Name_BMP); - FILE *Image = fopen(Name_BMP, "rb"); - if (!Image) { - return(file_not_found); - } - - fread(&BMP_Header, 1, sizeof(BMP_Header), Image); // get the BMP Header - INFO("bfType %04X", BMP_Header.bfType); - //HexDump("BMP_Header", (uint8_t *)&BMP_Header, sizeof(BMP_Header)); - if (BMP_Header.bfType != BF_TYPE) { - fclose(Image); - return(not_bmp_format); - } - + // Now, Read the bitmap info header fread(&BMP_Info, 1, sizeof(BMP_Info), Image); //HexDump("BMP_Info", (uint8_t *)&BMP_Info, sizeof(BMP_Info)); BPP_t = BMP_Info.biBitCount; @@ -513,11 +527,11 @@ SetGraphicsCursor(x, y); _StartGraphicsStream(); - start_data = BMP_Header.bfOffBits; - HexDump("Raw Data", (uint8_t *)&start_data, 32); + //start_data = BMP_Header.bfOffBits; + //HexDump("Raw Data", (uint8_t *)&start_data, 32); //INFO("(%d,%d) (%d,%d), [%d,%d]", x,y, PixelWidth,PixelHeight, lineBufSize, padd); for (j = PixelHeight - 1; j >= 0; j--) { //Lines bottom up - offset = start_data + j * (lineBufSize + padd); // start of line + offset = fileOffset + j * (lineBufSize + padd); // start of line fseek(Image, offset, SEEK_SET); fread(lineBuffer, 1, lineBufSize, Image); // read a line - slow ! //INFO("offset: %6X", offset); @@ -544,14 +558,89 @@ } pixelStream(pixelBuffer, PixelWidth, x, y++); } + _EndGraphicsStream(); + WindowMax(); free(lineBuffer); free(colorPalette); - fclose(Image); - _EndGraphicsStream(); - WindowMax(); return (noerror); } + +RetCode_t GraphicsDisplay::RenderImageFile(loc_t x, loc_t y, const char *FileName) +{ + if (mystrnicmp(FileName + strlen(FileName) - 4, ".bmp", 4) == 0) { + return RenderBitmapFile(x,y,FileName); + } else if (mystrnicmp(FileName + strlen(FileName) - 4, ".ico", 4) == 0) { + return RenderIconFile(x,y,FileName); + } else { + return not_supported_format; + } +} + +RetCode_t GraphicsDisplay::RenderBitmapFile(loc_t x, loc_t y, const char *Name_BMP) +{ + BITMAPFILEHEADER BMP_Header; + + INFO("Opening {%s}", Name_BMP); + FILE *Image = fopen(Name_BMP, "rb"); + if (!Image) { + return(file_not_found); + } + + fread(&BMP_Header, 1, sizeof(BMP_Header), Image); // get the BMP Header + INFO("bfType %04X", BMP_Header.bfType); + //HexDump("BMP_Header", (uint8_t *)&BMP_Header, sizeof(BMP_Header)); + if (BMP_Header.bfType != BF_TYPE) { + fclose(Image); + return(not_bmp_format); + } + RetCode_t rt = _RenderBitmap(x, y, BMP_Header.bfOffBits, Image); + if (rt != noerror) { + return rt; + } else { + fclose(Image); + return (noerror); + } +} + +RetCode_t GraphicsDisplay::RenderIconFile(loc_t x, loc_t y, const char *Name_ICO) +{ + ICOFILEHEADER ICO_Header; + ICODIRENTRY ICO_DirEntry; + + INFO("Opening {%s}", Name_ICO); + FILE *Image = fopen(Name_ICO, "rb"); + if (!Image) { + return(file_not_found); + } + + fread(&ICO_Header, 1, sizeof(ICO_Header), Image); // get the BMP Header + HexDump("ICO_Header", (uint8_t *)&ICO_Header, sizeof(ICO_Header)); + if (ICO_Header.Reserved_zero != 0 + || ICO_Header.icType != IC_TYPE + || ICO_Header.icImageCount == 0) { + fclose(Image); + return(not_ico_format); + } + + // Read ONLY the first of n possible directory entries. + fread(&ICO_DirEntry, 1, sizeof(ICO_DirEntry), Image); + HexDump("ICO_DirEntry", (uint8_t *)&ICO_DirEntry, sizeof(ICO_DirEntry)); + INFO("biBitCount %04X", ICO_DirEntry.biBitCount); + if (ICO_DirEntry.biBitCount != 0) { // Expecting this to be zero for ico + fclose(Image); + return(not_supported_format); + } + + RetCode_t rt = _RenderBitmap(x, y, ICO_DirEntry.bfOffBits, Image); + if (rt == noerror) { + fclose(Image); + return (noerror); + } else { + return rt; + } +} + int GraphicsDisplay::columns() { return width() / 8;