Claw 1.7.3
targa_reader.cpp
Go to the documentation of this file.
1/*
2 CLAW - a C++ Library Absolutely Wonderful
3
4 CLAW is a free library without any particular aim but being useful to
5 anyone.
6
7 Copyright (C) 2005-2011 Julien Jorge
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
23 contact: julien.jorge@gamned.org
24*/
30#include <claw/targa.hpp>
31#include <claw/exception.hpp>
32
33
34
35//********************* targa::reader::file_input_buffer ***********************
36
37
38
39namespace claw
40{
41 namespace graphic
42 {
43 /*------------------------------------------------------------------------*/
50 template< >
51 rgba_pixel_8 targa::reader::file_input_buffer<rgba_pixel_8>::get_pixel()
52 {
53 rgba_pixel_8 result;
54
55 if ( this->remaining() < 4 )
56 this->read_more(4);
57
58 assert( this->remaining() >= 4 );
59
60 result.components.blue = this->get_next();
61 result.components.green = this->get_next();
62 result.components.red = this->get_next();
63 result.components.alpha = this->get_next();
64
65 return result;
66 } // targa::reader::file_input_buffer::get_pixel()
67 } // namespace graphic
68} // namespace claw
69
70namespace claw
71{
72 namespace graphic
73 {
74 /*------------------------------------------------------------------------*/
81 template< >
82 rgba_pixel_8 targa::reader::file_input_buffer<rgb_pixel_8>::get_pixel()
83 {
84 rgba_pixel_8 result;
85
86 if ( this->remaining() < 3 )
87 this->read_more(3);
88
89 assert( this->remaining() >= 3 );
90
91 result.components.blue = this->get_next();
92 result.components.green = this->get_next();
93 result.components.red = this->get_next();
94 result.components.alpha =
95 std::numeric_limits<claw::graphic::rgba_pixel_8::component_type>::max();
96
97 return result;
98 } // targa::reader::file_input_buffer::get_pixel()
99 } // namespace graphic
100} // namespace claw
101
102namespace claw
103{
104 namespace graphic
105 {
106 /*------------------------------------------------------------------------*/
113 template< >
114 rgba_pixel_8 targa::reader::file_input_buffer<targa::pixel16>::get_pixel()
115 {
116 rgba_pixel_8 result;
117
118 if ( this->remaining() < 2 )
119 this->read_more(2);
120
121 assert( this->remaining() >= 2 );
122
123 unsigned char second_byte = this->get_next();
124 unsigned char first_byte = this->get_next();
125
126 unsigned char r = (first_byte & 0x7C) >> 2;
127 unsigned char g =
128 ((first_byte & 0x03) << 3) | ((second_byte & 0xE0) >> 5);
129 unsigned char b = second_byte & 0x1F;
130
131 result.components.blue = b * 8;
132 result.components.green = g * 8;
133 result.components.red = r * 8;
134 result.components.alpha =
135 std::numeric_limits<claw::graphic::rgba_pixel_8::component_type>::max();
136
137 return result;
138 } // targa::reader::file_input_buffer::get_pixel()
139 } // namespace graphic
140} // namespace claw
141
142
143
144
145
146
147
148//****************** targa::reader::mapped_file_input_buffer *******************
149
150
151
152namespace claw
153{
154 namespace graphic
155 {
156 /*------------------------------------------------------------------------*/
163 template< >
165 targa::reader::mapped_file_input_buffer<targa::pixel8>::get_pixel()
166 {
167 if ( this->remaining() < 1 )
168 this->read_more(1);
169
170 assert( this->remaining() >= 1 );
171
172 unsigned char index = this->get_next();
173
174 return m_palette[index];
175 } // targa::reader::mapped_file_input_buffer::get_pixel()
176 } // namespace graphic
177} // namespace claw
178
179
180
181
182
183//****************************** targa::reader *********************************
184
185
186
187
188/*----------------------------------------------------------------------------*/
194 : m_image( img )
195{
196
197} // targa::reader::reader()
198
199/*----------------------------------------------------------------------------*/
207 : m_image( img )
208{
209 load(f);
210} // targa::reader::reader()
211
212/*----------------------------------------------------------------------------*/
218{
219 CLAW_PRECOND( !!f );
220 std::istream::pos_type init_pos = f.tellg();
221
222 try
223 {
224 check_if_targa(f);
225
226 header h;
227
228 f.read( reinterpret_cast<char*>(&h), sizeof(header) );
229
230 if ( f.rdstate() == std::ios_base::goodbit )
231 {
232 m_image.set_size( h.image_specification.width,
234
235 switch(h.image_type)
236 {
237 case color_mapped: load_color_mapped(h, f); break;
238 case rle_color_mapped: load_rle_color_mapped(h, f); break;
239 case true_color: load_true_color(h, f); break;
240 case rle_true_color: load_rle_true_color(h, f); break;
241 default :
242 throw claw::bad_format
243 ( "targa::reader::targa: unsupported image type" );
244 }
245 }
246 else
247 throw claw::bad_format
248 ( "claw::targa::reader::targa: can't read header" );
249 }
250 catch(...)
251 {
252 f.clear();
253 f.seekg( init_pos, std::ios_base::beg );
254 throw;
255 }
256} // targa::reader::load()
257
258/*----------------------------------------------------------------------------*/
263void claw::graphic::targa::reader::check_if_targa( std::istream& f ) const
264{
265 CLAW_PRECOND( !!f );
266
267 std::istream::pos_type init_pos = f.tellg();
268
269 footer foot;
270
271 f.seekg( -(std::istream::off_type)sizeof(footer), std::ios::end );
272 f.read( reinterpret_cast<char*>(&foot), sizeof(footer) );
273 f.seekg( init_pos , std::ios::beg );
274
275 if ( !foot.is_valid() )
276 throw CLAW_EXCEPTION( "Not a Targa file." );
277} // targa::reader::check_if_targa()
278
279/*----------------------------------------------------------------------------*/
287void claw::graphic::targa::reader::load_palette
288( const header& h, std::istream& f, color_palette32& palette ) const
289{
290 assert((h.image_type == color_mapped) || (h.image_type == rle_color_mapped));
291
292 switch( h.color_map_specification.entry_size )
293 {
294 case 16: load_palette_content<pixel16>(f, palette); break;
295 case 24: load_palette_content<rgb_pixel_8>(f, palette); break;
296 case 32: load_palette_content<rgba_pixel_8>(f, palette); break;
297 default:
298 throw claw::bad_format
299 ( "targa::reader::load_palette: unsupported entry size" );
300 }
301} // targa::reader::load_palette()
302
303/*----------------------------------------------------------------------------*/
310void claw::graphic::targa::reader::load_color_mapped
311( const header& h, std::istream& f )
312{
313 assert(h.image_type == color_mapped);
314
315 f.seekg( h.id_length, std::ios_base::cur );
316
317 color_palette32 palette( h.color_map_specification.length );
318 load_palette( h, f, palette );
319
320 switch(h.image_specification.bpp)
321 {
322 case 8: load_color_mapped_raw<pixel8>(h, f, palette); break;
323 default:
324 throw claw::bad_format
325 ( "targa::reader::load_color_mapped: unsupported color depth" );
326 }
327} // targa::reader::load_color_mapped()
328
329/*----------------------------------------------------------------------------*/
336void claw::graphic::targa::reader::load_rle_color_mapped
337( const header& h, std::istream& f )
338{
339 assert(h.image_type == rle_color_mapped);
340
341 f.seekg( h.id_length, std::ios_base::cur );
342
343 color_palette32 palette( h.color_map_specification.length );
344 load_palette( h, f, palette );
345
346 switch(h.image_specification.bpp)
347 {
348 case 8: decompress_rle_color_mapped<rle8_decoder>(h, f, palette); break;
349 default:
350 throw claw::bad_format
351 ( "targa::reader::load_rle_color_mapped: unsupported color depth" );
352 }
353} // targa::reader::load_color_mapped()
354
355/*----------------------------------------------------------------------------*/
362void claw::graphic::targa::reader::load_true_color
363( const header& h, std::istream& f )
364{
365 assert(h.image_type == true_color);
366
367 f.seekg( h.id_length, std::ios_base::cur );
368
369 switch(h.image_specification.bpp)
370 {
371 case 16 : load_true_color_raw<pixel16>(h, f); break;
372 case 24 : load_true_color_raw<rgb_pixel_8>(h, f); break;
373 case 32 : load_true_color_raw<rgba_pixel_8>(h, f); break;
374 default :
375 throw claw::bad_format
376 ( "targa::reader::load_true_color: unsupported color depth" );
377 }
378} // targa::reader::load_true_color()
379
380/*----------------------------------------------------------------------------*/
387void claw::graphic::targa::reader::load_rle_true_color
388( const header& h, std::istream& f )
389{
390 assert(h.image_type == rle_true_color);
391
392 f.seekg( h.id_length, std::ios_base::cur );
393
394 switch(h.image_specification.bpp)
395 {
396 case 16 : decompress_rle_true_color<rle16_decoder>(h, f); break;
397 case 24 : decompress_rle_true_color<rle24_decoder>(h, f); break;
398 case 32 : decompress_rle_true_color<rle32_decoder>(h, f); break;
399 default :
400 throw claw::bad_format
401 ( "targa::reader::load_rle_true_color: unsupported color depth" );
402 }
403} // targa::reader::load_rle_true_color()
404
#define CLAW_PRECOND(b)
Abort the program if a precondition is not true.
Definition assert.hpp:98
Exception thrown when accessing bad formated data.
Definition exception.hpp:72
A class to deal with images.
Definition image.hpp:50
specification image_specification
The specification of the image.
Definition targa.hpp:123
void load(std::istream &f)
Load an image from a targa file.
reader(image &img)
Constructor.
A simple class to use as exception with string message.
#define CLAW_EXCEPTION(m)
Create an exception and add the name of the current function to the message.
Definition exception.hpp:90
rgba_pixel rgba_pixel_8
A color with 8 bits per component and an alpha channel.
Definition pixel.hpp:126
This is the main namespace.
Definition algorithm.hpp:34
A class for targa pictures.