Fork of David Smart's RA8875 library for the purpose of adding touch screen support

Fork of RA8875 by David Smart

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;