Graphical demo for the LPC4088 Experiment Base Board with one of the Display Expansion Kits. This demo shows a rotating 3D cube with and without textures.
Diff: bmp.cpp
- Revision:
- 0:c828045bbe69
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bmp.cpp Fri Oct 03 12:48:37 2014 +0000 @@ -0,0 +1,214 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support - ROUSSET - + * ---------------------------------------------------------------------------- + * Copyright (c) 2006, Atmel Corporation + + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaiimer below. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the disclaimer below in the documentation and/or + * other materials provided with the distribution. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include "mbed.h" +#include "bmp.h" + +//------------------------------------------------------------------------------ +// Internal constants +//------------------------------------------------------------------------------ + +/// BMP magic number ('BM'). +#define BMP_TYPE 0x4D42 + +//------------------------------------------------------------------------------ +// Internal types +//------------------------------------------------------------------------------ + +struct BMPPaletteEntry { + + unsigned char b; + unsigned char g; + unsigned char r; + unsigned char filler; +}; + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Returns 1 if the header of a BMP file is valid; otherwise returns 0. +/// \param file Buffer holding the file to examinate. +//------------------------------------------------------------------------------ +unsigned char BMP_IsValid(void *file) +{ + return ((struct BMPHeader *) file)->type == BMP_TYPE; +} + +//------------------------------------------------------------------------------ +/// Returns the size of a BMP image given at least its header (the file does +/// not have to be complete). +/// \param file Pointer to the buffer which holds the BMP file. +//------------------------------------------------------------------------------ +unsigned int BMP_GetFileSize(void *file) +{ + return ((struct BMPHeader *) file)->fileSize; +} + +//------------------------------------------------------------------------------ +/// Loads a BMP image located at the given address, decodes it and stores the +/// resulting image inside the provided buffer. Image must have the specified +/// width & height. +/// Returns 0 if the image has been loaded; otherwise returns an error code. +/// \param file Buffer which holds the BMP file. +/// \param buffer Buffer in which to store the decoded image. +/// \param width Buffer width in pixels. +/// \param height Buffer height in pixels. +/// \param bpp Number of bits per pixels that the buffer stores. +//------------------------------------------------------------------------------ +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)) { + + printf("BMP_Decode: File type is not 'BM' (0x%x).\n\r", + header->type); + return 1; + } + + // Check that parameters match + if ((header->compression != 0) + || (header->width != width) + || (header->height != height)) { + + printf("BMP_Decode: File format not supported\n\r"); + printf(" -> .compression = %d\n\r", header->compression); + printf(" -> .width = %d\n\r", header->width); + printf(" -> .height = %d\n\r", header->height); + printf(" -> .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) { + + printf("BMP_Decode: Output resolution not supported\n\r"); + return 3; + } + else if (header->bits == 24) { + + // Modified by Embedded Artists. This padding was not handled in the original + // implementation. Each row in the Pixel Array is padded to a multiple of 4 bytes in size + int rowWidthBytes = width * 3; + rowWidthBytes += (rowWidthBytes % 4); + + // Copy raw data from BMP to buffer (reversing row order) + for (i=0; i < height; i++) { +#if 1 + // Modified by Embedded Artists to convert to 565-format instead of 24 bit + int x; + for(x=0; x<width; x++) + { + r = *(unsigned char *)(image + (height - i - 1) * rowWidthBytes + 3*x + 2); + g = *(unsigned char *)(image + (height - i - 1) * rowWidthBytes + 3*x + 1); + b = *(unsigned char *)(image + (height - i - 1) * rowWidthBytes + 3*x + 0); + *(unsigned short *)(buffer + (i * width) * 2 + 2*x) = (((unsigned short)r & 0xF8) << 8) | + (((unsigned short)g & 0xFC) << 3) | + (((unsigned short)b & 0xF8) >> 3); + } +#else + memcpy(buffer + (i * width) * 3, + image + ((height - i - 1) * width) * 3, + width * 3); +#endif + } + +#if 0 + // Swap red and blue + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + + r = buffer[(i * width + j) * 3 + 2]; + g = buffer[(i * width + j) * 3 + 1]; + b = buffer[(i * width + j) * 3]; + + buffer[(i * width + j) * 3] = r; + buffer[(i * width + j) * 3 + 1] = g; + buffer[(i * width + j) * 3 + 2] = b; + } + } +#endif + } + else if (header->bits == 8) { + + // 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 { + + printf("BMP_Decode: Input resolution not supported\n\r"); + return 4; + } + + return 0; +} +