CLAW Library (a C++ Library Absolutely Wonderful) 1.5.5
|
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-2010 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@yahoo.fr 00024 */ 00030 #ifndef __CLAW_PCX_HPP__ 00031 #define __CLAW_PCX_HPP__ 00032 00033 #include <iostream> 00034 #include <claw/image.hpp> 00035 #include <claw/rle_decoder.hpp> 00036 #include <claw/rle_encoder.hpp> 00037 #include <claw/color_palette.hpp> 00038 #include <claw/types.hpp> 00039 #include <claw/buffered_istream.hpp> 00040 00041 namespace claw 00042 { 00043 namespace graphic 00044 { 00049 class pcx : public image 00050 { 00051 private: 00052 /* Some convenient renaming. */ 00053 typedef unsigned_integer_of_size<8>::type u_int_8; 00054 typedef unsigned_integer_of_size<16>::type u_int_16; 00055 00056 typedef integer_of_size<8>::type int_8; 00057 typedef integer_of_size<16>::type int_16; 00058 00059 enum format_version 00060 { 00061 v_2_5 = 0, 00062 v_2_8_with_palette = 2, 00063 v_2_8_without_palette = 3, 00064 v_win = 4, 00065 v_3_0 = 5 00066 }; // enum format_version 00067 00068 # pragma pack (push,1) 00069 00070 /*--------------------------------------------------------------------*/ 00074 class header 00075 { 00076 public: 00078 u_int_8 manufacturer; 00079 00081 u_int_8 version; 00082 00084 u_int_8 encoded; 00085 00087 u_int_8 bpp; 00088 00089 struct 00090 { 00092 u_int_16 x_min; 00093 00095 u_int_16 y_min; 00096 00098 u_int_16 x_max; 00099 00101 u_int_16 y_max; 00102 00103 } window; 00104 00106 u_int_16 horizontal_dpi; 00107 00109 u_int_16 vertical_dpi; 00110 00112 rgb_pixel_8 color_map[16]; 00113 00115 u_int_8 reserved; 00116 00118 u_int_8 color_planes; 00119 00122 u_int_16 bytes_per_line; 00123 00125 u_int_16 palette_info; 00126 00128 struct 00129 { 00131 u_int_16 horizontal; 00132 00134 u_int_16 vertical; 00135 00136 } screen_size; 00137 00139 u_int_8 filler[54]; 00140 }; // struct header 00141 # pragma pack (pop) 00142 00143 00144 /*----------------------------------------------------------------------*/ 00146 typedef color_palette<rgba_pixel_8> color_palette32; 00147 00149 typedef std::vector<u_int_8> color_plane_type; 00150 00151 public: 00152 /*----------------------------------------------------------------------*/ 00158 class reader 00159 { 00160 private: 00161 /*--------------------------------------------------------------------*/ 00166 typedef buffered_istream<std::istream> rle_pcx_input_buffer; 00167 00168 /*--------------------------------------------------------------------*/ 00172 class rle_pcx_output_buffer 00173 { 00174 public: 00175 rle_pcx_output_buffer( color_plane_type& result ); 00176 00177 void fill( unsigned int n, u_int_8 pattern ); 00178 void copy( unsigned int n, rle_pcx_input_buffer& buffer ); 00179 00180 bool completed() const; 00181 00182 private: 00184 color_plane_type& m_result; 00185 00187 unsigned int m_position; 00188 00189 }; // class rle_pcx_output_buffer 00190 00191 /*--------------------------------------------------------------------*/ 00195 class rle_pcx_decoder 00196 : public rle_decoder< u_int_8, 00197 rle_pcx_input_buffer, 00198 rle_pcx_output_buffer > 00199 { 00200 private: 00201 virtual void 00202 read_mode( input_buffer_type& input, output_buffer_type& output ); 00203 00204 }; // class rle_pcx_decoder 00205 00206 /*--------------------------------------------------------------------*/ 00211 class converter_mono 00212 { 00213 public: 00214 void operator() 00215 ( const std::vector<color_plane_type>& scanline, image& img, 00216 unsigned int y ) const; 00217 }; // class converter_mono 00218 00219 /*--------------------------------------------------------------------*/ 00224 class converter_16 00225 { 00226 public: 00227 converter_16( const header& h ); 00228 void operator() 00229 ( const std::vector<color_plane_type>& scanline, image& img, 00230 unsigned int y ) const; 00231 00232 private: 00234 const header& m_header; 00235 00236 }; // class converter_16 00237 00238 /*--------------------------------------------------------------------*/ 00243 class converter_256 00244 { 00245 public: 00246 converter_256( const color_palette32& palette ); 00247 void operator() 00248 ( const std::vector<color_plane_type>& scanline, image& img, 00249 unsigned int y ) const; 00250 00251 private: 00253 const color_palette32& m_palette; 00254 00255 }; // class converter_256 00256 00257 /*--------------------------------------------------------------------*/ 00262 class converter_true_color 00263 { 00264 public: 00265 void operator() 00266 ( const std::vector<color_plane_type>& scanline, image& img, 00267 unsigned int y ) const; 00268 00269 }; // class converter_true_color 00270 00271 public: 00272 reader( image& img ); 00273 reader( image& img, std::istream& f ); 00274 00275 void load( std::istream& f ); 00276 00277 private: 00278 void check_if_pcx( const header& h ) const; 00279 00280 void load_mono( const header& h, std::istream& f ); 00281 void load_16_color_mapped( const header& h, std::istream& f ); 00282 void load_true_color( const header& h, std::istream& f ); 00283 void load_256_color_mapped( const header& h, std::istream& f ); 00284 00285 void 00286 decompress_line( std::istream& f, color_plane_type& scanline ) const; 00287 00288 template<typename Converter> 00289 void decompress 00290 ( const header& h, std::istream& f, const Converter& convert ); 00291 00292 private: 00294 image& m_image; 00295 00296 }; // class reader 00297 00298 /*----------------------------------------------------------------------*/ 00303 class writer 00304 { 00305 public: 00306 /*--------------------------------------------------------------------*/ 00311 class file_output_buffer 00312 { 00313 public: 00315 typedef u_int_8 pattern_type; 00316 00317 public: 00318 file_output_buffer( std::ostream& os ); 00319 void encode( unsigned int n, pattern_type pattern ); 00320 00321 template<typename Iterator> 00322 void raw( Iterator first, Iterator last ); 00323 00324 unsigned int min_interesting() const; 00325 unsigned int max_encodable() const; 00326 00327 private: 00329 std::ostream& m_stream; 00330 00331 }; // class file_output_buffer 00332 00333 /*--------------------------------------------------------------------*/ 00338 typedef rle_encoder<file_output_buffer> rle_pcx_encoder; 00339 00340 public: 00341 writer( const image& img ); 00342 writer( const image& img, std::ostream& f ); 00343 00344 void save( std::ostream& os ) const; 00345 00346 private: 00347 void write_header 00348 ( std::ostream& os, unsigned int bytes_per_line ) const; 00349 void save_rle_true_color 00350 ( std::ostream& os, unsigned int bytes_per_line ) const; 00351 00352 private: 00354 const image& m_image; 00355 00356 }; // class writer 00357 00358 public: 00359 pcx( unsigned int w, unsigned int h ); 00360 pcx( const image& that ); 00361 pcx( std::istream& f ); 00362 00363 void save( std::ostream& os ) const; 00364 00365 }; // class pcx 00366 } // namespace graphic 00367 } // namespace claw 00368 00369 #include <claw/impl/pcx_writer.tpp> 00370 #include <claw/impl/pcx_reader.tpp> 00371 00372 #endif // __CLAW_PCX_HPP__