CLAW Library (a C++ Library Absolutely Wonderful) 1.5.5
Classes | Public Member Functions | Private Types | Private Member Functions | Private Attributes
claw::graphic::gif::reader Class Reference

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>

List of all members.

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_pixelpalette_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

imagem_image
 The gif file on which we work.
frame_list m_frame
 The images in which we store the data we read.

Detailed Description

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.

Author:
Julien Jorge

Definition at line 279 of file gif.hpp.


Member Typedef Documentation

LZW decoder for the GIF data.

Definition at line 396 of file gif.hpp.

The type of the color palettes in the file.

Definition at line 283 of file gif.hpp.


Constructor & Destructor Documentation

claw::graphic::gif::reader::reader ( image img)

Constructor.

Parameters:
imgThe 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.

Parameters:
imgThe image in which we store the data.
fThe 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().

  : m_image(&img)
{
  load( f );
} // gif::reader::reader()
claw::graphic::gif::reader::reader ( frame_list frames,
std::istream &  f 
)

Constructor.

Parameters:
framesThe frames read from the file.
fThe 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.

  : m_image(NULL) 
{
  load( f );
  frames = m_frame;
  m_frame.clear();
} // gif::reader::reader()
claw::graphic::gif::reader::reader ( image img,
frame_list frames,
std::istream &  f 
)

Constructor.

Parameters:
imgThe image in which we store the data.
framesThe frames read from the file.
fThe 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.

  : m_image(&img) 
{
  load( f );
  frames = m_frame;
  m_frame.clear();
} // gif::reader::reader()
claw::graphic::gif::reader::~reader ( )

Destructor.

Definition at line 331 of file gif_reader.cpp.

{
  clear();
} // gif::reader::~reader()

Member Function Documentation

void claw::graphic::gif::reader::check_if_gif ( std::istream &  f) const [private]

Check if a stream contains gif data.

Parameters:
fThe 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.

Parameters:
fThe stream to read.
paletteThe color palette to use.
idThe descriptor of the current frame.
transparent_color_indexThe index of the transparent color in p.
the_frame(in/out) The frame in which we save the pixels.
Precondition:
The cursor in the stream f is positioned at the beginning of an LZW encoded block (just on the code size byte).

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.

Parameters:
imgThe image to fill.
infoThe 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.

Parameters:
fThe 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.

Parameters:
fThe 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().

{
  clear();

  inside_load(f);

  if ( !m_frame.empty() && (m_image!=NULL) )
    *m_image = *m_frame.front();
} // gif::reader::load()
void claw::graphic::gif::reader::make_frames ( const reader_info info) [private]

Create the frames of the final animation.

Parameters:
infoThe 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.

Parameters:
fThe stream to read.
infoSome 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.

Parameters:
fThe stream to read.
infoSome 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.

Parameters:
fThe stream to read.
infoSome global data needed when reading the file.
the_frame(in/out) The frame in which we save the pixels.
Precondition:
The cursor in the stream f is positioned at the beginning of an image_descriptor block (just after the separator code).

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.

Parameters:
fThe stream to read.
infoSome 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.

Parameters:
fThe 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.

Parameters:
fThe 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.

Parameters:
fThe stream to read.
Precondition:
The label of the extension is already 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()

Member Data Documentation

The images in which we store the data we read.

Definition at line 435 of file gif.hpp.

The gif file on which we work.

Definition at line 432 of file gif.hpp.


The documentation for this class was generated from the following files: