BMP_Decode
Default mainpageat91libutilityBMP_Decode
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;
}