Claw  1.7.3
gif.hpp
Go to the documentation of this file.
1 /*
2  CLAW - a C++ Library Absolutely Wonderful
3 
4  CLAW is a free library without any particular aim but being useful to
5  anyone.
6 
7  Copyright (C) 2005-2011 Julien Jorge
8 
9  This library is free software; you can redistribute it and/or
10  modify it under the terms of the GNU Lesser General Public
11  License as published by the Free Software Foundation; either
12  version 2.1 of the License, or (at your option) any later version.
13 
14  This library is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public
20  License along with this library; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 
23  contact: julien.jorge@gamned.org
24 */
30 #ifndef __CLAW_GIF_HPP__
31 #define __CLAW_GIF_HPP__
32 
33 #include <claw/color_palette.hpp>
34 #include <claw/functional.hpp>
35 #include <claw/image.hpp>
36 #include <claw/iterator.hpp>
37 #include <claw/lzw_decoder.hpp>
38 #include <claw/types.hpp>
39 
40 #include <list>
41 
42 namespace claw
43 {
44  namespace graphic
45  {
50  class gif:
51  public image
52  {
53  public:
55  class frame:
56  public image
57  {
58  public:
60  typedef image super;
61 
62  public:
63  frame();
64  frame( std::size_t w, std::size_t h );
65 
66  void set_delay(unsigned int d);
67  unsigned int get_delay() const;
68 
69  private:
72  unsigned int m_delay;
73 
74  }; // class frame
75 
76  private:
78  typedef std::list<frame*> frame_list;
79 
81  typedef image super;
82 
83  public:
85  typedef wrapped_iterator
86  < frame,
89 
91  typedef wrapped_iterator
92  < const frame,
95 
96  private:
97 #pragma pack(push, 1)
98 
100  struct header
101  {
103  u_int_8 signature[3];
104 
106  u_int_8 version[3];
107 
108  }; // struct header
109 
111  struct screen_descriptor
112  {
113  public:
114  bool has_global_color_table() const;
115  unsigned int color_palette_size() const;
116 
117  public:
119  u_int_16 screen_width;
120 
122  u_int_16 screen_height;
123 
125  u_int_8 packed;
126 
128  u_int_8 background_color;
129 
131  u_int_8 aspect_ratio;
132 
133  }; // struct screen_descriptor
134 
136  struct image_descriptor
137  {
138  public:
140  static const u_int_8 block_id = 0x2C;
141 
142  public:
143  bool has_color_table() const;
144  bool is_interlaced() const;
145  unsigned int color_palette_size() const;
146 
147  public:
149  u_int_16 left;
150 
152  u_int_16 top;
153 
155  u_int_16 width;
156 
159 
161  u_int_8 packed;
162 
163  }; // struct image_descriptor
164 
166  struct extension
167  {
169  static const u_int_8 block_id = 0x21;
170 
171  // no field
172  }; // struct extension
173 
175  struct trailer
176  {
178  static const u_int_8 block_id = 0x3B;
179 
180  // no field
181  }; // trailer
182 
184  struct graphic_control_extension
185  {
186  public:
188  static const u_int_8 block_label = 0xF9;
189 
192  enum disposal_method
193  {
196  dispose_none,
197 
199  dispose_do_not_dispose,
200 
203  dispose_background,
204 
208  dispose_previous
209 
210  }; // enum disposal_method
211 
212  public:
213  disposal_method get_disposal_method() const;
214  bool has_transparent_color() const;
215 
216  public:
218  u_int_8 block_size;
219 
221  u_int_8 packed;
222 
224  u_int_16 delay;
225 
227  u_int_8 transparent_color;
228 
230  u_int_8 terminator;
231 
232  }; // struct graphic_control_extension
233 
235  struct comment_extension
236  {
237  public:
239  static const u_int_8 block_label = 0xFE;
240 
241  public:
242  // this block is ignored.
243 
244  }; // struct comment_extension
245 
247  struct plain_text_extension
248  {
249  public:
251  static const u_int_8 block_label = 0x01;
252 
253  public:
254  // this block is ignored.
255 
256  }; // struct plain_text_extension
257 
259  struct application_extension
260  {
261  public:
263  static const u_int_8 block_label = 0xFF;
264 
265  public:
266  // this block is ignored.
267 
268  }; // struct application_extension
269 #pragma pack(pop)
270 
271  public:
272  /*----------------------------------------------------------------------*/
279  class reader
280  {
281  private:
284 
286  struct reader_info
287  {
289  screen_descriptor sd;
290 
292  palette_type* palette;
293 
295  int transparent_color_index;
296 
298  std::vector<graphic_control_extension::disposal_method>
299  disposal_method;
300 
301  }; // struct reader_info
302 
304  class input_buffer
305  {
306  public:
307  input_buffer( std::istream& is, u_int_8 code_size );
308 
309  bool end_of_data() const;
310  bool end_of_information() const;
311  unsigned int symbols_count() const;
312  unsigned int get_next();
313 
314  void reset();
315  void new_code( unsigned int code );
316 
317  private:
318  void fill_buffer();
319 
320  private:
322  unsigned int m_val;
323 
325  std::istream& m_input;
326 
333  char m_buffer[257];
334 
336  std::size_t m_pending;
337 
339  unsigned char m_pending_bits;
340 
342  std::size_t m_pending_end;
343 
345  u_int_8 m_next_data_length;
346 
348  const unsigned int m_initial_code_size;
349 
351  unsigned int m_code_size;
352 
354  unsigned int m_code_limit;
355 
356  }; // class input_buffer
357 
359  class output_buffer
360  {
361  public:
362  output_buffer
363  ( const palette_type& p, const image_descriptor& id,
364  int transparent_color_index, image& output );
365 
366  void write( unsigned int code );
367 
368  private:
370  const palette_type& m_palette;
371 
373  const image_descriptor& m_id;
374 
376  const int m_transparent_color_index;
377 
379  image& m_output;
380 
382  std::size_t m_x;
383 
385  std::size_t m_y;
386 
388  int m_interlace_pass;
389 
391  int m_interlace_step;
392 
393  }; // class output_buffer
394 
397 
398  public:
399  reader( image& img );
400  reader( image& img, std::istream& f );
401  reader( frame_list& frames, std::istream& f );
402  reader( image& img, frame_list& frames, std::istream& f );
403  ~reader();
404 
405  void load( std::istream& f );
406 
407  private:
408  void clear();
409  void inside_load( std::istream& f );
410  void make_frames( const reader_info& info );
411  void fill_background( image& img, const reader_info& info ) const;
412 
413  void check_if_gif( std::istream& f ) const;
414  void read_screen_descriptor( std::istream& f, reader_info& info );
415 
416  void read_palette( std::istream& f, palette_type& p ) const;
417  void read_data( std::istream& f, reader_info& info );
418  void read_frame( std::istream& f, reader_info& info );
419  void read_frame_with_gce( std::istream& f, reader_info& info );
420 
421  void skip_extension( std::istream& f ) const;
422  void read_frame_data
423  ( std::istream& f, const reader_info& info, frame& the_frame ) const;
424 
425  void decode_data
426  ( std::istream& f, const palette_type& palette,
427  const image_descriptor& id, int transparent_color_index,
428  frame& the_frame ) const;
429 
430  private:
432  image* m_image;
433 
435  frame_list m_frame;
436 
437  }; // class reader
438 
439  public:
440  gif();
441  gif( const gif& that );
442  gif( std::istream& f );
443  ~gif();
444 
445  gif& operator=( const gif& that );
446  void swap( gif& that );
447 
452 
453  private:
455  frame_list m_frame;
456 
457  }; // class gif
458  } // namespace graphic
459 } // namespace claw
460 
461 namespace std
462 {
463  void swap( claw::graphic::gif& a, claw::graphic::gif& b );
464 } // namespace std
465 
466 #endif // __CLAW_GIF_HPP__