Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00030 #include <claw/targa.hpp>
00031 #include <claw/exception.hpp>
00032
00033
00034
00035
00036
00037
00038
00039 namespace claw
00040 {
00041 namespace graphic
00042 {
00043
00050 template< >
00051 rgba_pixel_8 targa::reader::file_input_buffer<rgba_pixel_8>::get_pixel()
00052 {
00053 rgba_pixel_8 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 }
00067 }
00068 }
00069
00070 namespace claw
00071 {
00072 namespace graphic
00073 {
00074
00081 template< >
00082 rgba_pixel_8 targa::reader::file_input_buffer<rgb_pixel_8>::get_pixel()
00083 {
00084 rgba_pixel_8 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::rgba_pixel_8::component_type>::max();
00096
00097 return result;
00098 }
00099 }
00100 }
00101
00102 namespace claw
00103 {
00104 namespace graphic
00105 {
00106
00113 template< >
00114 rgba_pixel_8 targa::reader::file_input_buffer<targa::pixel16>::get_pixel()
00115 {
00116 rgba_pixel_8 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::rgba_pixel_8::component_type>::max();
00136
00137 return result;
00138 }
00139 }
00140 }
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 namespace claw
00153 {
00154 namespace graphic
00155 {
00156
00163 template< >
00164 rgba_pixel_8
00165 targa::reader::mapped_file_input_buffer<targa::pixel8>::get_pixel()
00166 {
00167 if ( this->remaining() < 1 )
00168 this->read_more(1);
00169
00170 assert( this->remaining() >= 1 );
00171
00172 unsigned char index = this->get_next();
00173
00174 return m_palette[index];
00175 }
00176 }
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00193 claw::graphic::targa::reader::reader( image& img )
00194 : m_image( img )
00195 {
00196
00197 }
00198
00199
00206 claw::graphic::targa::reader::reader( image& img, std::istream& f )
00207 : m_image( img )
00208 {
00209 load(f);
00210 }
00211
00212
00217 void claw::graphic::targa::reader::load( std::istream& f )
00218 {
00219 CLAW_PRECOND( !!f );
00220 std::istream::pos_type init_pos = f.tellg();
00221
00222 try
00223 {
00224 check_if_targa(f);
00225
00226 header h;
00227
00228 f.read( reinterpret_cast<char*>(&h), sizeof(header) );
00229
00230 if ( f.rdstate() == std::ios_base::goodbit )
00231 {
00232 m_image.set_size( h.image_specification.width,
00233 h.image_specification.height );
00234
00235 switch(h.image_type)
00236 {
00237 case color_mapped: load_color_mapped(h, f); break;
00238 case rle_color_mapped: load_rle_color_mapped(h, f); break;
00239 case true_color: load_true_color(h, f); break;
00240 case rle_true_color: load_rle_true_color(h, f); break;
00241 default :
00242 throw claw::bad_format
00243 ( "targa::reader::targa: unsupported image type" );
00244 }
00245 }
00246 else
00247 throw claw::bad_format
00248 ( "claw::targa::reader::targa: can't read header" );
00249 }
00250 catch(...)
00251 {
00252 f.clear();
00253 f.seekg( init_pos, std::ios_base::beg );
00254 throw;
00255 }
00256 }
00257
00258
00263 void claw::graphic::targa::reader::check_if_targa( std::istream& f ) const
00264 {
00265 CLAW_PRECOND( !!f );
00266
00267 std::istream::pos_type init_pos = f.tellg();
00268
00269 footer foot;
00270
00271 f.seekg( -(std::istream::off_type)sizeof(footer), std::ios::end );
00272 f.read( reinterpret_cast<char*>(&foot), sizeof(footer) );
00273 f.seekg( init_pos , std::ios::beg );
00274
00275 if ( !foot.is_valid() )
00276 throw CLAW_EXCEPTION( "Not a Targa file." );
00277 }
00278
00279
00287 void claw::graphic::targa::reader::load_palette
00288 ( const header& h, std::istream& f, color_palette32& palette ) const
00289 {
00290 assert((h.image_type == color_mapped) || (h.image_type == rle_color_mapped));
00291
00292 switch( h.color_map_specification.entry_size )
00293 {
00294 case 16: load_palette_content<pixel16>(f, palette); break;
00295 case 24: load_palette_content<rgb_pixel_8>(f, palette); break;
00296 case 32: load_palette_content<rgba_pixel_8>(f, palette); break;
00297 default:
00298 throw claw::bad_format
00299 ( "targa::reader::load_palette: unsupported entry size" );
00300 }
00301 }
00302
00303
00310 void claw::graphic::targa::reader::load_color_mapped
00311 ( const header& h, std::istream& f )
00312 {
00313 assert(h.image_type == color_mapped);
00314
00315 f.seekg( h.id_length, std::ios_base::cur );
00316
00317 color_palette32 palette( h.color_map_specification.length );
00318 load_palette( h, f, palette );
00319
00320 switch(h.image_specification.bpp)
00321 {
00322 case 8: load_color_mapped_raw<pixel8>(h, f, palette); break;
00323 default:
00324 throw claw::bad_format
00325 ( "targa::reader::load_color_mapped: unsupported color depth" );
00326 }
00327 }
00328
00329
00336 void claw::graphic::targa::reader::load_rle_color_mapped
00337 ( const header& h, std::istream& f )
00338 {
00339 assert(h.image_type == rle_color_mapped);
00340
00341 f.seekg( h.id_length, std::ios_base::cur );
00342
00343 color_palette32 palette( h.color_map_specification.length );
00344 load_palette( h, f, palette );
00345
00346 switch(h.image_specification.bpp)
00347 {
00348 case 8: decompress_rle_color_mapped<rle8_decoder>(h, f, palette); break;
00349 default:
00350 throw claw::bad_format
00351 ( "targa::reader::load_rle_color_mapped: unsupported color depth" );
00352 }
00353 }
00354
00355
00362 void claw::graphic::targa::reader::load_true_color
00363 ( const header& h, std::istream& f )
00364 {
00365 assert(h.image_type == true_color);
00366
00367 f.seekg( h.id_length, std::ios_base::cur );
00368
00369 switch(h.image_specification.bpp)
00370 {
00371 case 16 : load_true_color_raw<pixel16>(h, f); break;
00372 case 24 : load_true_color_raw<rgb_pixel_8>(h, f); break;
00373 case 32 : load_true_color_raw<rgba_pixel_8>(h, f); break;
00374 default :
00375 throw claw::bad_format
00376 ( "targa::reader::load_true_color: unsupported color depth" );
00377 }
00378 }
00379
00380
00387 void claw::graphic::targa::reader::load_rle_true_color
00388 ( const header& h, std::istream& f )
00389 {
00390 assert(h.image_type == rle_true_color);
00391
00392 f.seekg( h.id_length, std::ios_base::cur );
00393
00394 switch(h.image_specification.bpp)
00395 {
00396 case 16 : decompress_rle_true_color<rle16_decoder>(h, f); break;
00397 case 24 : decompress_rle_true_color<rle24_decoder>(h, f); break;
00398 case 32 : decompress_rle_true_color<rle32_decoder>(h, f); break;
00399 default :
00400 throw claw::bad_format
00401 ( "targa::reader::load_rle_true_color: unsupported color depth" );
00402 }
00403 }
00404