]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A5_SAMA5D4x_EK_IAR/AtmelFiles/libboard_sama5d4x-ek/source/bmp.c
Core kernel files:
[freertos] / FreeRTOS / Demo / CORTEX_A5_SAMA5D4x_EK_IAR / AtmelFiles / libboard_sama5d4x-ek / source / bmp.c
1 /* ----------------------------------------------------------------------------\r
2  *         SAM Software Package License\r
3  * ----------------------------------------------------------------------------\r
4  * Copyright (c) 2011, Atmel Corporation\r
5  *\r
6  * All rights reserved.\r
7  *\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
10  *\r
11  * - Redistributions of source code must retain the above copyright notice,\r
12  * this list of conditions and the disclaimer below.\r
13  *\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
16  *\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
28  */\r
29 \r
30 /** \file */\r
31 \r
32 /*----------------------------------------------------------------------------\r
33  *        Headers\r
34  *----------------------------------------------------------------------------*/\r
35 \r
36 #include "board.h"\r
37 #include <string.h>\r
38 \r
39 /*----------------------------------------------------------------------------\r
40  *        Definition\r
41  *----------------------------------------------------------------------------*/\r
42 \r
43 /// BMP offset for header\r
44 #define  IMAGE_OFFSET       0x100\r
45 \r
46 /*----------------------------------------------------------------------------\r
47  *        Internal types\r
48  *----------------------------------------------------------------------------*/\r
49 /** Describe the BMP palette */\r
50 typedef struct _BMPPaletteEntry\r
51 {\r
52     /** Blue value */\r
53     uint8_t b;\r
54     /** Green value */\r
55     uint8_t g;\r
56     /** Red value */\r
57     uint8_t r;\r
58     /** Filler character value */\r
59     uint8_t filler;\r
60 } BMPPaletteEntry ;\r
61 \r
62 /*----------------------------------------------------------------------------\r
63  *        Exported functions\r
64  *----------------------------------------------------------------------------*/\r
65 /**\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
69  */\r
70 uint8_t BMP_IsValid( void *file )\r
71 {\r
72     return ((BMPHeader*) file)->type == BMP_TYPE ;\r
73 }\r
74 \r
75 /**\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
80  */\r
81 uint32_t BMP_GetFileSize( void *file )\r
82 {\r
83     return ((BMPHeader *) file)->fileSize ;\r
84 }\r
85 \r
86 /**\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
93  */\r
94 void WriteBMPheader( uint32_t* pAddressHeader, uint32_t  bmpHSize, uint32_t  bmpVSize, uint8_t bmpRgb, uint8_t nbByte_Pixels )\r
95 {\r
96     uint32_t i;\r
97     uint32_t* fill;\r
98     BMPHeader *Header;\r
99     bmpRgb = bmpRgb;\r
100 \r
101     fill = pAddressHeader;\r
102     for ( i=0 ; i < IMAGE_OFFSET ; i+=4 )\r
103     {\r
104         *fill++ = 0;\r
105     }\r
106 \r
107     Header = (BMPHeader*) pAddressHeader;\r
108 \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
125 }\r
126 \r
127 \r
128 /**\r
129  * \brief Debug function, dislay BMP header\r
130  * \param pAddressHeader Address of the BMP\r
131  */\r
132 void BMP_displayHeader( uint32_t* pAddressHeader )\r
133 {\r
134   #if (TRACE_LEVEL >= TRACE_LEVEL_INFO)\r
135     BMPHeader *header;\r
136 \r
137     header = (BMPHeader*) pAddressHeader;\r
138     \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
156   #else\r
157     pAddressHeader = pAddressHeader;\r
158   #endif\r
159 }\r
160 \r
161 /**\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
164  * width & height.\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
173  */\r
174 uint8_t BMP_Decode( void *file, uint8_t *buffer, uint32_t width, uint32_t height, uint8_t bpp )\r
175 {\r
176     BMPHeader *header;\r
177     uint32_t i, j;\r
178     uint8_t r, g, b;\r
179     uint8_t *image;\r
180 \r
181     // Read header information\r
182     header = (BMPHeader*) file;\r
183 \r
184     // Verify that the file is valid\r
185     if ( !BMP_IsValid( file ) )\r
186     {\r
187         TRACE_ERROR("BMP_Decode: File type is not 'BM' (0x%04X).\n\r",header->type);\r
188 \r
189         return 1;\r
190     }\r
191 \r
192     // Check that parameters match\r
193     if ( (header->compression != 0) || (header->width != width) || (header->height != height))\r
194     {\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
200 \r
201         return 2;\r
202     }\r
203 \r
204     // Get image data\r
205     image = (uint8_t *) ((uint32_t) file + header->offset);\r
206 \r
207     // Check that the bpp resolution is supported\r
208     // Only a 24-bit output & 24- or 8-bit input are supported\r
209     if ( bpp != 24 )\r
210     {\r
211         TRACE_ERROR("BMP_Decode: Output resolution not supported\n\r");\r
212 \r
213         return 3;\r
214     }\r
215     else\r
216     {\r
217         if (header->bits == 24)\r
218         {\r
219             // Decoding is ok\r
220             if (!buffer) return 0;\r
221 \r
222             // Get image data (swapping red & blue)\r
223             for ( i=0 ; i < height ; i++ )\r
224             {\r
225                 for ( j=0 ; j < width; j++ )\r
226                 {\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
230 \r
231     #if defined(BOARD_LCD_RGB565)\r
232                     // Interlacing\r
233                     r = ((r << 1) & 0xF0) | ((g & 0x80) >> 4) | ((r & 0x80) >> 5);\r
234                     g = (g << 1) & 0xF8;\r
235                     b = b & 0xF8;\r
236 \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
240 \r
241     #else\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
246                 }\r
247             }\r
248         }\r
249         else\r
250         {\r
251             if ( header->bits == 8 )\r
252             {\r
253                 // Decoding is ok\r
254                 if (!buffer) return 0;\r
255 \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
259 \r
260                 // Decode image (reversing row order)\r
261                 for ( i=0 ; i < height ; i++ )\r
262                 {\r
263                     for (j=0; j < width; j++)\r
264                     {\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
268 \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
272                     }\r
273                 }\r
274             }\r
275             else\r
276             {\r
277 \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
280                 return 4 ;\r
281             }\r
282         }\r
283     }\r
284 \r
285     return 0 ;\r
286 }\r
287 \r
288 /**\r
289  * \brief Convert RGB 565 to RGB 555 (RGB 555 is adapted to LCD)\r
290  *\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
296   */\r
297 void RGB565toBGR555( uint8_t *fileSource, uint8_t *fileDestination, uint32_t width, uint32_t height, uint8_t bpp )\r
298 {\r
299     uint32_t i;\r
300     uint32_t j;\r
301     uint32_t row;\r
302 \r
303     for (i=0; i < height*(bpp/8); i++)\r
304     {\r
305         row = (i*width*(bpp/8));\r
306 \r
307         for (j=0; j <= width*(bpp/8); j+=2)\r
308         {\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
313         }\r
314     }\r
315 }\r