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:
Wed Apr 27 01:29:55 2016 +0000
Revision:
112:325ca91bc03d
Parent:
111:efe436c43aba
Child:
113:843888f7785b
Child:
114:dbfb996bfbf3
Added support for monochrome BMP format.; Tiny optimization (simplified the code, no noticeable performance increase).

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