00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
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 };
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 };
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 };
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 };
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 };
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 };
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 };
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 };
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 };
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 };
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 };
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 };
00366 }
00367 }
00368
00369 #include <claw/impl/pcx_writer.tpp>
00370 #include <claw/impl/pcx_reader.tpp>
00371
00372 #endif // __CLAW_PCX_HPP__