CLAW Library (a C++ Library Absolutely Wonderful) 1.5.5

pcx.hpp

Go to the documentation of this file.
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__