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
Diff: Application/Image.cpp
- Revision:
- 0:4977187e90c7
- Child:
- 1:46c8df4608c8
diff -r 000000000000 -r 4977187e90c7 Application/Image.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Application/Image.cpp Thu Dec 11 11:03:57 2014 +0000 @@ -0,0 +1,188 @@ + +#include "mbed.h" +#include "Image.h" + +#include "bmp.h" +#include "lodepng.h" + +int Image::decode(const unsigned char* pDataIn, unsigned int sizeIn, Resolution resolution, ImageData_t* pDataOut) +{ + Image::Type type = imageType(pDataIn, sizeIn); + int result = -1; + switch (type) + { + case BMP: + { + struct BMPHeader* hdr = (struct BMPHeader *) pDataIn; + if (resolution == RES_16BIT) { + pDataOut->pixels = (uint16_t*)malloc(hdr->width * hdr->height * 2); + } else if (resolution == RES_24BIT) { + pDataOut->pixels = (uint16_t*)malloc(hdr->width * hdr->height * 4); + } else { + return -1; + } + if (pDataOut->pixels != NULL) + { + unsigned char error = BMP_Decode((void*)pDataIn, (unsigned char*)pDataOut->pixels, + hdr->width, hdr->height, 24, ((resolution == RES_16BIT) ? 16 : 24)); + if (error == 0) + { + pDataOut->width = hdr->width; + pDataOut->height = hdr->height; + pDataOut->res = resolution; + return 0; + } + free(pDataOut->pixels); + } + } + break; + + case PNG: + { + unsigned char* pTmp; + unsigned error = lodepng_decode24(&pTmp, &pDataOut->width, &pDataOut->height, pDataIn, sizeIn); + pDataOut->res = resolution; + if (error == 0) + { + int x, y; + uint8_t r; + uint8_t g; + uint8_t b; + int off = 0; + + result = 0; + if (resolution == RES_16BIT) { + pDataOut->pixels = (uint16_t*)malloc(pDataOut->width * pDataOut->height * 2); + if (pDataOut->pixels != NULL) + { + uint16_t* pConverted = pDataOut->pixels; + + for (y = 0; y < pDataOut->height; y++) { + for (x = 0; x < pDataOut->width; x++) { + r = pTmp[off ]; + g = pTmp[off + 1]; + b = pTmp[off + 2]; + *pConverted = (((unsigned short)r & 0xF8) << 8) | + (((unsigned short)g & 0xFC) << 3) | + (((unsigned short)b & 0xF8) >> 3); + pConverted++; + off += 3; + } + } + } + } else if (resolution == RES_24BIT) { + uint32_t* pConverted = (uint32_t*)malloc(pDataOut->width * pDataOut->height * 4); + pDataOut->pixels = (uint16_t*)pConverted; + if (pDataOut->pixels != NULL) + { + uint8_t* p = pTmp; + int num = pDataOut->width * pDataOut->height; + for (int i = 0; i < num; i++) { + uint32_t a = 0; + a |= (*p++) << 16; // red + a |= (*p++) << 8; // green + a |= (*p++) << 0; // blue + *pConverted++ = a; +// *pConverted++ = 0; // alpha +// *pConverted++ = *p++; // red +// *pConverted++ = *p++; // green +// *pConverted++ = *p++; // blue + } + } + } else { + // unknown format + result = -2; + } + free(pTmp); + return result; + } + } + break; + + default: + break; + } + + pDataOut->pixels = NULL; + pDataOut->width = 0; + pDataOut->height = 0; + return result; +} + +int Image::decode(const char* filename, Resolution res, ImageData_t* pDataOut) +{ + FILE* fh = NULL; + uint8_t* buff = NULL; + int result = 1; + + do + { + fh = fopen(filename, "r"); + if (fh == NULL) { + break; + } + + uint32_t size = fileSize(fh); + buff = (uint8_t*)malloc(size); + if (buff == NULL) { + return 1; + } + + uint32_t num; + uint32_t left = size; + uint32_t off = 0; + do + { + num = fread(buff+off, 1, left, fh); + if (num > 0) { + left -= num; + off += num; + } + } while (left > 0 && num > 0); + if (left > 0) { + break; + } + + if (Image::decode(buff, size, res, pDataOut) == 1) { + break; + } + + // success + result = 0; + + } while (false); + + if (fh != NULL) { + fclose(fh); + } + if (buff != NULL) { + free(buff); + } + return result; +} + +Image::Type Image::imageType(const unsigned char* pDataIn, unsigned int sizeIn) +{ + if (sizeIn > 4) + { + if (pDataIn[0] == 0x89 && pDataIn[1] == 'P' && pDataIn[2] == 'N' && pDataIn[3] == 'G') + { + return PNG; + } + } + if (BMP_IsValid((void*)pDataIn)) + { + return BMP; + } + return UNKNOWN; +} + +uint32_t Image::fileSize(FILE* f) +{ + uint32_t pos = ftell(f); + fseek(f, 0, SEEK_END); + uint32_t size = ftell(f); + fseek(f, pos, SEEK_SET); + return size; +} +