Claw
1.7.0
|
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_GIF_HPP__ 00031 #define __CLAW_GIF_HPP__ 00032 00033 #include <claw/color_palette.hpp> 00034 #include <claw/functional.hpp> 00035 #include <claw/image.hpp> 00036 #include <claw/iterator.hpp> 00037 #include <claw/lzw_decoder.hpp> 00038 #include <claw/types.hpp> 00039 00040 #include <list> 00041 00042 namespace claw 00043 { 00044 namespace graphic 00045 { 00050 class gif: 00051 public image 00052 { 00053 public: 00055 class frame: 00056 public image 00057 { 00058 public: 00060 typedef image super; 00061 00062 public: 00063 frame(); 00064 frame( std::size_t w, std::size_t h ); 00065 00066 void set_delay(unsigned int d); 00067 unsigned int get_delay() const; 00068 00069 private: 00072 unsigned int m_delay; 00073 00074 }; // class frame 00075 00076 private: 00078 typedef std::list<frame*> frame_list; 00079 00081 typedef image super; 00082 00083 public: 00085 typedef wrapped_iterator 00086 < frame, 00087 frame_list::iterator, 00088 claw::dereference<frame> >::iterator_type frame_iterator; 00089 00091 typedef wrapped_iterator 00092 < const frame, 00093 frame_list::const_iterator, 00094 claw::const_dereference<frame> >::iterator_type const_frame_iterator; 00095 00096 private: 00097 #pragma pack(push, 1) 00098 00100 struct header 00101 { 00103 u_int_8 signature[3]; 00104 00106 u_int_8 version[3]; 00107 00108 }; // struct header 00109 00111 struct screen_descriptor 00112 { 00113 public: 00114 bool has_global_color_table() const; 00115 unsigned int color_palette_size() const; 00116 00117 public: 00119 u_int_16 screen_width; 00120 00122 u_int_16 screen_height; 00123 00125 u_int_8 packed; 00126 00128 u_int_8 background_color; 00129 00131 u_int_8 aspect_ratio; 00132 00133 }; // struct screen_descriptor 00134 00136 struct image_descriptor 00137 { 00138 public: 00140 static const u_int_8 block_id = 0x2C; 00141 00142 public: 00143 bool has_color_table() const; 00144 bool is_interlaced() const; 00145 unsigned int color_palette_size() const; 00146 00147 public: 00149 u_int_16 left; 00150 00152 u_int_16 top; 00153 00155 u_int_16 width; 00156 00158 u_int_16 height; 00159 00161 u_int_8 packed; 00162 00163 }; // struct image_descriptor 00164 00166 struct extension 00167 { 00169 static const u_int_8 block_id = 0x21; 00170 00171 // no field 00172 }; // struct extension 00173 00175 struct trailer 00176 { 00178 static const u_int_8 block_id = 0x3B; 00179 00180 // no field 00181 }; // trailer 00182 00184 struct graphic_control_extension 00185 { 00186 public: 00188 static const u_int_8 block_label = 0xF9; 00189 00192 enum disposal_method 00193 { 00196 dispose_none, 00197 00199 dispose_do_not_dispose, 00200 00203 dispose_background, 00204 00208 dispose_previous 00209 00210 }; // enum disposal_method 00211 00212 public: 00213 disposal_method get_disposal_method() const; 00214 bool has_transparent_color() const; 00215 00216 public: 00218 u_int_8 block_size; 00219 00221 u_int_8 packed; 00222 00224 u_int_16 delay; 00225 00227 u_int_8 transparent_color; 00228 00230 u_int_8 terminator; 00231 00232 }; // struct graphic_control_extension 00233 00235 struct comment_extension 00236 { 00237 public: 00239 static const u_int_8 block_label = 0xFE; 00240 00241 public: 00242 // this block is ignored. 00243 00244 }; // struct comment_extension 00245 00247 struct plain_text_extension 00248 { 00249 public: 00251 static const u_int_8 block_label = 0x01; 00252 00253 public: 00254 // this block is ignored. 00255 00256 }; // struct plain_text_extension 00257 00259 struct application_extension 00260 { 00261 public: 00263 static const u_int_8 block_label = 0xFF; 00264 00265 public: 00266 // this block is ignored. 00267 00268 }; // struct application_extension 00269 #pragma pack(pop) 00270 00271 public: 00272 /*----------------------------------------------------------------------*/ 00279 class reader 00280 { 00281 private: 00283 typedef color_palette<rgb_pixel> palette_type; 00284 00286 struct reader_info 00287 { 00289 screen_descriptor sd; 00290 00292 palette_type* palette; 00293 00295 int transparent_color_index; 00296 00298 std::vector<graphic_control_extension::disposal_method> 00299 disposal_method; 00300 00301 }; // struct reader_info 00302 00304 class input_buffer 00305 { 00306 public: 00307 input_buffer( std::istream& is, u_int_8 code_size ); 00308 00309 bool end_of_data() const; 00310 bool end_of_information() const; 00311 unsigned int symbols_count() const; 00312 unsigned int get_next(); 00313 00314 void reset(); 00315 void new_code( unsigned int code ); 00316 00317 private: 00318 void fill_buffer(); 00319 00320 private: 00322 unsigned int m_val; 00323 00325 std::istream& m_input; 00326 00333 char m_buffer[257]; 00334 00336 std::size_t m_pending; 00337 00339 unsigned char m_pending_bits; 00340 00342 std::size_t m_pending_end; 00343 00345 u_int_8 m_next_data_length; 00346 00348 const unsigned int m_initial_code_size; 00349 00351 unsigned int m_code_size; 00352 00354 unsigned int m_code_limit; 00355 00356 }; // class input_buffer 00357 00359 class output_buffer 00360 { 00361 public: 00362 output_buffer 00363 ( const palette_type& p, const image_descriptor& id, 00364 int transparent_color_index, image& output ); 00365 00366 void write( unsigned int code ); 00367 00368 private: 00370 const palette_type& m_palette; 00371 00373 const image_descriptor& m_id; 00374 00376 const int m_transparent_color_index; 00377 00379 image& m_output; 00380 00382 std::size_t m_x; 00383 00385 std::size_t m_y; 00386 00388 int m_interlace_pass; 00389 00391 int m_interlace_step; 00392 00393 }; // class output_buffer 00394 00396 typedef claw::lzw_decoder<input_buffer, output_buffer> gif_lzw_decoder; 00397 00398 public: 00399 reader( image& img ); 00400 reader( image& img, std::istream& f ); 00401 reader( frame_list& frames, std::istream& f ); 00402 reader( image& img, frame_list& frames, std::istream& f ); 00403 ~reader(); 00404 00405 void load( std::istream& f ); 00406 00407 private: 00408 void clear(); 00409 void inside_load( std::istream& f ); 00410 void make_frames( const reader_info& info ); 00411 void fill_background( image& img, const reader_info& info ) const; 00412 00413 void check_if_gif( std::istream& f ) const; 00414 void read_screen_descriptor( std::istream& f, reader_info& info ); 00415 00416 void read_palette( std::istream& f, palette_type& p ) const; 00417 void read_data( std::istream& f, reader_info& info ); 00418 void read_frame( std::istream& f, reader_info& info ); 00419 void read_frame_with_gce( std::istream& f, reader_info& info ); 00420 00421 void skip_extension( std::istream& f ) const; 00422 void read_frame_data 00423 ( std::istream& f, const reader_info& info, frame& the_frame ) const; 00424 00425 void decode_data 00426 ( std::istream& f, const palette_type& palette, 00427 const image_descriptor& id, int transparent_color_index, 00428 frame& the_frame ) const; 00429 00430 private: 00432 image* m_image; 00433 00435 frame_list m_frame; 00436 00437 }; // class reader 00438 00439 public: 00440 gif(); 00441 gif( const gif& that ); 00442 gif( std::istream& f ); 00443 ~gif(); 00444 00445 gif& operator=( const gif& that ); 00446 void swap( gif& that ); 00447 00448 frame_iterator frame_begin(); 00449 frame_iterator frame_end(); 00450 const_frame_iterator frame_begin() const; 00451 const_frame_iterator frame_end() const; 00452 00453 private: 00455 frame_list m_frame; 00456 00457 }; // class gif 00458 } // namespace graphic 00459 } // namespace claw 00460 00461 namespace std 00462 { 00463 void swap( claw::graphic::gif& a, claw::graphic::gif& b ); 00464 } // namespace std 00465 00466 #endif // __CLAW_GIF_HPP__