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:
Thu Dec 17 12:16:40 2015 +0000
Revision:
98:ecebed9b80b2
Parent:
95:ef538bd687c0
Child:
100:0b084475d5a9
Significant changes to the support for Soft Fonts (User defined fonts), to directly leverage the output of the GLCD Font Creator tool and require nearly zero manual changes. This deprecates the old API setfont in favor of SelectUserFont.

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