Marcel Visser
/
DisplayBRW
brw1
Embed:
(wiki syntax)
Show/hide line numbers
GraphicsDisplay.cpp
00001 /* mbed GraphicsDisplay Display Library Base Class 00002 * Copyright (c) 2007-2009 sford 00003 * Released under the MIT License: http://mbed.org/license/mit 00004 * 00005 * Derivative work by D.Smart 2014 00006 */ 00007 00008 #include "GraphicsDisplay.h" 00009 #include "Bitmap.h" 00010 #include "string.h" 00011 00012 //#define DEBUG "GD" 00013 // ... 00014 // INFO("Stuff to show %d", var); // new-line is automatically appended 00015 // 00016 #if (defined(DEBUG) && !defined(TARGET_LPC11U24)) 00017 #define INFO(x, ...) std::printf("[INF %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00018 #define WARN(x, ...) std::printf("[WRN %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00019 #define ERR(x, ...) std::printf("[ERR %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00020 static void HexDump(char * title, uint8_t * p, int count) 00021 { 00022 int i; 00023 char buf[100] = "0000: "; 00024 00025 if (*title) 00026 INFO("%s", title); 00027 for (i=0; i<count; ) { 00028 sprintf(buf + strlen(buf), "%02X ", *(p+i)); 00029 if ((++i & 0x0F) == 0x00) { 00030 INFO("%s", buf); 00031 if (i < count) 00032 sprintf(buf, "%04X: ", i); 00033 else 00034 buf[0] = '\0'; 00035 } 00036 } 00037 if (strlen(buf)) 00038 INFO("%s", buf); 00039 } 00040 #else 00041 #define INFO(x, ...) 00042 #define WARN(x, ...) 00043 #define ERR(x, ...) 00044 #define HexDump(a, b, c) 00045 #endif 00046 00047 #ifdef LOCALFONT 00048 const unsigned char FONT8x8[97][8] = { 00049 0x08, 0x08, 0x08, 0X00, 0X00, 0X00, 0X00, 0X00, // columns, rows, num_bytes_per_char 00050 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, // space 0x20 00051 0x30, 0x78, 0x78, 0x30, 0x30, 0X00, 0x30, 0X00, // ! 00052 0x6C, 0x6C, 0x6C, 0X00, 0X00, 0X00, 0X00, 0X00, // " 00053 0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0X00, // # 00054 0x18, 0x3E, 0x60, 0x3C, 0x06, 0x7C, 0x18, 0X00, // $ 00055 0X00, 0x63, 0x66, 0x0C, 0x18, 0x33, 0x63, 0X00, // % 00056 0x1C, 0x36, 0x1C, 0x3B, 0x6E, 0x66, 0x3B, 0X00, // & 00057 0x30, 0x30, 0x60, 0X00, 0X00, 0X00, 0X00, 0X00, // ' 00058 0x0C, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0C, 0X00, // ( 00059 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0X00, // ) 00060 0X00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0X00, 0X00, // * 00061 0X00, 0x30, 0x30, 0xFC, 0x30, 0x30, 0X00, 0X00, // + 00062 0X00, 0X00, 0X00, 0X00, 0X00, 0x18, 0x18, 0x30, // , 00063 0X00, 0X00, 0X00, 0x7E, 0X00, 0X00, 0X00, 0X00, // - 00064 0X00, 0X00, 0X00, 0X00, 0X00, 0x18, 0x18, 0X00, // . 00065 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0X00, // / (forward slash) 00066 0x3E, 0x63, 0x63, 0x6B, 0x63, 0x63, 0x3E, 0X00, // 0 0x30 00067 0x18, 0x38, 0x58, 0x18, 0x18, 0x18, 0x7E, 0X00, // 1 00068 0x3C, 0x66, 0x06, 0x1C, 0x30, 0x66, 0x7E, 0X00, // 2 00069 0x3C, 0x66, 0x06, 0x1C, 0x06, 0x66, 0x3C, 0X00, // 3 00070 0x0E, 0x1E, 0x36, 0x66, 0x7F, 0x06, 0x0F, 0X00, // 4 00071 0x7E, 0x60, 0x7C, 0x06, 0x06, 0x66, 0x3C, 0X00, // 5 00072 0x1C, 0x30, 0x60, 0x7C, 0x66, 0x66, 0x3C, 0X00, // 6 00073 0x7E, 0x66, 0x06, 0x0C, 0x18, 0x18, 0x18, 0X00, // 7 00074 0x3C, 0x66, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0X00, // 8 00075 0x3C, 0x66, 0x66, 0x3E, 0x06, 0x0C, 0x38, 0X00, // 9 00076 0X00, 0x18, 0x18, 0X00, 0X00, 0x18, 0x18, 0X00, // : 00077 0X00, 0x18, 0x18, 0X00, 0X00, 0x18, 0x18, 0x30, // ; 00078 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0X00, // < 00079 0X00, 0X00, 0x7E, 0X00, 0X00, 0x7E, 0X00, 0X00, // = 00080 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0X00, // > 00081 0x3C, 0x66, 0x06, 0x0C, 0x18, 0X00, 0x18, 0X00, // ? 00082 0x3E, 0x63, 0x6F, 0x69, 0x6F, 0x60, 0x3E, 0X00, // @ 0x40 00083 0x18, 0x3C, 0x66, 0x66, 0x7E, 0x66, 0x66, 0X00, // A 00084 0x7E, 0x33, 0x33, 0x3E, 0x33, 0x33, 0x7E, 0X00, // B 00085 0x1E, 0x33, 0x60, 0x60, 0x60, 0x33, 0x1E, 0X00, // C 00086 0x7C, 0x36, 0x33, 0x33, 0x33, 0x36, 0x7C, 0X00, // D 00087 0x7F, 0x31, 0x34, 0x3C, 0x34, 0x31, 0x7F, 0X00, // E 00088 0x7F, 0x31, 0x34, 0x3C, 0x34, 0x30, 0x78, 0X00, // F 00089 0x1E, 0x33, 0x60, 0x60, 0x67, 0x33, 0x1F, 0X00, // G 00090 0x66, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0X00, // H 00091 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0X00, // I 00092 0x0F, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3C, 0X00, // J 00093 0x73, 0x33, 0x36, 0x3C, 0x36, 0x33, 0x73, 0X00, // K 00094 0x78, 0x30, 0x30, 0x30, 0x31, 0x33, 0x7F, 0X00, // L 00095 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0X00, // M 00096 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x63, 0x63, 0X00, // N 00097 0x3E, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3E, 0X00, // O 00098 0x7E, 0x33, 0x33, 0x3E, 0x30, 0x30, 0x78, 0X00, // P 0x50 00099 0x3C, 0x66, 0x66, 0x66, 0x6E, 0x3C, 0x0E, 0X00, // Q 00100 0x7E, 0x33, 0x33, 0x3E, 0x36, 0x33, 0x73, 0X00, // R 00101 0x3C, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x3C, 0X00, // S 00102 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x3C, 0X00, // T 00103 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7E, 0X00, // U 00104 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0X00, // V 00105 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0X00, // W 00106 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0X00, // X 00107 0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x3C, 0X00, // Y 00108 0x7F, 0x63, 0x46, 0x0C, 0x19, 0x33, 0x7F, 0X00, // Z 00109 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0X00, // [ 00110 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0X00, // \ (back slash) 00111 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C, 0X00, // ] 00112 0x08, 0x1C, 0x36, 0x63, 0X00, 0X00, 0X00, 0X00, // ^ 00113 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0xFF, // _ 00114 0x18, 0x18, 0x0C, 0X00, 0X00, 0X00, 0X00, 0X00, // ` 0x60 00115 0X00, 0X00, 0x3C, 0x06, 0x3E, 0x66, 0x3B, 0X00, // a 00116 0x70, 0x30, 0x3E, 0x33, 0x33, 0x33, 0x6E, 0X00, // b 00117 0X00, 0X00, 0x3C, 0x66, 0x60, 0x66, 0x3C, 0X00, // c 00118 0x0E, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x3B, 0X00, // d 00119 0X00, 0X00, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0X00, // e 00120 0x1C, 0x36, 0x30, 0x78, 0x30, 0x30, 0x78, 0X00, // f 00121 0X00, 0X00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x7C, // g 00122 0x70, 0x30, 0x36, 0x3B, 0x33, 0x33, 0x73, 0X00, // h 00123 0x18, 0X00, 0x38, 0x18, 0x18, 0x18, 0x3C, 0X00, // i 00124 0x06, 0X00, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3C, // j 00125 0x70, 0x30, 0x33, 0x36, 0x3C, 0x36, 0x73, 0X00, // k 00126 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0X00, // l 00127 0X00, 0X00, 0x66, 0x7F, 0x7F, 0x6B, 0x63, 0X00, // m 00128 0X00, 0X00, 0x7C, 0x66, 0x66, 0x66, 0x66, 0X00, // n 00129 0X00, 0X00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0X00, // o 00130 0X00, 0X00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78, // p 00131 0X00, 0X00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F, // q 00132 0X00, 0X00, 0x6E, 0x3B, 0x33, 0x30, 0x78, 0X00, // r 00133 0X00, 0X00, 0x3E, 0x60, 0x3C, 0x06, 0x7C, 0X00, // s 00134 0x08, 0x18, 0x3E, 0x18, 0x18, 0x1A, 0x0C, 0X00, // t 00135 0X00, 0X00, 0x66, 0x66, 0x66, 0x66, 0x3B, 0X00, // u 00136 0X00, 0X00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0X00, // v 00137 0X00, 0X00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0X00, // w 00138 0X00, 0X00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0X00, // x 00139 0X00, 0X00, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x7C, // y 00140 0X00, 0X00, 0x7E, 0x4C, 0x18, 0x32, 0x7E, 0X00, // z 00141 0x0E, 0x18, 0x18, 0x70, 0x18, 0x18, 0x0E, 0X00, // { 00142 0x0C, 0x0C, 0x0C, 0X00, 0x0C, 0x0C, 0x0C, 0X00, // | 00143 0x70, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x70, 0X00, // } 00144 0x3B, 0x6E, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, // ~ 00145 0x1C, 0x36, 0x36, 0x1C, 0X00, 0X00, 0X00, 0X00 // DEL 00146 }; 00147 #endif // LOCALFONT 00148 00149 char mytolower(char a) { 00150 if (a >= 'A' && a <= 'Z') 00151 return (a - 'A' + 'a'); 00152 else 00153 return a; 00154 } 00155 /// mystrnicmp exists because not all compiler libraries have this function. 00156 /// 00157 /// Some have strnicmp, others _strnicmp, and others have C++ methods, which 00158 /// is outside the scope of this C-portable set of functions. 00159 /// 00160 /// @param l is a pointer to the string on the left 00161 /// @param r is a pointer to the string on the right 00162 /// @param n is the number of characters to compare 00163 /// @returns -1 if l < r 00164 /// @returns 0 if l == r 00165 /// @returns +1 if l > r 00166 /// 00167 int mystrnicmp(const char *l, const char *r, size_t n) { 00168 int result = 0; 00169 00170 if (n != 0) { 00171 do { 00172 result = mytolower(*l++) - mytolower(*r++); 00173 } while ((result == 0) && (*l != '\0') && (--n > 0)); 00174 } 00175 if (result < -1) 00176 result = -1; 00177 else if (result > 1) 00178 result = 1; 00179 return result; 00180 } 00181 00182 00183 GraphicsDisplay::GraphicsDisplay(const char *name) 00184 : TextDisplay(name) 00185 { 00186 font = NULL; 00187 } 00188 00189 RetCode_t GraphicsDisplay::set_font(const unsigned char * _font) 00190 { 00191 font = _font; // trusting them, but it might be good to put some checks in here... 00192 return noerror; 00193 } 00194 00195 #ifdef LOCALFONT 00196 int GraphicsDisplay::character(int x, int y, int value) 00197 { 00198 if (value <= 0x1F && value >= 7F) 00199 return 0; 00200 00201 return blitbit(x, y, FONT8X8[0][0], FONT8X8[0][1], 00202 (char *)&(FONT8x8[value - 0x1F][0])); 00203 } 00204 #else 00205 int GraphicsDisplay::character(int x, int y, int c) 00206 { 00207 unsigned int offset; 00208 const unsigned char * charRecord; 00209 00210 if (c <= 0x1F || c >= 0x7F) 00211 return 0; 00212 offset = font[0]; // bytes / char 00213 charRecord = &font[((c - ' ') * offset) + 4]; // start of char bitmap 00214 return fontblit(x, y, font, charRecord); 00215 } 00216 #endif 00217 00218 RetCode_t GraphicsDisplay::window(loc_t x, loc_t y, dim_t w, dim_t h) 00219 { 00220 // current pixel location 00221 _x = x; 00222 _y = y; 00223 // window settings 00224 _x1 = x; 00225 _x2 = x + w - 1; 00226 _y1 = y; 00227 _y2 = y + h - 1; 00228 return noerror; 00229 } 00230 00231 RetCode_t GraphicsDisplay::WindowMax(void) 00232 { 00233 return window(0,0, width(),height()); 00234 } 00235 00236 RetCode_t GraphicsDisplay::_putp(color_t color) 00237 { 00238 pixel(_x, _y, color); 00239 // update pixel location based on window settings 00240 _x++; 00241 if(_x > _x2) { 00242 _x = _x1; 00243 _y++; 00244 if(_y > _y2) { 00245 _y = _y1; 00246 } 00247 } 00248 return noerror; 00249 } 00250 00251 RetCode_t GraphicsDisplay::fill(int x, int y, int w, int h, color_t color) 00252 { 00253 return fillrect(x,y, x+w, y+h, color); 00254 } 00255 00256 RetCode_t GraphicsDisplay::cls(uint16_t layers) 00257 { 00258 return fill(0, 0, width(), height(), _background); 00259 } 00260 00261 RetCode_t GraphicsDisplay::blit(int x, int y, int w, int h, const int * color) 00262 { 00263 window(x, y, w, h); 00264 _StartGraphicsStream(); 00265 for (int i=0; i<w*h; i++) { 00266 _putp(color[i]); 00267 } 00268 _EndGraphicsStream(); 00269 return WindowMax(); 00270 } 00271 00272 #ifdef LOCALFONT 00273 int GraphicsDisplay::blitbit(int x, int y, int w, int h, const char * color) 00274 { 00275 _foreground = 0xFFFF; 00276 INFO("blitbit(%d,%d, %d,%d, %02X) [%04X,%04X]", x,y, w,h, *color, _foreground, _background); 00277 INFO("%lu %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", 00278 color, 00279 color[0], color[1], color[2], color[3], color[4], color[5], color[6], color[7], 00280 color[8], color[9], color[10], color[11], color[12], color[13], color[14], color[15]); 00281 window(x, y, w, h); 00282 _StartGraphicsStream(); 00283 for (int i = 0; i < w*h; i++) { 00284 char byte = color[i >> 3]; 00285 int offset = i & 0x7; 00286 if (offset == 0) 00287 INFO(" %2d = %02X", i>>3, byte); 00288 int c = ((byte << offset) & 0x80) ? _foreground : _background; 00289 _putp(c); 00290 } 00291 _EndGraphicsStream(); 00292 WindowMax(); 00293 return w; 00294 } 00295 #endif 00296 00297 00298 int GraphicsDisplay::fontblit(int x, int y, const unsigned char * fontTable, const unsigned char * fontChar) 00299 { 00300 //int fontWidth = font[1]; // get hor size of font 00301 int fontHeight = font[2]; // get vert size of font 00302 int bytesPerLine = font[3]; // bytes per line 00303 int charWidth = fontChar[0]; // width of this character 00304 int px, py; 00305 00306 //INFO("(%d,%d) %lu, %lu %X/%X", x,y, fontTable, fontChar, _foreground, _background); 00307 //INFO("char size (%d,%d)", charWidth, fontHeight); 00308 //HexDump("char", (uint8_t *)fontChar, 32); 00309 //INFO("(f,b) = (%04X,%04X)", _foreground, _background) 00310 window(x, y, charWidth, fontHeight); 00311 _StartGraphicsStream(); 00312 //INFO("(f,b) = (%04X,%04X)", _foreground, _background) 00313 for (py = 0; py < fontHeight; py++) { 00314 int bitmask = 1 << (py & 7); 00315 00316 for (px = 0; px < charWidth; px++) { 00317 int offset = (py / 8) + px * bytesPerLine; 00318 unsigned char byte = fontChar[offset + 1]; // skip the char's # bits wide value 00319 color_t c = (byte & bitmask) ? _foreground : _background; 00320 //INFO("(%2d,%2d) %02X & %02X => %04X [%04X,%04X]", px, py, byte, bitmask, c, _foreground, _background); 00321 //pixel(x+px, y+py, c); 00322 _putp(c); 00323 } 00324 } 00325 _EndGraphicsStream(); 00326 WindowMax(); 00327 return charWidth; 00328 } 00329 00330 // BMP Color Palette is BGRx 00331 // BBBB BBBB GGGG GGGG RRRR RRRR 0000 0000 00332 // RGB16 is 00333 // RRRR RGGG GGGB BBBB 00334 // swap to little endian 00335 // GGGB BBBB RRRR RGGG 00336 color_t GraphicsDisplay::RGBQuadToRGB16(RGBQUAD * colorPalette, uint16_t i) 00337 { 00338 color_t c; 00339 00340 c = ((colorPalette[i].rgbBlue >> 3) << 0); 00341 c |= ((colorPalette[i].rgbGreen >> 2) << 5); 00342 c |= ((colorPalette[i].rgbRed >> 3) << 11); 00343 return c; 00344 } 00345 00346 /// RRRR RGGG GGGB BBBB 00347 RGBQUAD GraphicsDisplay::RGB16ToRGBQuad(color_t c) 00348 { 00349 RGBQUAD q; 00350 00351 memset(&q, 0, sizeof(q)); 00352 q.rgbBlue = ((c & 0x001F) << 3) | (c & 0x07); /* Blue value */ 00353 q.rgbGreen = ((c & 0x07E0) >> 3) | ((c >> 7) & 0x03); /* Green value */ 00354 q.rgbRed = ((c & 0xF800) >> 8) | ((c >> 11) & 0x07); /* Red value */ 00355 q.rgbReserved = 0; 00356 return q; 00357 } 00358 00359 RetCode_t GraphicsDisplay::_RenderBitmap(loc_t x, loc_t y, uint32_t fileOffset, FILE * Image) 00360 { 00361 BITMAPINFOHEADER BMP_Info; 00362 RGBQUAD * colorPalette = NULL; 00363 int colorCount; 00364 uint8_t * lineBuffer = NULL; 00365 color_t * pixelBuffer = NULL; 00366 uint16_t BPP_t; 00367 uint32_t PixelWidth, PixelHeight; 00368 unsigned int i, offset; 00369 int padd,j; 00370 #ifdef DEBUG 00371 uint32_t start_data; 00372 #endif 00373 00374 // Now, Read the bitmap info header 00375 fread(&BMP_Info, 1, sizeof(BMP_Info), Image); 00376 HexDump("BMP_Info", (uint8_t *)&BMP_Info, sizeof(BMP_Info)); 00377 BPP_t = BMP_Info.biBitCount; 00378 INFO("biBitCount %04X", BPP_t); 00379 if (BPP_t != 4 && BPP_t != 8 && BPP_t != 16 && BPP_t != 24) { // Support 4, 8, 16, 24-bits per pixel 00380 fclose(Image); 00381 return(not_supported_format); 00382 } 00383 00384 PixelHeight = BMP_Info.biHeight; 00385 PixelWidth = BMP_Info.biWidth; 00386 INFO("(%d,%d) (%d,%d) (%d,%d)", x,y, PixelWidth,PixelHeight, width(), height()); 00387 if (PixelHeight > height() + y || PixelWidth > width() + x) { 00388 fclose(Image); 00389 return(image_too_big); 00390 } 00391 if (BMP_Info.biBitCount <= 8) { 00392 int paletteSize; 00393 // Read the color palette 00394 colorCount = 1 << BMP_Info.biBitCount; 00395 paletteSize = sizeof(RGBQUAD) * colorCount; 00396 colorPalette = (RGBQUAD *)malloc(paletteSize); 00397 if (colorPalette == NULL) { 00398 fclose(Image); 00399 return(not_enough_ram); 00400 } 00401 fread(colorPalette, 1, paletteSize, Image); 00402 HexDump("Color Palette", (uint8_t *)colorPalette, paletteSize); 00403 } 00404 00405 int lineBufSize = ((BPP_t * PixelWidth + 7)/8); 00406 INFO("BPP_t %d, PixelWidth %d, lineBufSize %d", BPP_t, PixelWidth, lineBufSize); 00407 lineBuffer = (uint8_t *)malloc(lineBufSize); 00408 if (lineBuffer == NULL) { 00409 free(colorPalette); 00410 fclose(Image); 00411 return(not_enough_ram); 00412 } 00413 pixelBuffer = (color_t *)malloc(PixelWidth * sizeof(color_t)); 00414 if (pixelBuffer == NULL) { 00415 free(lineBuffer); 00416 if (colorPalette) 00417 free(colorPalette); 00418 fclose(Image); 00419 return(not_enough_ram); 00420 } 00421 00422 // the Raw Data records are padded to a multiple of 4 bytes 00423 int recordSize = 2; 00424 if (BPP_t == 4) { 00425 recordSize = 1; 00426 } else if (BPP_t == 8) { 00427 recordSize = 1; 00428 } else if (BPP_t == 16) { 00429 recordSize = 2; 00430 } else if (BPP_t == 24) { 00431 recordSize = 3; 00432 } 00433 padd = -1; 00434 do { 00435 padd++; 00436 } while ((PixelWidth * recordSize + padd) % 4 != 0); 00437 00438 // Define window for top to bottom and left to right so writing auto-wraps 00439 window(x,y, PixelWidth,PixelHeight); 00440 SetGraphicsCursor(x, y); 00441 _StartGraphicsStream(); 00442 00443 //start_data = BMP_Header.bfOffBits; 00444 HexDump("Raw Data", (uint8_t *)&start_data, 32); 00445 INFO("(%d,%d) (%d,%d), [%d,%d]", x,y, PixelWidth,PixelHeight, lineBufSize, padd); 00446 for (j = PixelHeight - 1; j >= 0; j--) { //Lines bottom up 00447 offset = fileOffset + j * (lineBufSize + padd); // start of line 00448 fseek(Image, offset, SEEK_SET); 00449 fread(lineBuffer, 1, lineBufSize, Image); // read a line - slow ! 00450 //INFO("offset: %6X", offset); 00451 for (i = 0; i < PixelWidth; i++) { // copy pixel data to TFT 00452 if (BPP_t == 4) { 00453 uint8_t dPix = lineBuffer[i/2]; 00454 if ((i & 1) == 0) 00455 dPix >>= 4; 00456 dPix &= 0x0F; 00457 pixelBuffer[i] = RGBQuadToRGB16(colorPalette, dPix); 00458 } else if (BPP_t == 8) { 00459 pixelBuffer[i] = RGBQuadToRGB16(colorPalette, lineBuffer[i]); 00460 } else if (BPP_t == 16) { 00461 pixelBuffer[i] = lineBuffer[i]; 00462 } else if (BPP_t == 24) { 00463 color_t color; 00464 color = RGB(lineBuffer[i*3+2], lineBuffer[i*3+1], lineBuffer[i*3+0]); 00465 pixelBuffer[i] = color; 00466 } 00467 } 00468 pixelStream(pixelBuffer, PixelWidth, x, y++); 00469 } 00470 _EndGraphicsStream(); 00471 WindowMax(); 00472 free(pixelBuffer); // don't leak memory 00473 free(lineBuffer); 00474 if (colorPalette) 00475 free(colorPalette); 00476 return (noerror); 00477 } 00478 00479 00480 RetCode_t GraphicsDisplay::RenderImageFile(loc_t x, loc_t y, const char *FileName) 00481 { 00482 if (mystrnicmp(FileName + strlen(FileName) - 4, ".bmp", 4) == 0) { 00483 return RenderBitmapFile(x,y,FileName); 00484 } else if (mystrnicmp(FileName + strlen(FileName) - 4, ".ico", 4) == 0) { 00485 return RenderIconFile(x,y,FileName); 00486 } else { 00487 return not_supported_format; 00488 } 00489 } 00490 00491 RetCode_t GraphicsDisplay::RenderBitmapFile(loc_t x, loc_t y, const char *Name_BMP) 00492 { 00493 BITMAPFILEHEADER BMP_Header; 00494 00495 INFO("Opening {%s}", Name_BMP); 00496 FILE *Image = fopen(Name_BMP, "rb"); 00497 if (!Image) { 00498 return(file_not_found); 00499 } 00500 00501 fread(&BMP_Header, 1, sizeof(BMP_Header), Image); // get the BMP Header 00502 INFO("bfType %04X", BMP_Header.bfType); 00503 HexDump("BMP_Header", (uint8_t *)&BMP_Header, sizeof(BMP_Header)); 00504 if (BMP_Header.bfType != BF_TYPE) { 00505 fclose(Image); 00506 return(not_bmp_format); 00507 } 00508 RetCode_t rt = _RenderBitmap(x, y, BMP_Header.bfOffBits, Image); 00509 if (rt != noerror) { 00510 return rt; 00511 } else { 00512 fclose(Image); 00513 return (noerror); 00514 } 00515 } 00516 00517 RetCode_t GraphicsDisplay::RenderIconFile(loc_t x, loc_t y, const char *Name_ICO) 00518 { 00519 ICOFILEHEADER ICO_Header; 00520 ICODIRENTRY ICO_DirEntry; 00521 00522 INFO("Opening {%s}", Name_ICO); 00523 FILE *Image = fopen(Name_ICO, "rb"); 00524 if (!Image) { 00525 return(file_not_found); 00526 } 00527 00528 fread(&ICO_Header, 1, sizeof(ICO_Header), Image); // get the BMP Header 00529 HexDump("ICO_Header", (uint8_t *)&ICO_Header, sizeof(ICO_Header)); 00530 if (ICO_Header.Reserved_zero != 0 00531 || ICO_Header.icType != IC_TYPE 00532 || ICO_Header.icImageCount == 0) { 00533 fclose(Image); 00534 return(not_ico_format); 00535 } 00536 00537 // Read ONLY the first of n possible directory entries. 00538 fread(&ICO_DirEntry, 1, sizeof(ICO_DirEntry), Image); 00539 HexDump("ICO_DirEntry", (uint8_t *)&ICO_DirEntry, sizeof(ICO_DirEntry)); 00540 INFO("biBitCount %04X", ICO_DirEntry.biBitCount); 00541 if (ICO_DirEntry.biBitCount != 0) { // Expecting this to be zero for ico 00542 fclose(Image); 00543 return(not_supported_format); 00544 } 00545 00546 RetCode_t rt = _RenderBitmap(x, y, ICO_DirEntry.bfOffBits, Image); 00547 if (rt == noerror) { 00548 fclose(Image); 00549 return (noerror); 00550 } else { 00551 return rt; 00552 } 00553 } 00554 00555 int GraphicsDisplay::columns() 00556 { 00557 return width() / 8; 00558 } 00559 00560 int GraphicsDisplay::rows() 00561 { 00562 return height() / 8; 00563 }
Generated on Fri Jul 15 2022 05:44:41 by 1.7.2