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:
Sun Apr 04 20:14:06 2021 +0000
Revision:
209:08fc22dea762
Parent:
202:a22cbc04f332
Fix a long-standing defect in the FT5206 where it reported 'touch' code even for hold and release events.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dreschpe 0:de9d1462a835 1 /* mbed GraphicsDisplay Display Library Base Class
WiredHome 167:8aa3fb2a5a31 2 * Copyright © 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
WiredHome 153:8a85efb3eb71 6 * 201807 Scalable soft-fonts and gif support
WiredHome 153:8a85efb3eb71 7 *
dreschpe 0:de9d1462a835 8 */
WiredHome 19:3f82c1161fd2 9
dreschpe 0:de9d1462a835 10 #include "GraphicsDisplay.h"
WiredHome 31:c72e12cd5c67 11 #include "Bitmap.h"
WiredHome 42:7cbdfd2bbfc5 12 #include "string.h"
dreschpe 0:de9d1462a835 13
WiredHome 145:5eb2492acdda 14 //#include "Utility.h" // private memory manager
WiredHome 145:5eb2492acdda 15 #ifndef UTILITY_H
WiredHome 145:5eb2492acdda 16 #define swMalloc malloc // use the standard
WiredHome 145:5eb2492acdda 17 #define swFree free
WiredHome 145:5eb2492acdda 18 #endif
WiredHome 145:5eb2492acdda 19
WiredHome 121:6bc4911f5e55 20 //#define DEBUG "GD "
WiredHome 29:422616aa04bd 21 // ...
WiredHome 29:422616aa04bd 22 // INFO("Stuff to show %d", var); // new-line is automatically appended
WiredHome 29:422616aa04bd 23 //
WiredHome 29:422616aa04bd 24 #if (defined(DEBUG) && !defined(TARGET_LPC11U24))
WiredHome 190:3132b7dfad82 25 #define INFO(x, ...) std::printf("[INF %s %4d] " x "\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 190:3132b7dfad82 26 #define WARN(x, ...) std::printf("[WRN %s %4d] " x "\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 190:3132b7dfad82 27 #define ERR(x, ...) std::printf("[ERR %s %4d] " x "\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 98:ecebed9b80b2 28 static void HexDump(const char * title, const uint8_t * p, int count)
WiredHome 31:c72e12cd5c67 29 {
WiredHome 31:c72e12cd5c67 30 int i;
WiredHome 31:c72e12cd5c67 31 char buf[100] = "0000: ";
WiredHome 190:3132b7dfad82 32
WiredHome 31:c72e12cd5c67 33 if (*title)
WiredHome 31:c72e12cd5c67 34 INFO("%s", title);
WiredHome 31:c72e12cd5c67 35 for (i=0; i<count; ) {
WiredHome 31:c72e12cd5c67 36 sprintf(buf + strlen(buf), "%02X ", *(p+i));
WiredHome 31:c72e12cd5c67 37 if ((++i & 0x0F) == 0x00) {
WiredHome 31:c72e12cd5c67 38 INFO("%s", buf);
WiredHome 31:c72e12cd5c67 39 if (i < count)
WiredHome 31:c72e12cd5c67 40 sprintf(buf, "%04X: ", i);
WiredHome 31:c72e12cd5c67 41 else
WiredHome 31:c72e12cd5c67 42 buf[0] = '\0';
WiredHome 31:c72e12cd5c67 43 }
WiredHome 31:c72e12cd5c67 44 }
WiredHome 31:c72e12cd5c67 45 if (strlen(buf))
WiredHome 31:c72e12cd5c67 46 INFO("%s", buf);
WiredHome 31:c72e12cd5c67 47 }
WiredHome 29:422616aa04bd 48 #else
WiredHome 29:422616aa04bd 49 #define INFO(x, ...)
WiredHome 29:422616aa04bd 50 #define WARN(x, ...)
WiredHome 29:422616aa04bd 51 #define ERR(x, ...)
WiredHome 32:0e4f2ae512e2 52 #define HexDump(a, b, c)
WiredHome 29:422616aa04bd 53 #endif
WiredHome 29:422616aa04bd 54
WiredHome 19:3f82c1161fd2 55
WiredHome 42:7cbdfd2bbfc5 56 char mytolower(char a) {
WiredHome 42:7cbdfd2bbfc5 57 if (a >= 'A' && a <= 'Z')
WiredHome 42:7cbdfd2bbfc5 58 return (a - 'A' + 'a');
WiredHome 42:7cbdfd2bbfc5 59 else
WiredHome 42:7cbdfd2bbfc5 60 return a;
WiredHome 42:7cbdfd2bbfc5 61 }
WiredHome 42:7cbdfd2bbfc5 62 /// mystrnicmp exists because not all compiler libraries have this function.
WiredHome 42:7cbdfd2bbfc5 63 ///
WiredHome 42:7cbdfd2bbfc5 64 /// Some have strnicmp, others _strnicmp, and others have C++ methods, which
WiredHome 42:7cbdfd2bbfc5 65 /// is outside the scope of this C-portable set of functions.
WiredHome 42:7cbdfd2bbfc5 66 ///
WiredHome 42:7cbdfd2bbfc5 67 /// @param l is a pointer to the string on the left
WiredHome 42:7cbdfd2bbfc5 68 /// @param r is a pointer to the string on the right
WiredHome 42:7cbdfd2bbfc5 69 /// @param n is the number of characters to compare
WiredHome 42:7cbdfd2bbfc5 70 /// @returns -1 if l < r
WiredHome 42:7cbdfd2bbfc5 71 /// @returns 0 if l == r
WiredHome 42:7cbdfd2bbfc5 72 /// @returns +1 if l > r
WiredHome 42:7cbdfd2bbfc5 73 ///
WiredHome 42:7cbdfd2bbfc5 74 int mystrnicmp(const char *l, const char *r, size_t n) {
WiredHome 42:7cbdfd2bbfc5 75 int result = 0;
WiredHome 42:7cbdfd2bbfc5 76
WiredHome 42:7cbdfd2bbfc5 77 if (n != 0) {
WiredHome 42:7cbdfd2bbfc5 78 do {
WiredHome 42:7cbdfd2bbfc5 79 result = mytolower(*l++) - mytolower(*r++);
WiredHome 42:7cbdfd2bbfc5 80 } while ((result == 0) && (*l != '\0') && (--n > 0));
WiredHome 42:7cbdfd2bbfc5 81 }
WiredHome 42:7cbdfd2bbfc5 82 if (result < -1)
WiredHome 42:7cbdfd2bbfc5 83 result = -1;
WiredHome 42:7cbdfd2bbfc5 84 else if (result > 1)
WiredHome 42:7cbdfd2bbfc5 85 result = 1;
WiredHome 42:7cbdfd2bbfc5 86 return result;
WiredHome 42:7cbdfd2bbfc5 87 }
WiredHome 42:7cbdfd2bbfc5 88
WiredHome 42:7cbdfd2bbfc5 89
WiredHome 190:3132b7dfad82 90 GraphicsDisplay::GraphicsDisplay(const char *name)
WiredHome 29:422616aa04bd 91 : TextDisplay(name)
WiredHome 19:3f82c1161fd2 92 {
WiredHome 29:422616aa04bd 93 font = NULL;
WiredHome 182:8832d03a2a29 94 img_x = 0;
WiredHome 182:8832d03a2a29 95 img_y = 0;
WiredHome 182:8832d03a2a29 96 _x = 0;
WiredHome 182:8832d03a2a29 97 _y = 0;
WiredHome 182:8832d03a2a29 98 fontScaleX = 0;
WiredHome 182:8832d03a2a29 99 fontScaleY = 0;
WiredHome 182:8832d03a2a29 100 memset(&screen_descriptor, 0, sizeof(gif_screen_descriptor_t));
WiredHome 152:a013ac0133e4 101 global_color_table = NULL;
WiredHome 182:8832d03a2a29 102 global_color_table_size = 0;
WiredHome 152:a013ac0133e4 103 local_color_table = NULL;
WiredHome 182:8832d03a2a29 104 local_color_table_size = 0;
WiredHome 152:a013ac0133e4 105 screen_descriptor_isvalid = false;
WiredHome 182:8832d03a2a29 106 memset(&windowrect, 0, sizeof(rect_t));
dreschpe 0:de9d1462a835 107 }
WiredHome 19:3f82c1161fd2 108
WiredHome 104:8d1d3832a215 109 //GraphicsDisplay::~GraphicsDisplay()
WiredHome 104:8d1d3832a215 110 //{
WiredHome 104:8d1d3832a215 111 //}
WiredHome 104:8d1d3832a215 112
WiredHome 198:9b6851107426 113 #if 0
WiredHome 198:9b6851107426 114 rect_t GraphicsDisplay::GetWindow() {
WiredHome 198:9b6851107426 115 return windowrect;
WiredHome 198:9b6851107426 116 }
WiredHome 198:9b6851107426 117
WiredHome 198:9b6851107426 118 rect_t GraphicsDisplay::SetWindow(rect_t r)
WiredHome 198:9b6851107426 119 {
WiredHome 198:9b6851107426 120 return SetWindow(r.p1.x, r.p1.y, r.p2.x, r.p2.y);
WiredHome 198:9b6851107426 121 }
WiredHome 198:9b6851107426 122
WiredHome 198:9b6851107426 123 rect_t GraphicsDisplay::SetWindow(loc_t x1, loc_t y1, loc_t x2, loc_t y2)
WiredHome 198:9b6851107426 124 {
WiredHome 198:9b6851107426 125 rect_t oldWin = windowrect;
WiredHome 198:9b6851107426 126 dim_t tempWidth, tempHeight;
WiredHome 198:9b6851107426 127 INFO("SetWindow(%d,%d)-(%d,%d)", x1, y1, x2, y2);
WiredHome 198:9b6851107426 128 // Correct the initial values (0,-1) - (0,-1)
WiredHome 198:9b6851107426 129 if (x2 == (loc_t)-1) x2 = width() - 1;
WiredHome 198:9b6851107426 130 if (y2 == (loc_t)-1) y2 = height() - 1;
WiredHome 198:9b6851107426 131 // Sanity check the parameters.
WiredHome 198:9b6851107426 132 if (x1 < 0 || y1 < 0 || x2 < 0 || y2 < 0
WiredHome 198:9b6851107426 133 || x1 >= width() || y1 >= height()
WiredHome 198:9b6851107426 134 || x2 >= width() || y2 >= height()) {
WiredHome 198:9b6851107426 135 rect_t nullRect = { 0,0,0,0 };
WiredHome 198:9b6851107426 136 return nullRect;
WiredHome 198:9b6851107426 137 }
WiredHome 198:9b6851107426 138 switch (screen_orientation) {
WiredHome 198:9b6851107426 139 case rotate_0:
WiredHome 198:9b6851107426 140 case rotate_180:
WiredHome 198:9b6851107426 141 windowrect.p1.x = x1;
WiredHome 198:9b6851107426 142 windowrect.p1.y = y1;
WiredHome 198:9b6851107426 143 windowrect.p2.x = x2;
WiredHome 198:9b6851107426 144 windowrect.p2.y = y2;
WiredHome 202:a22cbc04f332 145 tempWidth = RAmax(virt_screenwidth, virt_screenheight);
WiredHome 202:a22cbc04f332 146 tempHeight = RAmin(virt_screenwidth, virt_screenheight);
WiredHome 198:9b6851107426 147 virt_screenwidth = tempWidth;
WiredHome 198:9b6851107426 148 virt_screenheight = tempHeight;
WiredHome 198:9b6851107426 149 //GraphicsDisplay::SetWindow(x1, y1, x2, y2);
WiredHome 198:9b6851107426 150 WriteCommandW(RA8875_HSAW0, x1);
WiredHome 198:9b6851107426 151 WriteCommandW(RA8875_VSAW0, y1);
WiredHome 198:9b6851107426 152 WriteCommandW(RA8875_HEAW0, x2);
WiredHome 198:9b6851107426 153 WriteCommandW(RA8875_VEAW0, y2);
WiredHome 198:9b6851107426 154 break;
WiredHome 198:9b6851107426 155 case rotate_90:
WiredHome 198:9b6851107426 156 case rotate_270:
WiredHome 198:9b6851107426 157 windowrect.p1.x = y1;
WiredHome 198:9b6851107426 158 windowrect.p1.y = x1;
WiredHome 198:9b6851107426 159 windowrect.p2.x = y2;
WiredHome 198:9b6851107426 160 windowrect.p2.y = x2;
WiredHome 202:a22cbc04f332 161 tempWidth = RAmin(virt_screenwidth, virt_screenheight);
WiredHome 202:a22cbc04f332 162 tempHeight = RAmax(virt_screenwidth, virt_screenheight);
WiredHome 198:9b6851107426 163 virt_screenwidth = tempWidth;
WiredHome 198:9b6851107426 164 virt_screenheight = tempHeight;
WiredHome 198:9b6851107426 165 //GraphicsDisplay::SetWindow(x1, y1, x2, y2);
WiredHome 198:9b6851107426 166 WriteCommandW(RA8875_HSAW0, y1);
WiredHome 198:9b6851107426 167 WriteCommandW(RA8875_VSAW0, x1);
WiredHome 198:9b6851107426 168 WriteCommandW(RA8875_HEAW0, y2);
WiredHome 198:9b6851107426 169 WriteCommandW(RA8875_VEAW0, x2);
WiredHome 198:9b6851107426 170 break;
WiredHome 198:9b6851107426 171 }
WiredHome 198:9b6851107426 172 return oldWin;
WiredHome 198:9b6851107426 173 }
WiredHome 198:9b6851107426 174 #endif
WiredHome 198:9b6851107426 175
WiredHome 98:ecebed9b80b2 176 RetCode_t GraphicsDisplay::SelectUserFont(const unsigned char * _font)
WiredHome 29:422616aa04bd 177 {
WiredHome 98:ecebed9b80b2 178 font = _font; // trusting them, but it might be good to put some checks in here...
WiredHome 98:ecebed9b80b2 179 return noerror;
WiredHome 29:422616aa04bd 180 }
WiredHome 98:ecebed9b80b2 181
WiredHome 29:422616aa04bd 182 int GraphicsDisplay::character(int x, int y, int c)
WiredHome 29:422616aa04bd 183 {
WiredHome 101:e0aad446094a 184 return fontblit(x, y, c);
WiredHome 29:422616aa04bd 185 }
WiredHome 19:3f82c1161fd2 186
WiredHome 55:dfbabef7003e 187 RetCode_t GraphicsDisplay::_putp(color_t color)
WiredHome 19:3f82c1161fd2 188 {
WiredHome 198:9b6851107426 189 rect_t win = GetWindow();
WiredHome 33:b6b710758ab3 190 pixel(_x, _y, color);
dreschpe 0:de9d1462a835 191 // update pixel location based on window settings
dreschpe 0:de9d1462a835 192 _x++;
WiredHome 198:9b6851107426 193 if(_x > win.p2.x) {
WiredHome 198:9b6851107426 194 _x = win.p1.x;
dreschpe 0:de9d1462a835 195 _y++;
WiredHome 198:9b6851107426 196 if(_y > win.p2.y) {
WiredHome 198:9b6851107426 197 _y = win.p1.y;
dreschpe 0:de9d1462a835 198 }
dreschpe 0:de9d1462a835 199 }
WiredHome 32:0e4f2ae512e2 200 return noerror;
dreschpe 0:de9d1462a835 201 }
dreschpe 0:de9d1462a835 202
WiredHome 109:7b94f06f085b 203 RetCode_t GraphicsDisplay::fill(loc_t x, loc_t y, dim_t w, dim_t h, color_t color)
WiredHome 19:3f82c1161fd2 204 {
WiredHome 79:544eb4964795 205 return fillrect(x,y, x+w, y+h, color);
dreschpe 0:de9d1462a835 206 }
WiredHome 19:3f82c1161fd2 207
WiredHome 61:8f3153bf0baa 208 RetCode_t GraphicsDisplay::cls(uint16_t layers)
WiredHome 19:3f82c1161fd2 209 {
WiredHome 198:9b6851107426 210 uint16_t oldLayer = 0;
WiredHome 142:6e9bff59878a 211 if (layers & 1) {
WiredHome 198:9b6851107426 212 oldLayer = SelectDrawingLayer(0);
WiredHome 142:6e9bff59878a 213 fill(0, 0, width(), height(), _background);
WiredHome 142:6e9bff59878a 214 }
WiredHome 142:6e9bff59878a 215 if (layers & 2) {
WiredHome 198:9b6851107426 216 oldLayer = SelectDrawingLayer(1);
WiredHome 142:6e9bff59878a 217 fill(0, 0, width(), height(), _background);
WiredHome 142:6e9bff59878a 218 }
WiredHome 198:9b6851107426 219 SelectDrawingLayer(oldLayer);
WiredHome 142:6e9bff59878a 220 return noerror;
dreschpe 0:de9d1462a835 221 }
WiredHome 19:3f82c1161fd2 222
WiredHome 198:9b6851107426 223
WiredHome 109:7b94f06f085b 224 RetCode_t GraphicsDisplay::blit(loc_t x, loc_t y, dim_t w, dim_t h, const int * color)
WiredHome 19:3f82c1161fd2 225 {
WiredHome 198:9b6851107426 226 rect_t restore = SetWindow(x, y, x + w, y + h);
WiredHome 37:f19b7e7449dc 227 _StartGraphicsStream();
WiredHome 31:c72e12cd5c67 228 for (int i=0; i<w*h; i++) {
WiredHome 55:dfbabef7003e 229 _putp(color[i]);
dreschpe 0:de9d1462a835 230 }
WiredHome 37:f19b7e7449dc 231 _EndGraphicsStream();
WiredHome 198:9b6851107426 232 SetWindow(restore);
WiredHome 198:9b6851107426 233 return noerror;
dreschpe 0:de9d1462a835 234 }
WiredHome 19:3f82c1161fd2 235
WiredHome 98:ecebed9b80b2 236 // 8 byte "info" section
WiredHome 98:ecebed9b80b2 237 //0x00, // unknown ????????
WiredHome 98:ecebed9b80b2 238 //0x00, // unknown ????????
WiredHome 98:ecebed9b80b2 239 //0x20,0x00, // First char 32
WiredHome 98:ecebed9b80b2 240 //0x7F,0x00, // Last char 127
WiredHome 98:ecebed9b80b2 241 //0x25, // Font Height 37
WiredHome 98:ecebed9b80b2 242 //0x00, // Unknown 0 ????????
WiredHome 98:ecebed9b80b2 243 //
WiredHome 98:ecebed9b80b2 244 //0x01,0x88,0x01,0x00 // ' ' is 1 pixel wide, data is at offset 0x0188
WiredHome 98:ecebed9b80b2 245 //0x0B,0xAD,0x01,0x00 // '!' is 11 pixels wide, data is at offset 0x01AD
WiredHome 98:ecebed9b80b2 246 //0x0D,0xF7,0x01,0x00 // '"' is 13 pixels wide, data is at offset 0x01F7
WiredHome 98:ecebed9b80b2 247 //...
WiredHome 98:ecebed9b80b2 248 //0x00,... // ' ' data stream.
WiredHome 98:ecebed9b80b2 249 //0x00,0x06,0x00,0x07,0x80,0x07,0xC0,0x07,0xC0,0x07,0xC0 // '!'
WiredHome 98:ecebed9b80b2 250 //...
WiredHome 101:e0aad446094a 251
WiredHome 101:e0aad446094a 252
WiredHome 109:7b94f06f085b 253 const uint8_t * GraphicsDisplay::getCharMetrics(const unsigned char c, dim_t * width, dim_t * height)
WiredHome 19:3f82c1161fd2 254 {
WiredHome 98:ecebed9b80b2 255 uint16_t offsetToCharLookup;
WiredHome 98:ecebed9b80b2 256 uint16_t firstChar = font[3] * 256 + font[2];
WiredHome 98:ecebed9b80b2 257 uint16_t lastChar = font[5] * 256 + font[4];
WiredHome 109:7b94f06f085b 258 dim_t charHeight = font[6];
WiredHome 98:ecebed9b80b2 259 const unsigned char * charRecord; // width, data, data, data, ...
WiredHome 190:3132b7dfad82 260
WiredHome 198:9b6851107426 261 INFO("first:%d, last:%d, c:%02X '%c'", firstChar, lastChar, c, (c >= ' ' && c <= '~') ? c : '-');
WiredHome 98:ecebed9b80b2 262 if (c < firstChar || c > lastChar)
WiredHome 101:e0aad446094a 263 return NULL; // advance zero pixels since it was unprintable...
WiredHome 190:3132b7dfad82 264
WiredHome 101:e0aad446094a 265 // 8 bytes of preamble to the first level lookup table
WiredHome 101:e0aad446094a 266 offsetToCharLookup = 8 + 4 * (c - firstChar); // 4-bytes: width(pixels), 16-bit offset from table start, 0
WiredHome 109:7b94f06f085b 267 dim_t charWidth = font[offsetToCharLookup];
WiredHome 101:e0aad446094a 268 charRecord = font + font[offsetToCharLookup + 2] * 256 + font[offsetToCharLookup + 1];
WiredHome 101:e0aad446094a 269 //INFO("hgt:%d, wdt:%d", charHeight, charWidth);
WiredHome 101:e0aad446094a 270 if (width)
WiredHome 101:e0aad446094a 271 *width = charWidth;
WiredHome 101:e0aad446094a 272 if (height)
WiredHome 101:e0aad446094a 273 *height = charHeight;
WiredHome 101:e0aad446094a 274 return charRecord;
WiredHome 101:e0aad446094a 275 }
WiredHome 101:e0aad446094a 276
WiredHome 109:7b94f06f085b 277
WiredHome 109:7b94f06f085b 278 int GraphicsDisplay::fontblit(loc_t x, loc_t y, const unsigned char c)
WiredHome 101:e0aad446094a 279 {
WiredHome 153:8a85efb3eb71 280 const uint8_t * charRecord; // pointer to char data; width, data, data, data, ...
WiredHome 153:8a85efb3eb71 281 dim_t charWidth, charHeight; // metrics for the raw char in the font table
WiredHome 101:e0aad446094a 282 charRecord = getCharMetrics(c, &charWidth, &charHeight);
WiredHome 101:e0aad446094a 283 if (charRecord) {
WiredHome 198:9b6851107426 284 INFO("wdt:%d, hgt:%d", charWidth, charHeight);
WiredHome 109:7b94f06f085b 285 booleanStream(x,y,charWidth, charHeight, charRecord);
WiredHome 153:8a85efb3eb71 286 return charWidth * fontScaleX;
WiredHome 101:e0aad446094a 287 } else {
WiredHome 101:e0aad446094a 288 return 0;
WiredHome 29:422616aa04bd 289 }
dreschpe 0:de9d1462a835 290 }
dreschpe 0:de9d1462a835 291
WiredHome 31:c72e12cd5c67 292 // BMP Color Palette is BGRx
WiredHome 31:c72e12cd5c67 293 // BBBB BBBB GGGG GGGG RRRR RRRR 0000 0000
WiredHome 31:c72e12cd5c67 294 // RGB16 is
WiredHome 31:c72e12cd5c67 295 // RRRR RGGG GGGB BBBB
WiredHome 31:c72e12cd5c67 296 // swap to little endian
WiredHome 31:c72e12cd5c67 297 // GGGB BBBB RRRR RGGG
WiredHome 32:0e4f2ae512e2 298 color_t GraphicsDisplay::RGBQuadToRGB16(RGBQUAD * colorPalette, uint16_t i)
WiredHome 31:c72e12cd5c67 299 {
WiredHome 31:c72e12cd5c67 300 color_t c;
WiredHome 190:3132b7dfad82 301
WiredHome 31:c72e12cd5c67 302 c = ((colorPalette[i].rgbBlue >> 3) << 0);
WiredHome 31:c72e12cd5c67 303 c |= ((colorPalette[i].rgbGreen >> 2) << 5);
WiredHome 31:c72e12cd5c67 304 c |= ((colorPalette[i].rgbRed >> 3) << 11);
WiredHome 31:c72e12cd5c67 305 return c;
WiredHome 31:c72e12cd5c67 306 }
WiredHome 29:422616aa04bd 307
WiredHome 198:9b6851107426 308 // RGB16 little endian
WiredHome 198:9b6851107426 309
WiredHome 93:6fbc516de05e 310 // GGGB BBBB RRRR RGGG
WiredHome 93:6fbc516de05e 311 // swap
WiredHome 93:6fbc516de05e 312 // RRRR RGGG GGGB BBBB
WiredHome 93:6fbc516de05e 313 // RRRR R
WiredHome 93:6fbc516de05e 314 // extend to BMP Color Palette is BGRx
WiredHome 93:6fbc516de05e 315 // BBBB BBBB GGGG GGGG RRRR RRRR 0000 0000
WiredHome 41:2956a0a221e5 316 RGBQUAD GraphicsDisplay::RGB16ToRGBQuad(color_t c)
WiredHome 41:2956a0a221e5 317 {
WiredHome 41:2956a0a221e5 318 RGBQUAD q;
WiredHome 190:3132b7dfad82 319
WiredHome 41:2956a0a221e5 320 memset(&q, 0, sizeof(q));
WiredHome 162:a2d7f1988711 321 //c = (c << 8) | (c >> 8); // swap
WiredHome 72:ecffe56af969 322 q.rgbBlue = ((c & 0x001F) << 3) | (c & 0x07); /* Blue value */
WiredHome 93:6fbc516de05e 323 q.rgbGreen = ((c & 0x07E0) >> 3) | ((c >> 9) & 0x03); /* Green value */
WiredHome 93:6fbc516de05e 324 q.rgbRed = ((c & 0xF800) >> 8) | ((c >> 13) & 0x07); /* Red value */
WiredHome 41:2956a0a221e5 325 q.rgbReserved = 0;
WiredHome 41:2956a0a221e5 326 return q;
WiredHome 41:2956a0a221e5 327 }
WiredHome 41:2956a0a221e5 328
WiredHome 190:3132b7dfad82 329 RetCode_t GraphicsDisplay::_RenderBitmap(loc_t x, loc_t y, uint32_t fileOffset, FILE * Image, rect_t * infoOnly)
WiredHome 31:c72e12cd5c67 330 {
WiredHome 31:c72e12cd5c67 331 BITMAPINFOHEADER BMP_Info;
WiredHome 31:c72e12cd5c67 332 RGBQUAD * colorPalette = NULL;
WiredHome 31:c72e12cd5c67 333 int colorCount;
WiredHome 32:0e4f2ae512e2 334 uint8_t * lineBuffer = NULL;
WiredHome 69:636867df24a1 335 color_t * pixelBuffer = NULL;
WiredHome 31:c72e12cd5c67 336 uint16_t BPP_t;
WiredHome 95:ef538bd687c0 337 dim_t PixelWidth, PixelHeight;
WiredHome 31:c72e12cd5c67 338 unsigned int i, offset;
WiredHome 31:c72e12cd5c67 339 int padd,j;
WiredHome 59:fb40aad4efd4 340 #ifdef DEBUG
WiredHome 112:325ca91bc03d 341 //uint32_t start_data;
WiredHome 59:fb40aad4efd4 342 #endif
WiredHome 31:c72e12cd5c67 343
WiredHome 42:7cbdfd2bbfc5 344 // Now, Read the bitmap info header
WiredHome 31:c72e12cd5c67 345 fread(&BMP_Info, 1, sizeof(BMP_Info), Image);
WiredHome 198:9b6851107426 346 //HexDump("BMP_Info", (uint8_t *)&BMP_Info, sizeof(BMP_Info));
WiredHome 31:c72e12cd5c67 347 BPP_t = BMP_Info.biBitCount;
WiredHome 198:9b6851107426 348 //INFO("biBitCount %04X", BPP_t);
WiredHome 112:325ca91bc03d 349 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 350 fclose(Image);
WiredHome 31:c72e12cd5c67 351 return(not_supported_format);
WiredHome 31:c72e12cd5c67 352 }
WiredHome 112:325ca91bc03d 353 if (BMP_Info.biCompression != 0) { // Only the "no comporession" option is supported.
WiredHome 112:325ca91bc03d 354 fclose(Image);
WiredHome 112:325ca91bc03d 355 return(not_supported_format);
WiredHome 112:325ca91bc03d 356 }
WiredHome 31:c72e12cd5c67 357 PixelHeight = BMP_Info.biHeight;
WiredHome 31:c72e12cd5c67 358 PixelWidth = BMP_Info.biWidth;
WiredHome 198:9b6851107426 359 //INFO("(%d x,%d h) (%d w,%d h) (%d w,%d h)", x,y, PixelWidth,PixelHeight, width(), height());
WiredHome 190:3132b7dfad82 360 if (infoOnly) {
WiredHome 190:3132b7dfad82 361 infoOnly->p1.x = x;
WiredHome 190:3132b7dfad82 362 infoOnly->p1.y = y;
WiredHome 198:9b6851107426 363 infoOnly->p2.x = x+PixelWidth-1;
WiredHome 198:9b6851107426 364 infoOnly->p2.y = y+PixelHeight-1;
WiredHome 190:3132b7dfad82 365 return (noerror);
WiredHome 190:3132b7dfad82 366 }
WiredHome 190:3132b7dfad82 367
WiredHome 31:c72e12cd5c67 368 if (PixelHeight > height() + y || PixelWidth > width() + x) {
WiredHome 31:c72e12cd5c67 369 fclose(Image);
WiredHome 190:3132b7dfad82 370 ERR("too big: img: (%d,%d), xy: (%d,%d), screen: (%d,%d)\r\n",
WiredHome 190:3132b7dfad82 371 PixelWidth, PixelHeight, x, y, width(), height());
WiredHome 31:c72e12cd5c67 372 return(image_too_big);
WiredHome 31:c72e12cd5c67 373 }
WiredHome 31:c72e12cd5c67 374 if (BMP_Info.biBitCount <= 8) {
WiredHome 31:c72e12cd5c67 375 int paletteSize;
WiredHome 31:c72e12cd5c67 376 // Read the color palette
WiredHome 31:c72e12cd5c67 377 colorCount = 1 << BMP_Info.biBitCount;
WiredHome 31:c72e12cd5c67 378 paletteSize = sizeof(RGBQUAD) * colorCount;
WiredHome 145:5eb2492acdda 379 colorPalette = (RGBQUAD *)swMalloc(paletteSize);
WiredHome 31:c72e12cd5c67 380 if (colorPalette == NULL) {
WiredHome 31:c72e12cd5c67 381 fclose(Image);
WiredHome 31:c72e12cd5c67 382 return(not_enough_ram);
WiredHome 31:c72e12cd5c67 383 }
WiredHome 31:c72e12cd5c67 384 fread(colorPalette, 1, paletteSize, Image);
WiredHome 198:9b6851107426 385 //HexDump("Color Palette", (uint8_t *)colorPalette, paletteSize);
WiredHome 31:c72e12cd5c67 386 }
WiredHome 31:c72e12cd5c67 387
WiredHome 32:0e4f2ae512e2 388 int lineBufSize = ((BPP_t * PixelWidth + 7)/8);
WiredHome 198:9b6851107426 389 //INFO("BPP_t %d, PixelWidth %d, lineBufSize %d", BPP_t, PixelWidth, lineBufSize);
WiredHome 145:5eb2492acdda 390 lineBuffer = (uint8_t *)swMalloc(lineBufSize);
WiredHome 31:c72e12cd5c67 391 if (lineBuffer == NULL) {
WiredHome 145:5eb2492acdda 392 swFree(colorPalette);
WiredHome 31:c72e12cd5c67 393 fclose(Image);
WiredHome 31:c72e12cd5c67 394 return(not_enough_ram);
WiredHome 31:c72e12cd5c67 395 }
WiredHome 145:5eb2492acdda 396 pixelBuffer = (color_t *)swMalloc(PixelWidth * sizeof(color_t));
WiredHome 41:2956a0a221e5 397 if (pixelBuffer == NULL) {
WiredHome 145:5eb2492acdda 398 swFree(lineBuffer);
WiredHome 69:636867df24a1 399 if (colorPalette)
WiredHome 145:5eb2492acdda 400 swFree(colorPalette);
WiredHome 41:2956a0a221e5 401 fclose(Image);
WiredHome 41:2956a0a221e5 402 return(not_enough_ram);
WiredHome 41:2956a0a221e5 403 }
WiredHome 31:c72e12cd5c67 404
WiredHome 112:325ca91bc03d 405 padd = (lineBufSize % 4);
WiredHome 112:325ca91bc03d 406 if (padd)
WiredHome 112:325ca91bc03d 407 padd = 4 - padd;
WiredHome 31:c72e12cd5c67 408
WiredHome 32:0e4f2ae512e2 409 // Define window for top to bottom and left to right so writing auto-wraps
WiredHome 198:9b6851107426 410 rect_t restore = SetWindow(x,y, x+PixelWidth-1,y+PixelHeight-1);
WiredHome 136:224e03d5c31f 411 // SetGraphicsCursor(x, y);
WiredHome 136:224e03d5c31f 412 // _StartGraphicsStream();
WiredHome 112:325ca91bc03d 413
WiredHome 112:325ca91bc03d 414 //start_data = BMP_Info.bfOffBits;
WiredHome 112:325ca91bc03d 415 //HexDump("Raw Data", (uint8_t *)&start_data, 32);
WiredHome 198:9b6851107426 416 //INFO("(%d,%d) (%d,%d), [%d,%d]", x,y, PixelWidth,PixelHeight, lineBufSize, padd);
WiredHome 32:0e4f2ae512e2 417 for (j = PixelHeight - 1; j >= 0; j--) { //Lines bottom up
WiredHome 42:7cbdfd2bbfc5 418 offset = fileOffset + j * (lineBufSize + padd); // start of line
WiredHome 31:c72e12cd5c67 419 fseek(Image, offset, SEEK_SET);
WiredHome 32:0e4f2ae512e2 420 fread(lineBuffer, 1, lineBufSize, Image); // read a line - slow !
WiredHome 79:544eb4964795 421 //INFO("offset: %6X", offset);
WiredHome 112:325ca91bc03d 422 //HexDump("Line", lineBuffer, lineBufSize);
WiredHome 32:0e4f2ae512e2 423 for (i = 0; i < PixelWidth; i++) { // copy pixel data to TFT
WiredHome 112:325ca91bc03d 424 if (BPP_t == 1) {
WiredHome 112:325ca91bc03d 425 uint8_t dPix = lineBuffer[i/8];
WiredHome 112:325ca91bc03d 426 uint8_t bMask = 0x80 >> (i % 8);
WiredHome 112:325ca91bc03d 427 uint8_t bit = (bMask & dPix) ? 0 : 1;
WiredHome 136:224e03d5c31f 428 pixelBuffer[i] = RGBQuadToRGB16(colorPalette, bit);
WiredHome 112:325ca91bc03d 429 } else if (BPP_t == 4) {
WiredHome 31:c72e12cd5c67 430 uint8_t dPix = lineBuffer[i/2];
WiredHome 31:c72e12cd5c67 431 if ((i & 1) == 0)
WiredHome 31:c72e12cd5c67 432 dPix >>= 4;
WiredHome 31:c72e12cd5c67 433 dPix &= 0x0F;
WiredHome 41:2956a0a221e5 434 pixelBuffer[i] = RGBQuadToRGB16(colorPalette, dPix);
WiredHome 31:c72e12cd5c67 435 } else if (BPP_t == 8) {
WiredHome 41:2956a0a221e5 436 pixelBuffer[i] = RGBQuadToRGB16(colorPalette, lineBuffer[i]);
WiredHome 32:0e4f2ae512e2 437 } else if (BPP_t == 16) {
WiredHome 41:2956a0a221e5 438 pixelBuffer[i] = lineBuffer[i];
WiredHome 32:0e4f2ae512e2 439 } else if (BPP_t == 24) {
WiredHome 37:f19b7e7449dc 440 color_t color;
WiredHome 32:0e4f2ae512e2 441 color = RGB(lineBuffer[i*3+2], lineBuffer[i*3+1], lineBuffer[i*3+0]);
WiredHome 41:2956a0a221e5 442 pixelBuffer[i] = color;
WiredHome 31:c72e12cd5c67 443 }
WiredHome 31:c72e12cd5c67 444 }
WiredHome 41:2956a0a221e5 445 pixelStream(pixelBuffer, PixelWidth, x, y++);
WiredHome 31:c72e12cd5c67 446 }
WiredHome 136:224e03d5c31f 447 // _EndGraphicsStream();
WiredHome 198:9b6851107426 448 SetWindow(restore);
WiredHome 145:5eb2492acdda 449 swFree(pixelBuffer); // don't leak memory
WiredHome 145:5eb2492acdda 450 swFree(lineBuffer);
WiredHome 69:636867df24a1 451 if (colorPalette)
WiredHome 145:5eb2492acdda 452 swFree(colorPalette);
WiredHome 32:0e4f2ae512e2 453 return (noerror);
WiredHome 31:c72e12cd5c67 454 }
WiredHome 31:c72e12cd5c67 455
WiredHome 198:9b6851107426 456 rect_t GraphicsDisplay::GetImageRect(loc_t x, loc_t y, const char* Filename)
WiredHome 42:7cbdfd2bbfc5 457 {
WiredHome 198:9b6851107426 458 rect_t r = { 0, 0, 0, 0 };
WiredHome 198:9b6851107426 459
WiredHome 198:9b6851107426 460 RenderImageFile(x, y, Filename, &r);
WiredHome 198:9b6851107426 461 return r;
WiredHome 198:9b6851107426 462 }
WiredHome 190:3132b7dfad82 463
WiredHome 198:9b6851107426 464 rect_t GraphicsDisplay::GetImageRect(point_t pt, const char* Filename)
WiredHome 198:9b6851107426 465 {
WiredHome 198:9b6851107426 466 rect_t r = { 0, 0, 0, 0 };
WiredHome 198:9b6851107426 467
WiredHome 198:9b6851107426 468 RenderImageFile(pt, Filename, &r);
WiredHome 190:3132b7dfad82 469 return r;
WiredHome 190:3132b7dfad82 470 }
WiredHome 190:3132b7dfad82 471
WiredHome 198:9b6851107426 472 RetCode_t GraphicsDisplay::RenderImageFile(point_t pt, const char* FileName, rect_t* getDim) {
WiredHome 198:9b6851107426 473 return RenderImageFile(pt.x, pt.y, FileName, getDim);
WiredHome 198:9b6851107426 474 }
WiredHome 198:9b6851107426 475
WiredHome 190:3132b7dfad82 476 RetCode_t GraphicsDisplay::RenderImageFile(loc_t x, loc_t y, const char * FileName, rect_t * getDim) {
WiredHome 42:7cbdfd2bbfc5 477 if (mystrnicmp(FileName + strlen(FileName) - 4, ".bmp", 4) == 0) {
WiredHome 190:3132b7dfad82 478 return RenderBitmapFile(x, y, FileName, getDim);
WiredHome 115:c9862fd0c689 479 } else if (mystrnicmp(FileName + strlen(FileName) - 4, ".jpg", 4) == 0) {
WiredHome 190:3132b7dfad82 480 if (getDim)
WiredHome 198:9b6851107426 481 return bad_parameter;
WiredHome 190:3132b7dfad82 482 return RenderJpegFile(x, y, FileName);
WiredHome 42:7cbdfd2bbfc5 483 } else if (mystrnicmp(FileName + strlen(FileName) - 4, ".ico", 4) == 0) {
WiredHome 190:3132b7dfad82 484 if (getDim)
WiredHome 198:9b6851107426 485 return bad_parameter;
WiredHome 190:3132b7dfad82 486 return RenderIconFile(x, y, FileName);
WiredHome 152:a013ac0133e4 487 } else if (mystrnicmp(FileName + strlen(FileName) - 4, ".gif", 4) == 0) {
WiredHome 190:3132b7dfad82 488 if (getDim)
WiredHome 198:9b6851107426 489 return bad_parameter;
WiredHome 190:3132b7dfad82 490 return RenderGIFFile(x, y, FileName);
WiredHome 42:7cbdfd2bbfc5 491 } else {
WiredHome 198:9b6851107426 492 return bad_parameter;
WiredHome 42:7cbdfd2bbfc5 493 }
WiredHome 42:7cbdfd2bbfc5 494 }
WiredHome 42:7cbdfd2bbfc5 495
WiredHome 190:3132b7dfad82 496 RetCode_t GraphicsDisplay::RenderBitmapFile(loc_t x, loc_t y, const char *Name_BMP, rect_t * getDim)
WiredHome 190:3132b7dfad82 497 {
WiredHome 190:3132b7dfad82 498 BITMAPFILEHEADER BMP_Header;
WiredHome 190:3132b7dfad82 499
WiredHome 190:3132b7dfad82 500 INFO("Opening {%s}", Name_BMP);
WiredHome 190:3132b7dfad82 501 FILE *Image = fopen(Name_BMP, "rb");
WiredHome 190:3132b7dfad82 502 if (!Image) {
WiredHome 190:3132b7dfad82 503 return(file_not_found);
WiredHome 190:3132b7dfad82 504 }
WiredHome 190:3132b7dfad82 505
WiredHome 190:3132b7dfad82 506 fread(&BMP_Header, 1, sizeof(BMP_Header), Image); // get the BMP Header
WiredHome 190:3132b7dfad82 507 INFO("bfType %04X, Header size: %d", BMP_Header.bfType, sizeof(BITMAPFILEHEADER));
WiredHome 198:9b6851107426 508 //HexDump("BMP_Header", (uint8_t *)&BMP_Header, sizeof(BMP_Header));
WiredHome 190:3132b7dfad82 509 if (BMP_Header.bfType != BF_TYPE) {
WiredHome 190:3132b7dfad82 510 fclose(Image);
WiredHome 190:3132b7dfad82 511 return(not_bmp_format);
WiredHome 190:3132b7dfad82 512 }
WiredHome 198:9b6851107426 513 //INFO("bfOffits %04lX", BMP_Header.bfOffBits);
WiredHome 190:3132b7dfad82 514 RetCode_t rt = _RenderBitmap(x, y, BMP_Header.bfOffBits, Image, getDim);
WiredHome 190:3132b7dfad82 515 if (rt != noerror) {
WiredHome 190:3132b7dfad82 516 return rt;
WiredHome 190:3132b7dfad82 517 } else {
WiredHome 190:3132b7dfad82 518 fclose(Image);
WiredHome 190:3132b7dfad82 519 return (noerror);
WiredHome 190:3132b7dfad82 520 }
WiredHome 190:3132b7dfad82 521 }
WiredHome 190:3132b7dfad82 522
WiredHome 115:c9862fd0c689 523 RetCode_t GraphicsDisplay::RenderJpegFile(loc_t x, loc_t y, const char *Name_JPG)
WiredHome 115:c9862fd0c689 524 {
WiredHome 145:5eb2492acdda 525 #define JPEG_WORK_SPACE_SIZE 3100 // Worst case requirements for the decompression
WiredHome 115:c9862fd0c689 526 JDEC * jdec;
WiredHome 115:c9862fd0c689 527 uint16_t * work;
WiredHome 115:c9862fd0c689 528 RetCode_t r = noerror; // start optimistic
WiredHome 115:c9862fd0c689 529 FILE * fh = fopen(Name_JPG, "rb");
WiredHome 190:3132b7dfad82 530
WiredHome 115:c9862fd0c689 531 if (!fh)
WiredHome 115:c9862fd0c689 532 return(file_not_found);
WiredHome 120:be2aaa3adf72 533 //INFO("RenderJpegFile(%d,%d,%s)", x,y, Name_JPG);
WiredHome 145:5eb2492acdda 534 work = (uint16_t *)swMalloc(JPEG_WORK_SPACE_SIZE);
WiredHome 115:c9862fd0c689 535 if (work) {
WiredHome 145:5eb2492acdda 536 jdec = (JDEC *)swMalloc(sizeof(JDEC));
WiredHome 115:c9862fd0c689 537 if (jdec) {
WiredHome 182:8832d03a2a29 538 // Original
WiredHome 182:8832d03a2a29 539 //memset(work, 0, JPEG_WORK_SPACE_SIZE/sizeof(uint16_t));
WiredHome 182:8832d03a2a29 540 // Revised
WiredHome 182:8832d03a2a29 541 memset(work, 0, JPEG_WORK_SPACE_SIZE);
WiredHome 120:be2aaa3adf72 542 memset(jdec, 0, sizeof(JDEC));
WiredHome 115:c9862fd0c689 543 r = (RetCode_t)jd_prepare(jdec, NULL, work, JPEG_WORK_SPACE_SIZE, fh);
WiredHome 115:c9862fd0c689 544 INFO("jd_prepare returned %d", r);
WiredHome 190:3132b7dfad82 545
WiredHome 115:c9862fd0c689 546 if (r == noerror) {
WiredHome 136:224e03d5c31f 547 img_x = x; // save the origin for the privOutput function
WiredHome 136:224e03d5c31f 548 img_y = y;
WiredHome 115:c9862fd0c689 549 r = (RetCode_t)jd_decomp(jdec, NULL, 0);
WiredHome 115:c9862fd0c689 550 } else {
WiredHome 115:c9862fd0c689 551 r = not_supported_format; // error("jd_prepare error:%d", r);
WiredHome 115:c9862fd0c689 552 }
WiredHome 145:5eb2492acdda 553 swFree(jdec);
WiredHome 115:c9862fd0c689 554 } else {
WiredHome 115:c9862fd0c689 555 WARN("checkpoint");
WiredHome 115:c9862fd0c689 556 r = not_enough_ram;
WiredHome 115:c9862fd0c689 557 }
WiredHome 145:5eb2492acdda 558 swFree(work);
WiredHome 115:c9862fd0c689 559 } else {
WiredHome 115:c9862fd0c689 560 WARN("checkpoint");
WiredHome 115:c9862fd0c689 561 r = not_enough_ram;
WiredHome 115:c9862fd0c689 562 }
WiredHome 115:c9862fd0c689 563 fclose(fh);
WiredHome 115:c9862fd0c689 564 return r; // error("jd_decomp error:%d", r);
WiredHome 115:c9862fd0c689 565 }
WiredHome 115:c9862fd0c689 566
WiredHome 42:7cbdfd2bbfc5 567 RetCode_t GraphicsDisplay::RenderIconFile(loc_t x, loc_t y, const char *Name_ICO)
WiredHome 42:7cbdfd2bbfc5 568 {
WiredHome 42:7cbdfd2bbfc5 569 ICOFILEHEADER ICO_Header;
WiredHome 42:7cbdfd2bbfc5 570 ICODIRENTRY ICO_DirEntry;
WiredHome 42:7cbdfd2bbfc5 571
WiredHome 42:7cbdfd2bbfc5 572 INFO("Opening {%s}", Name_ICO);
WiredHome 42:7cbdfd2bbfc5 573 FILE *Image = fopen(Name_ICO, "rb");
WiredHome 42:7cbdfd2bbfc5 574 if (!Image) {
WiredHome 42:7cbdfd2bbfc5 575 return(file_not_found);
WiredHome 42:7cbdfd2bbfc5 576 }
WiredHome 42:7cbdfd2bbfc5 577
WiredHome 42:7cbdfd2bbfc5 578 fread(&ICO_Header, 1, sizeof(ICO_Header), Image); // get the BMP Header
WiredHome 42:7cbdfd2bbfc5 579 HexDump("ICO_Header", (uint8_t *)&ICO_Header, sizeof(ICO_Header));
WiredHome 42:7cbdfd2bbfc5 580 if (ICO_Header.Reserved_zero != 0
WiredHome 42:7cbdfd2bbfc5 581 || ICO_Header.icType != IC_TYPE
WiredHome 42:7cbdfd2bbfc5 582 || ICO_Header.icImageCount == 0) {
WiredHome 42:7cbdfd2bbfc5 583 fclose(Image);
WiredHome 42:7cbdfd2bbfc5 584 return(not_ico_format);
WiredHome 42:7cbdfd2bbfc5 585 }
WiredHome 42:7cbdfd2bbfc5 586
WiredHome 42:7cbdfd2bbfc5 587 // Read ONLY the first of n possible directory entries.
WiredHome 42:7cbdfd2bbfc5 588 fread(&ICO_DirEntry, 1, sizeof(ICO_DirEntry), Image);
WiredHome 42:7cbdfd2bbfc5 589 HexDump("ICO_DirEntry", (uint8_t *)&ICO_DirEntry, sizeof(ICO_DirEntry));
WiredHome 42:7cbdfd2bbfc5 590 INFO("biBitCount %04X", ICO_DirEntry.biBitCount);
WiredHome 42:7cbdfd2bbfc5 591 if (ICO_DirEntry.biBitCount != 0) { // Expecting this to be zero for ico
WiredHome 42:7cbdfd2bbfc5 592 fclose(Image);
WiredHome 42:7cbdfd2bbfc5 593 return(not_supported_format);
WiredHome 42:7cbdfd2bbfc5 594 }
WiredHome 42:7cbdfd2bbfc5 595
WiredHome 42:7cbdfd2bbfc5 596 RetCode_t rt = _RenderBitmap(x, y, ICO_DirEntry.bfOffBits, Image);
WiredHome 42:7cbdfd2bbfc5 597 if (rt == noerror) {
WiredHome 42:7cbdfd2bbfc5 598 fclose(Image);
WiredHome 42:7cbdfd2bbfc5 599 return (noerror);
WiredHome 42:7cbdfd2bbfc5 600 } else {
WiredHome 42:7cbdfd2bbfc5 601 return rt;
WiredHome 42:7cbdfd2bbfc5 602 }
WiredHome 42:7cbdfd2bbfc5 603 }
WiredHome 42:7cbdfd2bbfc5 604
WiredHome 19:3f82c1161fd2 605 int GraphicsDisplay::columns()
WiredHome 19:3f82c1161fd2 606 {
WiredHome 19:3f82c1161fd2 607 return width() / 8;
dreschpe 0:de9d1462a835 608 }
dreschpe 0:de9d1462a835 609
WiredHome 19:3f82c1161fd2 610 int GraphicsDisplay::rows()
WiredHome 19:3f82c1161fd2 611 {
WiredHome 19:3f82c1161fd2 612 return height() / 8;
WiredHome 19:3f82c1161fd2 613 }