Shows how to use a display and the onboard SD Card. Requires a display module with an adapter

Dependencies:   DmTftLibrary SDFileSystem mbed

Committer:
displaymodule
Date:
Mon Sep 01 11:06:18 2014 +0000
Revision:
6:592bba211e38
Parent:
5:ed6a302e0917
Removed dependency on mbed-src for LPC1549

Who changed what in which revision?

UserRevisionLine numberNew contents of line
displaymodule 0:ee27d4c12433 1 /**********************************************************************************************
displaymodule 0:ee27d4c12433 2 Copyright (c) 2014 DisplayModule. All rights reserved.
displaymodule 0:ee27d4c12433 3
displaymodule 0:ee27d4c12433 4 Redistribution and use of this source code, part of this source code or any compiled binary
displaymodule 0:ee27d4c12433 5 based on this source code is permitted as long as the above copyright notice and following
displaymodule 0:ee27d4c12433 6 disclaimer is retained.
displaymodule 0:ee27d4c12433 7
displaymodule 0:ee27d4c12433 8 DISCLAIMER:
displaymodule 0:ee27d4c12433 9 THIS SOFTWARE IS SUPPLIED "AS IS" WITHOUT ANY WARRANTIES AND SUPPORT. DISPLAYMODULE ASSUMES
displaymodule 0:ee27d4c12433 10 NO RESPONSIBILITY OR LIABILITY FOR THE USE OF THE SOFTWARE.
displaymodule 0:ee27d4c12433 11 ********************************************************************************************/
displaymodule 0:ee27d4c12433 12
displaymodule 0:ee27d4c12433 13 #include "DmDrawBmpBase.h"
displaymodule 0:ee27d4c12433 14
displaymodule 0:ee27d4c12433 15 bool DmDrawBmpBase::drawBitmap(DmTftBase& tft, uint16_t x, uint16_t y, readFunc func, uint32_t userData) {
displaymodule 0:ee27d4c12433 16 _readFunc = func;
displaymodule 0:ee27d4c12433 17 _userData = userData;
displaymodule 0:ee27d4c12433 18 _readPos = 0;
displaymodule 0:ee27d4c12433 19
displaymodule 0:ee27d4c12433 20 if (readBmpHeader()) {
displaymodule 0:ee27d4c12433 21 if (IsValid565Bitmap()) {
displaymodule 0:ee27d4c12433 22 return draw565Bitmap(tft, x, y);
displaymodule 0:ee27d4c12433 23 }
displaymodule 0:ee27d4c12433 24 if (IsValid888Bitmap()) {
displaymodule 0:ee27d4c12433 25 return draw888Bitmap(tft, x, y);
displaymodule 0:ee27d4c12433 26 }
displaymodule 0:ee27d4c12433 27 }
displaymodule 0:ee27d4c12433 28 return false;
displaymodule 0:ee27d4c12433 29 }
displaymodule 0:ee27d4c12433 30
displaymodule 0:ee27d4c12433 31 bool DmDrawBmpBase::draw888Bitmap(DmTftBase& tft, uint16_t x, uint16_t y) {
displaymodule 0:ee27d4c12433 32 const uint8_t bytesPerPixel = 3;
displaymodule 0:ee27d4c12433 33 uint8_t red, green, blue;
displaymodule 0:ee27d4c12433 34 uint16_t row, column;
displaymodule 0:ee27d4c12433 35 uint16_t bytesPerRow = (bytesPerPixel*_width + 3) & ~3;
displaymodule 0:ee27d4c12433 36 uint8_t buff[20*bytesPerPixel];
displaymodule 0:ee27d4c12433 37 uint8_t buffPos = sizeof(buff);
displaymodule 3:030be860c83d 38 uint16_t clipX = _width;
displaymodule 3:030be860c83d 39 uint16_t clipY = _height;
displaymodule 3:030be860c83d 40
displaymodule 3:030be860c83d 41 //make sure image fits
displaymodule 3:030be860c83d 42 if ((x + clipX) > tft.width()) {
displaymodule 3:030be860c83d 43 clipX = tft.width() - x;
displaymodule 3:030be860c83d 44 }
displaymodule 3:030be860c83d 45 if ((y + clipY) > tft.height()) {
displaymodule 3:030be860c83d 46 clipY = tft.height() - y;
displaymodule 3:030be860c83d 47 }
displaymodule 3:030be860c83d 48
displaymodule 0:ee27d4c12433 49 tft.select();
displaymodule 3:030be860c83d 50 tft.setAddress(x, y, x+clipX-1, y+clipY-1);
displaymodule 0:ee27d4c12433 51 tft.unSelect();
displaymodule 0:ee27d4c12433 52
displaymodule 0:ee27d4c12433 53 for(row=0; row<_height; row++) {
displaymodule 3:030be860c83d 54 _readPos = _bitmapOffset + (_height - 1 -row ) * bytesPerRow;
displaymodule 0:ee27d4c12433 55 buffPos = sizeof(buff);
displaymodule 0:ee27d4c12433 56
displaymodule 0:ee27d4c12433 57 for(column=0; column<_width; column++) {
displaymodule 0:ee27d4c12433 58 if (buffPos >= sizeof(buff)) {
displaymodule 0:ee27d4c12433 59 tft.unSelect();
displaymodule 0:ee27d4c12433 60 _readFunc(_userData, buff, _readPos, sizeof(buff));
displaymodule 0:ee27d4c12433 61 _readPos += sizeof(buff);
displaymodule 0:ee27d4c12433 62 tft.select();
displaymodule 0:ee27d4c12433 63 buffPos = 0;
displaymodule 0:ee27d4c12433 64 }
displaymodule 0:ee27d4c12433 65
displaymodule 0:ee27d4c12433 66 blue = buff[buffPos++];
displaymodule 0:ee27d4c12433 67 green = buff[buffPos++];
displaymodule 0:ee27d4c12433 68 red = buff[buffPos++];
displaymodule 0:ee27d4c12433 69
displaymodule 3:030be860c83d 70 if (row < clipY && column < clipX) {
displaymodule 3:030be860c83d 71 tft.sendData(Convert888to565(red, green, blue));
displaymodule 3:030be860c83d 72 }
displaymodule 0:ee27d4c12433 73 }
displaymodule 0:ee27d4c12433 74 }
displaymodule 0:ee27d4c12433 75 tft.unSelect();
displaymodule 0:ee27d4c12433 76 return true;
displaymodule 0:ee27d4c12433 77 }
displaymodule 0:ee27d4c12433 78
displaymodule 0:ee27d4c12433 79 bool DmDrawBmpBase::draw565Bitmap(DmTftBase& tft, uint16_t x, uint16_t y) {
displaymodule 0:ee27d4c12433 80 const uint8_t bytesPerPixel = 2;
displaymodule 0:ee27d4c12433 81 uint8_t buff[30*bytesPerPixel]; // Should be dividable by bytesPerPixel
displaymodule 0:ee27d4c12433 82 uint8_t buffPos = sizeof(buff);
displaymodule 0:ee27d4c12433 83 uint16_t bytesPerRow = (bytesPerPixel * _width + 3) & ~3; // bytes Per Row including padding to 4 bytes boundary
displaymodule 0:ee27d4c12433 84 uint16_t paddingSize = bytesPerRow - (bytesPerPixel * _width); // paddingSize for each row
displaymodule 0:ee27d4c12433 85 uint16_t height = -_height; // Change if load bottom-top
displaymodule 0:ee27d4c12433 86 uint16_t pixel;
displaymodule 0:ee27d4c12433 87 uint16_t row, column;
displaymodule 3:030be860c83d 88 uint16_t clipX = _width;
displaymodule 3:030be860c83d 89 uint16_t clipY = height;
displaymodule 0:ee27d4c12433 90 _readPos = _bitmapOffset;
displaymodule 0:ee27d4c12433 91
displaymodule 0:ee27d4c12433 92 //_imageFile.seek(_bitmapOffset);
displaymodule 0:ee27d4c12433 93
displaymodule 3:030be860c83d 94 //make sure image fits
displaymodule 3:030be860c83d 95 if ((x + clipX) > tft.width()) {
displaymodule 3:030be860c83d 96 clipX = tft.width() - x;
displaymodule 3:030be860c83d 97 }
displaymodule 3:030be860c83d 98 if ((y + clipY) > tft.height()) {
displaymodule 3:030be860c83d 99 clipY = tft.height() - y;
displaymodule 3:030be860c83d 100 }
displaymodule 3:030be860c83d 101
displaymodule 0:ee27d4c12433 102 tft.select();
displaymodule 3:030be860c83d 103 tft.setAddress(x, y, x+clipX-1, y+clipY-1);
displaymodule 0:ee27d4c12433 104 tft.unSelect();
displaymodule 0:ee27d4c12433 105
displaymodule 0:ee27d4c12433 106 for(row=0; row<height; row++) {
displaymodule 0:ee27d4c12433 107 for(column=0; column<_width; column++) {
displaymodule 0:ee27d4c12433 108 if (buffPos >= sizeof(buff)) {
displaymodule 0:ee27d4c12433 109 tft.unSelect();
displaymodule 0:ee27d4c12433 110 _readFunc(_userData, buff, _readPos, sizeof(buff));
displaymodule 0:ee27d4c12433 111 _readPos += sizeof(buff);
displaymodule 0:ee27d4c12433 112 //_imageFile.read(buff, sizeof(buff));
displaymodule 0:ee27d4c12433 113 tft.select();
displaymodule 0:ee27d4c12433 114 buffPos = 0;
displaymodule 0:ee27d4c12433 115 }
displaymodule 0:ee27d4c12433 116 pixel = buff[buffPos++] & 0xFF;
displaymodule 0:ee27d4c12433 117 pixel |= buff[buffPos++] << 8;
displaymodule 3:030be860c83d 118 if (row < clipY && column < clipX) {
displaymodule 3:030be860c83d 119 tft.sendData(pixel);
displaymodule 3:030be860c83d 120 }
displaymodule 0:ee27d4c12433 121 }
displaymodule 0:ee27d4c12433 122
displaymodule 0:ee27d4c12433 123 if ( paddingSize > 0 ) { // Check if there is padding in the file
displaymodule 0:ee27d4c12433 124 if ((sizeof(buff) - buffPos) >= paddingSize) { // Most common case, the padding is in the buffer
displaymodule 0:ee27d4c12433 125 buffPos += paddingSize;
displaymodule 0:ee27d4c12433 126 }
displaymodule 0:ee27d4c12433 127 else { // Padding is not in the buffer, we have to load the buffer from file
displaymodule 0:ee27d4c12433 128 tft.unSelect();
displaymodule 0:ee27d4c12433 129 _readFunc(_userData, buff, _readPos, sizeof(buff));
displaymodule 0:ee27d4c12433 130 _readPos += sizeof(buff);
displaymodule 0:ee27d4c12433 131 // _imageFile.read(buff, sizeof(buff));
displaymodule 0:ee27d4c12433 132 tft.select();
displaymodule 0:ee27d4c12433 133 buffPos = paddingSize-(sizeof(buff) - buffPos); // paddingSize (0-3) spaceLeftInBuffer (0-3) where spaceLeftInBuffer < paddingSize
displaymodule 0:ee27d4c12433 134 }
displaymodule 0:ee27d4c12433 135 }
displaymodule 0:ee27d4c12433 136 }
displaymodule 0:ee27d4c12433 137 tft.unSelect();
displaymodule 0:ee27d4c12433 138
displaymodule 0:ee27d4c12433 139 return true;
displaymodule 0:ee27d4c12433 140 }
displaymodule 0:ee27d4c12433 141
displaymodule 0:ee27d4c12433 142 void DmDrawBmpBase::printBmpHeaderInfo() {
displaymodule 0:ee27d4c12433 143 printf("Image size: %d\n", _fileSize);
displaymodule 0:ee27d4c12433 144 printf("Image offset: %d\n", _bitmapOffset);
displaymodule 0:ee27d4c12433 145 printf("Image size: %d, %d\n", _width, _height);
displaymodule 0:ee27d4c12433 146 printf("BitsPerPixel: %d\n",_bitsPerPixel);
displaymodule 0:ee27d4c12433 147 printf("Compression: %d\n",_compression);
displaymodule 0:ee27d4c12433 148 printf("Is 24-bit bmp: %d\n", IsValid888Bitmap());
displaymodule 0:ee27d4c12433 149 printf("Is 16-bit 565 bmp: %d\n", IsValid565Bitmap());
displaymodule 0:ee27d4c12433 150 printf("Has 565 color mask: %d\n", Is565ColorMask());
displaymodule 0:ee27d4c12433 151 }
displaymodule 0:ee27d4c12433 152
displaymodule 0:ee27d4c12433 153 bool DmDrawBmpBase::readBmpHeader() {
displaymodule 0:ee27d4c12433 154 if (read16() !=0x4D42){ // read magic byte
displaymodule 0:ee27d4c12433 155 return false;
displaymodule 0:ee27d4c12433 156 }
displaymodule 0:ee27d4c12433 157
displaymodule 0:ee27d4c12433 158 _fileSize = read32();
displaymodule 0:ee27d4c12433 159 read32(); // Value depends on application which created the image
displaymodule 0:ee27d4c12433 160 _bitmapOffset = read32();
displaymodule 0:ee27d4c12433 161
displaymodule 0:ee27d4c12433 162 // read DIB header
displaymodule 0:ee27d4c12433 163 _headerSize = read32();
displaymodule 0:ee27d4c12433 164 _width = readInt32();
displaymodule 0:ee27d4c12433 165 _height = readInt32();
displaymodule 0:ee27d4c12433 166
displaymodule 0:ee27d4c12433 167 if (read16() != 1) { // number of color planes must be 1
displaymodule 0:ee27d4c12433 168 return false;
displaymodule 0:ee27d4c12433 169 }
displaymodule 0:ee27d4c12433 170
displaymodule 0:ee27d4c12433 171 _bitsPerPixel = read16();
displaymodule 0:ee27d4c12433 172 _compression = read32();
displaymodule 0:ee27d4c12433 173
displaymodule 0:ee27d4c12433 174 if (_bitmapOffset == 66 || _bitmapOffset == 70) { // V3 or v2 format
displaymodule 0:ee27d4c12433 175 //setPosition(54);
displaymodule 0:ee27d4c12433 176 _readPos = 54;
displaymodule 0:ee27d4c12433 177 _redMask = read32();
displaymodule 0:ee27d4c12433 178 _greenMask = read32();
displaymodule 0:ee27d4c12433 179 _blueMask = read32();
displaymodule 0:ee27d4c12433 180 }
displaymodule 0:ee27d4c12433 181 else {
displaymodule 0:ee27d4c12433 182 _redMask = 0x00;
displaymodule 0:ee27d4c12433 183 _greenMask = 0x00;
displaymodule 0:ee27d4c12433 184 _blueMask = 0x00;
displaymodule 0:ee27d4c12433 185 }
displaymodule 0:ee27d4c12433 186
displaymodule 0:ee27d4c12433 187 if (!IsValid888Bitmap() && !IsValid565Bitmap())
displaymodule 0:ee27d4c12433 188 {
displaymodule 0:ee27d4c12433 189 return false;
displaymodule 0:ee27d4c12433 190 }
displaymodule 0:ee27d4c12433 191
displaymodule 0:ee27d4c12433 192 return true;
displaymodule 0:ee27d4c12433 193 }
displaymodule 0:ee27d4c12433 194
displaymodule 0:ee27d4c12433 195 // In this context a valid bitmap
displaymodule 0:ee27d4c12433 196 // - Stored bottom to top
displaymodule 0:ee27d4c12433 197 // - 24-bit file
displaymodule 0:ee27d4c12433 198 // - No compression
displaymodule 0:ee27d4c12433 199 bool DmDrawBmpBase::IsValid888Bitmap() {
displaymodule 0:ee27d4c12433 200 if (_height > 0 && _bitsPerPixel == 24 && _compression == 0)
displaymodule 0:ee27d4c12433 201 {
displaymodule 0:ee27d4c12433 202 return true;
displaymodule 0:ee27d4c12433 203 }
displaymodule 0:ee27d4c12433 204 return false;
displaymodule 0:ee27d4c12433 205 }
displaymodule 0:ee27d4c12433 206
displaymodule 0:ee27d4c12433 207 // In this context a valid bitmap
displaymodule 0:ee27d4c12433 208 // - Stored top to bottom
displaymodule 0:ee27d4c12433 209 // - 16-bit file
displaymodule 0:ee27d4c12433 210 // - Compression 3 (BI_BITFIELDS)
displaymodule 0:ee27d4c12433 211 // - Have a 565 Colormask
displaymodule 0:ee27d4c12433 212 bool DmDrawBmpBase::IsValid565Bitmap() {
displaymodule 0:ee27d4c12433 213 if (_height < 0 && _bitsPerPixel == 16 && _compression == 3 && Is565ColorMask())
displaymodule 0:ee27d4c12433 214 {
displaymodule 0:ee27d4c12433 215 return true;
displaymodule 0:ee27d4c12433 216 }
displaymodule 0:ee27d4c12433 217 return false;
displaymodule 0:ee27d4c12433 218 }
displaymodule 0:ee27d4c12433 219
displaymodule 0:ee27d4c12433 220 bool DmDrawBmpBase::Is565ColorMask() {
displaymodule 0:ee27d4c12433 221 if (_redMask == 0xF800 && _greenMask == 0x7E0 && _blueMask == 0x1F)
displaymodule 0:ee27d4c12433 222 {
displaymodule 0:ee27d4c12433 223 return true;
displaymodule 0:ee27d4c12433 224 }
displaymodule 0:ee27d4c12433 225 return false;
displaymodule 0:ee27d4c12433 226 }
displaymodule 0:ee27d4c12433 227
displaymodule 0:ee27d4c12433 228 int32_t DmDrawBmpBase::readInt32() {
displaymodule 0:ee27d4c12433 229 int32_t d;
displaymodule 0:ee27d4c12433 230 uint16_t b;
displaymodule 0:ee27d4c12433 231
displaymodule 0:ee27d4c12433 232 b = read16();
displaymodule 0:ee27d4c12433 233 d = read16();
displaymodule 0:ee27d4c12433 234 d <<= 16;
displaymodule 0:ee27d4c12433 235 d |= b;
displaymodule 0:ee27d4c12433 236 return d;
displaymodule 0:ee27d4c12433 237 }
displaymodule 0:ee27d4c12433 238
displaymodule 0:ee27d4c12433 239 uint32_t DmDrawBmpBase::read32() {
displaymodule 0:ee27d4c12433 240 uint32_t d;
displaymodule 0:ee27d4c12433 241 uint16_t b;
displaymodule 0:ee27d4c12433 242
displaymodule 0:ee27d4c12433 243 b = read16();
displaymodule 0:ee27d4c12433 244 d = read16();
displaymodule 0:ee27d4c12433 245 d <<= 16;
displaymodule 0:ee27d4c12433 246 d |= b;
displaymodule 0:ee27d4c12433 247 return d;
displaymodule 0:ee27d4c12433 248 }
displaymodule 0:ee27d4c12433 249
displaymodule 0:ee27d4c12433 250 uint16_t DmDrawBmpBase::read16() {
displaymodule 0:ee27d4c12433 251 //uint16_t d;
displaymodule 0:ee27d4c12433 252 //uint8_t b;
displaymodule 0:ee27d4c12433 253 uint8_t buff[2];
displaymodule 0:ee27d4c12433 254 //b = _imageFile.read();
displaymodule 0:ee27d4c12433 255 //d = _imageFile.read();
displaymodule 0:ee27d4c12433 256 _readFunc(_userData, buff, _readPos, 2);
displaymodule 0:ee27d4c12433 257 _readPos+=2;
displaymodule 0:ee27d4c12433 258 //d <<= 8;
displaymodule 0:ee27d4c12433 259 //d |= b;
displaymodule 0:ee27d4c12433 260 //return d;
displaymodule 0:ee27d4c12433 261 return (buff[1] << 8) | buff[0];
displaymodule 0:ee27d4c12433 262 }
displaymodule 0:ee27d4c12433 263
displaymodule 0:ee27d4c12433 264 // http://stackoverflow.com/questions/2442576/how-does-one-convert-16-bit-rgb565-to-24-bit-rgb888
displaymodule 0:ee27d4c12433 265 uint16_t DmDrawBmpBase::Convert888to565(uint8_t red, uint8_t green, uint8_t blue){
displaymodule 0:ee27d4c12433 266 return ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | (blue >> 3);
displaymodule 0:ee27d4c12433 267 }
displaymodule 0:ee27d4c12433 268