2 CLAW - a C++ Library Absolutely Wonderful
4 CLAW is a free library without any particular aim but being useful to
7 Copyright (C) 2005-2011 Julien Jorge
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.
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.
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
23 contact: julien.jorge@gamned.org
26 * \file targa_reader.tpp
27 * \brief Implementation of the template methods of the targa::reader class and
29 * \author Julien Jorge
34/*----------------------------------------------------------------------------*/
37 * \param f The file to read.
39template< typename Pixel >
40claw::graphic::targa::reader::file_input_buffer<Pixel>::file_input_buffer
42 : buffered_istream<std::istream>(f)
45} // targa::reader::file_input_buffer::file_input_buffer
50//*****************************************************************************/
55/*----------------------------------------------------------------------------*/
58 * \param f The file to read.
59 * \param p The color palette.
61template< typename Pixel >
62claw::graphic::targa::reader::mapped_file_input_buffer<Pixel>::
63mapped_file_input_buffer
64( std::istream& f, const color_palette32& p )
65 : buffered_istream<std::istream>(f), m_palette(p)
68} // targa::reader::mapped_file_input_buffer::mapped_file_input_buffer
73//*****************************************************************************/
78/*----------------------------------------------------------------------------*/
81 * \param img The targa image we're loading.
82 * \param up_down Tell if the image is stored from top to bottom.
83 * \param left_right Tell if the image is stored from left to right.
85template<typename InputBuffer>
86claw::graphic::targa::reader::rle_targa_output_buffer<InputBuffer>::
87rle_targa_output_buffer( image& img, bool up_down, bool left_right )
88 : m_image(img), m_x_inc(left_right ? 1 : -1), m_y_inc(up_down ? 1 : -1)
93 m_y = m_image.height() - 1;
98 m_x = m_image.width() - 1;
99} // targa::reader::rle_targa_output_buffer::rle_targa_output_buffer()
101/*----------------------------------------------------------------------------*/
103 * \brief Copy a pixel a certain number of times.
104 * \param n The number of pixel to write.
105 * \param pattern The pixel to copy.
107template<typename InputBuffer>
108void claw::graphic::targa::reader::rle_targa_output_buffer<InputBuffer>::fill
109( unsigned int n, rgba_pixel_8 pattern )
111 assert( (int)(m_x + m_x_inc * n) >= -1 );
112 assert( m_x + m_x_inc * n <= m_image.width() );
114 const int bound = (int)m_x + m_x_inc * n;
117 for ( ; x != bound; x += m_x_inc )
118 m_image[m_y][x] = pattern;
121} // targa::reader::rle_targa_output_buffer::fill()
123/*----------------------------------------------------------------------------*/
125 * \brief Direct copy of a certain number of pixels from the file.
126 * \param n The number of pixels to write.
127 * \param buffer The buffer from which we read.
129template<typename InputBuffer>
130void claw::graphic::targa::reader::rle_targa_output_buffer<InputBuffer>::copy
131( unsigned int n, input_buffer_type& buffer )
133 assert( (int)(m_x + m_x_inc * n) >= -1 );
134 assert( m_x + m_x_inc * n <= m_image.width() );
136 const int bound = (int)m_x + m_x_inc * n;
139 for ( ; x != bound; x += m_x_inc )
140 m_image[m_y][x] = buffer.get_pixel();
143} // targa::reader::rle_targa_output_buffer::copy()
145/*----------------------------------------------------------------------------*/
147 * \brief Tell if we have completely filled the image.
149template<typename InputBuffer>
150bool claw::graphic::targa::reader::rle_targa_output_buffer<InputBuffer>::
153 return ( (int)m_y == -1 ) || ( m_y == m_image.height() );
154} // targa::reader::rle_targa_output_buffer::completed()
156/*----------------------------------------------------------------------------*/
158 * \brief Recalculate the position in the file.
159 * \param x The x-coordinate where we stopped.
161 * If \a x is lower tha zero, the position is set at the end of the previous
162 * line ; if \a is greater or equal to the width of the image, the position is
163 * set at the begining of the next line ; otherwise the position is set to \a x.
165template<typename InputBuffer>
167claw::graphic::targa::reader::rle_targa_output_buffer<InputBuffer>::
168adjust_position(int x)
172 m_x = m_image.width() - 1;
175 else if (x >= (int)m_image.width())
182} // targa::reader::rle_targa_output_buffer::adjust_position()
186//*****************************************************************************/
190/*----------------------------------------------------------------------------*/
192 * \brief Get the type of the following data in the input buffer.
193 * \param input The input stream (the targa file).
194 * \param output The output stream (the targa image).
196template< typename InputBuffer, typename OutputBuffer >
198claw::graphic::targa::reader::rle_targa_decoder<InputBuffer, OutputBuffer>::
199read_mode( input_buffer_type& input, output_buffer_type& output )
201 this->m_mode = this->stop;
202 bool ok = !output.completed();
204 if ( ok && (input.remaining() < 1) )
205 ok = input.read_more(1);
209 char key = input.get_next();
211 this->m_count = (key & 0x7F) + 1;
213 if (key & 0x80) // compressed
215 this->m_mode = this->compressed;
216 this->m_pattern = input.get_pixel();
219 this->m_mode = this->raw;
221} // targa::reader::rle_targa_decoder::read_mode()
225//*****************************************************************************/
228/*----------------------------------------------------------------------------*/
230 * \brief Load an uncompressed true color targa file.
231 * \param h File's header, must have been read before call.
232 * \param f Targa file.
233 * \param palette The color palette of the image.
236template<typename Pixel>
237void claw::graphic::targa::reader::load_color_mapped_raw
238( const header& h, std::istream& f, const color_palette32& palette )
240 /* We use a part of the rle framework but there isn't any compressed data
241 here. We only use the direct copy of the rle algorithm. */
243 typedef mapped_file_input_buffer<Pixel> input_buffer_type;
245 rle_targa_output_buffer<input_buffer_type> output
246 ( m_image, h.image_specification.up_down_oriented(),
247 h.image_specification.left_right_oriented() );
248 input_buffer_type input(f, palette);
250 for ( unsigned int i=0; i!=m_image.height(); ++i )
251 output.copy( m_image.width(), input );
252} // targa::reader::load_true_color_raw()
254/*----------------------------------------------------------------------------*/
256 * \brief Load a RLE color mapped targa file.
257 * \param h File's header, must have been read before call.
258 * \param f Targa file.
259 * \param palette The color palette of the image.
262template<typename Decoder>
263void claw::graphic::targa::reader::decompress_rle_color_mapped
264( const header& h, std::istream& f, const color_palette32& palette )
267 typename Decoder::output_buffer_type output_buffer
268 (m_image, h.image_specification.up_down_oriented(),
269 h.image_specification.left_right_oriented() );
270 typename Decoder::input_buffer_type input_buffer(f, palette);
272 decoder.decode(input_buffer, output_buffer);
273} // targa::reader::decompress_rle_color_mapped()
275/*----------------------------------------------------------------------------*/
277 * \brief Load an uncompressed true color targa file.
278 * \param h File's header, must have been read before call.
279 * \param f Targa file.
280 * \pre f.is_open() && !h.color_map
282template<typename Pixel>
283void claw::graphic::targa::reader::load_true_color_raw
284( const header& h, std::istream& f )
286 assert(!h.color_map);
288 /* We use a part of the rle framework but there isn't any compressed data
289 here. We only use the direct copy of the rle algorithm. */
291 typedef file_input_buffer<Pixel> input_buffer_type;
293 rle_targa_output_buffer<input_buffer_type> output
294 ( m_image, h.image_specification.up_down_oriented(),
295 h.image_specification.left_right_oriented() );
296 input_buffer_type input(f);
298 for ( unsigned int i=0; i!=m_image.height(); ++i )
299 output.copy( m_image.width(), input );
300} // targa::reader::load_true_color_raw()
302/*----------------------------------------------------------------------------*/
304 * \brief Load a true color RLE targa file.
305 * \param h File's header, must have been read before call.
306 * \param f Targa file.
307 * \pre f.is_open() && !h.color_map
309template<typename Decoder>
310void claw::graphic::targa::reader::decompress_rle_true_color
311( const header& h, std::istream& f )
313 assert(!h.color_map);
316 typename Decoder::output_buffer_type output_buffer
317 (m_image, h.image_specification.up_down_oriented(),
318 h.image_specification.left_right_oriented() );
319 typename Decoder::input_buffer_type input_buffer(f);
321 decoder.decode(input_buffer, output_buffer);
322} // targa::reader::decompress_rle_true_color()
324/*----------------------------------------------------------------------------*/
326 * \brief Load the content of the color palette.
327 * \param f Targa file.
328 * \param palette (out) The color palette.
330template<typename Pixel>
331void claw::graphic::targa::reader::load_palette_content
332( std::istream& f, color_palette32& palette ) const
334 file_input_buffer<Pixel> input(f);
336 for (unsigned int i=0; i!=palette.size(); ++i)
337 palette[i] = input.get_pixel();
338} // targa::reader::load_palette_content()