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:
Tue May 20 15:42:31 2014 +0000
Revision:
0:ee27d4c12433
Child:
3:030be860c83d
First version

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 uint32_t filePosition = _bitmapOffset;
displaymodule 0:ee27d4c12433 34 uint8_t red, green, blue;
displaymodule 0:ee27d4c12433 35 uint16_t row, column;
displaymodule 0:ee27d4c12433 36 uint16_t bytesPerRow = (bytesPerPixel*_width + 3) & ~3;
displaymodule 0:ee27d4c12433 37 uint8_t buff[20*bytesPerPixel];
displaymodule 0:ee27d4c12433 38 uint8_t buffPos = sizeof(buff);
displaymodule 0:ee27d4c12433 39
displaymodule 0:ee27d4c12433 40 tft.select();
displaymodule 0:ee27d4c12433 41 tft.setAddress(x, y, x+_width-1, y+_height-1);
displaymodule 0:ee27d4c12433 42 tft.unSelect();
displaymodule 0:ee27d4c12433 43
displaymodule 0:ee27d4c12433 44 for(row=0; row<_height; row++) {
displaymodule 0:ee27d4c12433 45 _readPos = filePosition = _bitmapOffset + (_height - 1 -row ) * bytesPerRow;
displaymodule 0:ee27d4c12433 46 // if(_imageFile.position() != filePosition) {
displaymodule 0:ee27d4c12433 47 // tft.unSelect();
displaymodule 0:ee27d4c12433 48 // _imageFile.seek(filePosition);
displaymodule 0:ee27d4c12433 49 // tft.select();
displaymodule 0:ee27d4c12433 50 // buffPos = sizeof(buff);
displaymodule 0:ee27d4c12433 51 // }
displaymodule 0:ee27d4c12433 52 buffPos = sizeof(buff);
displaymodule 0:ee27d4c12433 53
displaymodule 0:ee27d4c12433 54 for(column=0; column<_width; column++) {
displaymodule 0:ee27d4c12433 55 if (buffPos >= sizeof(buff)) {
displaymodule 0:ee27d4c12433 56 tft.unSelect();
displaymodule 0:ee27d4c12433 57 _readFunc(_userData, buff, _readPos, sizeof(buff));
displaymodule 0:ee27d4c12433 58 _readPos += sizeof(buff);
displaymodule 0:ee27d4c12433 59 // _imageFile.read(buff, sizeof(buff));
displaymodule 0:ee27d4c12433 60 tft.select();
displaymodule 0:ee27d4c12433 61 buffPos = 0;
displaymodule 0:ee27d4c12433 62 }
displaymodule 0:ee27d4c12433 63
displaymodule 0:ee27d4c12433 64 blue = buff[buffPos++];
displaymodule 0:ee27d4c12433 65 green = buff[buffPos++];
displaymodule 0:ee27d4c12433 66 red = buff[buffPos++];
displaymodule 0:ee27d4c12433 67
displaymodule 0:ee27d4c12433 68 tft.sendData(Convert888to565(red, green, blue));
displaymodule 0:ee27d4c12433 69 }
displaymodule 0:ee27d4c12433 70 }
displaymodule 0:ee27d4c12433 71 tft.unSelect();
displaymodule 0:ee27d4c12433 72 return true;
displaymodule 0:ee27d4c12433 73 }
displaymodule 0:ee27d4c12433 74
displaymodule 0:ee27d4c12433 75 bool DmDrawBmpBase::draw565Bitmap(DmTftBase& tft, uint16_t x, uint16_t y) {
displaymodule 0:ee27d4c12433 76 const uint8_t bytesPerPixel = 2;
displaymodule 0:ee27d4c12433 77 uint8_t buff[30*bytesPerPixel]; // Should be dividable by bytesPerPixel
displaymodule 0:ee27d4c12433 78 uint8_t buffPos = sizeof(buff);
displaymodule 0:ee27d4c12433 79 uint16_t bytesPerRow = (bytesPerPixel * _width + 3) & ~3; // bytes Per Row including padding to 4 bytes boundary
displaymodule 0:ee27d4c12433 80 uint16_t paddingSize = bytesPerRow - (bytesPerPixel * _width); // paddingSize for each row
displaymodule 0:ee27d4c12433 81 uint16_t height = -_height; // Change if load bottom-top
displaymodule 0:ee27d4c12433 82 uint16_t pixel;
displaymodule 0:ee27d4c12433 83 uint16_t row, column;
displaymodule 0:ee27d4c12433 84 _readPos = _bitmapOffset;
displaymodule 0:ee27d4c12433 85
displaymodule 0:ee27d4c12433 86 //_imageFile.seek(_bitmapOffset);
displaymodule 0:ee27d4c12433 87
displaymodule 0:ee27d4c12433 88 tft.select();
displaymodule 0:ee27d4c12433 89 tft.setAddress(x, y, x+_width-1, y+height-1);
displaymodule 0:ee27d4c12433 90 tft.unSelect();
displaymodule 0:ee27d4c12433 91
displaymodule 0:ee27d4c12433 92 for(row=0; row<height; row++) {
displaymodule 0:ee27d4c12433 93 for(column=0; column<_width; column++) {
displaymodule 0:ee27d4c12433 94 if (buffPos >= sizeof(buff)) {
displaymodule 0:ee27d4c12433 95 tft.unSelect();
displaymodule 0:ee27d4c12433 96 _readFunc(_userData, buff, _readPos, sizeof(buff));
displaymodule 0:ee27d4c12433 97 _readPos += sizeof(buff);
displaymodule 0:ee27d4c12433 98 //_imageFile.read(buff, sizeof(buff));
displaymodule 0:ee27d4c12433 99 tft.select();
displaymodule 0:ee27d4c12433 100 buffPos = 0;
displaymodule 0:ee27d4c12433 101 }
displaymodule 0:ee27d4c12433 102 pixel = buff[buffPos++] & 0xFF;
displaymodule 0:ee27d4c12433 103 pixel |= buff[buffPos++] << 8;
displaymodule 0:ee27d4c12433 104 tft.sendData(pixel);
displaymodule 0:ee27d4c12433 105 }
displaymodule 0:ee27d4c12433 106
displaymodule 0:ee27d4c12433 107 if ( paddingSize > 0 ) { // Check if there is padding in the file
displaymodule 0:ee27d4c12433 108 if ((sizeof(buff) - buffPos) >= paddingSize) { // Most common case, the padding is in the buffer
displaymodule 0:ee27d4c12433 109 buffPos += paddingSize;
displaymodule 0:ee27d4c12433 110 }
displaymodule 0:ee27d4c12433 111 else { // Padding is not in the buffer, we have to load the buffer from file
displaymodule 0:ee27d4c12433 112 tft.unSelect();
displaymodule 0:ee27d4c12433 113 _readFunc(_userData, buff, _readPos, sizeof(buff));
displaymodule 0:ee27d4c12433 114 _readPos += sizeof(buff);
displaymodule 0:ee27d4c12433 115 // _imageFile.read(buff, sizeof(buff));
displaymodule 0:ee27d4c12433 116 tft.select();
displaymodule 0:ee27d4c12433 117 buffPos = paddingSize-(sizeof(buff) - buffPos); // paddingSize (0-3) spaceLeftInBuffer (0-3) where spaceLeftInBuffer < paddingSize
displaymodule 0:ee27d4c12433 118 }
displaymodule 0:ee27d4c12433 119 }
displaymodule 0:ee27d4c12433 120 }
displaymodule 0:ee27d4c12433 121 tft.unSelect();
displaymodule 0:ee27d4c12433 122
displaymodule 0:ee27d4c12433 123 return true;
displaymodule 0:ee27d4c12433 124 }
displaymodule 0:ee27d4c12433 125
displaymodule 0:ee27d4c12433 126 void DmDrawBmpBase::printBmpHeaderInfo() {
displaymodule 0:ee27d4c12433 127 printf("Image size: %d\n", _fileSize);
displaymodule 0:ee27d4c12433 128 printf("Image offset: %d\n", _bitmapOffset);
displaymodule 0:ee27d4c12433 129 printf("Image size: %d, %d\n", _width, _height);
displaymodule 0:ee27d4c12433 130 printf("BitsPerPixel: %d\n",_bitsPerPixel);
displaymodule 0:ee27d4c12433 131 printf("Compression: %d\n",_compression);
displaymodule 0:ee27d4c12433 132 printf("Is 24-bit bmp: %d\n", IsValid888Bitmap());
displaymodule 0:ee27d4c12433 133 printf("Is 16-bit 565 bmp: %d\n", IsValid565Bitmap());
displaymodule 0:ee27d4c12433 134 printf("Has 565 color mask: %d\n", Is565ColorMask());
displaymodule 0:ee27d4c12433 135 }
displaymodule 0:ee27d4c12433 136
displaymodule 0:ee27d4c12433 137 bool DmDrawBmpBase::readBmpHeader() {
displaymodule 0:ee27d4c12433 138 if (read16() !=0x4D42){ // read magic byte
displaymodule 0:ee27d4c12433 139 return false;
displaymodule 0:ee27d4c12433 140 }
displaymodule 0:ee27d4c12433 141
displaymodule 0:ee27d4c12433 142 _fileSize = read32();
displaymodule 0:ee27d4c12433 143 read32(); // Value depends on application which created the image
displaymodule 0:ee27d4c12433 144 _bitmapOffset = read32();
displaymodule 0:ee27d4c12433 145
displaymodule 0:ee27d4c12433 146 // read DIB header
displaymodule 0:ee27d4c12433 147 _headerSize = read32();
displaymodule 0:ee27d4c12433 148 _width = readInt32();
displaymodule 0:ee27d4c12433 149 _height = readInt32();
displaymodule 0:ee27d4c12433 150
displaymodule 0:ee27d4c12433 151 if (read16() != 1) { // number of color planes must be 1
displaymodule 0:ee27d4c12433 152 return false;
displaymodule 0:ee27d4c12433 153 }
displaymodule 0:ee27d4c12433 154
displaymodule 0:ee27d4c12433 155 _bitsPerPixel = read16();
displaymodule 0:ee27d4c12433 156 _compression = read32();
displaymodule 0:ee27d4c12433 157
displaymodule 0:ee27d4c12433 158 if (_bitmapOffset == 66 || _bitmapOffset == 70) { // V3 or v2 format
displaymodule 0:ee27d4c12433 159 //setPosition(54);
displaymodule 0:ee27d4c12433 160 _readPos = 54;
displaymodule 0:ee27d4c12433 161 _redMask = read32();
displaymodule 0:ee27d4c12433 162 _greenMask = read32();
displaymodule 0:ee27d4c12433 163 _blueMask = read32();
displaymodule 0:ee27d4c12433 164 }
displaymodule 0:ee27d4c12433 165 else {
displaymodule 0:ee27d4c12433 166 _redMask = 0x00;
displaymodule 0:ee27d4c12433 167 _greenMask = 0x00;
displaymodule 0:ee27d4c12433 168 _blueMask = 0x00;
displaymodule 0:ee27d4c12433 169 }
displaymodule 0:ee27d4c12433 170
displaymodule 0:ee27d4c12433 171 if (!IsValid888Bitmap() && !IsValid565Bitmap())
displaymodule 0:ee27d4c12433 172 {
displaymodule 0:ee27d4c12433 173 return false;
displaymodule 0:ee27d4c12433 174 }
displaymodule 0:ee27d4c12433 175
displaymodule 0:ee27d4c12433 176 return true;
displaymodule 0:ee27d4c12433 177 }
displaymodule 0:ee27d4c12433 178
displaymodule 0:ee27d4c12433 179 // In this context a valid bitmap
displaymodule 0:ee27d4c12433 180 // - Stored bottom to top
displaymodule 0:ee27d4c12433 181 // - 24-bit file
displaymodule 0:ee27d4c12433 182 // - No compression
displaymodule 0:ee27d4c12433 183 bool DmDrawBmpBase::IsValid888Bitmap() {
displaymodule 0:ee27d4c12433 184 if (_height > 0 && _bitsPerPixel == 24 && _compression == 0)
displaymodule 0:ee27d4c12433 185 {
displaymodule 0:ee27d4c12433 186 return true;
displaymodule 0:ee27d4c12433 187 }
displaymodule 0:ee27d4c12433 188 return false;
displaymodule 0:ee27d4c12433 189 }
displaymodule 0:ee27d4c12433 190
displaymodule 0:ee27d4c12433 191 // In this context a valid bitmap
displaymodule 0:ee27d4c12433 192 // - Stored top to bottom
displaymodule 0:ee27d4c12433 193 // - 16-bit file
displaymodule 0:ee27d4c12433 194 // - Compression 3 (BI_BITFIELDS)
displaymodule 0:ee27d4c12433 195 // - Have a 565 Colormask
displaymodule 0:ee27d4c12433 196 bool DmDrawBmpBase::IsValid565Bitmap() {
displaymodule 0:ee27d4c12433 197 if (_height < 0 && _bitsPerPixel == 16 && _compression == 3 && Is565ColorMask())
displaymodule 0:ee27d4c12433 198 {
displaymodule 0:ee27d4c12433 199 return true;
displaymodule 0:ee27d4c12433 200 }
displaymodule 0:ee27d4c12433 201 return false;
displaymodule 0:ee27d4c12433 202 }
displaymodule 0:ee27d4c12433 203
displaymodule 0:ee27d4c12433 204 bool DmDrawBmpBase::Is565ColorMask() {
displaymodule 0:ee27d4c12433 205 if (_redMask == 0xF800 && _greenMask == 0x7E0 && _blueMask == 0x1F)
displaymodule 0:ee27d4c12433 206 {
displaymodule 0:ee27d4c12433 207 return true;
displaymodule 0:ee27d4c12433 208 }
displaymodule 0:ee27d4c12433 209 return false;
displaymodule 0:ee27d4c12433 210 }
displaymodule 0:ee27d4c12433 211
displaymodule 0:ee27d4c12433 212 int32_t DmDrawBmpBase::readInt32() {
displaymodule 0:ee27d4c12433 213 int32_t d;
displaymodule 0:ee27d4c12433 214 uint16_t b;
displaymodule 0:ee27d4c12433 215
displaymodule 0:ee27d4c12433 216 b = read16();
displaymodule 0:ee27d4c12433 217 d = read16();
displaymodule 0:ee27d4c12433 218 d <<= 16;
displaymodule 0:ee27d4c12433 219 d |= b;
displaymodule 0:ee27d4c12433 220 return d;
displaymodule 0:ee27d4c12433 221 }
displaymodule 0:ee27d4c12433 222
displaymodule 0:ee27d4c12433 223 uint32_t DmDrawBmpBase::read32() {
displaymodule 0:ee27d4c12433 224 uint32_t d;
displaymodule 0:ee27d4c12433 225 uint16_t b;
displaymodule 0:ee27d4c12433 226
displaymodule 0:ee27d4c12433 227 b = read16();
displaymodule 0:ee27d4c12433 228 d = read16();
displaymodule 0:ee27d4c12433 229 d <<= 16;
displaymodule 0:ee27d4c12433 230 d |= b;
displaymodule 0:ee27d4c12433 231 return d;
displaymodule 0:ee27d4c12433 232 }
displaymodule 0:ee27d4c12433 233
displaymodule 0:ee27d4c12433 234 uint16_t DmDrawBmpBase::read16() {
displaymodule 0:ee27d4c12433 235 //uint16_t d;
displaymodule 0:ee27d4c12433 236 //uint8_t b;
displaymodule 0:ee27d4c12433 237 uint8_t buff[2];
displaymodule 0:ee27d4c12433 238 //b = _imageFile.read();
displaymodule 0:ee27d4c12433 239 //d = _imageFile.read();
displaymodule 0:ee27d4c12433 240 _readFunc(_userData, buff, _readPos, 2);
displaymodule 0:ee27d4c12433 241 _readPos+=2;
displaymodule 0:ee27d4c12433 242 //d <<= 8;
displaymodule 0:ee27d4c12433 243 //d |= b;
displaymodule 0:ee27d4c12433 244 //return d;
displaymodule 0:ee27d4c12433 245 return (buff[1] << 8) | buff[0];
displaymodule 0:ee27d4c12433 246 }
displaymodule 0:ee27d4c12433 247
displaymodule 0:ee27d4c12433 248 // http://stackoverflow.com/questions/2442576/how-does-one-convert-16-bit-rgb565-to-24-bit-rgb888
displaymodule 0:ee27d4c12433 249 uint16_t DmDrawBmpBase::Convert888to565(uint8_t red, uint8_t green, uint8_t blue){
displaymodule 0:ee27d4c12433 250 return ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | (blue >> 3);
displaymodule 0:ee27d4c12433 251 }
displaymodule 0:ee27d4c12433 252