Fork of David Smart's RA8875 library

Fork of RA8875 by David Smart

Revision:
32:0e4f2ae512e2
Parent:
31:c72e12cd5c67
Child:
33:b6b710758ab3
--- a/GraphicsDisplay.cpp	Mon Jan 20 19:19:48 2014 +0000
+++ b/GraphicsDisplay.cpp	Tue Jan 21 03:28:36 2014 +0000
@@ -1,12 +1,21 @@
 /* mbed GraphicsDisplay Display Library Base Class
  * Copyright (c) 2007-2009 sford
  * Released under the MIT License: http://mbed.org/license/mit
+ *
+ * Software Rendering of a Bitmap from the localfilesystem
+ *      34 sec: 352x272 pixels, 8-bit color, 94.5kbytes
+ * Hardware Rendering
+ *       9 sec: same file.
  */
 
 #include "GraphicsDisplay.h"
 #include "Bitmap.h"
 
-#define DEBUG "GD"
+// Defining USE_HW causes compilation of code that uses hardware drawing
+// provided by the super-class.
+#define USE_HW
+
+//#define DEBUG "GD"
 // ...
 // INFO("Stuff to show %d", var); // new-line is automatically appended
 //
@@ -38,7 +47,7 @@
 #define INFO(x, ...)
 #define WARN(x, ...)
 #define ERR(x, ...)
-#define HexDump(a, b)
+#define HexDump(a, b, c)
 #endif
 
 // #define LOCALFONT
@@ -184,7 +193,7 @@
 }
 #endif
 
-void GraphicsDisplay::window(unsigned int x, unsigned int y, unsigned int w, unsigned int h)
+RetCode_t GraphicsDisplay::window(unsigned int x, unsigned int y, unsigned int w, unsigned int h)
 {
     // current pixel location
     _x = x;
@@ -194,6 +203,7 @@
     _x2 = x + w - 1;
     _y1 = y;
     _y2 = y + h - 1;
+    return noerror;
 }
 
 void GraphicsDisplay::WindowMax(void)
@@ -201,7 +211,7 @@
     window(0,0, width(),height());
 }
 
-void GraphicsDisplay::putp(color_t colour)
+RetCode_t GraphicsDisplay::putp(color_t colour)
 {
     // put pixel at current pixel location
     pixel(_x, _y, colour);
@@ -214,14 +224,19 @@
             _y = _y1;
         }
     }
+    return noerror;
 }
 
 void GraphicsDisplay::fill(int x, int y, int w, int h, color_t colour)
 {
+    #ifdef USE_HW
+    fillrect(x,y, x+w, y+h, colour);
+    #else
     window(x, y, w, h);
     for(int i=0; i<w*h; i++) {
         putp(colour);
     }
+    #endif
 }
 
 RetCode_t GraphicsDisplay::cls()
@@ -288,7 +303,7 @@
 //      RRRR RGGG GGGB BBBB
 // swap to little endian
 //      GGGB BBBB RRRR RGGG
-color_t RGBQuadToRGB16(RGBQUAD * colorPalette, uint16_t i)
+color_t GraphicsDisplay::RGBQuadToRGB16(RGBQUAD * colorPalette, uint16_t i)
 {
     color_t c;
  
@@ -302,7 +317,7 @@
 }
 
 
-RetCode_t GraphicsDisplay::BMP_16(unsigned int x, unsigned int y, const char *Name_BMP)
+RetCode_t GraphicsDisplay::RenderBitmapFile(unsigned int x, unsigned int y, const char *Name_BMP)
 {
     #define OffsetPixelWidth    18
     #define OffsetPixelHeight   22
@@ -310,12 +325,11 @@
     #define OffsetPixData       10
     #define OffsetBPP           28
 
-    char filename[50];
     BITMAPFILEHEADER BMP_Header;
     BITMAPINFOHEADER BMP_Info;
     RGBQUAD * colorPalette = NULL;
     int colorCount;
-    char * lineBuffer = NULL;
+    uint8_t * lineBuffer = NULL;
     
     uint16_t BPP_t;
     uint32_t PixelWidth, PixelHeight;
@@ -323,11 +337,8 @@
     unsigned int    i, offset;
     int padd,j;
 
-    // get the filename
-    LocalFileSystem local("local");
-    sprintf(filename,"/local/%s", Name_BMP);
-    INFO("Opening {%s}", filename);
-    FILE *Image = fopen(filename, "rb");  // open the bmp file
+    INFO("Opening {%s}", Name_BMP);
+    FILE *Image = fopen(Name_BMP, "rb");
     if (!Image) {
         return(file_not_found);
     }
@@ -335,22 +346,20 @@
     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) { // BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) {  // check magic byte
+    if (BMP_Header.bfType != BF_TYPE) {
         fclose(Image);
-        return(not_bmp_format);     // error no BMP file
+        return(not_bmp_format);
     }
 
     fread(&BMP_Info, 1, sizeof(BMP_Info), Image);
     //HexDump("BMP_Info", (uint8_t *)&BMP_Info, sizeof(BMP_Info));
     BPP_t = BMP_Info.biBitCount;
     INFO("biBitCount %04X", BPP_t);
-    if (BPP_t != 4 && BPP_t != 8 && BPP_t != 16) {   // Support 4, 8, 16-bits per pixel
+    if (BPP_t != 4 && BPP_t != 8 && BPP_t != 16 && BPP_t != 24) { // Support 4, 8, 16, 24-bits per pixel
         fclose(Image);
         return(not_supported_format);
     }
 
-    //PixelHeight = BMP_Header[OffsetPixelHeight] + (BMP_Header[OffsetPixelHeight + 1] << 8) + (BMP_Header[OffsetPixelHeight + 2] << 16) + (BMP_Header[OffsetPixelHeight + 3] << 24);
-    //PixelWidth = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24);
     PixelHeight = BMP_Info.biHeight;
     PixelWidth = BMP_Info.biWidth;
     if (PixelHeight > height() + y || PixelWidth > width() + x) {
@@ -358,77 +367,90 @@
         return(image_too_big);
     }
     INFO("(%d,%d) (%d,%d)", x,y, PixelWidth,PixelHeight);
-
     if (BMP_Info.biBitCount <= 8) {
         int paletteSize;
         // Read the color palette
         colorCount = 1 << BMP_Info.biBitCount;
         paletteSize = sizeof(RGBQUAD) * colorCount;
-        //INFO("colors: %d, paletteSize: %d", colorCount, paletteSize);
         colorPalette = (RGBQUAD *)malloc(paletteSize);
         if (colorPalette == NULL) {
             fclose(Image);
             return(not_enough_ram);
         }
         fread(colorPalette, 1, paletteSize, Image);
-        HexDump("Color Palette", (uint8_t *)colorPalette, paletteSize);
-    } else {
-        ERR("Bits per pixel > 8 [%d]", BMP_Info.biBitCount);
+        //HexDump("Color Palette", (uint8_t *)colorPalette, paletteSize);
     }
 
-    //start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24);
-    start_data = BMP_Header.bfOffBits;
-
-    //HexDump("Raw Data", (uint8_t *)&start_data, 32);
-    int lineBufSize = ((BPP_t * PixelWidth + 31)/32)*4;
-    //INFO("lineBufSize = %d", lineBufSize);
-    lineBuffer = (char *)malloc(lineBufSize);
+    int lineBufSize = ((BPP_t * PixelWidth + 7)/8);
+    //INFO("BPP_t %d, PixelWidth %d, lineBufSize %d", BPP_t, PixelWidth, lineBufSize);
+    lineBuffer = (uint8_t *)malloc(lineBufSize);
     if (lineBuffer == NULL) {
         free(colorPalette);
         fclose(Image);
         return(not_enough_ram);
     }
 
-    // the bmp lines are padded to multiple of 4 bytes
+    // the Raw Data records are padded to a multiple of 4 bytes
+    int recordSize = 2;
+    if (BPP_t == 4) {
+        recordSize = 1;
+    } else if (BPP_t == 8) {
+        recordSize = 1;
+    } else if (BPP_t == 16) {
+        recordSize = 2;
+    } else if (BPP_t == 24) {
+        recordSize = 3;
+    }
     padd = -1;
     do {
         padd++;
-    } while ((PixelWidth * sizeof(color_t) + padd) % 4 != 0);
+    } while ((PixelWidth * recordSize + padd) % 4 != 0);
 
-    // Define window for top to bottom and left to right
+    // Define window for top to bottom and left to right so writing auto-wraps
     window(x,y, PixelWidth,PixelHeight);
-    //INFO("(%d,%d) (%d,%d)", x,y, PixelWidth,PixelHeight);
-    for (j = PixelHeight - 1; j >= 0; j--) {               //Lines bottom up
-        //INFO("line %d", j);
-        offset = start_data + j * (lineBufSize + padd);   // start of line
+    SetGraphicsCursor(x, y);
+    _StartGraphicsStream();
+    
+    start_data = BMP_Header.bfOffBits;
+    HexDump("Raw Data", (uint8_t *)&start_data, 32);
+    //bool tag = true;
+    //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
         fseek(Image, offset, SEEK_SET);
-        fread(lineBuffer, 1, lineBufSize, Image);       // read a line - slow !
-        //HexDump("Line", (uint8_t *)lineBuffer, lineBufSize);
-        for (i = 0; i < PixelWidth; i++) {        // copy pixel data to TFT
+        fread(lineBuffer, 1, lineBufSize, Image);           // read a line - slow !
+        //INFO("offset: %6X", offset);
+        //if (tag)
+        //    HexDump("Line", (uint8_t *)lineBuffer, lineBufSize);
+        for (i = 0; i < PixelWidth; i++) {                  // copy pixel data to TFT
             if (BPP_t == 4) {
                 uint8_t dPix = lineBuffer[i/2];
                 if ((i & 1) == 0)
                     dPix >>= 4;
                 dPix &= 0x0F;
-                color_t color;
-                color = RGBQuadToRGB16(colorPalette, dPix);
-                putp(color);
+                putp(RGBQuadToRGB16(colorPalette, dPix));
             } else if (BPP_t == 8) {
-                color_t color;
-                color = RGBQuadToRGB16(colorPalette, lineBuffer[i]);
+                putp(RGBQuadToRGB16(colorPalette, lineBuffer[i]));
+            } else if (BPP_t == 16) {
+                putp(lineBuffer[i]);
+            } else if (BPP_t == 24) {
+                color_t color;  // BGR
+                color = RGB(lineBuffer[i*3+2], lineBuffer[i*3+1], lineBuffer[i*3+0]);
+                //if (tag) 
+                //    INFO("color[%2d]: RGB(%02X,%02X,%02X) => %04X", 
+                //        i, lineBuffer[i*2], lineBuffer[i*3+1], lineBuffer[i*3+0], color);
+                color = (color >> 8) | (color << 8);
                 putp(color);
-            } else if (BPP_t == 16) {
-                putp(lineBuffer[i] & 0xFF);
-                putp(lineBuffer[i] >> 8);
             }
         }
+        //tag = false;
     }
     free(lineBuffer);
     free(colorPalette);
     fclose(Image);
-    //INFO("Freed and closed");
+    _EndGraphicsStream();
     WindowMax();
-    return(noerror);
+    return (noerror);
 }
 
 int GraphicsDisplay::columns()
@@ -441,3 +463,4 @@
     return height() / 8;
 }
 
+