SAMV71 Xplained Ultra Software Package 1.5

bmp.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------- */
00002 /*                  Atmel Microcontroller Software Support                      */
00003 /*                       SAM Software Package License                           */
00004 /* ---------------------------------------------------------------------------- */
00005 /* Copyright (c) 2015, Atmel Corporation                                        */
00006 /*                                                                              */
00007 /* All rights reserved.                                                         */
00008 /*                                                                              */
00009 /* Redistribution and use in source and binary forms, with or without           */
00010 /* modification, are permitted provided that the following condition is met:    */
00011 /*                                                                              */
00012 /* - Redistributions of source code must retain the above copyright notice,     */
00013 /* this list of conditions and the disclaimer below.                            */
00014 /*                                                                              */
00015 /* Atmel's name may not be used to endorse or promote products derived from     */
00016 /* this software without specific prior written permission.                     */
00017 /*                                                                              */
00018 /* DISCLAIMER:  THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR   */
00019 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
00020 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE   */
00021 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,      */
00022 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
00023 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,  */
00024 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    */
00025 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING         */
00026 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
00027 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                           */
00028 /* ---------------------------------------------------------------------------- */
00029 
00030 /** \file */
00031 
00032 /*----------------------------------------------------------------------------
00033  *        Headers
00034  *----------------------------------------------------------------------------*/
00035 
00036 #include "board.h"
00037 #include <string.h>
00038 
00039 /*----------------------------------------------------------------------------
00040  *        Definition
00041  *----------------------------------------------------------------------------*/
00042 
00043 /// BMP offset for header
00044 #define  IMAGE_OFFSET       0x100
00045 
00046 /*----------------------------------------------------------------------------
00047  *        Internal types
00048  *----------------------------------------------------------------------------*/
00049 /** Describe the BMP palette */
00050 typedef struct _BMPPaletteEntry {
00051     /** Blue value */
00052     uint8_t b;
00053     /** Green value */
00054     uint8_t g;
00055     /** Red value */
00056     uint8_t r;
00057     /** Filler character value */
00058     uint8_t filler;
00059 } BMPPaletteEntry;
00060 
00061 /*----------------------------------------------------------------------------
00062  *        Exported functions
00063  *----------------------------------------------------------------------------*/
00064 /**
00065  * \brief Test if BMP is valid.
00066  * \param file  Buffer holding the file to examinate.
00067  * \return 1 if the header of a BMP file is valid; otherwise returns 0.
00068  */
00069 uint8_t BMP_IsValid(void *file)
00070 {
00071     return ((BMPHeader *) file)->type == BMP_TYPE;
00072 }
00073 
00074 /**
00075  * \brief Returns the size of a BMP image given at least its header (the file does
00076  * not have to be complete).
00077  * \param file  Pointer to the buffer which holds the BMP file.
00078  * \return size of BMP image
00079  */
00080 uint32_t BMP_GetFileSize(void *file)
00081 {
00082     return ((BMPHeader *) file)->fileSize;
00083 }
00084 
00085 /**
00086  * \brief Write a BMP header
00087  * \param pAddressHeader Begin address of the BMP
00088  * \param bmpHSize BMP heigth size
00089  * \param bmpVSize BMP width size
00090  * \param bmpRgb Type of BMP (YUV or RGB)
00091  * \param nbByte_Pixels Number of byte per pixels
00092  */
00093 void WriteBMPheader(uint32_t *pAddressHeader, uint32_t  bmpHSize,
00094                      uint32_t  bmpVSize, uint8_t nbByte_Pixels)
00095 {
00096     uint32_t i;
00097     uint32_t *fill;
00098     BMPHeader *Header;
00099 
00100     fill = pAddressHeader;
00101 
00102     for (i = 0; i < IMAGE_OFFSET; i += 4)
00103         * fill++ = 0;
00104 
00105     Header = (BMPHeader *) pAddressHeader;
00106 
00107     Header->type = BMP_TYPE;
00108     Header->fileSize = (bmpHSize * bmpVSize * nbByte_Pixels) + IMAGE_OFFSET;
00109     Header->reserved1 = 0;
00110     Header->reserved2 = 0;
00111     Header->offset = IMAGE_OFFSET;
00112     Header->headerSize = BITMAPINFOHEADER;
00113     Header->width  = bmpHSize;
00114     Header->height = bmpVSize;
00115     Header->planes = 1;
00116     Header->bits = nbByte_Pixels * 8;
00117     Header->compression = 0;
00118     Header->imageSize = bmpHSize * bmpVSize * nbByte_Pixels;
00119     Header->xresolution = 0;
00120     Header->yresolution = 0;
00121     Header->ncolours = 0;
00122     Header->importantcolours = 0;
00123 }
00124 
00125 
00126 /**
00127  * \brief Debug function, dislay BMP header
00128  * \param pAddressHeader Address of the BMP
00129  */
00130 void BMP_displayHeader(uint32_t *pAddressHeader)
00131 {
00132 #if (TRACE_LEVEL >= TRACE_LEVEL_INFO)
00133     BMPHeader *header;
00134 
00135     header = (BMPHeader *) pAddressHeader;
00136 
00137     TRACE_INFO("BMP\n\r");
00138     TRACE_INFO("type       0x%X \n\r", header->type);
00139     TRACE_INFO("fileSize   %ld \n\r", header->fileSize);
00140     TRACE_INFO("reserved1  %d \n\r", header->reserved1);
00141     TRACE_INFO("reserved2  %d \n\r", header->reserved2);
00142     TRACE_INFO("offset     %ld \n\r", header->offset);
00143     TRACE_INFO("headerSize %ld \n\r", header->headerSize);
00144     TRACE_INFO("width      %ld \n\r", header->width);
00145     TRACE_INFO("height     %ld \n\r", header->height);
00146     TRACE_INFO("planes     %d \n\r", header->planes);
00147     TRACE_INFO("bits       %d \n\r", header->bits);
00148     TRACE_INFO("compression %ld \n\r", header->compression);
00149     TRACE_INFO("imageSize   %ld \n\r", header->imageSize);
00150     TRACE_INFO("xresolution %ld \n\r", header->xresolution);
00151     TRACE_INFO("yresolution %ld \n\r", header->yresolution);
00152     TRACE_INFO("ncolours    %ld \n\r", header->ncolours);
00153     TRACE_INFO("importantcolours %ld\n\r", header->importantcolours);
00154 #else
00155     pAddressHeader = pAddressHeader;
00156 #endif
00157 }
00158 
00159 /**
00160  * \brief Loads a BMP image located at the given address, decodes it and stores the
00161  * resulting image inside the provided buffer. Image must have the specified
00162  * width & height.
00163  * If no buffer is provided, this function simply checks if it is able to
00164  * decode the image.
00165  * \param file  Buffer which holds the BMP file.
00166  * \param buffer  Buffer in which to store the decoded image.
00167  * \param width  Buffer width in pixels.
00168  * \param height  Buffer height in pixels.
00169  * \param bpp  Number of bits per pixels that the buffer stores.
00170  * \return 0 if the image has been loaded; otherwise returns an error code.
00171  */
00172 uint8_t BMP_Decode(void *file, uint8_t *buffer, uint32_t width,
00173                     uint32_t height, uint8_t bpp)
00174 {
00175     BMPHeader *header;
00176     uint32_t i, j;
00177     uint8_t r, g, b;
00178     uint8_t *image;
00179 
00180     // Read header information
00181     header = (BMPHeader *) file;
00182 
00183     // Verify that the file is valid
00184     if (!BMP_IsValid(file)) {
00185         TRACE_ERROR("BMP_Decode: File type is not 'BM' (0x%04X).\n\r", header->type);
00186 
00187         return 1;
00188     }
00189 
00190     // Check that parameters match
00191     if ((header->compression != 0) || (header->width != width)
00192          || (header->height != height)) {
00193         TRACE_ERROR("BMP_Decode: File format not supported\n\r");
00194         TRACE_ERROR(" -> .compression = %u\n\r", (unsigned int)header->compression);
00195         TRACE_ERROR(" -> .width = %u\n\r", (unsigned int)header->width);
00196         TRACE_ERROR(" -> .height = %u\n\r", (unsigned int)header->height);
00197         TRACE_ERROR(" -> .bits = %d\n\r", header->bits);
00198 
00199         return 2;
00200     }
00201 
00202     // Get image data
00203     image = (uint8_t *) ((uint32_t) file + header->offset);
00204 
00205     // Check that the bpp resolution is supported
00206     // Only a 24-bit output & 24- or 8-bit input are supported
00207     if (bpp != 24) {
00208         TRACE_ERROR("BMP_Decode: Output resolution not supported\n\r");
00209 
00210         return 3;
00211     } else {
00212         if (header->bits == 24) {
00213             // Decoding is ok
00214             if (!buffer) return 0;
00215 
00216             // Get image data (swapping red & blue)
00217             for (i = 0; i < height; i++) {
00218                 for (j = 0; j < width; j++) {
00219                     r = image[((height - i - 1) * width + j) * 3 + 2];
00220                     g = image[((height - i - 1) * width + j) * 3 + 1];
00221                     b = image[((height - i - 1) * width + j) * 3];
00222 
00223 #if defined(BOARD_LCD_RGB565)
00224                     // Interlacing
00225                     r = ((r << 1) & 0xF0) | ((g & 0x80) >> 4) | ((r & 0x80) >> 5);
00226                     g = (g << 1) & 0xF8;
00227                     b = b & 0xF8;
00228 
00229                     buffer[(i * width + j) * 3] = b;
00230                     buffer[(i * width + j) * 3 + 1] = g;
00231                     buffer[(i * width + j) * 3 + 2] = r;
00232 
00233 #else
00234                     buffer[(i * width + j) * 3] = r;
00235                     buffer[(i * width + j) * 3 + 1] = g;
00236                     buffer[(i * width + j) * 3 + 2] = b;
00237 #endif //#if defined(BOARD_LCD_RGB565)
00238                 }
00239             }
00240         } else {
00241             if (header->bits == 8) {
00242                 // Decoding is ok
00243                 if (!buffer) return 0;
00244 
00245                 // Retrieve palette
00246                 BMPPaletteEntry palette[256];
00247                 memcpy(palette, (uint8_t *) ((uint32_t) file + sizeof(BMPHeader)),
00248                         header->offset - sizeof(BMPHeader));
00249 
00250                 // Decode image (reversing row order)
00251                 for (i = 0; i < height; i++) {
00252                     for (j = 0; j < width; j++) {
00253                         r = palette[image[(height - i - 1) * width + j]].r;
00254                         g = palette[image[(height - i - 1) * width + j]].g;
00255                         b = palette[image[(height - i - 1) * width + j]].b;
00256 
00257                         buffer[(i * width + j) * 3] = r;
00258                         buffer[(i * width + j) * 3 + 1] = g;
00259                         buffer[(i * width + j) * 3 + 2] = b;
00260                     }
00261                 }
00262             } else {
00263 
00264                 TRACE_ERROR("BMP_Decode: Input resolution not supported\n\r");
00265                 TRACE_INFO("header->bits 0x%X \n\r", header->bits);
00266                 return 4;
00267             }
00268         }
00269     }
00270 
00271     return 0;
00272 }
00273 
00274 /**
00275  * \brief Convert RGB 565 to RGB 555 (RGB 555 is adapted to LCD)
00276  *
00277  * \param fileSource  Buffer which holds the RGB file
00278  * \param fileDestination  Buffer in which to store the decoded image
00279  * \param width  Buffer width in pixels.
00280  * \param height  Buffer height in pixels.
00281  * \param bpp  Number of bits per pixels that the buffer stores.
00282   */
00283 void RGB565toBGR555(uint8_t *fileSource, uint8_t *fileDestination,
00284                      uint32_t width, uint32_t height, uint8_t bpp)
00285 {
00286     uint32_t i;
00287     uint32_t j;
00288     uint32_t row;
00289 
00290     for (i = 0; i < height * (bpp / 8); i++) {
00291         row = (i * width * (bpp / 8));
00292 
00293         for (j = 0; j <= width * (bpp / 8); j += 2) {
00294             fileDestination[row + j] = ((fileSource[row + j + 1] >> 3) & 0x1F)
00295                                        | (fileSource[row + j] & 0xE0);
00296             fileDestination[row + j + 1] = (fileSource[row + j + 1] & 0x03)
00297                                            | ((fileSource[row + j] & 0x1F) << 2);
00298         }
00299     }
00300 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines