targa_reader.cpp

Go to the documentation of this file.
00001 /*
00002   CLAW - a C++ Library Absolutely Wonderful
00003 
00004   CLAW is a free library without any particular aim but being useful to 
00005   anyone.
00006 
00007   Copyright (C) 2005-2008 Julien Jorge
00008 
00009   This library is free software; you can redistribute it and/or
00010   modify it under the terms of the GNU Lesser General Public
00011   License as published by the Free Software Foundation; either
00012   version 2.1 of the License, or (at your option) any later version.
00013 
00014   This library is distributed in the hope that it will be useful,
00015   but WITHOUT ANY WARRANTY; without even the implied warranty of
00016   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017   Lesser General Public License for more details.
00018 
00019   You should have received a copy of the GNU Lesser General Public
00020   License along with this library; if not, write to the Free Software
00021   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00022 
00023   contact: julien_jorge@yahoo.fr
00024 */
00030 #include <claw/targa.hpp>
00031 #include <claw/exception.hpp>
00032 
00033 
00034 
00035 //********************* targa::reader::file_input_buffer ***********************
00036 
00037 
00038 
00039 namespace claw
00040 {
00041   namespace graphic
00042   {
00043     /*------------------------------------------------------------------------*/
00050     template< >
00051     pixel32 targa::reader::file_input_buffer<pixel32>::get_pixel()
00052     {
00053       pixel32 result;
00054       
00055       if ( this->remaining() < 4 )
00056         this->read_more(4);
00057       
00058       assert( this->remaining() >= 4 );
00059       
00060       result.components.blue  = this->get_next();
00061       result.components.green = this->get_next();
00062       result.components.red   = this->get_next();
00063       result.components.alpha = this->get_next();
00064       
00065       return result;
00066     } // targa::reader::file_input_buffer::get_pixel()
00067   } // namespace graphic
00068 } // namespace claw
00069 
00070 namespace claw
00071 {
00072   namespace graphic
00073   {
00074     /*------------------------------------------------------------------------*/
00081     template< >
00082     pixel32 targa::reader::file_input_buffer<pixel24>::get_pixel()
00083     {
00084       pixel32 result;
00085       
00086       if ( this->remaining() < 3 )
00087         this->read_more(3);
00088       
00089       assert( this->remaining() >= 3 );
00090       
00091       result.components.blue  = this->get_next();
00092       result.components.green = this->get_next();
00093       result.components.red   = this->get_next();
00094       result.components.alpha =
00095         std::numeric_limits<claw::graphic::pixel32::component_type>::max();
00096       
00097       return result;
00098     } // targa::reader::file_input_buffer::get_pixel()
00099   } // namespace graphic
00100 } // namespace claw
00101 
00102 namespace claw
00103 {
00104   namespace graphic
00105   {
00106     /*------------------------------------------------------------------------*/
00113     template< >
00114     pixel32 targa::reader::file_input_buffer<targa::pixel16>::get_pixel()
00115     {
00116       pixel32 result;
00117 
00118       if ( this->remaining() < 2 )
00119         this->read_more(2);
00120 
00121       assert( this->remaining() >= 2 );
00122 
00123       unsigned char second_byte  = this->get_next();
00124       unsigned char first_byte = this->get_next();
00125 
00126       unsigned char r = (first_byte & 0x7C) >> 2;
00127       unsigned char g =
00128         ((first_byte & 0x03) << 3) | ((second_byte & 0xE0) >> 5);
00129       unsigned char b = second_byte & 0x1F;
00130 
00131       result.components.blue  = b * 8;
00132       result.components.green = g * 8;
00133       result.components.red   = r * 8;
00134       result.components.alpha =
00135         std::numeric_limits<claw::graphic::pixel32::component_type>::max();
00136 
00137       return result;
00138     } // targa::reader::file_input_buffer::get_pixel()
00139   } // namespace graphic
00140 } // namespace claw
00141 
00142 
00143 
00144 
00145 
00146 
00147 
00148 //****************** targa::reader::mapped_file_input_buffer *******************
00149 
00150 
00151 
00152 namespace claw
00153 {
00154   namespace graphic
00155   {
00156     /*------------------------------------------------------------------------*/
00163     template< >
00164     pixel32 targa::reader::mapped_file_input_buffer<targa::pixel8>::get_pixel()
00165     {
00166       if ( this->remaining() < 1 )
00167         this->read_more(1);
00168       
00169       assert( this->remaining() >= 1 );
00170       
00171       unsigned char index = this->get_next();
00172 
00173       return m_palette[index];
00174     } // targa::reader::mapped_file_input_buffer::get_pixel()
00175   } // namespace graphic
00176 } // namespace claw
00177 
00178 
00179 
00180 
00181 
00182 //****************************** targa::reader *********************************
00183 
00184 
00185 
00186 
00187   /*----------------------------------------------------------------------------*/
00192 claw::graphic::targa::reader::reader( image& img )
00193   : m_image( img )
00194 {
00195 
00196 } // targa::reader::reader()
00197 
00198 /*----------------------------------------------------------------------------*/
00205 claw::graphic::targa::reader::reader( image& img, std::istream& f )
00206   : m_image( img )
00207 {
00208   load(f);
00209 } // targa::reader::reader()
00210 
00211 /*----------------------------------------------------------------------------*/
00216 void claw::graphic::targa::reader::load( std::istream& f )
00217 {
00218   CLAW_PRECOND( !!f );
00219   std::istream::pos_type init_pos = f.tellg();
00220 
00221   try
00222     {
00223       check_if_targa(f);
00224 
00225       header h;
00226 
00227       f.read( reinterpret_cast<char*>(&h), sizeof(header) );
00228       
00229       if ( f.rdstate() == std::ios_base::goodbit )
00230         {
00231           m_image.set_size( h.image_specification.width,
00232                             h.image_specification.height );
00233           
00234           switch(h.image_type)
00235             {
00236             case color_mapped: load_color_mapped(h, f); break;
00237             case rle_color_mapped: load_rle_color_mapped(h, f); break;
00238             case true_color: load_true_color(h, f); break;
00239             case rle_true_color: load_rle_true_color(h, f); break;
00240             default :
00241               throw claw::bad_format
00242                 ( "targa::reader::targa: unsupported image type" );
00243             }
00244         }
00245       else
00246         throw claw::bad_format
00247           ( "claw::targa::reader::targa: can't read header" );
00248     }
00249   catch(...)
00250     {
00251       f.clear();
00252       f.seekg( init_pos, std::ios_base::beg );
00253       throw;
00254     }
00255 } // targa::reader::load()
00256 
00257 /*----------------------------------------------------------------------------*/
00262 void claw::graphic::targa::reader::check_if_targa( std::istream& f ) const
00263 {
00264   CLAW_PRECOND( !!f );
00265 
00266   std::istream::pos_type init_pos = f.tellg();
00267 
00268   footer foot;
00269 
00270   f.seekg( -(std::istream::off_type)sizeof(footer), std::ios::end );
00271   f.read( reinterpret_cast<char*>(&foot), sizeof(footer) );
00272   f.seekg( init_pos , std::ios::beg );
00273   
00274   if ( !foot.is_valid() )
00275     throw CLAW_EXCEPTION( "Not a Targa file." );
00276 } // targa::reader::check_if_targa()
00277 
00278 /*----------------------------------------------------------------------------*/
00286 void claw::graphic::targa::reader::load_palette
00287 ( const header& h, std::istream& f, color_palette32& palette ) const
00288 {
00289   assert((h.image_type == color_mapped) || (h.image_type == rle_color_mapped));
00290 
00291   switch( h.color_map_specification.entry_size )
00292     {
00293     case 16: load_palette_content<pixel16>(f, palette); break;
00294     case 24: load_palette_content<pixel24>(f, palette); break;
00295     case 32: load_palette_content<pixel32>(f, palette); break;
00296     default: 
00297       throw claw::bad_format
00298         ( "targa::reader::load_palette: unsupported entry size" );
00299     }
00300 } // targa::reader::load_palette()
00301 
00302 /*----------------------------------------------------------------------------*/
00309 void claw::graphic::targa::reader::load_color_mapped
00310 ( const header& h, std::istream& f )
00311 {
00312   assert(h.image_type == color_mapped);
00313 
00314   f.seekg( h.id_length, std::ios_base::cur );
00315 
00316   color_palette32 palette( h.color_map_specification.length );
00317   load_palette( h, f, palette );
00318 
00319   switch(h.image_specification.bpp)
00320     {
00321     case 8: load_color_mapped_raw<pixel8>(h, f, palette); break;
00322     default: 
00323       throw claw::bad_format
00324         ( "targa::reader::load_color_mapped: unsupported color depth" );
00325     }
00326 } // targa::reader::load_color_mapped()
00327 
00328 /*----------------------------------------------------------------------------*/
00335 void claw::graphic::targa::reader::load_rle_color_mapped
00336 ( const header& h, std::istream& f )
00337 {
00338   assert(h.image_type == rle_color_mapped);
00339 
00340   f.seekg( h.id_length, std::ios_base::cur );
00341 
00342   color_palette32 palette( h.color_map_specification.length );
00343   load_palette( h, f, palette );
00344 
00345   switch(h.image_specification.bpp)
00346     {
00347     case 8: decompress_rle_color_mapped<rle8_decoder>(h, f, palette); break;
00348     default: 
00349       throw claw::bad_format
00350         ( "targa::reader::load_rle_color_mapped: unsupported color depth" );
00351     }
00352 } // targa::reader::load_color_mapped()
00353 
00354 /*----------------------------------------------------------------------------*/
00361 void claw::graphic::targa::reader::load_true_color
00362 ( const header& h, std::istream& f )
00363 {
00364   assert(h.image_type == true_color);
00365 
00366   f.seekg( h.id_length, std::ios_base::cur );
00367 
00368   switch(h.image_specification.bpp)
00369     {
00370     case 16 : load_true_color_raw<pixel16>(h, f); break;
00371     case 24 : load_true_color_raw<pixel24>(h, f); break;
00372     case 32 : load_true_color_raw<pixel32>(h, f); break;
00373     default : 
00374       throw claw::bad_format
00375         ( "targa::reader::load_true_color: unsupported color depth" );
00376     }
00377 } // targa::reader::load_true_color()
00378 
00379 /*----------------------------------------------------------------------------*/
00386 void claw::graphic::targa::reader::load_rle_true_color
00387 ( const header& h, std::istream& f )
00388 {
00389   assert(h.image_type == rle_true_color);
00390 
00391   f.seekg( h.id_length, std::ios_base::cur );
00392 
00393   switch(h.image_specification.bpp)
00394     {
00395     case 16 : decompress_rle_true_color<rle16_decoder>(h, f); break;
00396     case 24 : decompress_rle_true_color<rle24_decoder>(h, f); break;
00397     case 32 : decompress_rle_true_color<rle32_decoder>(h, f); break;
00398     default : 
00399       throw claw::bad_format
00400         ( "targa::reader::load_rle_true_color: unsupported color depth" );
00401     }
00402 } // targa::reader::load_rle_true_color()
00403 

Generated on Thu May 22 21:07:35 2008 for CLAW Library (a C++ Library Absolutely Wonderful) by  doxygen 1.5.5