Graphical demo for the LPC4088 Experiment Base Board with one of the Display Expansion Kits. This program decodes decodes and shows two png images.

Dependencies:   EALib mbed

Committer:
embeddedartists
Date:
Fri Oct 03 13:30:09 2014 +0000
Revision:
0:b567d56a59d7
First version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
embeddedartists 0:b567d56a59d7 1 /* ----------------------------------------------------------------------------
embeddedartists 0:b567d56a59d7 2 * ATMEL Microcontroller Software Support - ROUSSET -
embeddedartists 0:b567d56a59d7 3 * ----------------------------------------------------------------------------
embeddedartists 0:b567d56a59d7 4 * Copyright (c) 2006, Atmel Corporation
embeddedartists 0:b567d56a59d7 5
embeddedartists 0:b567d56a59d7 6 * All rights reserved.
embeddedartists 0:b567d56a59d7 7 *
embeddedartists 0:b567d56a59d7 8 * Redistribution and use in source and binary forms, with or without
embeddedartists 0:b567d56a59d7 9 * modification, are permitted provided that the following conditions are met:
embeddedartists 0:b567d56a59d7 10 *
embeddedartists 0:b567d56a59d7 11 * - Redistributions of source code must retain the above copyright notice,
embeddedartists 0:b567d56a59d7 12 * this list of conditions and the disclaiimer below.
embeddedartists 0:b567d56a59d7 13 *
embeddedartists 0:b567d56a59d7 14 * - Redistributions in binary form must reproduce the above copyright notice,
embeddedartists 0:b567d56a59d7 15 * this list of conditions and the disclaimer below in the documentation and/or
embeddedartists 0:b567d56a59d7 16 * other materials provided with the distribution.
embeddedartists 0:b567d56a59d7 17 *
embeddedartists 0:b567d56a59d7 18 * Atmel's name may not be used to endorse or promote products derived from
embeddedartists 0:b567d56a59d7 19 * this software without specific prior written permission.
embeddedartists 0:b567d56a59d7 20 *
embeddedartists 0:b567d56a59d7 21 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
embeddedartists 0:b567d56a59d7 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
embeddedartists 0:b567d56a59d7 23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
embeddedartists 0:b567d56a59d7 24 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
embeddedartists 0:b567d56a59d7 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
embeddedartists 0:b567d56a59d7 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
embeddedartists 0:b567d56a59d7 27 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
embeddedartists 0:b567d56a59d7 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
embeddedartists 0:b567d56a59d7 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
embeddedartists 0:b567d56a59d7 30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
embeddedartists 0:b567d56a59d7 31 * ----------------------------------------------------------------------------
embeddedartists 0:b567d56a59d7 32 */
embeddedartists 0:b567d56a59d7 33
embeddedartists 0:b567d56a59d7 34 //------------------------------------------------------------------------------
embeddedartists 0:b567d56a59d7 35 // Headers
embeddedartists 0:b567d56a59d7 36 //------------------------------------------------------------------------------
embeddedartists 0:b567d56a59d7 37
embeddedartists 0:b567d56a59d7 38 #include "mbed.h"
embeddedartists 0:b567d56a59d7 39 #include "bmp.h"
embeddedartists 0:b567d56a59d7 40
embeddedartists 0:b567d56a59d7 41 //------------------------------------------------------------------------------
embeddedartists 0:b567d56a59d7 42 // Internal constants
embeddedartists 0:b567d56a59d7 43 //------------------------------------------------------------------------------
embeddedartists 0:b567d56a59d7 44
embeddedartists 0:b567d56a59d7 45 /// BMP magic number ('BM').
embeddedartists 0:b567d56a59d7 46 #define BMP_TYPE 0x4D42
embeddedartists 0:b567d56a59d7 47
embeddedartists 0:b567d56a59d7 48 //------------------------------------------------------------------------------
embeddedartists 0:b567d56a59d7 49 // Internal types
embeddedartists 0:b567d56a59d7 50 //------------------------------------------------------------------------------
embeddedartists 0:b567d56a59d7 51
embeddedartists 0:b567d56a59d7 52 struct BMPPaletteEntry {
embeddedartists 0:b567d56a59d7 53
embeddedartists 0:b567d56a59d7 54 unsigned char b;
embeddedartists 0:b567d56a59d7 55 unsigned char g;
embeddedartists 0:b567d56a59d7 56 unsigned char r;
embeddedartists 0:b567d56a59d7 57 unsigned char filler;
embeddedartists 0:b567d56a59d7 58 };
embeddedartists 0:b567d56a59d7 59
embeddedartists 0:b567d56a59d7 60 //------------------------------------------------------------------------------
embeddedartists 0:b567d56a59d7 61 // Exported functions
embeddedartists 0:b567d56a59d7 62 //------------------------------------------------------------------------------
embeddedartists 0:b567d56a59d7 63
embeddedartists 0:b567d56a59d7 64 //------------------------------------------------------------------------------
embeddedartists 0:b567d56a59d7 65 /// Returns 1 if the header of a BMP file is valid; otherwise returns 0.
embeddedartists 0:b567d56a59d7 66 /// \param file Buffer holding the file to examinate.
embeddedartists 0:b567d56a59d7 67 //------------------------------------------------------------------------------
embeddedartists 0:b567d56a59d7 68 unsigned char BMP_IsValid(void *file)
embeddedartists 0:b567d56a59d7 69 {
embeddedartists 0:b567d56a59d7 70 return ((struct BMPHeader *) file)->type == BMP_TYPE;
embeddedartists 0:b567d56a59d7 71 }
embeddedartists 0:b567d56a59d7 72
embeddedartists 0:b567d56a59d7 73 //------------------------------------------------------------------------------
embeddedartists 0:b567d56a59d7 74 /// Returns the size of a BMP image given at least its header (the file does
embeddedartists 0:b567d56a59d7 75 /// not have to be complete).
embeddedartists 0:b567d56a59d7 76 /// \param file Pointer to the buffer which holds the BMP file.
embeddedartists 0:b567d56a59d7 77 //------------------------------------------------------------------------------
embeddedartists 0:b567d56a59d7 78 unsigned int BMP_GetFileSize(void *file)
embeddedartists 0:b567d56a59d7 79 {
embeddedartists 0:b567d56a59d7 80 return ((struct BMPHeader *) file)->fileSize;
embeddedartists 0:b567d56a59d7 81 }
embeddedartists 0:b567d56a59d7 82
embeddedartists 0:b567d56a59d7 83 //------------------------------------------------------------------------------
embeddedartists 0:b567d56a59d7 84 /// Loads a BMP image located at the given address, decodes it and stores the
embeddedartists 0:b567d56a59d7 85 /// resulting image inside the provided buffer. Image must have the specified
embeddedartists 0:b567d56a59d7 86 /// width & height.
embeddedartists 0:b567d56a59d7 87 /// Returns 0 if the image has been loaded; otherwise returns an error code.
embeddedartists 0:b567d56a59d7 88 /// \param file Buffer which holds the BMP file.
embeddedartists 0:b567d56a59d7 89 /// \param buffer Buffer in which to store the decoded image.
embeddedartists 0:b567d56a59d7 90 /// \param width Buffer width in pixels.
embeddedartists 0:b567d56a59d7 91 /// \param height Buffer height in pixels.
embeddedartists 0:b567d56a59d7 92 /// \param bpp Number of bits per pixels that the buffer stores.
embeddedartists 0:b567d56a59d7 93 //------------------------------------------------------------------------------
embeddedartists 0:b567d56a59d7 94 unsigned char BMP_Decode(
embeddedartists 0:b567d56a59d7 95 void *file,
embeddedartists 0:b567d56a59d7 96 unsigned char *buffer,
embeddedartists 0:b567d56a59d7 97 unsigned int width,
embeddedartists 0:b567d56a59d7 98 unsigned int height,
embeddedartists 0:b567d56a59d7 99 unsigned char bpp)
embeddedartists 0:b567d56a59d7 100 {
embeddedartists 0:b567d56a59d7 101 struct BMPHeader *header;
embeddedartists 0:b567d56a59d7 102 unsigned int i, j;
embeddedartists 0:b567d56a59d7 103 unsigned char r, g, b;
embeddedartists 0:b567d56a59d7 104 unsigned char *image;
embeddedartists 0:b567d56a59d7 105
embeddedartists 0:b567d56a59d7 106 // Read header information
embeddedartists 0:b567d56a59d7 107 header = (struct BMPHeader *) file;
embeddedartists 0:b567d56a59d7 108
embeddedartists 0:b567d56a59d7 109 // Verify that the file is valid
embeddedartists 0:b567d56a59d7 110 if (!BMP_IsValid(file)) {
embeddedartists 0:b567d56a59d7 111
embeddedartists 0:b567d56a59d7 112 printf("BMP_Decode: File type is not 'BM' (0x%x).\n\r",
embeddedartists 0:b567d56a59d7 113 header->type);
embeddedartists 0:b567d56a59d7 114 return 1;
embeddedartists 0:b567d56a59d7 115 }
embeddedartists 0:b567d56a59d7 116
embeddedartists 0:b567d56a59d7 117 // Check that parameters match
embeddedartists 0:b567d56a59d7 118 if ((header->compression != 0)
embeddedartists 0:b567d56a59d7 119 || (header->width != width)
embeddedartists 0:b567d56a59d7 120 || (header->height != height)) {
embeddedartists 0:b567d56a59d7 121
embeddedartists 0:b567d56a59d7 122 printf("BMP_Decode: File format not supported\n\r");
embeddedartists 0:b567d56a59d7 123 printf(" -> .compression = %d\n\r", header->compression);
embeddedartists 0:b567d56a59d7 124 printf(" -> .width = %d\n\r", header->width);
embeddedartists 0:b567d56a59d7 125 printf(" -> .height = %d\n\r", header->height);
embeddedartists 0:b567d56a59d7 126 printf(" -> .bits = %d\n\r", header->bits);
embeddedartists 0:b567d56a59d7 127 return 2;
embeddedartists 0:b567d56a59d7 128 }
embeddedartists 0:b567d56a59d7 129
embeddedartists 0:b567d56a59d7 130 // Get image data
embeddedartists 0:b567d56a59d7 131 image = (unsigned char *) ((unsigned int) file + header->offset);
embeddedartists 0:b567d56a59d7 132
embeddedartists 0:b567d56a59d7 133 // Check that the bpp resolution is supported
embeddedartists 0:b567d56a59d7 134 // Only a 24-bit output & 24- or 8-bit input are supported
embeddedartists 0:b567d56a59d7 135 if (bpp != 24) {
embeddedartists 0:b567d56a59d7 136
embeddedartists 0:b567d56a59d7 137 printf("BMP_Decode: Output resolution not supported\n\r");
embeddedartists 0:b567d56a59d7 138 return 3;
embeddedartists 0:b567d56a59d7 139 }
embeddedartists 0:b567d56a59d7 140 else if (header->bits == 24) {
embeddedartists 0:b567d56a59d7 141
embeddedartists 0:b567d56a59d7 142 // Modified by Embedded Artists. This padding was not handled in the original
embeddedartists 0:b567d56a59d7 143 // implementation. Each row in the Pixel Array is padded to a multiple of 4 bytes in size
embeddedartists 0:b567d56a59d7 144 int rowWidthBytes = width * 3;
embeddedartists 0:b567d56a59d7 145 rowWidthBytes += (rowWidthBytes % 4);
embeddedartists 0:b567d56a59d7 146
embeddedartists 0:b567d56a59d7 147 // Copy raw data from BMP to buffer (reversing row order)
embeddedartists 0:b567d56a59d7 148 for (i=0; i < height; i++) {
embeddedartists 0:b567d56a59d7 149 #if 1
embeddedartists 0:b567d56a59d7 150 // Modified by Embedded Artists to convert to 565-format instead of 24 bit
embeddedartists 0:b567d56a59d7 151 int x;
embeddedartists 0:b567d56a59d7 152 for(x=0; x<width; x++)
embeddedartists 0:b567d56a59d7 153 {
embeddedartists 0:b567d56a59d7 154 r = *(unsigned char *)(image + (height - i - 1) * rowWidthBytes + 3*x + 2);
embeddedartists 0:b567d56a59d7 155 g = *(unsigned char *)(image + (height - i - 1) * rowWidthBytes + 3*x + 1);
embeddedartists 0:b567d56a59d7 156 b = *(unsigned char *)(image + (height - i - 1) * rowWidthBytes + 3*x + 0);
embeddedartists 0:b567d56a59d7 157 *(unsigned short *)(buffer + (i * width) * 2 + 2*x) = (((unsigned short)r & 0xF8) << 8) |
embeddedartists 0:b567d56a59d7 158 (((unsigned short)g & 0xFC) << 3) |
embeddedartists 0:b567d56a59d7 159 (((unsigned short)b & 0xF8) >> 3);
embeddedartists 0:b567d56a59d7 160 }
embeddedartists 0:b567d56a59d7 161 #else
embeddedartists 0:b567d56a59d7 162 memcpy(buffer + (i * width) * 3,
embeddedartists 0:b567d56a59d7 163 image + ((height - i - 1) * width) * 3,
embeddedartists 0:b567d56a59d7 164 width * 3);
embeddedartists 0:b567d56a59d7 165 #endif
embeddedartists 0:b567d56a59d7 166 }
embeddedartists 0:b567d56a59d7 167
embeddedartists 0:b567d56a59d7 168 #if 0
embeddedartists 0:b567d56a59d7 169 // Swap red and blue
embeddedartists 0:b567d56a59d7 170 for (i=0; i < height; i++) {
embeddedartists 0:b567d56a59d7 171 for (j=0; j < width; j++) {
embeddedartists 0:b567d56a59d7 172
embeddedartists 0:b567d56a59d7 173 r = buffer[(i * width + j) * 3 + 2];
embeddedartists 0:b567d56a59d7 174 g = buffer[(i * width + j) * 3 + 1];
embeddedartists 0:b567d56a59d7 175 b = buffer[(i * width + j) * 3];
embeddedartists 0:b567d56a59d7 176
embeddedartists 0:b567d56a59d7 177 buffer[(i * width + j) * 3] = r;
embeddedartists 0:b567d56a59d7 178 buffer[(i * width + j) * 3 + 1] = g;
embeddedartists 0:b567d56a59d7 179 buffer[(i * width + j) * 3 + 2] = b;
embeddedartists 0:b567d56a59d7 180 }
embeddedartists 0:b567d56a59d7 181 }
embeddedartists 0:b567d56a59d7 182 #endif
embeddedartists 0:b567d56a59d7 183 }
embeddedartists 0:b567d56a59d7 184 else if (header->bits == 8) {
embeddedartists 0:b567d56a59d7 185
embeddedartists 0:b567d56a59d7 186 // Retrieve palette
embeddedartists 0:b567d56a59d7 187 struct BMPPaletteEntry palette[256];
embeddedartists 0:b567d56a59d7 188 memcpy(palette,
embeddedartists 0:b567d56a59d7 189 (unsigned char *) ((unsigned int) file + sizeof(struct BMPHeader)),
embeddedartists 0:b567d56a59d7 190 header->offset - sizeof(struct BMPHeader));
embeddedartists 0:b567d56a59d7 191
embeddedartists 0:b567d56a59d7 192 // Decode image (reversing row order)
embeddedartists 0:b567d56a59d7 193 for (i=0; i < height; i++) {
embeddedartists 0:b567d56a59d7 194 for (j=0; j < width; j++) {
embeddedartists 0:b567d56a59d7 195
embeddedartists 0:b567d56a59d7 196 r = palette[image[(height - i - 1) * width + j]].r;
embeddedartists 0:b567d56a59d7 197 g = palette[image[(height - i - 1) * width + j]].g;
embeddedartists 0:b567d56a59d7 198 b = palette[image[(height - i - 1) * width + j]].b;
embeddedartists 0:b567d56a59d7 199
embeddedartists 0:b567d56a59d7 200 buffer[(i * width + j) * 3] = r;
embeddedartists 0:b567d56a59d7 201 buffer[(i * width + j) * 3 + 1] = g;
embeddedartists 0:b567d56a59d7 202 buffer[(i * width + j) * 3 + 2] = b;
embeddedartists 0:b567d56a59d7 203 }
embeddedartists 0:b567d56a59d7 204 }
embeddedartists 0:b567d56a59d7 205 }
embeddedartists 0:b567d56a59d7 206 else {
embeddedartists 0:b567d56a59d7 207
embeddedartists 0:b567d56a59d7 208 printf("BMP_Decode: Input resolution not supported\n\r");
embeddedartists 0:b567d56a59d7 209 return 4;
embeddedartists 0:b567d56a59d7 210 }
embeddedartists 0:b567d56a59d7 211
embeddedartists 0:b567d56a59d7 212 return 0;
embeddedartists 0:b567d56a59d7 213 }
embeddedartists 0:b567d56a59d7 214
embeddedartists 0:b567d56a59d7 215