TextureBitmap.cpp

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 2002  Ryan Nunn and The Pentagram Team
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  */
00018 
00019 #include "pent_include.h"
00020 #include "TextureBitmap.h"
00021 #include "IDataSource.h"
00022 
00023 // graphics defines
00024 #define BITMAP_ID            0x4D42 // universal id for a bitmap
00025 
00026 //
00027 // Bitmap Header
00028 //
00029 struct BMPHeader {
00030                 uint16          bfType;
00031                 uint32          bfSize;
00032                 uint16          bfReserved1;
00033                 uint16          bfReserved2;
00034                 uint32          bfOffBits;
00035 
00036                 void Read(IDataSource *ds) {
00037                         bfType = ds->read2();
00038                         bfSize = ds->read4();
00039                         bfReserved1 = ds->read2();
00040                         bfReserved2 = ds->read2();
00041                         bfOffBits = ds->read4();
00042                 }
00043 };
00044 
00045 //
00046 // Bitmap Info Header
00047 //
00048 struct BMPInfoHeader {
00049                 uint32          biSize;
00050                 sint32          biWidth;
00051                 sint32          biHeight;
00052                 uint16          biPlanes;
00053                 uint16          biBitCount;
00054                 uint32          biCompression;
00055                 uint32          biSizeImage;
00056                 sint32          biXPelsPerMeter;
00057                 sint32          biYPelsPerMeter;
00058                 uint32          biClrUsed;
00059                 uint32          biClrImportant;
00060 
00061                 void Read(IDataSource *ds) {
00062                         biSize = ds->read4();
00063                         biWidth = ds->read4();
00064                 biHeight = ds->read4();
00065                 biPlanes = ds->read2();
00066                 biBitCount = ds->read2();
00067                 biCompression = ds->read4();
00068                 biSizeImage = ds->read4();
00069                 biXPelsPerMeter = ds->read4();
00070                 biYPelsPerMeter = ds->read4();
00071                 biClrUsed = ds->read4();
00072                 biClrImportant = ds->read4();
00073                 }
00074 };
00075 
00076 
00077 //
00078 // Read from a Data Source
00079 //
00080 bool TextureBitmap::Read(IDataSource *ds)
00081 {
00082         // Seek to start
00083         ds->seek(0);
00084 
00085     // looping index
00086         int index;
00087         
00088         // used to convert images to 32 bit
00089         uint8 *temp_buffer = NULL; 
00090 
00091         // this contains the bitmapfile header
00092         BMPHeader               bitmapfileheader;       
00093 
00094         // this is all the info including the palette
00095         BMPInfoHeader   bitmapinfoheader;       
00096         
00097         // now load the bitmap file header
00098         bitmapfileheader.Read(ds);
00099 
00100         // test if this is a bitmap file, if not return false
00101         if (bitmapfileheader.bfType!=BITMAP_ID) return false;
00102         
00103         // now we know this is a bitmap, so read in all the sections
00104         // first the bitmap infoheader
00105         bitmapinfoheader.Read(ds);
00106         
00107         // now load the color palette if there is one
00108         uint8 palette[768];
00109         if (bitmapinfoheader.biBitCount == 8)
00110         {
00111                 for (index=0; index < 256; index++)
00112                 {
00113                         palette[index*3] = ds->read1();
00114                         palette[index*3+1] = ds->read1();
00115                         palette[index*3+2] = ds->read1();
00116                         ds->skip(1);
00117                         
00118                 }
00119                 
00120     }
00121         
00122         // finally the image data itself
00123         ds->seek(ds->getSize()-bitmapinfoheader.biSizeImage);
00124         
00125         // allocate temporary buffer
00126         if (0 == (temp_buffer = new uint8 [bitmapinfoheader.biSizeImage]))
00127                 return false;
00128 
00129         // allocate final 32 bit storage buffer
00130         if (0 == (buffer=new uint32[bitmapinfoheader.biWidth * bitmapinfoheader.biHeight]))
00131         {
00132                 // release working buffer
00133                 delete [] temp_buffer;
00134                 
00135                 // return error
00136                 return false;
00137         } // end if
00138         
00139         // now read it in
00140         ds->read(static_cast<uint8 *>(temp_buffer),bitmapinfoheader.biSizeImage);
00141 
00142         // 8 Bit Palette
00143         if (bitmapinfoheader.biBitCount == 8) {
00144                 for (index=0; index<bitmapinfoheader.biWidth*bitmapinfoheader.biHeight; index++)
00145                 {
00146                         // extract RGB components (in BGR order), note the scaling
00147                         uint8 palindex = temp_buffer[index];
00148 
00149                         int row = index / bitmapinfoheader.biWidth;
00150                         int write = index % bitmapinfoheader.biWidth;
00151                         write += (bitmapinfoheader.biHeight-1-row) * bitmapinfoheader.biWidth;
00152                         
00153                         buffer[write] = (palette[palindex*3 + TEX32_B_SHIFT])
00154                                 | (palette[palindex*3 + 1] << TEX32_G_SHIFT)
00155                                 | (palette[palindex*3 + 2] << TEX32_R_SHIFT)
00156                                 | (255 << TEX32_A_SHIFT);
00157 
00158                 } // end for index
00159         }
00160         // 16 Bit High Colour
00161         else if (bitmapinfoheader.biBitCount == 16) {
00162                 // Colour shifting values
00163                 #define UNPACK_BMP16(pix,r,g,b) { r = static_cast<uint8>((((pix)&31)>>10)<<5); g = static_cast<uint8>((((pix)&31)>>5)<<5); b = static_cast<uint8>(((pix)&31)<<5); }
00164 
00165                 for (index=0; index<bitmapinfoheader.biWidth*bitmapinfoheader.biHeight; index++)
00166                 {
00167                         // extract RGB components, and pack them into an int
00168                         uint8 red, green, blue ;
00169                         uint16 color = temp_buffer[index*2 + 0] | (temp_buffer[index*2 + 1]<<8);
00170                         UNPACK_BMP16(color,red,green,blue);
00171 
00172                         int row = index / bitmapinfoheader.biWidth;
00173                         int write = index % bitmapinfoheader.biWidth;
00174                         write += (bitmapinfoheader.biHeight-1-row) * bitmapinfoheader.biWidth;
00175                         
00176 
00177                         buffer[write] = (blue << TEX32_B_SHIFT)
00178                                 | (green << TEX32_G_SHIFT)
00179                                 | (red << TEX32_R_SHIFT) 
00180                                 | (255 << TEX32_A_SHIFT);
00181                 }
00182         }
00183         // 24 Bit True Colour
00184         else if (bitmapinfoheader.biBitCount == 24) {
00185                 for (index=0; index<bitmapinfoheader.biWidth*bitmapinfoheader.biHeight; index++)
00186                 {
00187                         int row = index / bitmapinfoheader.biWidth;
00188                         int write = index % bitmapinfoheader.biWidth;
00189                         write += (bitmapinfoheader.biHeight-1-row) * bitmapinfoheader.biWidth;
00190 
00191                         // extract RGB components, and pack them into an int
00192                         buffer[write] = (temp_buffer[index*3 + 0] << TEX32_B_SHIFT)
00193                                 | (temp_buffer[index*3 + 1] << TEX32_G_SHIFT) 
00194                                 | (temp_buffer[index*3 + 2] << TEX32_R_SHIFT) 
00195                                 | (255 << TEX32_A_SHIFT);
00196 
00197                 }
00198         }
00199         
00200         // Make sure the width and height are correctly copied
00201         width = bitmapinfoheader.biWidth;
00202         height = bitmapinfoheader.biHeight;
00203         format = TEX_FMT_STANDARD;
00204         
00205         // Calc texture log2's 
00206         CalcLOG2s();
00207 
00208         // return success
00209         return true;
00210         
00211 }

Generated on Fri Jul 27 22:27:41 2007 for pentagram by  doxygen 1.4.7