Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of DMBasicGUI by
bmp.cpp
00001 /* ---------------------------------------------------------------------------- 00002 * ATMEL Microcontroller Software Support - ROUSSET - 00003 * ---------------------------------------------------------------------------- 00004 * Copyright (c) 2006, Atmel Corporation 00005 00006 * All rights reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions are met: 00010 * 00011 * - Redistributions of source code must retain the above copyright notice, 00012 * this list of conditions and the disclaiimer below. 00013 * 00014 * - Redistributions in binary form must reproduce the above copyright notice, 00015 * this list of conditions and the disclaimer below in the documentation and/or 00016 * other materials provided with the distribution. 00017 * 00018 * Atmel's name may not be used to endorse or promote products derived from 00019 * this software without specific prior written permission. 00020 * 00021 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR 00022 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00023 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 00024 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, 00025 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00026 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 00027 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 00030 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 * ---------------------------------------------------------------------------- 00032 */ 00033 00034 //------------------------------------------------------------------------------ 00035 // Headers 00036 //------------------------------------------------------------------------------ 00037 00038 #include "mbed.h" 00039 #include "bmp.h" 00040 00041 //------------------------------------------------------------------------------ 00042 // Internal constants 00043 //------------------------------------------------------------------------------ 00044 00045 /// BMP magic number ('BM'). 00046 #define BMP_TYPE 0x4D42 00047 00048 //------------------------------------------------------------------------------ 00049 // Internal types 00050 //------------------------------------------------------------------------------ 00051 00052 struct BMPPaletteEntry { 00053 00054 unsigned char b; 00055 unsigned char g; 00056 unsigned char r; 00057 unsigned char filler; 00058 }; 00059 00060 //------------------------------------------------------------------------------ 00061 // Exported functions 00062 //------------------------------------------------------------------------------ 00063 00064 //------------------------------------------------------------------------------ 00065 /// Returns 1 if the header of a BMP file is valid; otherwise returns 0. 00066 /// \param file Buffer holding the file to examinate. 00067 //------------------------------------------------------------------------------ 00068 unsigned char BMP_IsValid(void *file) 00069 { 00070 return ((struct BMPHeader *) file)->type == BMP_TYPE; 00071 } 00072 00073 //------------------------------------------------------------------------------ 00074 /// Returns the size of a BMP image given at least its header (the file does 00075 /// not have to be complete). 00076 /// \param file Pointer to the buffer which holds the BMP file. 00077 //------------------------------------------------------------------------------ 00078 unsigned int BMP_GetFileSize(void *file) 00079 { 00080 return ((struct BMPHeader *) file)->fileSize; 00081 } 00082 00083 //------------------------------------------------------------------------------ 00084 /// Loads a BMP image located at the given address, decodes it and stores the 00085 /// resulting image inside the provided buffer. Image must have the specified 00086 /// width & height. 00087 /// Returns 0 if the image has been loaded; otherwise returns an error code. 00088 /// \param file Buffer which holds the BMP file. 00089 /// \param buffer Buffer in which to store the decoded image. 00090 /// \param width Buffer width in pixels. 00091 /// \param height Buffer height in pixels. 00092 /// \param bpp Number of bits per pixels that the buffer stores. 00093 //------------------------------------------------------------------------------ 00094 unsigned char BMP_Decode( 00095 void *file, 00096 unsigned char *buffer, 00097 unsigned int width, 00098 unsigned int height, 00099 unsigned char bpp, 00100 unsigned char target_bpp) // 16 or 24 00101 { 00102 struct BMPHeader *header; 00103 unsigned int i, j; 00104 unsigned char r, g, b; 00105 unsigned char *image; 00106 00107 // Read header information 00108 header = (struct BMPHeader *) file; 00109 00110 // Verify that the file is valid 00111 if (!BMP_IsValid(file)) { 00112 00113 printf("BMP_Decode: File type is not 'BM' (0x%x).\n\r", 00114 header->type); 00115 return 1; 00116 } 00117 00118 // Check that parameters match 00119 if ((header->compression != 0) 00120 || (header->width != width) 00121 || (header->height != height)) { 00122 00123 printf("BMP_Decode: File format not supported\n\r"); 00124 printf(" -> .compression = %d\n\r", header->compression); 00125 printf(" -> .width = %d\n\r", header->width); 00126 printf(" -> .height = %d\n\r", header->height); 00127 printf(" -> .bits = %d\n\r", header->bits); 00128 return 2; 00129 } 00130 00131 // Get image data 00132 image = (unsigned char *) ((unsigned int) file + header->offset); 00133 00134 // Check that the bpp resolution is supported 00135 // Only a 24-bit output & 24- or 8-bit input are supported 00136 if (bpp != 24) { 00137 00138 printf("BMP_Decode: Output resolution not supported\n\r"); 00139 return 3; 00140 } 00141 else if (header->bits == 24) { 00142 00143 // Modified by Embedded Artists. This padding was not handled in the original 00144 // implementation. Each row in the Pixel Array is padded to a multiple of 4 bytes in size 00145 int rowWidthBytes = width * 3; 00146 rowWidthBytes += (rowWidthBytes % 4); 00147 00148 // Copy raw data from BMP to buffer (reversing row order) 00149 for (i=0; i < height; i++) { 00150 #if 1 00151 if (target_bpp == 16) { 00152 // Modified by Embedded Artists to convert to 565-format instead of 24 bit 00153 for(unsigned int x=0; x<width; x++) 00154 { 00155 r = *(unsigned char *)(image + (height - i - 1) * rowWidthBytes + 3*x + 2); 00156 g = *(unsigned char *)(image + (height - i - 1) * rowWidthBytes + 3*x + 1); 00157 b = *(unsigned char *)(image + (height - i - 1) * rowWidthBytes + 3*x + 0); 00158 *(unsigned short *)(buffer + (i * width) * 2 + 2*x) = (((unsigned short)r & 0xF8) << 8) | 00159 (((unsigned short)g & 0xFC) << 3) | 00160 (((unsigned short)b & 0xF8) >> 3); 00161 } 00162 } else { 00163 // Modified by Embedded Artists to add alpha channel in 24 bit output 00164 for(unsigned int x=0; x<width; x++) 00165 { 00166 r = *(unsigned char *)(image + (height - i - 1) * rowWidthBytes + 3*x + 2); 00167 g = *(unsigned char *)(image + (height - i - 1) * rowWidthBytes + 3*x + 1); 00168 b = *(unsigned char *)(image + (height - i - 1) * rowWidthBytes + 3*x + 0); 00169 *(unsigned int *)(buffer + (i * width) * 4 + 4*x) = (r << 16) | (g << 8) | b; 00170 } 00171 } 00172 #else 00173 memcpy(buffer + (i * width) * 3, 00174 image + ((height - i - 1) * width) * 3, 00175 width * 3); 00176 #endif 00177 } 00178 00179 #if 0 00180 // Swap red and blue 00181 for (i=0; i < height; i++) { 00182 for (j=0; j < width; j++) { 00183 00184 r = buffer[(i * width + j) * 3 + 2]; 00185 g = buffer[(i * width + j) * 3 + 1]; 00186 b = buffer[(i * width + j) * 3]; 00187 00188 buffer[(i * width + j) * 3] = r; 00189 buffer[(i * width + j) * 3 + 1] = g; 00190 buffer[(i * width + j) * 3 + 2] = b; 00191 } 00192 } 00193 #endif 00194 } 00195 else if (header->bits == 8) { 00196 00197 // Retrieve palette 00198 struct BMPPaletteEntry palette[256]; 00199 memcpy(palette, 00200 (unsigned char *) ((unsigned int) file + sizeof(struct BMPHeader)), 00201 header->offset - sizeof(struct BMPHeader)); 00202 00203 // Decode image (reversing row order) 00204 for (i=0; i < height; i++) { 00205 for (j=0; j < width; j++) { 00206 00207 r = palette[image[(height - i - 1) * width + j]].r; 00208 g = palette[image[(height - i - 1) * width + j]].g; 00209 b = palette[image[(height - i - 1) * width + j]].b; 00210 00211 buffer[(i * width + j) * 3] = r; 00212 buffer[(i * width + j) * 3 + 1] = g; 00213 buffer[(i * width + j) * 3 + 2] = b; 00214 } 00215 } 00216 } 00217 else { 00218 00219 printf("BMP_Decode: Input resolution not supported\n\r"); 00220 return 4; 00221 } 00222 00223 return 0; 00224 } 00225
Generated on Wed Jul 13 2022 03:01:50 by
1.7.2
