A basic graphics package for the LPC4088 Display Module.

Dependents:   lpc4088_displaymodule_demo_sphere sampleGUI sampleEmptyGUI lpc4088_displaymodule_fs_aid ... more

Fork of DMBasicGUI by EmbeddedArtists AB

Committer:
embeddedartists
Date:
Fri Mar 20 14:25:46 2015 +0100
Revision:
17:6e2abf107800
Parent:
10:651861441108
- Added a Resource concept to allow runtime selection of image source. The
resource can be loaded from an array in flash or from a file on any of the
available file systems. Using a resource makes it possible to have different
resources depending on display resolution
- Removed the basic_image data files
- Added support for the 5" display (800x480 resolution)
- Added possibility to change the default font in SWIM

Who changed what in which revision?

UserRevisionLine numberNew contents of line
embeddedartists 1:46c8df4608c8 1 /*
embeddedartists 1:46c8df4608c8 2 * Copyright 2014 Embedded Artists AB
embeddedartists 1:46c8df4608c8 3 *
embeddedartists 1:46c8df4608c8 4 * Licensed under the Apache License, Version 2.0 (the "License");
embeddedartists 1:46c8df4608c8 5 * you may not use this file except in compliance with the License.
embeddedartists 1:46c8df4608c8 6 * You may obtain a copy of the License at
embeddedartists 1:46c8df4608c8 7 *
embeddedartists 1:46c8df4608c8 8 * http://www.apache.org/licenses/LICENSE-2.0
embeddedartists 1:46c8df4608c8 9 *
embeddedartists 1:46c8df4608c8 10 * Unless required by applicable law or agreed to in writing, software
embeddedartists 1:46c8df4608c8 11 * distributed under the License is distributed on an "AS IS" BASIS,
embeddedartists 1:46c8df4608c8 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
embeddedartists 1:46c8df4608c8 13 * See the License for the specific language governing permissions and
embeddedartists 1:46c8df4608c8 14 * limitations under the License.
embeddedartists 1:46c8df4608c8 15 */
embeddedartists 0:4977187e90c7 16
embeddedartists 0:4977187e90c7 17 #include "mbed.h"
embeddedartists 0:4977187e90c7 18 #include "Image.h"
embeddedartists 17:6e2abf107800 19 #include "Resource.h"
embeddedartists 0:4977187e90c7 20
embeddedartists 0:4977187e90c7 21 #include "bmp.h"
embeddedartists 0:4977187e90c7 22 #include "lodepng.h"
embeddedartists 0:4977187e90c7 23
embeddedartists 5:f4de114c31c3 24 struct eaimg_header_t
embeddedartists 5:f4de114c31c3 25 {
embeddedartists 5:f4de114c31c3 26 char prefix[6];
embeddedartists 5:f4de114c31c3 27 uint16_t width;
embeddedartists 5:f4de114c31c3 28 uint16_t height;
embeddedartists 5:f4de114c31c3 29 } __attribute__ ((packed));
embeddedartists 5:f4de114c31c3 30
embeddedartists 0:4977187e90c7 31 int Image::decode(const unsigned char* pDataIn, unsigned int sizeIn, Resolution resolution, ImageData_t* pDataOut)
embeddedartists 0:4977187e90c7 32 {
embeddedartists 0:4977187e90c7 33 Image::Type type = imageType(pDataIn, sizeIn);
embeddedartists 0:4977187e90c7 34 int result = -1;
embeddedartists 0:4977187e90c7 35 switch (type)
embeddedartists 0:4977187e90c7 36 {
embeddedartists 0:4977187e90c7 37 case BMP:
embeddedartists 0:4977187e90c7 38 {
embeddedartists 0:4977187e90c7 39 struct BMPHeader* hdr = (struct BMPHeader *) pDataIn;
embeddedartists 0:4977187e90c7 40 if (resolution == RES_16BIT) {
embeddedartists 0:4977187e90c7 41 pDataOut->pixels = (uint16_t*)malloc(hdr->width * hdr->height * 2);
embeddedartists 0:4977187e90c7 42 } else if (resolution == RES_24BIT) {
embeddedartists 0:4977187e90c7 43 pDataOut->pixels = (uint16_t*)malloc(hdr->width * hdr->height * 4);
embeddedartists 0:4977187e90c7 44 } else {
embeddedartists 0:4977187e90c7 45 return -1;
embeddedartists 0:4977187e90c7 46 }
embeddedartists 5:f4de114c31c3 47 pDataOut->pointerToFree = pDataOut->pixels;
embeddedartists 0:4977187e90c7 48 if (pDataOut->pixels != NULL)
embeddedartists 0:4977187e90c7 49 {
embeddedartists 0:4977187e90c7 50 unsigned char error = BMP_Decode((void*)pDataIn, (unsigned char*)pDataOut->pixels,
embeddedartists 0:4977187e90c7 51 hdr->width, hdr->height, 24, ((resolution == RES_16BIT) ? 16 : 24));
embeddedartists 0:4977187e90c7 52 if (error == 0)
embeddedartists 0:4977187e90c7 53 {
embeddedartists 0:4977187e90c7 54 pDataOut->width = hdr->width;
embeddedartists 0:4977187e90c7 55 pDataOut->height = hdr->height;
embeddedartists 0:4977187e90c7 56 pDataOut->res = resolution;
embeddedartists 0:4977187e90c7 57 return 0;
embeddedartists 0:4977187e90c7 58 }
embeddedartists 0:4977187e90c7 59 free(pDataOut->pixels);
embeddedartists 5:f4de114c31c3 60 pDataOut->pointerToFree = NULL;
embeddedartists 0:4977187e90c7 61 }
embeddedartists 0:4977187e90c7 62 }
embeddedartists 0:4977187e90c7 63 break;
embeddedartists 0:4977187e90c7 64
embeddedartists 0:4977187e90c7 65 case PNG:
embeddedartists 0:4977187e90c7 66 {
embeddedartists 0:4977187e90c7 67 unsigned char* pTmp;
embeddedartists 10:651861441108 68 unsigned error = lodepng_decode24(&pTmp, (unsigned*)&pDataOut->width, (unsigned*)&pDataOut->height, pDataIn, sizeIn);
embeddedartists 0:4977187e90c7 69 pDataOut->res = resolution;
embeddedartists 0:4977187e90c7 70 if (error == 0)
embeddedartists 0:4977187e90c7 71 {
embeddedartists 10:651861441108 72 uint32_t x, y;
embeddedartists 0:4977187e90c7 73 uint8_t r;
embeddedartists 0:4977187e90c7 74 uint8_t g;
embeddedartists 0:4977187e90c7 75 uint8_t b;
embeddedartists 0:4977187e90c7 76 int off = 0;
embeddedartists 0:4977187e90c7 77
embeddedartists 0:4977187e90c7 78 result = 0;
embeddedartists 0:4977187e90c7 79 if (resolution == RES_16BIT) {
embeddedartists 0:4977187e90c7 80 pDataOut->pixels = (uint16_t*)malloc(pDataOut->width * pDataOut->height * 2);
embeddedartists 5:f4de114c31c3 81 pDataOut->pointerToFree = pDataOut->pixels;
embeddedartists 0:4977187e90c7 82 if (pDataOut->pixels != NULL)
embeddedartists 0:4977187e90c7 83 {
embeddedartists 0:4977187e90c7 84 uint16_t* pConverted = pDataOut->pixels;
embeddedartists 0:4977187e90c7 85
embeddedartists 0:4977187e90c7 86 for (y = 0; y < pDataOut->height; y++) {
embeddedartists 0:4977187e90c7 87 for (x = 0; x < pDataOut->width; x++) {
embeddedartists 0:4977187e90c7 88 r = pTmp[off ];
embeddedartists 0:4977187e90c7 89 g = pTmp[off + 1];
embeddedartists 0:4977187e90c7 90 b = pTmp[off + 2];
embeddedartists 0:4977187e90c7 91 *pConverted = (((unsigned short)r & 0xF8) << 8) |
embeddedartists 0:4977187e90c7 92 (((unsigned short)g & 0xFC) << 3) |
embeddedartists 0:4977187e90c7 93 (((unsigned short)b & 0xF8) >> 3);
embeddedartists 0:4977187e90c7 94 pConverted++;
embeddedartists 0:4977187e90c7 95 off += 3;
embeddedartists 0:4977187e90c7 96 }
embeddedartists 0:4977187e90c7 97 }
embeddedartists 0:4977187e90c7 98 }
embeddedartists 0:4977187e90c7 99 } else if (resolution == RES_24BIT) {
embeddedartists 0:4977187e90c7 100 uint32_t* pConverted = (uint32_t*)malloc(pDataOut->width * pDataOut->height * 4);
embeddedartists 0:4977187e90c7 101 pDataOut->pixels = (uint16_t*)pConverted;
embeddedartists 5:f4de114c31c3 102 pDataOut->pointerToFree = pDataOut->pixels;
embeddedartists 0:4977187e90c7 103 if (pDataOut->pixels != NULL)
embeddedartists 0:4977187e90c7 104 {
embeddedartists 0:4977187e90c7 105 uint8_t* p = pTmp;
embeddedartists 0:4977187e90c7 106 int num = pDataOut->width * pDataOut->height;
embeddedartists 0:4977187e90c7 107 for (int i = 0; i < num; i++) {
embeddedartists 0:4977187e90c7 108 uint32_t a = 0;
embeddedartists 0:4977187e90c7 109 a |= (*p++) << 16; // red
embeddedartists 0:4977187e90c7 110 a |= (*p++) << 8; // green
embeddedartists 0:4977187e90c7 111 a |= (*p++) << 0; // blue
embeddedartists 0:4977187e90c7 112 *pConverted++ = a;
embeddedartists 0:4977187e90c7 113 }
embeddedartists 0:4977187e90c7 114 }
embeddedartists 0:4977187e90c7 115 } else {
embeddedartists 0:4977187e90c7 116 // unknown format
embeddedartists 0:4977187e90c7 117 result = -2;
embeddedartists 0:4977187e90c7 118 }
embeddedartists 0:4977187e90c7 119 free(pTmp);
embeddedartists 0:4977187e90c7 120 return result;
embeddedartists 0:4977187e90c7 121 }
embeddedartists 0:4977187e90c7 122 }
embeddedartists 0:4977187e90c7 123 break;
embeddedartists 0:4977187e90c7 124
embeddedartists 5:f4de114c31c3 125 case RAW:
embeddedartists 5:f4de114c31c3 126 {
embeddedartists 5:f4de114c31c3 127 eaimg_header_t* hdr = (eaimg_header_t*)pDataIn;
embeddedartists 5:f4de114c31c3 128 pDataOut->width = hdr->width;
embeddedartists 5:f4de114c31c3 129 pDataOut->height = hdr->height;
embeddedartists 5:f4de114c31c3 130 pDataOut->pointerToFree = malloc(sizeIn-sizeof(eaimg_header_t));
embeddedartists 5:f4de114c31c3 131 pDataOut->pixels = (uint16_t*)pDataOut->pointerToFree;
embeddedartists 5:f4de114c31c3 132 pDataOut->res = RES_16BIT;
embeddedartists 5:f4de114c31c3 133 if (pDataOut->pixels != NULL)
embeddedartists 5:f4de114c31c3 134 {
embeddedartists 5:f4de114c31c3 135 memcpy(pDataOut->pixels, pDataIn+sizeof(eaimg_header_t), sizeIn-sizeof(eaimg_header_t));
embeddedartists 5:f4de114c31c3 136 return 0;
embeddedartists 5:f4de114c31c3 137 }
embeddedartists 5:f4de114c31c3 138 }
embeddedartists 5:f4de114c31c3 139 break;
embeddedartists 5:f4de114c31c3 140
embeddedartists 0:4977187e90c7 141 default:
embeddedartists 0:4977187e90c7 142 break;
embeddedartists 0:4977187e90c7 143 }
embeddedartists 0:4977187e90c7 144
embeddedartists 0:4977187e90c7 145 pDataOut->pixels = NULL;
embeddedartists 5:f4de114c31c3 146 pDataOut->pointerToFree = NULL;
embeddedartists 0:4977187e90c7 147 pDataOut->width = 0;
embeddedartists 0:4977187e90c7 148 pDataOut->height = 0;
embeddedartists 5:f4de114c31c3 149 pDataOut->res = resolution;
embeddedartists 0:4977187e90c7 150 return result;
embeddedartists 0:4977187e90c7 151 }
embeddedartists 0:4977187e90c7 152
embeddedartists 5:f4de114c31c3 153 int Image::decode(const char* filename, Resolution res, ImageData_t* pDataOut, Mutex* pLock)
embeddedartists 0:4977187e90c7 154 {
embeddedartists 0:4977187e90c7 155 FILE* fh = NULL;
embeddedartists 0:4977187e90c7 156 uint8_t* buff = NULL;
embeddedartists 0:4977187e90c7 157 int result = 1;
embeddedartists 0:4977187e90c7 158
embeddedartists 5:f4de114c31c3 159 pDataOut->height = 0;
embeddedartists 5:f4de114c31c3 160 pDataOut->width = 0;
embeddedartists 5:f4de114c31c3 161 pDataOut->pixels = NULL;
embeddedartists 5:f4de114c31c3 162 pDataOut->pointerToFree = NULL;
embeddedartists 5:f4de114c31c3 163 pDataOut->res = res;
embeddedartists 5:f4de114c31c3 164
embeddedartists 5:f4de114c31c3 165 if (pLock != NULL) {
embeddedartists 5:f4de114c31c3 166 pLock->lock();
embeddedartists 5:f4de114c31c3 167 }
embeddedartists 5:f4de114c31c3 168
embeddedartists 0:4977187e90c7 169 do
embeddedartists 0:4977187e90c7 170 {
embeddedartists 0:4977187e90c7 171 fh = fopen(filename, "r");
embeddedartists 0:4977187e90c7 172 if (fh == NULL) {
embeddedartists 0:4977187e90c7 173 break;
embeddedartists 0:4977187e90c7 174 }
embeddedartists 0:4977187e90c7 175
embeddedartists 0:4977187e90c7 176 uint32_t size = fileSize(fh);
embeddedartists 0:4977187e90c7 177 buff = (uint8_t*)malloc(size);
embeddedartists 0:4977187e90c7 178 if (buff == NULL) {
embeddedartists 0:4977187e90c7 179 return 1;
embeddedartists 0:4977187e90c7 180 }
embeddedartists 0:4977187e90c7 181
embeddedartists 0:4977187e90c7 182 uint32_t num;
embeddedartists 0:4977187e90c7 183 uint32_t left = size;
embeddedartists 0:4977187e90c7 184 uint32_t off = 0;
embeddedartists 0:4977187e90c7 185 do
embeddedartists 0:4977187e90c7 186 {
embeddedartists 0:4977187e90c7 187 num = fread(buff+off, 1, left, fh);
embeddedartists 0:4977187e90c7 188 if (num > 0) {
embeddedartists 0:4977187e90c7 189 left -= num;
embeddedartists 0:4977187e90c7 190 off += num;
embeddedartists 0:4977187e90c7 191 }
embeddedartists 0:4977187e90c7 192 } while (left > 0 && num > 0);
embeddedartists 0:4977187e90c7 193 if (left > 0) {
embeddedartists 0:4977187e90c7 194 break;
embeddedartists 0:4977187e90c7 195 }
embeddedartists 0:4977187e90c7 196
embeddedartists 5:f4de114c31c3 197 fclose(fh);
embeddedartists 5:f4de114c31c3 198 if (pLock != NULL) {
embeddedartists 5:f4de114c31c3 199 pLock->unlock();
embeddedartists 5:f4de114c31c3 200 }
embeddedartists 5:f4de114c31c3 201
embeddedartists 5:f4de114c31c3 202 Type type = imageType(buff, size);
embeddedartists 5:f4de114c31c3 203 if (type == RAW) {
embeddedartists 5:f4de114c31c3 204 pDataOut->width = ((eaimg_header_t*)buff)->width;
embeddedartists 5:f4de114c31c3 205 pDataOut->height = ((eaimg_header_t*)buff)->height;
embeddedartists 5:f4de114c31c3 206 pDataOut->pointerToFree = buff;
embeddedartists 5:f4de114c31c3 207 pDataOut->res = RES_16BIT;
embeddedartists 5:f4de114c31c3 208 pDataOut->pixels = (uint16_t*)(buff + sizeof(eaimg_header_t));
embeddedartists 5:f4de114c31c3 209 } else {
embeddedartists 5:f4de114c31c3 210 result = Image::decode(buff, size, res, pDataOut);
embeddedartists 5:f4de114c31c3 211 free(buff);
embeddedartists 6:7917b0894655 212 return result;
embeddedartists 0:4977187e90c7 213 }
embeddedartists 0:4977187e90c7 214
embeddedartists 0:4977187e90c7 215 // success
embeddedartists 5:f4de114c31c3 216 return 0;
embeddedartists 0:4977187e90c7 217
embeddedartists 0:4977187e90c7 218 } while (false);
embeddedartists 0:4977187e90c7 219
embeddedartists 0:4977187e90c7 220 if (fh != NULL) {
embeddedartists 0:4977187e90c7 221 fclose(fh);
embeddedartists 0:4977187e90c7 222 }
embeddedartists 0:4977187e90c7 223 if (buff != NULL) {
embeddedartists 0:4977187e90c7 224 free(buff);
embeddedartists 0:4977187e90c7 225 }
embeddedartists 5:f4de114c31c3 226 if (pLock != NULL) {
embeddedartists 5:f4de114c31c3 227 pLock->unlock();
embeddedartists 5:f4de114c31c3 228 }
embeddedartists 0:4977187e90c7 229 return result;
embeddedartists 0:4977187e90c7 230 }
embeddedartists 0:4977187e90c7 231
embeddedartists 17:6e2abf107800 232 int Image::decode(Resource* res, Resolution resolution, ImageData_t* pDataOut, Mutex* pLock)
embeddedartists 17:6e2abf107800 233 {
embeddedartists 17:6e2abf107800 234 int result = 0;
embeddedartists 17:6e2abf107800 235 if (res == NULL) {
embeddedartists 17:6e2abf107800 236 result = 1;
embeddedartists 17:6e2abf107800 237 } else {
embeddedartists 17:6e2abf107800 238 // Load the image only if it is not already cached
embeddedartists 17:6e2abf107800 239 if (res->_img.pixels == NULL) {
embeddedartists 17:6e2abf107800 240 if (res->_isFile) {
embeddedartists 17:6e2abf107800 241 result = decode(res->_filename, resolution, &res->_img, pLock);
embeddedartists 17:6e2abf107800 242 } else {
embeddedartists 17:6e2abf107800 243 result = decode(res->_data, res->_dataSize, resolution, &res->_img);
embeddedartists 17:6e2abf107800 244 }
embeddedartists 17:6e2abf107800 245 }
embeddedartists 17:6e2abf107800 246 if ((result == 0) && (res->_img.pixels != NULL)) {
embeddedartists 17:6e2abf107800 247 // Copy the cached copy to the user's data, but skip the pointerToFree
embeddedartists 17:6e2abf107800 248 // as that would break the cache
embeddedartists 17:6e2abf107800 249 memcpy(pDataOut, &res->_img, sizeof(ImageData_t));
embeddedartists 17:6e2abf107800 250 pDataOut->pointerToFree = NULL;
embeddedartists 17:6e2abf107800 251 }
embeddedartists 17:6e2abf107800 252 }
embeddedartists 17:6e2abf107800 253 return result;
embeddedartists 17:6e2abf107800 254 }
embeddedartists 17:6e2abf107800 255
embeddedartists 0:4977187e90c7 256 Image::Type Image::imageType(const unsigned char* pDataIn, unsigned int sizeIn)
embeddedartists 0:4977187e90c7 257 {
embeddedartists 0:4977187e90c7 258 if (sizeIn > 4)
embeddedartists 0:4977187e90c7 259 {
embeddedartists 0:4977187e90c7 260 if (pDataIn[0] == 0x89 && pDataIn[1] == 'P' && pDataIn[2] == 'N' && pDataIn[3] == 'G')
embeddedartists 0:4977187e90c7 261 {
embeddedartists 0:4977187e90c7 262 return PNG;
embeddedartists 0:4977187e90c7 263 }
embeddedartists 0:4977187e90c7 264 }
embeddedartists 0:4977187e90c7 265 if (BMP_IsValid((void*)pDataIn))
embeddedartists 0:4977187e90c7 266 {
embeddedartists 0:4977187e90c7 267 return BMP;
embeddedartists 0:4977187e90c7 268 }
embeddedartists 5:f4de114c31c3 269 if (sizeIn >= sizeof(eaimg_header_t))
embeddedartists 5:f4de114c31c3 270 {
embeddedartists 5:f4de114c31c3 271 eaimg_header_t* hdr = (eaimg_header_t*)pDataIn;
embeddedartists 5:f4de114c31c3 272 if (memcmp(hdr->prefix, "eaimg:", 6) == 0)
embeddedartists 5:f4de114c31c3 273 {
embeddedartists 5:f4de114c31c3 274 return RAW;
embeddedartists 5:f4de114c31c3 275 }
embeddedartists 5:f4de114c31c3 276 }
embeddedartists 0:4977187e90c7 277 return UNKNOWN;
embeddedartists 0:4977187e90c7 278 }
embeddedartists 0:4977187e90c7 279
embeddedartists 0:4977187e90c7 280 uint32_t Image::fileSize(FILE* f)
embeddedartists 0:4977187e90c7 281 {
embeddedartists 0:4977187e90c7 282 uint32_t pos = ftell(f);
embeddedartists 0:4977187e90c7 283 fseek(f, 0, SEEK_END);
embeddedartists 0:4977187e90c7 284 uint32_t size = ftell(f);
embeddedartists 0:4977187e90c7 285 fseek(f, pos, SEEK_SET);
embeddedartists 0:4977187e90c7 286 return size;
embeddedartists 0:4977187e90c7 287 }