Claw
1.7.3
|
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__