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