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