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:
Mon Feb 08 01:47:56 2016 +0000
Revision:
104:8d1d3832a215
Parent:
101:e0aad446094a
Child:
109:7b94f06f085b
comment out destructors - until I figure out the warning.

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