45 claw::graphic::gif::reader::input_buffer::input_buffer
46 ( std::istream& is,
u_int_8 code_size )
47 : m_val(0), m_input(is), m_pending(0), m_pending_bits(0), m_pending_end(0),
48 m_initial_code_size(code_size), m_code_size(m_initial_code_size+1),
49 m_code_limit(1 << m_code_size)
52 ( reinterpret_cast<char*>(&m_next_data_length),
53 sizeof(m_next_data_length) );
61 bool claw::graphic::gif::reader::input_buffer::end_of_data()
const
63 return (m_val == (
unsigned int)(1 << m_initial_code_size))
64 || end_of_information();
71 bool claw::graphic::gif::reader::input_buffer::end_of_information()
const
73 return !m_input || (m_val == (
unsigned int)(1 << m_initial_code_size)+1)
74 || ( (m_next_data_length == 0)
75 && (m_pending == m_pending_end)
76 && (m_pending_bits < m_code_size) );
83 unsigned int claw::graphic::gif::reader::input_buffer::symbols_count()
const
85 return (1 << m_initial_code_size) + 2;
92 unsigned int claw::graphic::gif::reader::input_buffer::get_next()
94 if ( m_pending == m_pending_end )
96 else if ( m_pending_bits + (m_pending_end - m_pending - 1) * CHAR_BIT
102 std::size_t n(m_code_size);
103 unsigned int cur_size = 0;
104 char* buf =
reinterpret_cast<char*
>(&m_val);
106 while ( (n != 0) && m_input )
108 while( (m_pending_bits != 0) && (n!=0) && m_input )
110 unsigned int bits = std::min((std::size_t)m_pending_bits, n);
112 if ( CHAR_BIT - cur_size < bits )
113 bits = CHAR_BIT - cur_size;
115 unsigned int mask = (1 << bits) - 1;
117 *buf |= (m_buffer[m_pending] & mask) << cur_size;
119 m_pending_bits -= bits;
120 m_buffer[m_pending] >>= bits;
123 if ( cur_size == CHAR_BIT )
130 if ( m_pending_bits == 0 )
134 if ( (m_pending == m_pending_end) && (n!=0) )
137 if ( m_pending == m_pending_end )
140 m_pending_bits = CHAR_BIT;
151 void claw::graphic::gif::reader::input_buffer::reset()
154 m_code_size = m_initial_code_size+1;
155 m_code_limit = 1 << m_code_size;
164 void claw::graphic::gif::reader::input_buffer::new_code(
unsigned int code )
166 if ( (code == m_code_limit) && (m_code_size != 12) )
169 m_code_limit = 1 << m_code_size;
177 void claw::graphic::gif::reader::input_buffer::fill_buffer()
180 std::copy( m_buffer + m_pending, m_buffer + m_pending_end, m_buffer );
181 m_pending_end = m_pending_end - m_pending;
184 if (m_next_data_length != 0)
186 assert( m_pending_end + m_next_data_length <=
sizeof(m_buffer) );
188 m_input.read( m_buffer + m_pending_end, m_next_data_length );
189 m_pending_end += m_next_data_length;
191 if ( (m_pending_bits == 0) && (m_pending != m_pending_end) )
192 m_pending_bits = CHAR_BIT;
195 ( reinterpret_cast<char*>(&m_next_data_length),
196 sizeof(m_next_data_length) );
211 claw::graphic::gif::reader::output_buffer::output_buffer
212 (
const palette_type& p,
const image_descriptor&
id,
213 int transparent_color_index,
image& output )
214 : m_palette(p), m_id(id), m_transparent_color_index(transparent_color_index),
215 m_output(output), m_x(0), m_y(0), m_interlace_pass(0),
226 void claw::graphic::gif::reader::output_buffer::write(
unsigned int code )
228 assert(code < m_palette.size());
229 assert(m_x < m_id.width);
230 assert(m_y < m_id.height);
232 m_output[m_y + m_id.top][m_x + m_id.left] = m_palette[code];
234 if ( m_transparent_color_index != -1 )
235 if ( code == (
unsigned int)m_transparent_color_index )
236 m_output[m_y + m_id.top][m_x + m_id.left].components.alpha = 0;
240 if (m_x == m_id.width)
244 if ( !m_id.is_interlaced() )
248 m_y += m_interlace_step;
250 while ( (m_y >= m_id.height) && (m_interlace_pass!=3) )
253 switch (m_interlace_pass)
255 case 1: m_y = 4; m_interlace_step = 8;
break;
256 case 2: m_y = 2; m_interlace_step = 4;
break;
257 case 3: m_y = 1; m_interlace_step = 2;
break;
300 ( frame_list& frames, std::istream& f )
319 (
image& img, frame_list& frames, std::istream& f )
347 if ( !m_frame.empty() && (m_image!=NULL) )
348 *m_image = *m_frame.front();
355 void claw::graphic::gif::reader::clear()
367 void claw::graphic::gif::reader::inside_load( std::istream& f )
369 std::istream::pos_type init_pos = f.tellg();
377 read_screen_descriptor(f, info);
387 f.seekg( init_pos, std::ios_base::beg );
397 void claw::graphic::gif::reader::make_frames(
const reader_info& info )
399 it_index<frame_list::const_iterator> it(m_frame.begin());
402 std::size_t cumul_count(0);
403 frame cumul(info.sd.screen_width, info.sd.screen_height);
406 if ( !info.disposal_method.empty() )
408 if ( info.disposal_method[0]
409 == graphic_control_extension::dispose_background )
410 fill_background(cumul, info);
415 for ( ; it!=m_frame.end(); ++it )
417 if ( info.disposal_method[it]
418 == graphic_control_extension::dispose_previous )
422 cumul.set_delay( (*it)->get_delay() );
425 if ( cumul.get_delay() > 0 )
427 result.push_back(
new frame(cumul) );
431 switch( info.disposal_method[it] )
433 case graphic_control_extension::dispose_background:
434 fill_background(cumul, info);
436 case graphic_control_extension::dispose_previous:
444 if ( cumul_count != 0 )
445 result.push_back(
new frame(cumul) );
457 void claw::graphic::gif::reader::fill_background
458 (
image& img,
const reader_info& info )
const
462 if ( info.sd.has_global_color_table() && (info.palette != NULL) )
463 if (info.sd.background_color < info.palette->size() )
464 clr = (*info.palette)[info.sd.background_color];
466 std::fill( img.begin(), img.end(), clr );
474 void claw::graphic::gif::reader::check_if_gif( std::istream& f )
const
479 f.read( reinterpret_cast<char*>(&h),
sizeof(header) );
483 if ( f.rdstate() == std::ios_base::goodbit )
484 if ( (h.signature[0] ==
'G')
485 && (h.signature[1] ==
'I')
486 && (h.signature[2] ==
'F')
487 && (h.version[0] ==
'8')
488 && ( (h.version[1] ==
'7') || (h.version[1] ==
'9') )
489 && (h.version[2] ==
'a') )
502 void claw::graphic::gif::reader::read_screen_descriptor
503 ( std::istream& f, reader_info& info )
505 f.read( reinterpret_cast<char*>(&info.sd),
sizeof(screen_descriptor) );
507 if ( info.sd.has_global_color_table() )
509 info.palette =
new palette_type(info.sd.color_palette_size());
510 read_palette(f, *info.palette);
520 void claw::graphic::gif::reader::read_palette
521 ( std::istream& f, palette_type& p )
const
525 for (std::size_t i=0; i!=p.size(); ++i)
527 f.read( reinterpret_cast<char*>(&red),
sizeof(
u_int_8) );
528 f.read( reinterpret_cast<char*>(&green),
sizeof(
u_int_8) );
529 f.read( reinterpret_cast<char*>(&blue),
sizeof(
u_int_8) );
531 p[i].components.red = red;
532 p[i].components.green = green;
533 p[i].components.blue = blue;
543 void claw::graphic::gif::reader::read_data
544 ( std::istream& f, reader_info& info )
551 f.read( reinterpret_cast<char*>(&code),
sizeof(code) );
556 case extension::block_id:
557 f.read( reinterpret_cast<char*>(&code),
sizeof(code) );
559 if (code == graphic_control_extension::block_label)
560 read_frame_with_gce(f, info);
565 case image_descriptor::block_id:
568 case trailer::block_id:
574 while ( f && (code != trailer::block_id) );
583 void claw::graphic::gif::reader::read_frame
584 ( std::istream& f, reader_info& info )
586 frame* new_frame(NULL);
590 new_frame =
new frame;
591 read_frame_data(f, info, *new_frame);
593 info.disposal_method.push_back(graphic_control_extension::dispose_none);
594 m_frame.push_back(new_frame);
609 void claw::graphic::gif::reader::read_frame_with_gce
610 ( std::istream& f, reader_info& info )
612 graphic_control_extension gce;
615 f.read( reinterpret_cast<char*>(&gce),
sizeof(gce) );
616 f.read( reinterpret_cast<char*>(&code),
sizeof(code) );
618 while ( (code == extension::block_id) && f )
620 f.read( reinterpret_cast<char*>(&code),
sizeof(code) );
622 if (code == graphic_control_extension::block_label)
623 f.read( reinterpret_cast<char*>(&gce),
sizeof(gce) );
628 f.read( reinterpret_cast<char*>(&code),
sizeof(code) );
631 if (code == image_descriptor::block_id)
633 frame* new_frame =
new frame;
634 new_frame->set_delay(gce.delay);
636 info.disposal_method.push_back(gce.get_disposal_method());
638 if ( gce.has_transparent_color() )
639 info.transparent_color_index = gce.transparent_color;
641 info.transparent_color_index = -1;
643 read_frame_data(f, info, *new_frame);
644 m_frame.push_back(new_frame);
654 void claw::graphic::gif::reader::skip_extension( std::istream& f )
const
658 f.read( reinterpret_cast<char*>(&block_size),
sizeof(block_size) );
660 while ( f && (block_size!=0) )
662 f.seekg( block_size, std::ios_base::cur );
663 f.read( reinterpret_cast<char*>(&block_size),
sizeof(block_size) );
676 void claw::graphic::gif::reader::read_frame_data
677 ( std::istream& f,
const reader_info& info, frame& the_frame )
const
681 f.read( reinterpret_cast<char*>(&
id),
sizeof(
id) );
683 the_frame.set_size(info.sd.screen_width, info.sd.screen_height);
687 palette_type* palette(info.palette);
689 if (
id.has_color_table() )
691 palette =
new palette_type(
id.color_palette_size());
692 read_palette(f, *palette);
695 decode_data(f, *palette,
id, info.transparent_color_index, the_frame);
697 if (
id.has_color_table() )
712 void claw::graphic::gif::reader::decode_data
713 ( std::istream& f,
const palette_type& palette,
const image_descriptor&
id,
714 int transparent_color_index, frame& the_frame )
const
718 f.read( reinterpret_cast<char*>(&code_size),
sizeof(code_size) );
719 input_buffer input(f, code_size);
720 output_buffer output(palette,
id, transparent_color_index, the_frame);
724 gif_lzw_decoder decoder;
726 decoder.decode(input, output);
728 while ( !input.end_of_information() );