summaryrefslogtreecommitdiff
path: root/utility/bmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'utility/bmp.c')
-rw-r--r--utility/bmp.c325
1 files changed, 325 insertions, 0 deletions
diff --git a/utility/bmp.c b/utility/bmp.c
new file mode 100644
index 0000000..ee4fb34
--- /dev/null
+++ b/utility/bmp.c
@@ -0,0 +1,325 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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 disclaimer below.
+ *
+ * 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 "bmp.h"
+#include <board.h>
+#include <utility/trace.h>
+
+#include <string.h>
+
+//-----------------------------------------------------------------------------
+// Define
+//-----------------------------------------------------------------------------
+/// BMP offset for header
+#define IMAGE_OFFSET 0x100
+
+
+//------------------------------------------------------------------------------
+// Internal constants
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+// Internal types
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Describe the BMP palette
+//------------------------------------------------------------------------------
+struct BMPPaletteEntry {
+
+ /// Blue value
+ unsigned char b;
+ /// Green value
+ unsigned char g;
+ /// Red value
+ unsigned char r;
+ /// Filler character value
+ unsigned char filler;
+};
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Test if BMP is valid
+/// \param file Buffer holding the file to examinate.
+/// \return 1 if the header of a BMP file is valid; otherwise returns 0.
+//------------------------------------------------------------------------------
+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.
+/// \return size of BMP image
+//------------------------------------------------------------------------------
+unsigned int BMP_GetFileSize(void *file)
+{
+ return ((struct BMPHeader *) file)->fileSize;
+}
+
+//-----------------------------------------------------------------------------
+/// Write a BMP header
+/// \param pAddressHeader Begin address of the BMP
+/// \param bmpHSize BMP heigth size
+/// \param bmpVSize BMP width size
+/// \param bmpRgb Type of BMP (YUV or RGB)
+/// \param nbByte_Pixels Number of byte per pixels
+//-----------------------------------------------------------------------------
+void WriteBMPheader(unsigned int* pAddressHeader,
+ unsigned int bmpHSize,
+ unsigned int bmpVSize,
+ unsigned char bmpRgb,
+ unsigned char nbByte_Pixels)
+{
+ unsigned int i;
+ unsigned int* fill;
+ struct BMPHeader *Header;
+
+ fill = pAddressHeader;
+ for (i=0; i<IMAGE_OFFSET; i+=4) {
+ *fill++ = 0;
+ }
+
+ Header = (struct BMPHeader*) pAddressHeader;
+
+ Header->type = BMP_TYPE;
+ Header->fileSize = (bmpHSize * bmpVSize * nbByte_Pixels) + IMAGE_OFFSET;
+ Header->reserved1 = 0;
+ Header->reserved2 = 0;
+ Header->offset = IMAGE_OFFSET;
+ Header->headerSize = BITMAPINFOHEADER;
+ Header->width = bmpHSize;
+ Header->height = bmpVSize;
+ Header->planes = 1;
+ Header->bits = nbByte_Pixels * 8;
+ Header->compression = 0;
+ Header->imageSize = bmpHSize * bmpVSize * nbByte_Pixels;
+ Header->xresolution = 0;
+ Header->yresolution = 0;
+ Header->ncolours = 0;
+ Header->importantcolours = 0;
+}
+
+
+//------------------------------------------------------------------------------
+/// debug function, dislay BMP header
+/// \param pAddressHeader Address of the BMP
+//------------------------------------------------------------------------------
+void BMP_displayHeader(unsigned int* pAddressHeader)
+{
+ struct BMPHeader *header;
+
+ header = (struct BMPHeader*) pAddressHeader;
+
+ TRACE_INFO("BMP\n\r");
+ TRACE_INFO("type 0x%X \n\r", header->type);
+ TRACE_INFO("fileSize %d \n\r", header->fileSize);
+ TRACE_INFO("reserved1 %d \n\r", header->reserved1);
+ TRACE_INFO("reserved2 %d \n\r", header->reserved2);
+ TRACE_INFO("offset %d \n\r", header->offset);
+ TRACE_INFO("headerSize %d \n\r", header->headerSize);
+ TRACE_INFO("width %d \n\r", header->width);
+ TRACE_INFO("height %d \n\r", header->height);
+ TRACE_INFO("planes %d \n\r", header->planes);
+ TRACE_INFO("bits %d \n\r", header->bits);
+ TRACE_INFO("compression %d \n\r", header->compression);
+ TRACE_INFO("imageSize %d \n\r", header->imageSize);
+ TRACE_INFO("xresolution %d \n\r", header->xresolution);
+ TRACE_INFO("yresolution %d \n\r", header->yresolution);
+ TRACE_INFO("ncolours %d \n\r", header->ncolours);
+ TRACE_INFO("importantcolours %d\n\r", header->importantcolours);
+}
+
+
+//------------------------------------------------------------------------------
+/// 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.
+/// If no buffer is provided, this function simply checks if it is able to
+/// decode the image.
+/// \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.
+/// \return 0 if the image has been loaded; otherwise returns an error code.
+//------------------------------------------------------------------------------
+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;
+#elif defined(BOARD_LCD_BGR565)
+ 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;
+}
+
+//------------------------------------------------------------------------------
+/// Convert RGB 565 to RGB 555 (RGB 555 is adapted to LCD)
+/// \param fileSource Buffer which holds the RGB file
+/// \param fileDestination 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.
+//------------------------------------------------------------------------------
+void RGB565toBGR555(
+ unsigned char *fileSource,
+ unsigned char *fileDestination,
+ unsigned int width,
+ unsigned int height,
+ unsigned char bpp)
+{
+ unsigned int i;
+ unsigned int j;
+ unsigned int row;
+
+ for (i=0; i < height*(bpp/8); i++) {
+ row = (i*width*(bpp/8));
+ for (j=0; j <= width*(bpp/8); j+=2) {
+ fileDestination[row+j] = ((fileSource[row+j+1]>>3)&0x1F)
+ | (fileSource[row+j]&0xE0);
+ fileDestination[row+j+1] = (fileSource[row+j+1]&0x03)
+ | ((fileSource[row+j]&0x1F)<<2);
+ }
+ }
+}
personal git repositories of Harald Welte. Your mileage may vary