SAMV71 Xplained Ultra Software Package 1.4

bmp.c

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