1 /* ----------------------------------------------------------------------------
\r
2 * SAM Software Package License
\r
3 * ----------------------------------------------------------------------------
\r
4 * Copyright (c) 2011, Atmel Corporation
\r
6 * All rights reserved.
\r
8 * Redistribution and use in source and binary forms, with or without
\r
9 * modification, are permitted provided that the following conditions are met:
\r
11 * - Redistributions of source code must retain the above copyright notice,
\r
12 * this list of conditions and the disclaimer below.
\r
14 * Atmel's name may not be used to endorse or promote products derived from
\r
15 * this software without specific prior written permission.
\r
17 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
\r
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
\r
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
\r
20 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
\r
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
\r
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
\r
23 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
\r
24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
\r
25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
\r
26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
27 * ----------------------------------------------------------------------------
\r
32 /*----------------------------------------------------------------------------
\r
34 *----------------------------------------------------------------------------*/
\r
39 /*----------------------------------------------------------------------------
\r
41 *----------------------------------------------------------------------------*/
\r
43 /// BMP offset for header
\r
44 #define IMAGE_OFFSET 0x100
\r
46 /*----------------------------------------------------------------------------
\r
48 *----------------------------------------------------------------------------*/
\r
49 /** Describe the BMP palette */
\r
50 typedef struct _BMPPaletteEntry
\r
58 /** Filler character value */
\r
62 /*----------------------------------------------------------------------------
\r
63 * Exported functions
\r
64 *----------------------------------------------------------------------------*/
\r
66 * \brief Test if BMP is valid.
\r
67 * \param file Buffer holding the file to examinate.
\r
68 * \return 1 if the header of a BMP file is valid; otherwise returns 0.
\r
70 uint8_t BMP_IsValid( void *file )
\r
72 return ((BMPHeader*) file)->type == BMP_TYPE ;
\r
76 * \brief Returns the size of a BMP image given at least its header (the file does
\r
77 * not have to be complete).
\r
78 * \param file Pointer to the buffer which holds the BMP file.
\r
79 * \return size of BMP image
\r
81 uint32_t BMP_GetFileSize( void *file )
\r
83 return ((BMPHeader *) file)->fileSize ;
\r
87 * \brief Write a BMP header
\r
88 * \param pAddressHeader Begin address of the BMP
\r
89 * \param bmpHSize BMP heigth size
\r
90 * \param bmpVSize BMP width size
\r
91 * \param bmpRgb Type of BMP (YUV or RGB)
\r
92 * \param nbByte_Pixels Number of byte per pixels
\r
94 void WriteBMPheader( uint32_t* pAddressHeader, uint32_t bmpHSize, uint32_t bmpVSize, uint8_t bmpRgb, uint8_t nbByte_Pixels )
\r
101 fill = pAddressHeader;
\r
102 for ( i=0 ; i < IMAGE_OFFSET ; i+=4 )
\r
107 Header = (BMPHeader*) pAddressHeader;
\r
109 Header->type = BMP_TYPE;
\r
110 Header->fileSize = (bmpHSize * bmpVSize * nbByte_Pixels) + IMAGE_OFFSET;
\r
111 Header->reserved1 = 0;
\r
112 Header->reserved2 = 0;
\r
113 Header->offset = IMAGE_OFFSET;
\r
114 Header->headerSize = BITMAPINFOHEADER;
\r
115 Header->width = bmpHSize;
\r
116 Header->height = bmpVSize;
\r
117 Header->planes = 1;
\r
118 Header->bits = nbByte_Pixels * 8;
\r
119 Header->compression = 0;
\r
120 Header->imageSize = bmpHSize * bmpVSize * nbByte_Pixels;
\r
121 Header->xresolution = 0;
\r
122 Header->yresolution = 0;
\r
123 Header->ncolours = 0;
\r
124 Header->importantcolours = 0;
\r
129 * \brief Debug function, dislay BMP header
\r
130 * \param pAddressHeader Address of the BMP
\r
132 void BMP_displayHeader( uint32_t* pAddressHeader )
\r
134 #if (TRACE_LEVEL >= TRACE_LEVEL_INFO)
\r
137 header = (BMPHeader*) pAddressHeader;
\r
139 TRACE_INFO("BMP\n\r");
\r
140 TRACE_INFO("type 0x%X \n\r", header->type);
\r
141 TRACE_INFO("fileSize %ld \n\r", header->fileSize);
\r
142 TRACE_INFO("reserved1 %d \n\r", header->reserved1);
\r
143 TRACE_INFO("reserved2 %d \n\r", header->reserved2);
\r
144 TRACE_INFO("offset %ld \n\r", header->offset);
\r
145 TRACE_INFO("headerSize %ld \n\r", header->headerSize);
\r
146 TRACE_INFO("width %ld \n\r", header->width);
\r
147 TRACE_INFO("height %ld \n\r", header->height);
\r
148 TRACE_INFO("planes %d \n\r", header->planes);
\r
149 TRACE_INFO("bits %d \n\r", header->bits);
\r
150 TRACE_INFO("compression %ld \n\r", header->compression);
\r
151 TRACE_INFO("imageSize %ld \n\r", header->imageSize);
\r
152 TRACE_INFO("xresolution %ld \n\r", header->xresolution);
\r
153 TRACE_INFO("yresolution %ld \n\r", header->yresolution);
\r
154 TRACE_INFO("ncolours %ld \n\r", header->ncolours);
\r
155 TRACE_INFO("importantcolours %ld\n\r", header->importantcolours);
\r
157 pAddressHeader = pAddressHeader;
\r
162 * \brief Loads a BMP image located at the given address, decodes it and stores the
\r
163 * resulting image inside the provided buffer. Image must have the specified
\r
165 * If no buffer is provided, this function simply checks if it is able to
\r
166 * decode the image.
\r
167 * \param file Buffer which holds the BMP file.
\r
168 * \param buffer Buffer in which to store the decoded image.
\r
169 * \param width Buffer width in pixels.
\r
170 * \param height Buffer height in pixels.
\r
171 * \param bpp Number of bits per pixels that the buffer stores.
\r
172 * \return 0 if the image has been loaded; otherwise returns an error code.
\r
174 uint8_t BMP_Decode( void *file, uint8_t *buffer, uint32_t width, uint32_t height, uint8_t bpp )
\r
181 // Read header information
\r
182 header = (BMPHeader*) file;
\r
184 // Verify that the file is valid
\r
185 if ( !BMP_IsValid( file ) )
\r
187 TRACE_ERROR("BMP_Decode: File type is not 'BM' (0x%04X).\n\r",header->type);
\r
192 // Check that parameters match
\r
193 if ( (header->compression != 0) || (header->width != width) || (header->height != height))
\r
195 TRACE_ERROR("BMP_Decode: File format not supported\n\r");
\r
196 TRACE_ERROR(" -> .compression = %u\n\r", (unsigned int)header->compression);
\r
197 TRACE_ERROR(" -> .width = %u\n\r", (unsigned int)header->width);
\r
198 TRACE_ERROR(" -> .height = %u\n\r", (unsigned int)header->height);
\r
199 TRACE_ERROR(" -> .bits = %d\n\r", header->bits);
\r
205 image = (uint8_t *) ((uint32_t) file + header->offset);
\r
207 // Check that the bpp resolution is supported
\r
208 // Only a 24-bit output & 24- or 8-bit input are supported
\r
211 TRACE_ERROR("BMP_Decode: Output resolution not supported\n\r");
\r
217 if (header->bits == 24)
\r
220 if (!buffer) return 0;
\r
222 // Get image data (swapping red & blue)
\r
223 for ( i=0 ; i < height ; i++ )
\r
225 for ( j=0 ; j < width; j++ )
\r
227 r = image[((height - i - 1) * width + j) * 3 + 2];
\r
228 g = image[((height - i - 1) * width + j) * 3 + 1];
\r
229 b = image[((height - i - 1) * width + j) * 3];
\r
231 #if defined(BOARD_LCD_RGB565)
\r
233 r = ((r << 1) & 0xF0) | ((g & 0x80) >> 4) | ((r & 0x80) >> 5);
\r
234 g = (g << 1) & 0xF8;
\r
237 buffer[(i * width + j) * 3] = b;
\r
238 buffer[(i * width + j) * 3 + 1] = g;
\r
239 buffer[(i * width + j) * 3 + 2] = r;
\r
242 buffer[(i * width + j) * 3] = r;
\r
243 buffer[(i * width + j) * 3 + 1] = g;
\r
244 buffer[(i * width + j) * 3 + 2] = b;
\r
245 #endif //#if defined(BOARD_LCD_RGB565)
\r
251 if ( header->bits == 8 )
\r
254 if (!buffer) return 0;
\r
256 // Retrieve palette
\r
257 BMPPaletteEntry palette[256];
\r
258 memcpy( palette, (uint8_t *) ((uint32_t) file + sizeof( BMPHeader )), header->offset - sizeof( BMPHeader ) ) ;
\r
260 // Decode image (reversing row order)
\r
261 for ( i=0 ; i < height ; i++ )
\r
263 for (j=0; j < width; j++)
\r
265 r = palette[image[(height - i - 1) * width + j]].r;
\r
266 g = palette[image[(height - i - 1) * width + j]].g;
\r
267 b = palette[image[(height - i - 1) * width + j]].b;
\r
269 buffer[(i * width + j) * 3] = r;
\r
270 buffer[(i * width + j) * 3 + 1] = g;
\r
271 buffer[(i * width + j) * 3 + 2] = b;
\r
278 TRACE_ERROR("BMP_Decode: Input resolution not supported\n\r");
\r
279 TRACE_INFO("header->bits 0x%X \n\r", header->bits);
\r
289 * \brief Convert RGB 565 to RGB 555 (RGB 555 is adapted to LCD)
\r
291 * \param fileSource Buffer which holds the RGB file
\r
292 * \param fileDestination Buffer in which to store the decoded image
\r
293 * \param width Buffer width in pixels.
\r
294 * \param height Buffer height in pixels.
\r
295 * \param bpp Number of bits per pixels that the buffer stores.
\r
297 void RGB565toBGR555( uint8_t *fileSource, uint8_t *fileDestination, uint32_t width, uint32_t height, uint8_t bpp )
\r
303 for (i=0; i < height*(bpp/8); i++)
\r
305 row = (i*width*(bpp/8));
\r
307 for (j=0; j <= width*(bpp/8); j+=2)
\r
309 fileDestination[row+j] = ((fileSource[row+j+1]>>3)&0x1F)
\r
310 | (fileSource[row+j]&0xE0);
\r
311 fileDestination[row+j+1] = (fileSource[row+j+1]&0x03)
\r
312 | ((fileSource[row+j]&0x1F)<<2);
\r