Claw  1.7.3
targa.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-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 */
00030 #ifndef __CLAW_TARGA_HPP__
00031 #define __CLAW_TARGA_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/buffered_istream.hpp>
00039 
00040 namespace claw
00041 {
00042   namespace graphic
00043   {
00048     class targa : public image
00049     {
00050     private:
00051       /*----------------------------------------------------------------------*/
00057       class file_structure
00058       {
00059       public:
00060         enum image_coding
00061           {
00062             color_mapped        = 1,
00063             true_color          = 2,
00064             black_and_white     = 3,
00065             rle_color_mapped    = 9,
00066             rle_true_color      = 10,
00067             rle_black_and_white = 11
00068           }; // enum image_coding
00069 
00070 #       pragma pack (push,1)
00071 
00072         /*--------------------------------------------------------------------*/
00076         class header
00077         {
00078         public:
00079           header();
00080           header( unsigned int w, unsigned int h );
00081 
00082         public:
00084           char id_length;
00086           char color_map;
00088           char image_type;
00089 
00091           struct
00092           {
00094             unsigned short first_entry_index;
00096             unsigned short length;
00098             unsigned char entry_size;
00099           } color_map_specification;
00100 
00102           struct specification
00103           {
00105             unsigned short x_origin;
00107             unsigned short y_origin;
00109             unsigned short width;
00111             unsigned short height;
00113             unsigned char bpp;
00115             unsigned char descriptor;
00116 
00117             bool up_down_oriented() const ;
00118             bool left_right_oriented() const ;
00119             unsigned char alpha() const;
00120           }; // struct specification
00121 
00123           specification image_specification;
00124         }; // struct header
00125 
00126         /*--------------------------------------------------------------------*/
00130         struct developer_item
00131         {
00133           unsigned short tag;
00135           unsigned int offset;
00137           unsigned int size;
00138         }; // struct developer_item
00139 
00140         /*--------------------------------------------------------------------*/
00145         struct extension
00146         {
00147            
00148         }; // struct extension
00149 
00150         /*--------------------------------------------------------------------*/
00154         class footer
00155         {
00156         public:
00157           footer();
00158 
00159           bool is_valid() const;
00160 
00161         public:
00163           unsigned int extension_offset;
00164 
00166           unsigned int developer_offset;
00167 
00170           char signature[18];
00171 
00172         private:
00174           static const std::string s_signature;
00175 
00176         }; // struct footer
00177 #       pragma pack (pop)
00178 
00179       }; // class file_structure
00180 
00181       /*----------------------------------------------------------------------*/
00188       struct pixel16
00189       {
00190       }; // struct pixel16
00191 
00192       /*----------------------------------------------------------------------*/
00199       struct pixel8
00200       {
00201       }; // struct pixel8
00202 
00203       /*----------------------------------------------------------------------*/
00207       typedef color_palette<rgba_pixel_8> color_palette32;
00208 
00209     public:
00210       /*----------------------------------------------------------------------*/
00216       class reader : private file_structure
00217       {
00218       private:
00219         /*--------------------------------------------------------------------*/
00227         template<typename Pixel>
00228         class file_input_buffer : public buffered_istream<std::istream>
00229         {
00230         private:
00232           typedef Pixel pixel_type;
00233 
00234         public:
00235           file_input_buffer( std::istream& f );
00236           rgba_pixel_8 get_pixel();
00237 
00238         }; // class file_input_buffer
00239 
00240         /*--------------------------------------------------------------------*/
00248         template<typename Pixel>
00249         class mapped_file_input_buffer:
00250           public buffered_istream<std::istream>
00251         {
00252         private:
00254           typedef Pixel pixel_type;
00255 
00256         public:
00257           mapped_file_input_buffer( std::istream& f, const color_palette32& p );
00258           rgba_pixel_8 get_pixel();
00259 
00260         private:
00262           const color_palette32& m_palette;
00263 
00264         }; // class mapped_file_input_buffer
00265 
00266         /*--------------------------------------------------------------------*/
00275         template< typename InputBuffer >
00276         class rle_targa_output_buffer
00277         {
00278         private:
00280           typedef rgba_pixel_8 pixel_type;
00281 
00283           typedef InputBuffer input_buffer_type;
00284 
00285         public:
00286           rle_targa_output_buffer( image& img, bool up_down, bool left_right );
00287         
00288           void fill( unsigned int n, rgba_pixel_8 pattern );
00289           void copy( unsigned int n, input_buffer_type& buffer );
00290         
00291           bool completed() const;
00292 
00293         private:
00294           void adjust_position(int x);
00295 
00296         private:
00298           image& m_image;
00299 
00301           unsigned int m_x;
00302 
00304           unsigned int m_y;
00305 
00307           const int m_x_inc;
00308 
00310           const int m_y_inc;
00311 
00312         }; // class rle_targa_output_buffer
00313 
00314         /*--------------------------------------------------------------------*/
00327         template< typename InputBuffer,
00328                   typename OutputBuffer = rle_targa_output_buffer<InputBuffer> >
00329         class rle_targa_decoder
00330           : public rle_decoder< rgba_pixel_8, InputBuffer, OutputBuffer >
00331         {
00332         public:
00334           typedef InputBuffer input_buffer_type;
00335 
00337           typedef OutputBuffer output_buffer_type;
00338 
00339         private:
00340           virtual void
00341           read_mode( input_buffer_type& input, output_buffer_type& output );
00342 
00343         }; // class rle_targa_decoder
00344 
00345         /*--------------------------------------------------------------------*/
00347         typedef
00348         rle_targa_decoder< file_input_buffer<rgba_pixel_8> > rle32_decoder;
00349 
00350         /*--------------------------------------------------------------------*/
00352         typedef
00353         rle_targa_decoder< file_input_buffer<rgb_pixel_8> > rle24_decoder;
00354       
00355         /*--------------------------------------------------------------------*/
00357         typedef rle_targa_decoder< file_input_buffer<pixel16> > rle16_decoder;
00358 
00359         /*--------------------------------------------------------------------*/
00361         typedef rle_targa_decoder< mapped_file_input_buffer<pixel8> >
00362         rle8_decoder;
00363 
00364       public:
00365         reader( image& img );
00366         reader( image& img, std::istream& f );
00367 
00368         void load( std::istream& f );
00369 
00370       private:
00371         void check_if_targa( std::istream& f ) const;
00372 
00373         void load_palette
00374         ( const header& h, std::istream& f, color_palette32& palette ) const;
00375 
00376         void load_color_mapped( const header& h, std::istream& f );
00377         void load_rle_color_mapped( const header& h, std::istream& f );
00378         void load_true_color( const header& h, std::istream& f );
00379         void load_rle_true_color( const header& h, std::istream& f );
00380         
00381         template<typename Pixel>
00382         void load_color_mapped_raw
00383         ( const header& h, std::istream& f, const color_palette32& palette );
00384 
00385         template<typename Decoder>
00386         void decompress_rle_color_mapped
00387         ( const header& h, std::istream& f, const color_palette32& palette );
00388 
00389         template<typename Pixel>
00390         void load_true_color_raw( const header& h, std::istream& f );
00391 
00392         template<typename Decoder>
00393         void decompress_rle_true_color( const header& h, std::istream& f );
00394 
00395         template<typename Pixel>
00396         void
00397         load_palette_content( std::istream& f, color_palette32& palette ) const;
00398 
00399      private:
00401         image& m_image;
00402 
00403       }; // class reader
00404 
00405       /*----------------------------------------------------------------------*/
00410       class writer : private file_structure
00411       {
00412       public:
00413         /*--------------------------------------------------------------------*/
00421         template<typename Pixel>
00422         class file_output_buffer
00423         {
00424         public:
00426           typedef Pixel pixel_type;
00427 
00429           typedef pixel_type pattern_type;
00430 
00431         public:
00432           file_output_buffer( std::ostream& os );
00433           void encode( unsigned int n, pattern_type pattern );
00434 
00435           template<typename Iterator>
00436           void raw( Iterator first, Iterator last );
00437 
00438           unsigned int min_interesting() const;
00439           unsigned int max_encodable() const;
00440 
00446           void order_pixel_bytes( const pixel_type& p );
00447 
00448         private:
00450           std::ostream& m_stream;
00451 
00452         }; // class file_output_buffer
00453 
00454         /*--------------------------------------------------------------------*/
00463         template<typename Pixel>
00464         class rle_targa_encoder
00465           : public rle_encoder< file_output_buffer<Pixel> >
00466         {
00467         public:
00469           typedef file_output_buffer<Pixel> output_buffer_type;
00470 
00471         }; // class rle_targa_encoder
00472 
00473         /*--------------------------------------------------------------------*/
00475         typedef rle_targa_encoder<rgba_pixel_8> rle32_encoder;
00476 
00477       public:
00478         writer( const image& img );
00479         writer( const image& img, std::ostream& f, bool rle );
00480 
00481         void save( std::ostream& f, bool rle ) const;
00482 
00483       private:
00484         void save_true_color( std::ostream& os ) const;
00485         void save_rle_true_color( std::ostream& os ) const;
00486 
00487       private:
00489         const image& m_image;
00490 
00491       }; // class writer
00492 
00493     public:
00494       targa( unsigned int w, unsigned int h );
00495       targa( const image& that );
00496       targa( std::istream& f );
00497 
00498       void save( std::ostream& os, bool rle ) const;
00499 
00500     }; // class targa
00501   } // namespace graphic
00502 } // namespace claw
00503 
00504 #include <claw/impl/targa_writer.tpp>
00505 #include <claw/impl/targa_reader.tpp>
00506 
00507 #endif // __CLAW_TARGA_HPP__