claw 1.9.0
 
Loading...
Searching...
No Matches
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@stuff-o-matic.com
24*/
31
32#include <claw/exception.hpp>
33
34//********************* targa::reader::file_input_buffer
35//***********************
36
37namespace claw
38{
39 namespace graphic
40 {
47 template <>
48 rgba_pixel_8 targa::reader::file_input_buffer<rgba_pixel_8>::get_pixel()
49 {
50 rgba_pixel_8 result;
51
52 if(this->remaining() < 4)
53 this->read_more(4);
54
55 assert(this->remaining() >= 4);
56
57 result.components.blue = this->get_next();
58 result.components.green = this->get_next();
59 result.components.red = this->get_next();
60 result.components.alpha = this->get_next();
61
62 return result;
63 }
64 }
65}
66
67namespace claw
68{
69 namespace graphic
70 {
77 template <>
78 rgba_pixel_8 targa::reader::file_input_buffer<rgb_pixel_8>::get_pixel()
79 {
80 rgba_pixel_8 result;
81
82 if(this->remaining() < 3)
83 this->read_more(3);
84
85 assert(this->remaining() >= 3);
86
87 result.components.blue = this->get_next();
88 result.components.green = this->get_next();
89 result.components.red = this->get_next();
90 result.components.alpha = std::numeric_limits<
92
93 return result;
94 }
95 }
96}
97
98namespace claw
99{
100 namespace graphic
101 {
108 template <>
109 rgba_pixel_8 targa::reader::file_input_buffer<targa::pixel16>::get_pixel()
110 {
111 rgba_pixel_8 result;
112
113 if(this->remaining() < 2)
114 this->read_more(2);
115
116 assert(this->remaining() >= 2);
117
118 unsigned char second_byte = this->get_next();
119 unsigned char first_byte = this->get_next();
120
121 unsigned char r = (first_byte & 0x7C) >> 2;
122 unsigned char g
123 = ((first_byte & 0x03) << 3) | ((second_byte & 0xE0) >> 5);
124 unsigned char b = second_byte & 0x1F;
125
126 result.components.blue = b * 8;
127 result.components.green = g * 8;
128 result.components.red = r * 8;
129 result.components.alpha = std::numeric_limits<
131
132 return result;
133 }
134 }
135}
136
137//****************** targa::reader::mapped_file_input_buffer
138//*******************
139
140namespace claw
141{
142 namespace graphic
143 {
150 template <>
152 targa::reader::mapped_file_input_buffer<targa::pixel8>::get_pixel()
153 {
154 if(this->remaining() < 1)
155 this->read_more(1);
156
157 assert(this->remaining() >= 1);
158
159 unsigned char index = this->get_next();
160
161 return m_palette[index];
162 }
163 }
164}
165
166//****************************** targa::reader
167//*********************************
168
174 : m_image(img)
175{}
176
184 : m_image(img)
185{
186 load(f);
187}
188
194{
195 CLAW_PRECOND(!!f);
196 std::istream::pos_type init_pos = f.tellg();
197
198 try
199 {
200 check_if_targa(f);
201
202 header h;
203
204 f.read(reinterpret_cast<char*>(&h), sizeof(header));
205
206 if(f.rdstate() == std::ios_base::goodbit)
207 {
208 m_image.set_size(h.image_specification.width,
210
211 switch(h.image_type)
212 {
213 case color_mapped:
214 load_color_mapped(h, f);
215 break;
216 case rle_color_mapped:
217 load_rle_color_mapped(h, f);
218 break;
219 case true_color:
220 load_true_color(h, f);
221 break;
222 case rle_true_color:
223 load_rle_true_color(h, f);
224 break;
225 default:
226 throw claw::bad_format(
227 "targa::reader::targa: unsupported image type");
228 }
229 }
230 else
231 throw claw::bad_format(
232 "claw::targa::reader::targa: can't read header");
233 }
234 catch(...)
235 {
236 f.clear();
237 f.seekg(init_pos, std::ios_base::beg);
238 throw;
239 }
240}
241
246void claw::graphic::targa::reader::check_if_targa(std::istream& f) const
247{
248 CLAW_PRECOND(!!f);
249
250 std::istream::pos_type init_pos = f.tellg();
251
252 footer foot;
253
254 f.seekg(-(std::istream::off_type)sizeof(footer), std::ios::end);
255 f.read(reinterpret_cast<char*>(&foot), sizeof(footer));
256 f.seekg(init_pos, std::ios::beg);
257
258 if(!foot.is_valid())
259 throw CLAW_EXCEPTION("Not a Targa file.");
260}
261
269void claw::graphic::targa::reader::load_palette(const header& h,
270 std::istream& f,
271 color_palette32& palette) const
272{
273 assert((h.image_type == color_mapped) || (h.image_type == rle_color_mapped));
274
275 switch(h.color_map_specification.entry_size)
276 {
277 case 16:
278 load_palette_content<pixel16>(f, palette);
279 break;
280 case 24:
281 load_palette_content<rgb_pixel_8>(f, palette);
282 break;
283 case 32:
284 load_palette_content<rgba_pixel_8>(f, palette);
285 break;
286 default:
287 throw claw::bad_format(
288 "targa::reader::load_palette: unsupported entry size");
289 }
290}
291
298void claw::graphic::targa::reader::load_color_mapped(const header& h,
299 std::istream& f)
300{
301 assert(h.image_type == color_mapped);
302
303 f.seekg(h.id_length, std::ios_base::cur);
304
305 color_palette32 palette(h.color_map_specification.length);
306 load_palette(h, f, palette);
307
308 switch(h.image_specification.bpp)
309 {
310 case 8:
311 load_color_mapped_raw<pixel8>(h, f, palette);
312 break;
313 default:
314 throw claw::bad_format(
315 "targa::reader::load_color_mapped: unsupported color depth");
316 }
317}
318
325void claw::graphic::targa::reader::load_rle_color_mapped(const header& h,
326 std::istream& f)
327{
328 assert(h.image_type == rle_color_mapped);
329
330 f.seekg(h.id_length, std::ios_base::cur);
331
332 color_palette32 palette(h.color_map_specification.length);
333 load_palette(h, f, palette);
334
335 switch(h.image_specification.bpp)
336 {
337 case 8:
338 decompress_rle_color_mapped<rle8_decoder>(h, f, palette);
339 break;
340 default:
341 throw claw::bad_format(
342 "targa::reader::load_rle_color_mapped: unsupported color depth");
343 }
344}
345
352void claw::graphic::targa::reader::load_true_color(const header& h,
353 std::istream& f)
354{
355 assert(h.image_type == true_color);
356
357 f.seekg(h.id_length, std::ios_base::cur);
358
359 switch(h.image_specification.bpp)
360 {
361 case 16:
362 load_true_color_raw<pixel16>(h, f);
363 break;
364 case 24:
365 load_true_color_raw<rgb_pixel_8>(h, f);
366 break;
367 case 32:
368 load_true_color_raw<rgba_pixel_8>(h, f);
369 break;
370 default:
371 throw claw::bad_format(
372 "targa::reader::load_true_color: unsupported color depth");
373 }
374}
375
382void claw::graphic::targa::reader::load_rle_true_color(const header& h,
383 std::istream& f)
384{
385 assert(h.image_type == rle_true_color);
386
387 f.seekg(h.id_length, std::ios_base::cur);
388
389 switch(h.image_specification.bpp)
390 {
391 case 16:
392 decompress_rle_true_color<rle16_decoder>(h, f);
393 break;
394 case 24:
395 decompress_rle_true_color<rle24_decoder>(h, f);
396 break;
397 case 32:
398 decompress_rle_true_color<rle32_decoder>(h, f);
399 break;
400 default:
401 throw claw::bad_format(
402 "targa::reader::load_rle_true_color: unsupported color depth");
403 }
404}
#define CLAW_PRECOND(b)
Abort the program if a precondition is not true.
Definition assert.hpp:94
Exception thrown when accessing bad formated data.
Definition exception.hpp:74
image()
Constructor. Creates an image without datas.
Definition image.cpp:95
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:92
Everything about image structures and processing.
Definition claw.hpp:58
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.
unsigned char component_type
The type of the components of the color.
Definition pixel.hpp:82
A class for targa pictures.