# Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics

[Home] [Tutorials] [All Classes] [Grouped Classes]

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/VL/BuildSystem/VL_DISTRO/Visualization_Library_SDK/src/vlCore/plugins/vlBMP.cpp

Go to the documentation of this file.

    00001 /**************************************************************************************/
    00002 /*                                                                                    */
    00003 /*  Visualization Library                                                             */
    00004 /*  http://www.visualizationlibrary.com                                               */
    00005 /*                                                                                    */
    00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
    00007 /*  All rights reserved.                                                              */
    00008 /*                                                                                    */
    00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
    00010 /*  are permitted provided that the following conditions are met:                     */
    00011 /*                                                                                    */
    00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
    00013 /*  list of conditions and the following disclaimer.                                  */
    00014 /*                                                                                    */
    00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
    00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
    00017 /*  other materials provided with the distribution.                                   */
    00018 /*                                                                                    */
    00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
    00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
    00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
    00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
    00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
    00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
    00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
    00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
    00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
    00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
    00029 /*                                                                                    */
    00030 /**************************************************************************************/
    00031
    00032 #include "vlBMP.hpp"
    00033 #include <vlCore/LoadWriterManager.hpp>
    00034 #include <vlCore/VisualizationLibrary.hpp>
    00035 #include <vlCore/FileSystem.hpp>
    00036 #include <vlCore/VirtualFile.hpp>
    00037 #include <vlCore/Image.hpp>
    00038
    00039 using namespace vl;
    00040
    00041 #include <vlCore/ImageTools.hpp>
    00042
    00043 //-----------------------------------------------------------------------------
    00044 // BMP loader
    00045 //-----------------------------------------------------------------------------
    00046 namespace
    00047 {
    00048   typedef struct
    00049   {
    00050     char mType[2];
    00051     char mSize[4];
    00052     char mReserved1[2];
    00053     char mReserved2[2];
    00054     char mOffBits[4];
    00055
    00056     unsigned short Type() const { return *(const unsigned short*)mType; }
    00057     unsigned int  Size() const { return *(const unsigned int*)mSize; }
    00058     unsigned short Reserved1() const { return *(const unsigned short*)mReserved1; }
    00059     unsigned short Reserved2() const { return *(const unsigned short*)mReserved2; }
    00060     unsigned int  OffBits() const { return *(const unsigned int*)mOffBits; }
    00061   } BitmapFileHeader;
    00062
    00063   typedef struct
    00064   {
    00065     unsigned int Size() { return *(unsigned int*)mSize; }
    00066     int Width() { return *(int*)mWidth; }
    00067     int Height() { return *(int*)mHeight; }
    00068     unsigned short Planes() { return *(unsigned short*)mPlanes; }
    00069     unsigned short BitCount() { return *(unsigned short*)mBitCount; }
    00070     unsigned int Compression() { return *(unsigned int*)mCompression; }
    00071     unsigned int SizeImage() { return *(unsigned int*)mSizeImage; }
    00072     int XPelsPerMeter() { return *(int*)mXPelsPerMeter; }
    00073     int YPelsPerMeter() { return *(int*)mYPelsPerMeter; }
    00074     unsigned int ClrUsed() { return *(unsigned int*)mClrUsed; }
    00075     unsigned int ClrImportant() { return *(unsigned int*)mClrImportant; }
    00076
    00077     char mSize[4];
    00078     char mWidth[4];
    00079     char mHeight[4];
    00080     char mPlanes[2];
    00081     char mBitCount[2];
    00082     char  mCompression[4];
    00083     char  mSizeImage[4];
    00084     char mXPelsPerMeter[4];
    00085     char mYPelsPerMeter[4];
    00086     char mClrUsed[4];
    00087     char mClrImportant[4];
    00088   } BitmapInfoHeader;
    00089
    00090   const unsigned int BMP_NoCompression  = 0;
    00091   const unsigned int BMP_XRGB  = 3;
    00092   // RLE8 = 1L;
    00093   // RLE4 = 2L;
    00094   // JPEG = 4L;
    00095   // PNG  = 5L;
    00096 }
    00097 //-----------------------------------------------------------------------------
    00104 ref<Image> vl::loadBMP( const String& path )
    00105 {
    00106   ref<VirtualFile> file = defFileSystem()->locateFile(path);
    00107   if ( !file )
    00108   {
    00109     Log::error( Say("File '%s' not found.\n") << path );
    00110     return NULL;
    00111   }
    00112
    00113   return loadBMP(file.get());
    00114 }
    00115 //-----------------------------------------------------------------------------
    00116 ref<Image> vl::loadBMP( VirtualFile* file )
    00117 {
    00118   if ( !file->open(OM_ReadOnly) )
    00119   {
    00120     Log::error( Say("loadBMP: error opening file: '%s'\n") << file->path() );
    00121     return NULL;
    00122   }
    00123
    00124   ref<Image> img = new Image;
    00125   img->setObjectName(file->path().toStdString());
    00126
    00127   BitmapFileHeader bfh;
    00128   memset(&bfh, 0, sizeof(bfh));
    00129   BitmapInfoHeader bih;
    00130   memset(&bih, 0, sizeof(bih));
    00131
    00132   file->read(&bfh, sizeof(bfh));
    00133   if (bfh.Type() != 0x4D42)
    00134   {
    00135     file->close();
    00136     Log::error( Say("The file '%s' is not a BMP file.\n") << file->path() );
    00137     return NULL;
    00138   }
    00139
    00140   int head = (int)file->position();
    00141
    00142   file->read(&bih, sizeof(bih));
    00143
    00144   bool flip = false;
    00145   if ( bih.Height() < 0 )
    00146   {
    00147     int *h = (int*)bih.mHeight;
    00148     *h = -*h;
    00149     flip = true;
    00150   }
    00151   VL_CHECK( bih.Height() * bih.Width() );
    00152
    00153   // TODO: support bih.Compression() == BMP_Type_RLE8 e BMP_XRGB meglio
    00154   if ( bih.Compression() != BMP_NoCompression && bih.Compression() != BMP_XRGB )
    00155   {
    00156     Log::error( Say("Compression %n unsupported for %s\n") << bih.Compression() << file->path() );
    00157     file->close();
    00158     return NULL;
    00159   }
    00160
    00161   switch( bih.BitCount() )
    00162   {
    00163     // 8 bit palettized
    00164     case 8:
    00165     {
    00166       img->allocate2D(bih.Width(), bih.Height(), 4, IF_BGRA, IT_UNSIGNED_BYTE);
    00167
    00168       TPalette4x256 palette;
    00169       memset(palette, 0, 256*4);
    00170
    00171       int br;
    00172       file->seekSet( (int)head + bih.Size() );
    00173       int palette_bytes = (bih.ClrUsed() ? bih.ClrUsed() : 256)*4;
    00174       br = (int)file->read(palette, palette_bytes);
    00175       /*// set alpha to 0xFF
    00176       for(int i=0; i<palette_bytes; i+=4)
    00177         palette[i+3] = 0xFF;*/
    00178       if(br != palette_bytes)
    00179       {
    00180         file->close();
    00181         Log::error( Say("File %s truncated: %n < %n.\n") << file->path() << br << palette_bytes );
    00182         return NULL;
    00183       }
    00184
    00185       int pad_bytes = (4 - (img->width() * 1) % 4) % 4;
    00186       int datasize = (img->width() * 1 + pad_bytes) * img->height();
    00187
    00188       // 8bpp uncompressed
    00189
    00190       if ( bih.Compression() == BMP_NoCompression )
    00191       {
    00192         br = (int)file->read(img->pixels(), datasize);
    00193         if(br != datasize)
    00194         {
    00195           // fclose(fin);
    00196           file->close();
    00197           Log::error( Say("file %s truncated.\n") << file->path() );
    00198           return NULL;
    00199         }
    00200       }
    00201       // BMP_Type_RLE8 not supported yet
    00202       else
    00203       {
    00204         // TODO
    00205       }
    00206
    00207       convert8ToRGBA( palette, img->pixels(), img->width(), img->height(), 4 );
    00208     } break;
    00209
    00210     case 32:
    00211     case 24:
    00212     {
    00213       img->allocate2D(bih.Width(), bih.Height(), 4, IF_BGRA, IT_UNSIGNED_BYTE);
    00214       file->seekSet(bfh.OffBits());
    00215
    00216       // usato solo se 24 bits.
    00217       int pad_bytes = (4 - (img->width() * 3) % 4) % 4;
    00218       // fa prima se lo si legge tutto insieme.
    00219       int datasize = bih.BitCount() == 32 ? img->width() * img->height() * 4 : (img->width() * 3 + pad_bytes) * img->height();
    00220       int rd = (int)file->read(img->pixels(), datasize);
    00221       if( rd < datasize )
    00222       {
    00223         file->close();
    00224         Log::error( Say("File %s truncated.\n") << file->path() );
    00225         return NULL;
    00226       }
    00227
    00228       // convert the buffer from 24 to 32bpp running from the end to the begining.
    00229       if (bih.BitCount() == 24)
    00230         convertRGBToRGBA(img->pixels(), img->width(), img->height(), 0xFF, 4);
    00231
    00232     } break;
    00233
    00234     default:
    00235     {
    00236       file->close();
    00237       Log::error( Say("BitCount %n unsupported for %s\n") << (int)bih.BitCount() << file->path() );
    00238       return NULL;
    00239     }
    00240   }
    00241
    00242   file->close();
    00243
    00244   // convert BGRA to RGBA
    00245   img = img->convertFormat(IF_RGBA);
    00246
    00247   // set alpha channel to 0xFF
    00248   for(int h=0; h<img->height(); ++h)
    00249   {
    00250     unsigned char* px = img->pixels() + img->pitch()*h;
    00251     for(int x=0; x<img->width()*4; x+=4)
    00252       px[x+3] = 0xFF;
    00253   }
    00254
    00255   // flip the image
    00256   if (flip)
    00257     img->flipVertically();
    00258
    00259   return img;
    00260 }
    00261 //-----------------------------------------------------------------------------
    00262 bool vl::isBMP(VirtualFile* file)
    00263 {
    00264   if (!file->open(OM_ReadOnly))
    00265     return false;
    00266
    00267   BitmapFileHeader bfh;
    00268   memset(&bfh, 0, sizeof(bfh));
    00269   BitmapInfoHeader bih;
    00270   memset(&bih, 0, sizeof(bih));
    00271
    00272   file->read(&bfh, sizeof(bfh));
    00273   file->read(&bih, sizeof(bih));
    00274   file->close();
    00275
    00276   if (bfh.Type() != 0x4D42)
    00277   {
    00278     return false;
    00279   }
    00280
    00281   // check bit count
    00282   switch( bih.BitCount() )
    00283   {
    00284   case 1:
    00285   case 4:
    00286   case 8:
    00287   case 16:
    00288   case 24:
    00289   case 32:
    00290     break;
    00291   default:
    00292     return false;
    00293   }
    00294
    00295   // check compression
    00296   switch( bih.Compression() )
    00297   {
    00298   case 0:
    00299   case 1:
    00300   case 2:
    00301   case 3:
    00302   case 4:
    00303   case 5:
    00304     break;
    00305   default:
    00306     return false;
    00307   }
    00308
    00309   return true;
    00310 }
    00311 //-----------------------------------------------------------------------------

Visualization Library v2011.05.1142 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 26 2011 22:51:21.
Permission is granted to use this page to write and publish articles regarding Visualization Library.