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 May 16 02:05:37 2016 +0000
Revision:
115:c9862fd0c689
Parent:
114:dbfb996bfbf3
Child:
119:d129b798f82f
Jpeg rendering - not yet working, just an intermediate check-point.

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