Description
Source
Call Graph
Start Line: 189
unsigned char BMP_Decode(void *file, unsigned char *buffer, unsigned int width, unsigned int height, unsigned char bpp)
{
struct BMPHeader *header;
unsigned int i, j;
unsigned char r, g, b;
unsigned char *image;
// Read header information
header = (struct BMPHeader *) file;
// Verify that the file is valid
if (!BMP_IsValid(file)) {
TRACE_ERROR("BMP_Decode: File type is not 'BM' (0x%04X).\n\r",header->type);
return 1;
}
// Check that parameters match
if ((header->compression != 0)
|| (header->width != width)
|| (header->height != height)) {
TRACE_ERROR("BMP_Decode: File format not supported\n\r");
TRACE_ERROR(" -> .compression = %u\n\r", header->compression);
TRACE_ERROR(" -> .width = %u\n\r", header->width);
TRACE_ERROR(" -> .height = %u\n\r", header->height);
TRACE_ERROR(" -> .bits = %d\n\r", header->bits);
return 2;
}
// Get image data
image = (unsigned char *) ((unsigned int) file + header->offset);
// Check that the bpp resolution is supported
// Only a 24-bit output & 24- or 8-bit input are supported
if (bpp != 24) {
TRACE_ERROR("BMP_Decode: Output resolution not supported\n\r");
return 3;
}
else if (header->bits == 24) {
// Decoding is ok
if (!buffer) return 0;
// Get image data (swapping red & blue)
for (i=0; i < height; i++) {
for (j=0; j < width; j++) {
r = image[((height - i - 1) * width + j) * 3 + 2];
g = image[((height - i - 1) * width + j) * 3 + 1];
b = image[((height - i - 1) * width + j) * 3];
#if defined(BOARD_LCD_RGB565)
// Interlacing
r = ((r << 1) & 0xF0) | ((g & 0x80) >> 4) | ((r & 0x80) >> 5);
g = (g << 1) & 0xF8;
b = b & 0xF8;
buffer[(i * width + j) * 3] = b;
buffer[(i * width + j) * 3 + 1] = g;
buffer[(i * width + j) * 3 + 2] = r;
#else
buffer[(i * width + j) * 3] = r;
buffer[(i * width + j) * 3 + 1] = g;
buffer[(i * width + j) * 3 + 2] = b;
#endif //#if defined(BOARD_LCD_RGB565)
}
}
}
else if (header->bits == 8) {
// Decoding is ok
if (!buffer) return 0;
// Retrieve palette
struct BMPPaletteEntry palette[256];
memcpy(palette,
(unsigned char *) ((unsigned int) file + sizeof(struct BMPHeader)),
header->offset - sizeof(struct BMPHeader));
// Decode image (reversing row order)
for (i=0; i < height; i++) {
for (j=0; j < width; j++) {
r = palette[image[(height - i - 1) * width + j]].r;
g = palette[image[(height - i - 1) * width + j]].g;
b = palette[image[(height - i - 1) * width + j]].b;
buffer[(i * width + j) * 3] = r;
buffer[(i * width + j) * 3 + 1] = g;
buffer[(i * width + j) * 3 + 2] = b;
}
}
}
else {
TRACE_ERROR("BMP_Decode: Input resolution not supported\n\r");
TRACE_INFO("header->bits 0x%X \n\r", header->bits);
return 4;
}
return 0;
}