Go to the documentation of this file.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_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 };
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 };
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 };
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 };
00164
00166 struct extension
00167 {
00169 static const u_int_8 block_id = 0x21;
00170
00171
00172 };
00173
00175 struct trailer
00176 {
00178 static const u_int_8 block_id = 0x3B;
00179
00180
00181 };
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 };
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 };
00233
00235 struct comment_extension
00236 {
00237 public:
00239 static const u_int_8 block_label = 0xFE;
00240
00241 public:
00242
00243
00244 };
00245
00247 struct plain_text_extension
00248 {
00249 public:
00251 static const u_int_8 block_label = 0x01;
00252
00253 public:
00254
00255
00256 };
00257
00259 struct application_extension
00260 {
00261 public:
00263 static const u_int_8 block_label = 0xFF;
00264
00265 public:
00266
00267
00268 };
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 };
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 };
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 };
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 };
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 };
00458 }
00459 }
00460
00461 namespace std
00462 {
00463 void swap( claw::graphic::gif& a, claw::graphic::gif& b );
00464 }
00465
00466 #endif // __CLAW_GIF_HPP__