Claw
1.7.0
|
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-2011 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@gamned.org 00024 */ 00031 #include <limits> 00032 #include <iterator> 00033 00034 /*----------------------------------------------------------------------------*/ 00039 template< typename Pixel > 00040 claw::graphic::targa::reader::file_input_buffer<Pixel>::file_input_buffer 00041 ( std::istream& f ) 00042 : buffered_istream<std::istream>(f) 00043 { 00044 00045 } // targa::reader::file_input_buffer::file_input_buffer 00046 00047 00048 00049 00050 //*****************************************************************************/ 00051 00052 00053 00054 00055 /*----------------------------------------------------------------------------*/ 00061 template< typename Pixel > 00062 claw::graphic::targa::reader::mapped_file_input_buffer<Pixel>:: 00063 mapped_file_input_buffer 00064 ( std::istream& f, const color_palette32& p ) 00065 : buffered_istream<std::istream>(f), m_palette(p) 00066 { 00067 00068 } // targa::reader::mapped_file_input_buffer::mapped_file_input_buffer 00069 00070 00071 00072 00073 //*****************************************************************************/ 00074 00075 00076 00077 00078 /*----------------------------------------------------------------------------*/ 00085 template<typename InputBuffer> 00086 claw::graphic::targa::reader::rle_targa_output_buffer<InputBuffer>:: 00087 rle_targa_output_buffer( image& img, bool up_down, bool left_right ) 00088 : m_image(img), m_x_inc(left_right ? 1 : -1), m_y_inc(up_down ? 1 : -1) 00089 { 00090 if (up_down) 00091 m_y = 0; 00092 else 00093 m_y = m_image.height() - 1; 00094 00095 if (left_right) 00096 m_x = 0; 00097 else 00098 m_x = m_image.width() - 1; 00099 } // targa::reader::rle_targa_output_buffer::rle_targa_output_buffer() 00100 00101 /*----------------------------------------------------------------------------*/ 00107 template<typename InputBuffer> 00108 void claw::graphic::targa::reader::rle_targa_output_buffer<InputBuffer>::fill 00109 ( unsigned int n, rgba_pixel_8 pattern ) 00110 { 00111 assert( (int)(m_x + m_x_inc * n) >= -1 ); 00112 assert( m_x + m_x_inc * n <= m_image.width() ); 00113 00114 const int bound = (int)m_x + m_x_inc * n; 00115 int x = m_x; 00116 00117 for ( ; x != bound; x += m_x_inc ) 00118 m_image[m_y][x] = pattern; 00119 00120 adjust_position(x); 00121 } // targa::reader::rle_targa_output_buffer::fill() 00122 00123 /*----------------------------------------------------------------------------*/ 00129 template<typename InputBuffer> 00130 void claw::graphic::targa::reader::rle_targa_output_buffer<InputBuffer>::copy 00131 ( unsigned int n, input_buffer_type& buffer ) 00132 { 00133 assert( (int)(m_x + m_x_inc * n) >= -1 ); 00134 assert( m_x + m_x_inc * n <= m_image.width() ); 00135 00136 const int bound = (int)m_x + m_x_inc * n; 00137 int x = m_x; 00138 00139 for ( ; x != bound; x += m_x_inc ) 00140 m_image[m_y][x] = buffer.get_pixel(); 00141 00142 adjust_position(x); 00143 } // targa::reader::rle_targa_output_buffer::copy() 00144 00145 /*----------------------------------------------------------------------------*/ 00149 template<typename InputBuffer> 00150 bool claw::graphic::targa::reader::rle_targa_output_buffer<InputBuffer>:: 00151 completed() const 00152 { 00153 return ( (int)m_y == -1 ) || ( m_y == m_image.height() ); 00154 } // targa::reader::rle_targa_output_buffer::completed() 00155 00156 /*----------------------------------------------------------------------------*/ 00165 template<typename InputBuffer> 00166 void 00167 claw::graphic::targa::reader::rle_targa_output_buffer<InputBuffer>:: 00168 adjust_position(int x) 00169 { 00170 if (x < 0) 00171 { 00172 m_x = m_image.width() - 1; 00173 m_y += m_y_inc; 00174 } 00175 else if (x >= (int)m_image.width()) 00176 { 00177 m_x = 0; 00178 m_y += m_y_inc; 00179 } 00180 else 00181 m_x = x; 00182 } // targa::reader::rle_targa_output_buffer::adjust_position() 00183 00184 00185 00186 //*****************************************************************************/ 00187 00188 00189 00190 /*----------------------------------------------------------------------------*/ 00196 template< typename InputBuffer, typename OutputBuffer > 00197 void 00198 claw::graphic::targa::reader::rle_targa_decoder<InputBuffer, OutputBuffer>:: 00199 read_mode( input_buffer_type& input, output_buffer_type& output ) 00200 { 00201 this->m_mode = this->stop; 00202 bool ok = !output.completed(); 00203 00204 if ( ok && (input.remaining() < 1) ) 00205 ok = input.read_more(1); 00206 00207 if (ok) 00208 { 00209 char key = input.get_next(); 00210 00211 this->m_count = (key & 0x7F) + 1; 00212 00213 if (key & 0x80) // compressed 00214 { 00215 this->m_mode = this->compressed; 00216 this->m_pattern = input.get_pixel(); 00217 } 00218 else 00219 this->m_mode = this->raw; 00220 } 00221 } // targa::reader::rle_targa_decoder::read_mode() 00222 00223 00224 00225 //*****************************************************************************/ 00226 00227 00228 /*----------------------------------------------------------------------------*/ 00236 template<typename Pixel> 00237 void claw::graphic::targa::reader::load_color_mapped_raw 00238 ( const header& h, std::istream& f, const color_palette32& palette ) 00239 { 00240 /* We use a part of the rle framework but there isn't any compressed data 00241 here. We only use the direct copy of the rle algorithm. */ 00242 00243 typedef mapped_file_input_buffer<Pixel> input_buffer_type; 00244 00245 rle_targa_output_buffer<input_buffer_type> output 00246 ( m_image, h.image_specification.up_down_oriented(), 00247 h.image_specification.left_right_oriented() ); 00248 input_buffer_type input(f, palette); 00249 00250 for ( unsigned int i=0; i!=m_image.height(); ++i ) 00251 output.copy( m_image.width(), input ); 00252 } // targa::reader::load_true_color_raw() 00253 00254 /*----------------------------------------------------------------------------*/ 00262 template<typename Decoder> 00263 void claw::graphic::targa::reader::decompress_rle_color_mapped 00264 ( const header& h, std::istream& f, const color_palette32& palette ) 00265 { 00266 Decoder decoder; 00267 typename Decoder::output_buffer_type output_buffer 00268 (m_image, h.image_specification.up_down_oriented(), 00269 h.image_specification.left_right_oriented() ); 00270 typename Decoder::input_buffer_type input_buffer(f, palette); 00271 00272 decoder.decode(input_buffer, output_buffer); 00273 } // targa::reader::decompress_rle_color_mapped() 00274 00275 /*----------------------------------------------------------------------------*/ 00282 template<typename Pixel> 00283 void claw::graphic::targa::reader::load_true_color_raw 00284 ( const header& h, std::istream& f ) 00285 { 00286 assert(!h.color_map); 00287 00288 /* We use a part of the rle framework but there isn't any compressed data 00289 here. We only use the direct copy of the rle algorithm. */ 00290 00291 typedef file_input_buffer<Pixel> input_buffer_type; 00292 00293 rle_targa_output_buffer<input_buffer_type> output 00294 ( m_image, h.image_specification.up_down_oriented(), 00295 h.image_specification.left_right_oriented() ); 00296 input_buffer_type input(f); 00297 00298 for ( unsigned int i=0; i!=m_image.height(); ++i ) 00299 output.copy( m_image.width(), input ); 00300 } // targa::reader::load_true_color_raw() 00301 00302 /*----------------------------------------------------------------------------*/ 00309 template<typename Decoder> 00310 void claw::graphic::targa::reader::decompress_rle_true_color 00311 ( const header& h, std::istream& f ) 00312 { 00313 assert(!h.color_map); 00314 00315 Decoder decoder; 00316 typename Decoder::output_buffer_type output_buffer 00317 (m_image, h.image_specification.up_down_oriented(), 00318 h.image_specification.left_right_oriented() ); 00319 typename Decoder::input_buffer_type input_buffer(f); 00320 00321 decoder.decode(input_buffer, output_buffer); 00322 } // targa::reader::decompress_rle_true_color() 00323 00324 /*----------------------------------------------------------------------------*/ 00330 template<typename Pixel> 00331 void claw::graphic::targa::reader::load_palette_content 00332 ( std::istream& f, color_palette32& palette ) const 00333 { 00334 file_input_buffer<Pixel> input(f); 00335 00336 for (unsigned int i=0; i!=palette.size(); ++i) 00337 palette[i] = input.get_pixel(); 00338 } // targa::reader::load_palette_content()