Library to control a Graphics TFT connected to 4-wire SPI - revised for the Raio RA8875 Display Controller.

Dependents:   FRDM_RA8875_mPaint RA8875_Demo RA8875_KeyPadDemo SignalGenerator ... more

Fork of SPI_TFT by Peter Drescher

See Components - RA8875 Based Display

Enhanced touch-screen support - where it previous supported both the Resistive Touch and Capacitive Touch based on the FT5206 Touch Controller, now it also has support for the GSL1680 Touch Controller.

Offline Help Manual (Windows chm)

/media/uploads/WiredHome/ra8875.zip.bin (download, rename to .zip and unzip)

Committer:
WiredHome
Date:
Sat Dec 19 15:55:09 2015 +0000
Revision:
100:0b084475d5a9
Parent:
98:ecebed9b80b2
Child:
101:e0aad446094a
Corrected a defect where the portrait mode might be incorrectly inferred - then limits many commands to partial screen.; Remove set_font(). Use SelectUserFont() instead.; Removed unnecessary code in several places (redundant work).

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dreschpe 0:de9d1462a835 1 /* mbed GraphicsDisplay Display Library Base Class
dreschpe 0:de9d1462a835 2 * Copyright (c) 2007-2009 sford
dreschpe 0:de9d1462a835 3 * Released under the MIT License: http://mbed.org/license/mit
WiredHome 32:0e4f2ae512e2 4 *
WiredHome 34:c99ec28fac66 5 * Derivative work by D.Smart 2014
dreschpe 0:de9d1462a835 6 */
WiredHome 19:3f82c1161fd2 7
dreschpe 0:de9d1462a835 8 #include "GraphicsDisplay.h"
WiredHome 31:c72e12cd5c67 9 #include "Bitmap.h"
WiredHome 42:7cbdfd2bbfc5 10 #include "string.h"
dreschpe 0:de9d1462a835 11
WiredHome 42:7cbdfd2bbfc5 12 //#define DEBUG "GD"
WiredHome 29:422616aa04bd 13 // ...
WiredHome 29:422616aa04bd 14 // INFO("Stuff to show %d", var); // new-line is automatically appended
WiredHome 29:422616aa04bd 15 //
WiredHome 29:422616aa04bd 16 #if (defined(DEBUG) && !defined(TARGET_LPC11U24))
WiredHome 29:422616aa04bd 17 #define INFO(x, ...) std::printf("[INF %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 29:422616aa04bd 18 #define WARN(x, ...) std::printf("[WRN %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 29:422616aa04bd 19 #define ERR(x, ...) std::printf("[ERR %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 98:ecebed9b80b2 20 static void HexDump(const char * title, const uint8_t * p, int count)
WiredHome 31:c72e12cd5c67 21 {
WiredHome 31:c72e12cd5c67 22 int i;
WiredHome 31:c72e12cd5c67 23 char buf[100] = "0000: ";
WiredHome 31:c72e12cd5c67 24
WiredHome 31:c72e12cd5c67 25 if (*title)
WiredHome 31:c72e12cd5c67 26 INFO("%s", title);
WiredHome 31:c72e12cd5c67 27 for (i=0; i<count; ) {
WiredHome 31:c72e12cd5c67 28 sprintf(buf + strlen(buf), "%02X ", *(p+i));
WiredHome 31:c72e12cd5c67 29 if ((++i & 0x0F) == 0x00) {
WiredHome 31:c72e12cd5c67 30 INFO("%s", buf);
WiredHome 31:c72e12cd5c67 31 if (i < count)
WiredHome 31:c72e12cd5c67 32 sprintf(buf, "%04X: ", i);
WiredHome 31:c72e12cd5c67 33 else
WiredHome 31:c72e12cd5c67 34 buf[0] = '\0';
WiredHome 31:c72e12cd5c67 35 }
WiredHome 31:c72e12cd5c67 36 }
WiredHome 31:c72e12cd5c67 37 if (strlen(buf))
WiredHome 31:c72e12cd5c67 38 INFO("%s", buf);
WiredHome 31:c72e12cd5c67 39 }
WiredHome 29:422616aa04bd 40 #else
WiredHome 29:422616aa04bd 41 #define INFO(x, ...)
WiredHome 29:422616aa04bd 42 #define WARN(x, ...)
WiredHome 29:422616aa04bd 43 #define ERR(x, ...)
WiredHome 32:0e4f2ae512e2 44 #define HexDump(a, b, c)
WiredHome 29:422616aa04bd 45 #endif
WiredHome 29:422616aa04bd 46
WiredHome 19:3f82c1161fd2 47
WiredHome 42:7cbdfd2bbfc5 48 char mytolower(char a) {
WiredHome 42:7cbdfd2bbfc5 49 if (a >= 'A' && a <= 'Z')
WiredHome 42:7cbdfd2bbfc5 50 return (a - 'A' + 'a');
WiredHome 42:7cbdfd2bbfc5 51 else
WiredHome 42:7cbdfd2bbfc5 52 return a;
WiredHome 42:7cbdfd2bbfc5 53 }
WiredHome 42:7cbdfd2bbfc5 54 /// mystrnicmp exists because not all compiler libraries have this function.
WiredHome 42:7cbdfd2bbfc5 55 ///
WiredHome 42:7cbdfd2bbfc5 56 /// Some have strnicmp, others _strnicmp, and others have C++ methods, which
WiredHome 42:7cbdfd2bbfc5 57 /// is outside the scope of this C-portable set of functions.
WiredHome 42:7cbdfd2bbfc5 58 ///
WiredHome 42:7cbdfd2bbfc5 59 /// @param l is a pointer to the string on the left
WiredHome 42:7cbdfd2bbfc5 60 /// @param r is a pointer to the string on the right
WiredHome 42:7cbdfd2bbfc5 61 /// @param n is the number of characters to compare
WiredHome 42:7cbdfd2bbfc5 62 /// @returns -1 if l < r
WiredHome 42:7cbdfd2bbfc5 63 /// @returns 0 if l == r
WiredHome 42:7cbdfd2bbfc5 64 /// @returns +1 if l > r
WiredHome 42:7cbdfd2bbfc5 65 ///
WiredHome 42:7cbdfd2bbfc5 66 int mystrnicmp(const char *l, const char *r, size_t n) {
WiredHome 42:7cbdfd2bbfc5 67 int result = 0;
WiredHome 42:7cbdfd2bbfc5 68
WiredHome 42:7cbdfd2bbfc5 69 if (n != 0) {
WiredHome 42:7cbdfd2bbfc5 70 do {
WiredHome 42:7cbdfd2bbfc5 71 result = mytolower(*l++) - mytolower(*r++);
WiredHome 42:7cbdfd2bbfc5 72 } while ((result == 0) && (*l != '\0') && (--n > 0));
WiredHome 42:7cbdfd2bbfc5 73 }
WiredHome 42:7cbdfd2bbfc5 74 if (result < -1)
WiredHome 42:7cbdfd2bbfc5 75 result = -1;
WiredHome 42:7cbdfd2bbfc5 76 else if (result > 1)
WiredHome 42:7cbdfd2bbfc5 77 result = 1;
WiredHome 42:7cbdfd2bbfc5 78 return result;
WiredHome 42:7cbdfd2bbfc5 79 }
WiredHome 42:7cbdfd2bbfc5 80
WiredHome 42:7cbdfd2bbfc5 81
WiredHome 29:422616aa04bd 82 GraphicsDisplay::GraphicsDisplay(const char *name)
WiredHome 29:422616aa04bd 83 : TextDisplay(name)
WiredHome 19:3f82c1161fd2 84 {
WiredHome 29:422616aa04bd 85 font = NULL;
dreschpe 0:de9d1462a835 86 }
WiredHome 19:3f82c1161fd2 87
WiredHome 98:ecebed9b80b2 88 RetCode_t GraphicsDisplay::SelectUserFont(const unsigned char * _font)
WiredHome 29:422616aa04bd 89 {
WiredHome 98:ecebed9b80b2 90 font = _font; // trusting them, but it might be good to put some checks in here...
WiredHome 98:ecebed9b80b2 91 return noerror;
WiredHome 29:422616aa04bd 92 }
WiredHome 98:ecebed9b80b2 93
WiredHome 29:422616aa04bd 94 int GraphicsDisplay::character(int x, int y, int c)
WiredHome 29:422616aa04bd 95 {
WiredHome 98:ecebed9b80b2 96 return fontblit(x, y, font, c);
WiredHome 29:422616aa04bd 97 }
WiredHome 19:3f82c1161fd2 98
WiredHome 37:f19b7e7449dc 99 RetCode_t GraphicsDisplay::window(loc_t x, loc_t y, dim_t w, dim_t h)
WiredHome 19:3f82c1161fd2 100 {
dreschpe 0:de9d1462a835 101 // current pixel location
dreschpe 0:de9d1462a835 102 _x = x;
dreschpe 0:de9d1462a835 103 _y = y;
dreschpe 0:de9d1462a835 104 // window settings
dreschpe 0:de9d1462a835 105 _x1 = x;
dreschpe 0:de9d1462a835 106 _x2 = x + w - 1;
dreschpe 0:de9d1462a835 107 _y1 = y;
dreschpe 0:de9d1462a835 108 _y2 = y + h - 1;
WiredHome 32:0e4f2ae512e2 109 return noerror;
dreschpe 0:de9d1462a835 110 }
WiredHome 19:3f82c1161fd2 111
WiredHome 79:544eb4964795 112 RetCode_t GraphicsDisplay::WindowMax(void)
WiredHome 31:c72e12cd5c67 113 {
WiredHome 79:544eb4964795 114 return window(0,0, width(),height());
WiredHome 31:c72e12cd5c67 115 }
WiredHome 31:c72e12cd5c67 116
WiredHome 55:dfbabef7003e 117 RetCode_t GraphicsDisplay::_putp(color_t color)
WiredHome 19:3f82c1161fd2 118 {
WiredHome 33:b6b710758ab3 119 pixel(_x, _y, color);
dreschpe 0:de9d1462a835 120 // update pixel location based on window settings
dreschpe 0:de9d1462a835 121 _x++;
dreschpe 0:de9d1462a835 122 if(_x > _x2) {
dreschpe 0:de9d1462a835 123 _x = _x1;
dreschpe 0:de9d1462a835 124 _y++;
dreschpe 0:de9d1462a835 125 if(_y > _y2) {
dreschpe 0:de9d1462a835 126 _y = _y1;
dreschpe 0:de9d1462a835 127 }
dreschpe 0:de9d1462a835 128 }
WiredHome 32:0e4f2ae512e2 129 return noerror;
dreschpe 0:de9d1462a835 130 }
dreschpe 0:de9d1462a835 131
WiredHome 79:544eb4964795 132 RetCode_t GraphicsDisplay::fill(int x, int y, int w, int h, color_t color)
WiredHome 19:3f82c1161fd2 133 {
WiredHome 79:544eb4964795 134 return fillrect(x,y, x+w, y+h, color);
dreschpe 0:de9d1462a835 135 }
WiredHome 19:3f82c1161fd2 136
WiredHome 61:8f3153bf0baa 137 RetCode_t GraphicsDisplay::cls(uint16_t layers)
WiredHome 19:3f82c1161fd2 138 {
WiredHome 79:544eb4964795 139 return fill(0, 0, width(), height(), _background);
dreschpe 0:de9d1462a835 140 }
WiredHome 19:3f82c1161fd2 141
WiredHome 79:544eb4964795 142 RetCode_t GraphicsDisplay::blit(int x, int y, int w, int h, const int * color)
WiredHome 19:3f82c1161fd2 143 {
dreschpe 0:de9d1462a835 144 window(x, y, w, h);
WiredHome 37:f19b7e7449dc 145 _StartGraphicsStream();
WiredHome 31:c72e12cd5c67 146 for (int i=0; i<w*h; i++) {
WiredHome 55:dfbabef7003e 147 _putp(color[i]);
dreschpe 0:de9d1462a835 148 }
WiredHome 37:f19b7e7449dc 149 _EndGraphicsStream();
WiredHome 79:544eb4964795 150 return WindowMax();
dreschpe 0:de9d1462a835 151 }
WiredHome 19:3f82c1161fd2 152
WiredHome 98:ecebed9b80b2 153 // 8 byte "info" section
WiredHome 98:ecebed9b80b2 154 //0x00, // unknown ????????
WiredHome 98:ecebed9b80b2 155 //0x00, // unknown ????????
WiredHome 98:ecebed9b80b2 156 //0x20,0x00, // First char 32
WiredHome 98:ecebed9b80b2 157 //0x7F,0x00, // Last char 127
WiredHome 98:ecebed9b80b2 158 //0x25, // Font Height 37
WiredHome 98:ecebed9b80b2 159 //0x00, // Unknown 0 ????????
WiredHome 98:ecebed9b80b2 160 //
WiredHome 98:ecebed9b80b2 161 //0x01,0x88,0x01,0x00 // ' ' is 1 pixel wide, data is at offset 0x0188
WiredHome 98:ecebed9b80b2 162 //0x0B,0xAD,0x01,0x00 // '!' is 11 pixels wide, data is at offset 0x01AD
WiredHome 98:ecebed9b80b2 163 //0x0D,0xF7,0x01,0x00 // '"' is 13 pixels wide, data is at offset 0x01F7
WiredHome 98:ecebed9b80b2 164 //...
WiredHome 98:ecebed9b80b2 165 //0x00,... // ' ' data stream.
WiredHome 98:ecebed9b80b2 166 //0x00,0x06,0x00,0x07,0x80,0x07,0xC0,0x07,0xC0,0x07,0xC0 // '!'
WiredHome 98:ecebed9b80b2 167 //...
WiredHome 98:ecebed9b80b2 168 int GraphicsDisplay::fontblit(int x, int y, const unsigned char * fontTable, const unsigned char c)
WiredHome 19:3f82c1161fd2 169 {
WiredHome 98:ecebed9b80b2 170 uint16_t offsetToCharLookup;
WiredHome 98:ecebed9b80b2 171 uint16_t firstChar = font[3] * 256 + font[2];
WiredHome 98:ecebed9b80b2 172 uint16_t lastChar = font[5] * 256 + font[4];
WiredHome 98:ecebed9b80b2 173 uint8_t charHeight = font[6];
WiredHome 98:ecebed9b80b2 174 const unsigned char * charRecord; // width, data, data, data, ...
WiredHome 98:ecebed9b80b2 175
WiredHome 98:ecebed9b80b2 176 INFO("first:%d, last:%d, c:%d", firstChar, lastChar, c);
WiredHome 98:ecebed9b80b2 177 if (c < firstChar || c > lastChar)
WiredHome 98:ecebed9b80b2 178 return 0; // advance zero pixels since it was unprintable...
WiredHome 98:ecebed9b80b2 179
WiredHome 98:ecebed9b80b2 180 // 8 bytes of preamble to the first level lookup table
WiredHome 98:ecebed9b80b2 181 offsetToCharLookup = 8 + 4 * (c - firstChar); // 4-bytes: width(pixels), 16-bit offset from table start, 0
WiredHome 98:ecebed9b80b2 182 uint8_t charWidth = font[offsetToCharLookup];
WiredHome 98:ecebed9b80b2 183 charRecord = font + font[offsetToCharLookup + 2] * 256 + font[offsetToCharLookup + 1];
WiredHome 29:422616aa04bd 184
WiredHome 98:ecebed9b80b2 185 INFO("hgt:%d, wdt:%d", charHeight, charWidth);
WiredHome 98:ecebed9b80b2 186 // clip to the edge of the screen
WiredHome 98:ecebed9b80b2 187 //if (x + charWidth >= width())
WiredHome 98:ecebed9b80b2 188 // charWidth = width() - x;
WiredHome 98:ecebed9b80b2 189 //if (y + charHeight >= height())
WiredHome 98:ecebed9b80b2 190 // charHeight = height() - y;
WiredHome 98:ecebed9b80b2 191 window(x, y, charWidth, charHeight);
WiredHome 37:f19b7e7449dc 192 _StartGraphicsStream();
WiredHome 98:ecebed9b80b2 193 while (charHeight--) {
WiredHome 98:ecebed9b80b2 194 uint8_t pixels = charWidth;
WiredHome 98:ecebed9b80b2 195 uint8_t bitmask = 0x01;
WiredHome 29:422616aa04bd 196
WiredHome 98:ecebed9b80b2 197 while (pixels) {
WiredHome 98:ecebed9b80b2 198 uint8_t byte = *charRecord;
WiredHome 98:ecebed9b80b2 199 INFO("byte, mask: %02X, %02X", byte, bitmask);
WiredHome 37:f19b7e7449dc 200 color_t c = (byte & bitmask) ? _foreground : _background;
WiredHome 55:dfbabef7003e 201 _putp(c);
WiredHome 98:ecebed9b80b2 202 bitmask <<= 1;
WiredHome 98:ecebed9b80b2 203 if (pixels > 1 && bitmask == 0) {
WiredHome 98:ecebed9b80b2 204 bitmask = 0x01;
WiredHome 98:ecebed9b80b2 205 charRecord++;
WiredHome 98:ecebed9b80b2 206 }
WiredHome 98:ecebed9b80b2 207 pixels--;
WiredHome 29:422616aa04bd 208 }
WiredHome 98:ecebed9b80b2 209 charRecord++;
WiredHome 29:422616aa04bd 210 }
WiredHome 37:f19b7e7449dc 211 _EndGraphicsStream();
WiredHome 37:f19b7e7449dc 212 WindowMax();
WiredHome 29:422616aa04bd 213 return charWidth;
dreschpe 0:de9d1462a835 214 }
dreschpe 0:de9d1462a835 215
WiredHome 31:c72e12cd5c67 216 // BMP Color Palette is BGRx
WiredHome 31:c72e12cd5c67 217 // BBBB BBBB GGGG GGGG RRRR RRRR 0000 0000
WiredHome 31:c72e12cd5c67 218 // RGB16 is
WiredHome 31:c72e12cd5c67 219 // RRRR RGGG GGGB BBBB
WiredHome 31:c72e12cd5c67 220 // swap to little endian
WiredHome 31:c72e12cd5c67 221 // GGGB BBBB RRRR RGGG
WiredHome 32:0e4f2ae512e2 222 color_t GraphicsDisplay::RGBQuadToRGB16(RGBQUAD * colorPalette, uint16_t i)
WiredHome 31:c72e12cd5c67 223 {
WiredHome 31:c72e12cd5c67 224 color_t c;
WiredHome 31:c72e12cd5c67 225
WiredHome 31:c72e12cd5c67 226 c = ((colorPalette[i].rgbBlue >> 3) << 0);
WiredHome 31:c72e12cd5c67 227 c |= ((colorPalette[i].rgbGreen >> 2) << 5);
WiredHome 31:c72e12cd5c67 228 c |= ((colorPalette[i].rgbRed >> 3) << 11);
WiredHome 31:c72e12cd5c67 229 return c;
WiredHome 31:c72e12cd5c67 230 }
WiredHome 29:422616aa04bd 231
WiredHome 93:6fbc516de05e 232 // RGB16 little endian
WiredHome 93:6fbc516de05e 233 // GGGB BBBB RRRR RGGG
WiredHome 93:6fbc516de05e 234 // swap
WiredHome 93:6fbc516de05e 235 // RRRR RGGG GGGB BBBB
WiredHome 93:6fbc516de05e 236 // RRRR R
WiredHome 93:6fbc516de05e 237 // extend to BMP Color Palette is BGRx
WiredHome 93:6fbc516de05e 238 // BBBB BBBB GGGG GGGG RRRR RRRR 0000 0000
WiredHome 41:2956a0a221e5 239 RGBQUAD GraphicsDisplay::RGB16ToRGBQuad(color_t c)
WiredHome 41:2956a0a221e5 240 {
WiredHome 41:2956a0a221e5 241 RGBQUAD q;
WiredHome 41:2956a0a221e5 242
WiredHome 41:2956a0a221e5 243 memset(&q, 0, sizeof(q));
WiredHome 93:6fbc516de05e 244 c = (c << 8) | (c >> 8); // swap
WiredHome 72:ecffe56af969 245 q.rgbBlue = ((c & 0x001F) << 3) | (c & 0x07); /* Blue value */
WiredHome 93:6fbc516de05e 246 q.rgbGreen = ((c & 0x07E0) >> 3) | ((c >> 9) & 0x03); /* Green value */
WiredHome 93:6fbc516de05e 247 q.rgbRed = ((c & 0xF800) >> 8) | ((c >> 13) & 0x07); /* Red value */
WiredHome 41:2956a0a221e5 248 q.rgbReserved = 0;
WiredHome 41:2956a0a221e5 249 return q;
WiredHome 41:2956a0a221e5 250 }
WiredHome 41:2956a0a221e5 251
WiredHome 42:7cbdfd2bbfc5 252 RetCode_t GraphicsDisplay::_RenderBitmap(loc_t x, loc_t y, uint32_t fileOffset, FILE * Image)
WiredHome 31:c72e12cd5c67 253 {
WiredHome 31:c72e12cd5c67 254 BITMAPINFOHEADER BMP_Info;
WiredHome 31:c72e12cd5c67 255 RGBQUAD * colorPalette = NULL;
WiredHome 31:c72e12cd5c67 256 int colorCount;
WiredHome 32:0e4f2ae512e2 257 uint8_t * lineBuffer = NULL;
WiredHome 69:636867df24a1 258 color_t * pixelBuffer = NULL;
WiredHome 31:c72e12cd5c67 259 uint16_t BPP_t;
WiredHome 95:ef538bd687c0 260 dim_t PixelWidth, PixelHeight;
WiredHome 31:c72e12cd5c67 261 unsigned int i, offset;
WiredHome 31:c72e12cd5c67 262 int padd,j;
WiredHome 59:fb40aad4efd4 263 #ifdef DEBUG
WiredHome 59:fb40aad4efd4 264 uint32_t start_data;
WiredHome 59:fb40aad4efd4 265 #endif
WiredHome 31:c72e12cd5c67 266
WiredHome 42:7cbdfd2bbfc5 267 // Now, Read the bitmap info header
WiredHome 31:c72e12cd5c67 268 fread(&BMP_Info, 1, sizeof(BMP_Info), Image);
WiredHome 59:fb40aad4efd4 269 HexDump("BMP_Info", (uint8_t *)&BMP_Info, sizeof(BMP_Info));
WiredHome 31:c72e12cd5c67 270 BPP_t = BMP_Info.biBitCount;
WiredHome 31:c72e12cd5c67 271 INFO("biBitCount %04X", BPP_t);
WiredHome 32:0e4f2ae512e2 272 if (BPP_t != 4 && BPP_t != 8 && BPP_t != 16 && BPP_t != 24) { // Support 4, 8, 16, 24-bits per pixel
WiredHome 31:c72e12cd5c67 273 fclose(Image);
WiredHome 31:c72e12cd5c67 274 return(not_supported_format);
WiredHome 31:c72e12cd5c67 275 }
WiredHome 31:c72e12cd5c67 276
WiredHome 31:c72e12cd5c67 277 PixelHeight = BMP_Info.biHeight;
WiredHome 31:c72e12cd5c67 278 PixelWidth = BMP_Info.biWidth;
WiredHome 79:544eb4964795 279 INFO("(%d,%d) (%d,%d) (%d,%d)", x,y, PixelWidth,PixelHeight, width(), height());
WiredHome 31:c72e12cd5c67 280 if (PixelHeight > height() + y || PixelWidth > width() + x) {
WiredHome 31:c72e12cd5c67 281 fclose(Image);
WiredHome 31:c72e12cd5c67 282 return(image_too_big);
WiredHome 31:c72e12cd5c67 283 }
WiredHome 31:c72e12cd5c67 284 if (BMP_Info.biBitCount <= 8) {
WiredHome 31:c72e12cd5c67 285 int paletteSize;
WiredHome 31:c72e12cd5c67 286 // Read the color palette
WiredHome 31:c72e12cd5c67 287 colorCount = 1 << BMP_Info.biBitCount;
WiredHome 31:c72e12cd5c67 288 paletteSize = sizeof(RGBQUAD) * colorCount;
WiredHome 31:c72e12cd5c67 289 colorPalette = (RGBQUAD *)malloc(paletteSize);
WiredHome 31:c72e12cd5c67 290 if (colorPalette == NULL) {
WiredHome 31:c72e12cd5c67 291 fclose(Image);
WiredHome 31:c72e12cd5c67 292 return(not_enough_ram);
WiredHome 31:c72e12cd5c67 293 }
WiredHome 31:c72e12cd5c67 294 fread(colorPalette, 1, paletteSize, Image);
WiredHome 59:fb40aad4efd4 295 HexDump("Color Palette", (uint8_t *)colorPalette, paletteSize);
WiredHome 31:c72e12cd5c67 296 }
WiredHome 31:c72e12cd5c67 297
WiredHome 32:0e4f2ae512e2 298 int lineBufSize = ((BPP_t * PixelWidth + 7)/8);
WiredHome 59:fb40aad4efd4 299 INFO("BPP_t %d, PixelWidth %d, lineBufSize %d", BPP_t, PixelWidth, lineBufSize);
WiredHome 32:0e4f2ae512e2 300 lineBuffer = (uint8_t *)malloc(lineBufSize);
WiredHome 31:c72e12cd5c67 301 if (lineBuffer == NULL) {
WiredHome 31:c72e12cd5c67 302 free(colorPalette);
WiredHome 31:c72e12cd5c67 303 fclose(Image);
WiredHome 31:c72e12cd5c67 304 return(not_enough_ram);
WiredHome 31:c72e12cd5c67 305 }
WiredHome 69:636867df24a1 306 pixelBuffer = (color_t *)malloc(PixelWidth * sizeof(color_t));
WiredHome 41:2956a0a221e5 307 if (pixelBuffer == NULL) {
WiredHome 41:2956a0a221e5 308 free(lineBuffer);
WiredHome 69:636867df24a1 309 if (colorPalette)
WiredHome 69:636867df24a1 310 free(colorPalette);
WiredHome 41:2956a0a221e5 311 fclose(Image);
WiredHome 41:2956a0a221e5 312 return(not_enough_ram);
WiredHome 41:2956a0a221e5 313 }
WiredHome 31:c72e12cd5c67 314
WiredHome 32:0e4f2ae512e2 315 // the Raw Data records are padded to a multiple of 4 bytes
WiredHome 32:0e4f2ae512e2 316 int recordSize = 2;
WiredHome 32:0e4f2ae512e2 317 if (BPP_t == 4) {
WiredHome 32:0e4f2ae512e2 318 recordSize = 1;
WiredHome 32:0e4f2ae512e2 319 } else if (BPP_t == 8) {
WiredHome 32:0e4f2ae512e2 320 recordSize = 1;
WiredHome 32:0e4f2ae512e2 321 } else if (BPP_t == 16) {
WiredHome 32:0e4f2ae512e2 322 recordSize = 2;
WiredHome 32:0e4f2ae512e2 323 } else if (BPP_t == 24) {
WiredHome 32:0e4f2ae512e2 324 recordSize = 3;
WiredHome 32:0e4f2ae512e2 325 }
WiredHome 31:c72e12cd5c67 326 padd = -1;
WiredHome 31:c72e12cd5c67 327 do {
WiredHome 31:c72e12cd5c67 328 padd++;
WiredHome 32:0e4f2ae512e2 329 } while ((PixelWidth * recordSize + padd) % 4 != 0);
WiredHome 31:c72e12cd5c67 330
WiredHome 32:0e4f2ae512e2 331 // Define window for top to bottom and left to right so writing auto-wraps
WiredHome 31:c72e12cd5c67 332 window(x,y, PixelWidth,PixelHeight);
WiredHome 32:0e4f2ae512e2 333 SetGraphicsCursor(x, y);
WiredHome 32:0e4f2ae512e2 334 _StartGraphicsStream();
WiredHome 32:0e4f2ae512e2 335
WiredHome 42:7cbdfd2bbfc5 336 //start_data = BMP_Header.bfOffBits;
WiredHome 59:fb40aad4efd4 337 HexDump("Raw Data", (uint8_t *)&start_data, 32);
WiredHome 59:fb40aad4efd4 338 INFO("(%d,%d) (%d,%d), [%d,%d]", x,y, PixelWidth,PixelHeight, lineBufSize, padd);
WiredHome 32:0e4f2ae512e2 339 for (j = PixelHeight - 1; j >= 0; j--) { //Lines bottom up
WiredHome 42:7cbdfd2bbfc5 340 offset = fileOffset + j * (lineBufSize + padd); // start of line
WiredHome 31:c72e12cd5c67 341 fseek(Image, offset, SEEK_SET);
WiredHome 32:0e4f2ae512e2 342 fread(lineBuffer, 1, lineBufSize, Image); // read a line - slow !
WiredHome 79:544eb4964795 343 //INFO("offset: %6X", offset);
WiredHome 32:0e4f2ae512e2 344 for (i = 0; i < PixelWidth; i++) { // copy pixel data to TFT
WiredHome 31:c72e12cd5c67 345 if (BPP_t == 4) {
WiredHome 31:c72e12cd5c67 346 uint8_t dPix = lineBuffer[i/2];
WiredHome 31:c72e12cd5c67 347 if ((i & 1) == 0)
WiredHome 31:c72e12cd5c67 348 dPix >>= 4;
WiredHome 31:c72e12cd5c67 349 dPix &= 0x0F;
WiredHome 41:2956a0a221e5 350 pixelBuffer[i] = RGBQuadToRGB16(colorPalette, dPix);
WiredHome 31:c72e12cd5c67 351 } else if (BPP_t == 8) {
WiredHome 41:2956a0a221e5 352 pixelBuffer[i] = RGBQuadToRGB16(colorPalette, lineBuffer[i]);
WiredHome 32:0e4f2ae512e2 353 } else if (BPP_t == 16) {
WiredHome 41:2956a0a221e5 354 pixelBuffer[i] = lineBuffer[i];
WiredHome 32:0e4f2ae512e2 355 } else if (BPP_t == 24) {
WiredHome 37:f19b7e7449dc 356 color_t color;
WiredHome 32:0e4f2ae512e2 357 color = RGB(lineBuffer[i*3+2], lineBuffer[i*3+1], lineBuffer[i*3+0]);
WiredHome 41:2956a0a221e5 358 pixelBuffer[i] = color;
WiredHome 31:c72e12cd5c67 359 }
WiredHome 31:c72e12cd5c67 360 }
WiredHome 41:2956a0a221e5 361 pixelStream(pixelBuffer, PixelWidth, x, y++);
WiredHome 31:c72e12cd5c67 362 }
WiredHome 42:7cbdfd2bbfc5 363 _EndGraphicsStream();
WiredHome 42:7cbdfd2bbfc5 364 WindowMax();
WiredHome 69:636867df24a1 365 free(pixelBuffer); // don't leak memory
WiredHome 31:c72e12cd5c67 366 free(lineBuffer);
WiredHome 69:636867df24a1 367 if (colorPalette)
WiredHome 69:636867df24a1 368 free(colorPalette);
WiredHome 32:0e4f2ae512e2 369 return (noerror);
WiredHome 31:c72e12cd5c67 370 }
WiredHome 31:c72e12cd5c67 371
WiredHome 42:7cbdfd2bbfc5 372
WiredHome 42:7cbdfd2bbfc5 373 RetCode_t GraphicsDisplay::RenderImageFile(loc_t x, loc_t y, const char *FileName)
WiredHome 42:7cbdfd2bbfc5 374 {
WiredHome 42:7cbdfd2bbfc5 375 if (mystrnicmp(FileName + strlen(FileName) - 4, ".bmp", 4) == 0) {
WiredHome 42:7cbdfd2bbfc5 376 return RenderBitmapFile(x,y,FileName);
WiredHome 42:7cbdfd2bbfc5 377 } else if (mystrnicmp(FileName + strlen(FileName) - 4, ".ico", 4) == 0) {
WiredHome 42:7cbdfd2bbfc5 378 return RenderIconFile(x,y,FileName);
WiredHome 42:7cbdfd2bbfc5 379 } else {
WiredHome 42:7cbdfd2bbfc5 380 return not_supported_format;
WiredHome 42:7cbdfd2bbfc5 381 }
WiredHome 42:7cbdfd2bbfc5 382 }
WiredHome 42:7cbdfd2bbfc5 383
WiredHome 42:7cbdfd2bbfc5 384 RetCode_t GraphicsDisplay::RenderBitmapFile(loc_t x, loc_t y, const char *Name_BMP)
WiredHome 42:7cbdfd2bbfc5 385 {
WiredHome 42:7cbdfd2bbfc5 386 BITMAPFILEHEADER BMP_Header;
WiredHome 42:7cbdfd2bbfc5 387
WiredHome 42:7cbdfd2bbfc5 388 INFO("Opening {%s}", Name_BMP);
WiredHome 42:7cbdfd2bbfc5 389 FILE *Image = fopen(Name_BMP, "rb");
WiredHome 42:7cbdfd2bbfc5 390 if (!Image) {
WiredHome 42:7cbdfd2bbfc5 391 return(file_not_found);
WiredHome 42:7cbdfd2bbfc5 392 }
WiredHome 42:7cbdfd2bbfc5 393
WiredHome 42:7cbdfd2bbfc5 394 fread(&BMP_Header, 1, sizeof(BMP_Header), Image); // get the BMP Header
WiredHome 42:7cbdfd2bbfc5 395 INFO("bfType %04X", BMP_Header.bfType);
WiredHome 59:fb40aad4efd4 396 HexDump("BMP_Header", (uint8_t *)&BMP_Header, sizeof(BMP_Header));
WiredHome 42:7cbdfd2bbfc5 397 if (BMP_Header.bfType != BF_TYPE) {
WiredHome 42:7cbdfd2bbfc5 398 fclose(Image);
WiredHome 42:7cbdfd2bbfc5 399 return(not_bmp_format);
WiredHome 42:7cbdfd2bbfc5 400 }
WiredHome 42:7cbdfd2bbfc5 401 RetCode_t rt = _RenderBitmap(x, y, BMP_Header.bfOffBits, Image);
WiredHome 42:7cbdfd2bbfc5 402 if (rt != noerror) {
WiredHome 42:7cbdfd2bbfc5 403 return rt;
WiredHome 42:7cbdfd2bbfc5 404 } else {
WiredHome 42:7cbdfd2bbfc5 405 fclose(Image);
WiredHome 42:7cbdfd2bbfc5 406 return (noerror);
WiredHome 42:7cbdfd2bbfc5 407 }
WiredHome 42:7cbdfd2bbfc5 408 }
WiredHome 42:7cbdfd2bbfc5 409
WiredHome 42:7cbdfd2bbfc5 410 RetCode_t GraphicsDisplay::RenderIconFile(loc_t x, loc_t y, const char *Name_ICO)
WiredHome 42:7cbdfd2bbfc5 411 {
WiredHome 42:7cbdfd2bbfc5 412 ICOFILEHEADER ICO_Header;
WiredHome 42:7cbdfd2bbfc5 413 ICODIRENTRY ICO_DirEntry;
WiredHome 42:7cbdfd2bbfc5 414
WiredHome 42:7cbdfd2bbfc5 415 INFO("Opening {%s}", Name_ICO);
WiredHome 42:7cbdfd2bbfc5 416 FILE *Image = fopen(Name_ICO, "rb");
WiredHome 42:7cbdfd2bbfc5 417 if (!Image) {
WiredHome 42:7cbdfd2bbfc5 418 return(file_not_found);
WiredHome 42:7cbdfd2bbfc5 419 }
WiredHome 42:7cbdfd2bbfc5 420
WiredHome 42:7cbdfd2bbfc5 421 fread(&ICO_Header, 1, sizeof(ICO_Header), Image); // get the BMP Header
WiredHome 42:7cbdfd2bbfc5 422 HexDump("ICO_Header", (uint8_t *)&ICO_Header, sizeof(ICO_Header));
WiredHome 42:7cbdfd2bbfc5 423 if (ICO_Header.Reserved_zero != 0
WiredHome 42:7cbdfd2bbfc5 424 || ICO_Header.icType != IC_TYPE
WiredHome 42:7cbdfd2bbfc5 425 || ICO_Header.icImageCount == 0) {
WiredHome 42:7cbdfd2bbfc5 426 fclose(Image);
WiredHome 42:7cbdfd2bbfc5 427 return(not_ico_format);
WiredHome 42:7cbdfd2bbfc5 428 }
WiredHome 42:7cbdfd2bbfc5 429
WiredHome 42:7cbdfd2bbfc5 430 // Read ONLY the first of n possible directory entries.
WiredHome 42:7cbdfd2bbfc5 431 fread(&ICO_DirEntry, 1, sizeof(ICO_DirEntry), Image);
WiredHome 42:7cbdfd2bbfc5 432 HexDump("ICO_DirEntry", (uint8_t *)&ICO_DirEntry, sizeof(ICO_DirEntry));
WiredHome 42:7cbdfd2bbfc5 433 INFO("biBitCount %04X", ICO_DirEntry.biBitCount);
WiredHome 42:7cbdfd2bbfc5 434 if (ICO_DirEntry.biBitCount != 0) { // Expecting this to be zero for ico
WiredHome 42:7cbdfd2bbfc5 435 fclose(Image);
WiredHome 42:7cbdfd2bbfc5 436 return(not_supported_format);
WiredHome 42:7cbdfd2bbfc5 437 }
WiredHome 42:7cbdfd2bbfc5 438
WiredHome 42:7cbdfd2bbfc5 439 RetCode_t rt = _RenderBitmap(x, y, ICO_DirEntry.bfOffBits, Image);
WiredHome 42:7cbdfd2bbfc5 440 if (rt == noerror) {
WiredHome 42:7cbdfd2bbfc5 441 fclose(Image);
WiredHome 42:7cbdfd2bbfc5 442 return (noerror);
WiredHome 42:7cbdfd2bbfc5 443 } else {
WiredHome 42:7cbdfd2bbfc5 444 return rt;
WiredHome 42:7cbdfd2bbfc5 445 }
WiredHome 42:7cbdfd2bbfc5 446 }
WiredHome 42:7cbdfd2bbfc5 447
WiredHome 19:3f82c1161fd2 448 int GraphicsDisplay::columns()
WiredHome 19:3f82c1161fd2 449 {
WiredHome 19:3f82c1161fd2 450 return width() / 8;
dreschpe 0:de9d1462a835 451 }
dreschpe 0:de9d1462a835 452
WiredHome 19:3f82c1161fd2 453 int GraphicsDisplay::rows()
WiredHome 19:3f82c1161fd2 454 {
WiredHome 19:3f82c1161fd2 455 return height() / 8;
WiredHome 19:3f82c1161fd2 456 }