This class reads data from a gif file. The image is resized to the size of the screen (as defined in the gif file) and the frames are stored in a list of frames passed as parameter. More...
#include <gif.hpp>
Classes | |
class | input_buffer |
The buffer passed to the LZW decoder to decode the input. More... | |
class | output_buffer |
Buffer passed to the LZW decoder to write decoded data. More... | |
struct | reader_info |
Some global data needed when reading the file. More... | |
Public Member Functions | |
reader (image &img) | |
Constructor. | |
reader (image &img, std::istream &f) | |
Constructor. | |
reader (frame_list &frames, std::istream &f) | |
Constructor. | |
reader (image &img, frame_list &frames, std::istream &f) | |
Constructor. | |
~reader () | |
Destructor. | |
void | load (std::istream &f) |
Load the image data from a stream. | |
Private Types | |
typedef color_palette< rgb_pixel > | palette_type |
The type of the color palettes in the file. | |
typedef claw::lzw_decoder < input_buffer, output_buffer > | gif_lzw_decoder |
LZW decoder for the GIF data. | |
Private Member Functions | |
void | clear () |
Clear the data read from a file. | |
void | inside_load (std::istream &f) |
Load the image data from a stream. | |
void | make_frames (const reader_info &info) |
Create the frames of the final animation. | |
void | fill_background (image &img, const reader_info &info) const |
Fill an image with the correct background color. | |
void | check_if_gif (std::istream &f) const |
Check if a stream contains gif data. | |
void | read_screen_descriptor (std::istream &f, reader_info &info) |
Read the screen descriptor and initialize the screen. | |
void | read_palette (std::istream &f, palette_type &p) const |
Read a palette. | |
void | read_data (std::istream &f, reader_info &info) |
Read the data of the gif stream. | |
void | read_frame (std::istream &f, reader_info &info) |
Read a frame without graphic control extension. | |
void | read_frame_with_gce (std::istream &f, reader_info &info) |
Read the data of the gif stream. | |
void | skip_extension (std::istream &f) const |
Skip an extension block. | |
void | read_frame_data (std::istream &f, const reader_info &info, frame &the_frame) const |
Read the data of a frame. | |
void | decode_data (std::istream &f, const palette_type &palette, const image_descriptor &id, int transparent_color_index, frame &the_frame) const |
Decode the pixels of a frame. | |
Private Attributes | |
image * | m_image |
The gif file on which we work. | |
frame_list | m_frame |
The images in which we store the data we read. |
This class reads data from a gif file. The image is resized to the size of the screen (as defined in the gif file) and the frames are stored in a list of frames passed as parameter.
Definition at line 279 of file gif.hpp.
typedef claw::lzw_decoder<input_buffer, output_buffer> claw::graphic::gif::reader::gif_lzw_decoder [private] |
typedef color_palette<rgb_pixel> claw::graphic::gif::reader::palette_type [private] |
claw::graphic::gif::reader::reader | ( | image & | img ) |
Constructor.
img | The image in which we store the data. |
Definition at line 272 of file gif_reader.cpp.
: m_image(&img) { } // gif::reader::reader()
claw::graphic::gif::reader::reader | ( | image & | img, |
std::istream & | f | ||
) |
Constructor.
img | The image in which we store the data. |
f | The stream from which we read the data (gif file format). |
The first frame of the gif will be saved in the image passed to the constructor.
Definition at line 287 of file gif_reader.cpp.
References load().
claw::graphic::gif::reader::reader | ( | frame_list & | frames, |
std::istream & | f | ||
) |
Constructor.
frames | The frames read from the file. |
f | The stream from which we read the data (gif file format). |
Definition at line 300 of file gif_reader.cpp.
References claw::graphic::image::load(), and claw::graphic::gif::m_frame.
claw::graphic::gif::reader::reader | ( | image & | img, |
frame_list & | frames, | ||
std::istream & | f | ||
) |
Constructor.
img | The image in which we store the data. |
frames | The frames read from the file. |
f | The stream from which we read the data (gif file format). |
The first frame of the gif will be saved in the image passed to the constructor.
Definition at line 319 of file gif_reader.cpp.
References claw::graphic::image::load(), and claw::graphic::gif::m_frame.
claw::graphic::gif::reader::~reader | ( | ) |
void claw::graphic::gif::reader::check_if_gif | ( | std::istream & | f ) | const [private] |
Check if a stream contains gif data.
f | The stream to check. |
Definition at line 474 of file gif_reader.cpp.
References CLAW_PRECOND, claw::graphic::gif::header::signature, and claw::graphic::gif::header::version.
{ CLAW_PRECOND( !!f ); header h; f.read( reinterpret_cast<char*>(&h), sizeof(header) ); bool valid = false; if ( f.rdstate() == std::ios_base::goodbit ) if ( (h.signature[0] == 'G') && (h.signature[1] == 'I') && (h.signature[2] == 'F') && (h.version[0] == '8') && ( (h.version[1] == '7') || (h.version[1] == '9') ) && (h.version[2] == 'a') ) valid = true; if ( !valid ) throw claw::bad_format( "Not a GIF file." ); } // gif::reader::check_if_gif()
void claw::graphic::gif::reader::clear | ( | ) | [private] |
Clear the data read from a file.
Definition at line 355 of file gif_reader.cpp.
References claw::graphic::gif::m_frame.
{ std::for_each ( m_frame.begin(), m_frame.end(), claw::delete_function<frame*>() ); m_frame.clear(); } // gif::reader::clear()
void claw::graphic::gif::reader::decode_data | ( | std::istream & | f, |
const palette_type & | palette, | ||
const image_descriptor & | id, | ||
int | transparent_color_index, | ||
frame & | the_frame | ||
) | const [private] |
Decode the pixels of a frame.
f | The stream to read. |
palette | The color palette to use. |
id | The descriptor of the current frame. |
transparent_color_index | The index of the transparent color in p. |
the_frame | (in/out) The frame in which we save the pixels. |
Definition at line 713 of file gif_reader.cpp.
References claw::lzw_decoder< InputBuffer, OutputBuffer >::decode(), claw::graphic::gif::reader::input_buffer::end_of_information(), and claw::graphic::gif::reader::input_buffer::reset().
{ u_int_8 code_size; f.read( reinterpret_cast<char*>(&code_size), sizeof(code_size) ); input_buffer input(f, code_size); output_buffer output(palette, id, transparent_color_index, the_frame); do { gif_lzw_decoder decoder; input.reset(); decoder.decode(input, output); } while ( !input.end_of_information() ); } // gif::reader::decode_data()
void claw::graphic::gif::reader::fill_background | ( | image & | img, |
const reader_info & | info | ||
) | const [private] |
Fill an image with the correct background color.
img | The image to fill. |
info | The informations on the gif file. |
Definition at line 458 of file gif_reader.cpp.
References claw::graphic::gif::screen_descriptor::background_color, claw::graphic::image::begin(), claw::graphic::image::end(), claw::graphic::image::fill(), claw::graphic::gif::screen_descriptor::has_global_color_table(), claw::graphic::gif::reader::reader_info::palette, claw::graphic::gif::reader::reader_info::sd, claw::graphic::color_palette< Color >::size(), and claw::graphic::transparent_pixel.
{ rgba_pixel clr(transparent_pixel); if ( info.sd.has_global_color_table() && (info.palette != NULL) ) if (info.sd.background_color < info.palette->size() ) clr = (*info.palette)[info.sd.background_color]; std::fill( img.begin(), img.end(), clr ); } // gif::reader::fill_background()
void claw::graphic::gif::reader::inside_load | ( | std::istream & | f ) | [private] |
Load the image data from a stream.
f | The stream from which we read the data (gif file format). |
Definition at line 367 of file gif_reader.cpp.
References claw::graphic::gif::reader::reader_info::palette.
{ std::istream::pos_type init_pos = f.tellg(); reader_info info; info.palette = NULL; try { check_if_gif(f); read_screen_descriptor(f, info); read_data(f, info); make_frames(info); delete info.palette; } catch(...) { delete info.palette; f.seekg( init_pos, std::ios_base::beg ); throw; } } // gif::reader::inside_load()
void claw::graphic::gif::reader::load | ( | std::istream & | f ) |
Load the image data from a stream.
f | The stream from which we read the data (gif file format). |
Definition at line 341 of file gif_reader.cpp.
References claw::graphic::gif::m_frame.
Referenced by reader().
void claw::graphic::gif::reader::make_frames | ( | const reader_info & | info ) | [private] |
Create the frames of the final animation.
info | The informations on the gif file. |
Definition at line 397 of file gif_reader.cpp.
References claw::graphic::image::begin(), claw::graphic::gif::reader::reader_info::disposal_method, claw::graphic::gif::graphic_control_extension::dispose_background, claw::graphic::gif::graphic_control_extension::dispose_previous, claw::graphic::image::end(), claw::graphic::image::fill(), claw::graphic::gif::frame::get_delay(), claw::graphic::gif::m_frame, claw::graphic::image::merge(), claw::graphic::gif::screen_descriptor::screen_height, claw::graphic::gif::screen_descriptor::screen_width, claw::graphic::gif::reader::reader_info::sd, claw::graphic::gif::frame::set_delay(), claw::graphic::gif::swap(), and claw::graphic::transparent_pixel.
{ it_index<frame_list::const_iterator> it(m_frame.begin()); frame_list result; std::size_t cumul_count(0); frame cumul(info.sd.screen_width, info.sd.screen_height); frame prev; if ( !info.disposal_method.empty() ) { if ( info.disposal_method[0] == graphic_control_extension::dispose_background ) fill_background(cumul, info); else std::fill(cumul.begin(), cumul.end(), transparent_pixel); } for ( ; it!=m_frame.end(); ++it ) { if ( info.disposal_method[it] == graphic_control_extension::dispose_previous ) prev = cumul; cumul.merge(**it); cumul.set_delay( (*it)->get_delay() ); ++cumul_count; if ( cumul.get_delay() > 0 ) { result.push_back( new frame(cumul) ); cumul_count = 0; } switch( info.disposal_method[it] ) { case graphic_control_extension::dispose_background: fill_background(cumul, info); break; case graphic_control_extension::dispose_previous: cumul = prev; break; default: { /* nothing to do */ } } } if ( cumul_count != 0 ) result.push_back( new frame(cumul) ); clear(); std::swap( m_frame, result ); } // gif::reader::make_frames()
void claw::graphic::gif::reader::read_data | ( | std::istream & | f, |
reader_info & | info | ||
) | [private] |
Read the data of the gif stream.
f | The stream to read. |
info | Some global data needed when reading the file. |
Definition at line 544 of file gif_reader.cpp.
References claw::graphic::gif::trailer::block_id, claw::graphic::gif::image_descriptor::block_id, claw::graphic::gif::extension::block_id, and claw::graphic::gif::graphic_control_extension::block_label.
{ u_int_8 code; do { code = 0; f.read( reinterpret_cast<char*>(&code), sizeof(code) ); if (f) switch(code) { case extension::block_id: f.read( reinterpret_cast<char*>(&code), sizeof(code) ); if (code == graphic_control_extension::block_label) read_frame_with_gce(f, info); else skip_extension(f); break; case image_descriptor::block_id: read_frame(f, info); break; case trailer::block_id: break; default: throw claw::bad_format( "gif::reader: invalid code" ); } } while ( f && (code != trailer::block_id) ); } // gif::reader::read_data()
void claw::graphic::gif::reader::read_frame | ( | std::istream & | f, |
reader_info & | info | ||
) | [private] |
Read a frame without graphic control extension.
f | The stream to read. |
info | Some global data needed when reading the file. |
Definition at line 584 of file gif_reader.cpp.
References claw::graphic::gif::reader::reader_info::disposal_method, claw::graphic::gif::graphic_control_extension::dispose_none, and claw::graphic::gif::m_frame.
{ frame* new_frame(NULL); try { new_frame = new frame; read_frame_data(f, info, *new_frame); info.disposal_method.push_back(graphic_control_extension::dispose_none); m_frame.push_back(new_frame); } catch(...) { delete new_frame; throw; } } // gif::reader::read_frame()
void claw::graphic::gif::reader::read_frame_data | ( | std::istream & | f, |
const reader_info & | info, | ||
frame & | the_frame | ||
) | const [private] |
Read the data of a frame.
f | The stream to read. |
info | Some global data needed when reading the file. |
the_frame | (in/out) The frame in which we save the pixels. |
Definition at line 677 of file gif_reader.cpp.
References claw::graphic::image::begin(), claw::graphic::image::end(), claw::graphic::image::fill(), claw::graphic::gif::reader::reader_info::palette, claw::graphic::gif::screen_descriptor::screen_height, claw::graphic::gif::screen_descriptor::screen_width, claw::graphic::gif::reader::reader_info::sd, claw::graphic::image::set_size(), claw::graphic::gif::reader::reader_info::transparent_color_index, and claw::graphic::transparent_pixel.
{ image_descriptor id; f.read( reinterpret_cast<char*>(&id), sizeof(id) ); the_frame.set_size(info.sd.screen_width, info.sd.screen_height); std::fill( the_frame.begin(), the_frame.end(), transparent_pixel ); palette_type* palette(info.palette); if ( id.has_color_table() ) { palette = new palette_type(id.color_palette_size()); read_palette(f, *palette); } decode_data(f, *palette, id, info.transparent_color_index, the_frame); if ( id.has_color_table() ) delete palette; } // gif::reader::read_frame_data()
void claw::graphic::gif::reader::read_frame_with_gce | ( | std::istream & | f, |
reader_info & | info | ||
) | [private] |
Read the data of the gif stream.
f | The stream to read. |
info | Some global data needed when reading the file. |
Definition at line 610 of file gif_reader.cpp.
References claw::graphic::gif::image_descriptor::block_id, claw::graphic::gif::extension::block_id, claw::graphic::gif::graphic_control_extension::block_label, claw::graphic::gif::graphic_control_extension::delay, claw::graphic::gif::reader::reader_info::disposal_method, claw::graphic::gif::graphic_control_extension::get_disposal_method(), claw::graphic::gif::graphic_control_extension::has_transparent_color(), claw::graphic::gif::m_frame, claw::graphic::gif::frame::set_delay(), claw::graphic::gif::graphic_control_extension::transparent_color, and claw::graphic::gif::reader::reader_info::transparent_color_index.
{ graphic_control_extension gce; u_int_8 code; f.read( reinterpret_cast<char*>(&gce), sizeof(gce) ); f.read( reinterpret_cast<char*>(&code), sizeof(code) ); while ( (code == extension::block_id) && f ) { f.read( reinterpret_cast<char*>(&code), sizeof(code) ); if (code == graphic_control_extension::block_label) f.read( reinterpret_cast<char*>(&gce), sizeof(gce) ); else // unknown extension skip_extension(f); // read the code of the following block f.read( reinterpret_cast<char*>(&code), sizeof(code) ); } if (code == image_descriptor::block_id) { frame* new_frame = new frame; new_frame->set_delay(gce.delay); info.disposal_method.push_back(gce.get_disposal_method()); if ( gce.has_transparent_color() ) info.transparent_color_index = gce.transparent_color; else info.transparent_color_index = -1; read_frame_data(f, info, *new_frame); m_frame.push_back(new_frame); } } // gif::reader::read_frame_with_gce()
void claw::graphic::gif::reader::read_palette | ( | std::istream & | f, |
palette_type & | p | ||
) | const [private] |
Read a palette.
f | The stream from which we read the palette. |
p | (out) The palette. |
Definition at line 521 of file gif_reader.cpp.
References claw::graphic::color_palette< Color >::size().
{ u_int_8 red, green, blue; for (std::size_t i=0; i!=p.size(); ++i) { f.read( reinterpret_cast<char*>(&red), sizeof(u_int_8) ); f.read( reinterpret_cast<char*>(&green), sizeof(u_int_8) ); f.read( reinterpret_cast<char*>(&blue), sizeof(u_int_8) ); p[i].components.red = red; p[i].components.green = green; p[i].components.blue = blue; } } // gif::reader::read_palette()
void claw::graphic::gif::reader::read_screen_descriptor | ( | std::istream & | f, |
reader_info & | info | ||
) | [private] |
Read the screen descriptor and initialize the screen.
f | The stream from which we read the data (gif file format). |
info | (out) Some global data needed when reading the file. |
Definition at line 503 of file gif_reader.cpp.
References claw::graphic::gif::screen_descriptor::color_palette_size(), claw::graphic::gif::screen_descriptor::has_global_color_table(), claw::graphic::gif::reader::reader_info::palette, and claw::graphic::gif::reader::reader_info::sd.
{ f.read( reinterpret_cast<char*>(&info.sd), sizeof(screen_descriptor) ); if ( info.sd.has_global_color_table() ) { info.palette = new palette_type(info.sd.color_palette_size()); read_palette(f, *info.palette); } } // gif::reader::read_screen_descriptor()
void claw::graphic::gif::reader::skip_extension | ( | std::istream & | f ) | const [private] |
Skip an extension block.
f | The stream to read. |
Definition at line 654 of file gif_reader.cpp.
{ u_int_8 block_size(0); f.read( reinterpret_cast<char*>(&block_size), sizeof(block_size) ); while ( f && (block_size!=0) ) { f.seekg( block_size, std::ios_base::cur ); f.read( reinterpret_cast<char*>(&block_size), sizeof(block_size) ); } } // gif::reader::skip_extension()
image* claw::graphic::gif::reader::m_image [private] |