static Gif_Stream * read_gif ( Gif_Reader * grr , int read_flags , const char * landmark , Gif_ReadErrorHandler handler ) {
 Gif_Stream * gfs ;
 Gif_Image * gfi ;
 Gif_Context gfc ;
 int unknown_block_type = 0 ;
 if ( gifgetc ( grr ) != 'G' || gifgetc ( grr ) != 'I' || gifgetc ( grr ) != 'F' ) return 0 ;
 ( void ) gifgetc ( grr ) ;
 ( void ) gifgetc ( grr ) ;
 ( void ) gifgetc ( grr ) ;
 gfs = Gif_NewStream ( ) ;
 gfi = Gif_NewImage ( ) ;
 gfc . stream = gfs ;
 gfc . prefix = Gif_NewArray ( Gif_Code , GIF_MAX_CODE ) ;
 gfc . suffix = Gif_NewArray ( uint8_t , GIF_MAX_CODE ) ;
 gfc . length = Gif_NewArray ( uint16_t , GIF_MAX_CODE ) ;
 gfc . handler = handler ;
 gfc . gfi = gfi ;
 gfc . errors [ 0 ] = gfc . errors [ 1 ] = 0 ;
 if ( ! gfs || ! gfi || ! gfc . prefix || ! gfc . suffix || ! gfc . length ) goto done ;
 gfs -> landmark = landmark ;
 GIF_DEBUG ( ( "\nGIF " ) ) ;
 if ( ! read_logical_screen_descriptor ( gfs , grr ) ) goto done ;
 GIF_DEBUG ( ( "logscrdesc " ) ) ;
 while ( ! gifeof ( grr ) ) {
 uint8_t block = gifgetbyte ( grr ) ;
 switch ( block ) {
 case ',' : GIF_DEBUG ( ( "imageread %d " , gfs -> nimages ) ) ;
 gfi -> identifier = last_name ;
 last_name = 0 ;
 if ( ! Gif_AddImage ( gfs , gfi ) ) goto done ;
 else if ( ! read_image ( grr , & gfc , gfi , read_flags ) ) {
 Gif_RemoveImage ( gfs , gfs -> nimages - 1 ) ;
 gfi = 0 ;
 goto done ;
 }
 gfc . gfi = gfi = Gif_NewImage ( ) ;
 if ( ! gfi ) goto done ;
 break ;
 case ';
' : GIF_DEBUG ( ( "term\n" ) ) ;
 goto done ;
 case '!' : block = gifgetbyte ( grr ) ;
 GIF_DEBUG ( ( "ext(0x%02X) " , block ) ) ;
 switch ( block ) {
 case 0xF9 : read_graphic_control_extension ( & gfc , gfi , grr ) ;
 break ;
 case 0xCE : last_name = suck_data ( last_name , 0 , grr ) ;
 break ;
 case 0xFE : if ( ! read_comment_extension ( gfi , grr ) ) goto done ;
 break ;
 case 0xFF : read_application_extension ( & gfc , grr ) ;
 break ;
 default : read_unknown_extension ( & gfc , grr , block , 0 , 0 ) ;
 break ;
 }
 break ;
 default : if ( ! unknown_block_type ) {
 char buf [ 256 ] ;
 sprintf ( buf , "unknown block type %d at file offset %u" , block , grr -> pos - 1 ) ;
 gif_read_error ( & gfc , 1 , buf ) ;
 unknown_block_type = 1 ;
 }
 break ;
 }
 }
 done : if ( gfs && gfi ) {
 Gif_Extension * gfex ;
 gfs -> end_comment = gfi -> comment ;
 gfi -> comment = 0 ;
 gfs -> end_extension_list = gfi -> extension_list ;
 gfi -> extension_list = 0 ;
 for ( gfex = gfs -> end_extension_list ;
 gfex ;
 gfex = gfex -> next ) gfex -> image = NULL ;
 }
 Gif_DeleteImage ( gfi ) ;
 Gif_DeleteArray ( last_name ) ;
 Gif_DeleteArray ( gfc . prefix ) ;
 Gif_DeleteArray ( gfc . suffix ) ;
 Gif_DeleteArray ( gfc . length ) ;
 gfc . gfi = 0 ;
 if ( gfs ) gfs -> errors = gfc . errors [ 1 ] ;
 if ( gfs && gfc . errors [ 1 ] == 0 && ! ( read_flags & GIF_READ_TRAILING_GARBAGE_OK ) && ! grr -> eofer ( grr ) ) gif_read_error ( & gfc , 0 , "trailing garbage after GIF ignored" ) ;
 gif_read_error ( & gfc , - 1 , 0 ) ;
 return gfs ;
 }
static Gif_Stream * read_gif ( Gif_Reader * grr , int read_flags , const char * landmark , Gif_ReadErrorHandler handler ) {
 Gif_Stream * gfs ;
 Gif_Image * gfi ;
 Gif_Context gfc ;
 int unknown_block_type = 0 ;
 if ( gifgetc ( grr ) != 'G' || gifgetc ( grr ) != 'I' || gifgetc ( grr ) != 'F' ) return 0 ;
 ( void ) gifgetc ( grr ) ;
 ( void ) gifgetc ( grr ) ;
 ( void ) gifgetc ( grr ) ;
 gfs = Gif_NewStream ( ) ;
 gfi = Gif_NewImage ( ) ;
 gfc . stream = gfs ;
 gfc . prefix = Gif_NewArray ( Gif_Code , GIF_MAX_CODE ) ;
 gfc . suffix = Gif_NewArray ( uint8_t , GIF_MAX_CODE ) ;
 gfc . length = Gif_NewArray ( uint16_t , GIF_MAX_CODE ) ;
 gfc . handler = handler ;
 gfc . gfi = gfi ;
 gfc . errors [ 0 ] = gfc . errors [ 1 ] = 0 ;
 if ( ! gfs || ! gfi || ! gfc . prefix || ! gfc . suffix || ! gfc . length ) goto done ;
 gfs -> landmark = landmark ;
 GIF_DEBUG ( ( "\nGIF " ) ) ;
 if ( ! read_logical_screen_descriptor ( gfs , grr ) ) goto done ;
 GIF_DEBUG ( ( "logscrdesc " ) ) ;
 while ( ! gifeof ( grr ) ) {
 uint8_t block = gifgetbyte ( grr ) ;
 switch ( block ) {
 case ',' : GIF_DEBUG ( ( "imageread %d " , gfs -> nimages ) ) ;
 gfi -> identifier = last_name ;
 last_name = 0 ;
 if ( ! Gif_AddImage ( gfs , gfi ) ) goto done ;
 else if ( ! read_image ( grr , & gfc , gfi , read_flags ) ) {
 Gif_RemoveImage ( gfs , gfs -> nimages - 1 ) ;
 gfi = 0 ;
 goto done ;
 }
 gfc . gfi = gfi = Gif_NewImage ( ) ;
 if ( ! gfi ) goto done ;
 break ;
 case ';
' : GIF_DEBUG ( ( "term\n" ) ) ;
 goto done ;
 case '!' : block = gifgetbyte ( grr ) ;
 GIF_DEBUG ( ( "ext(0x%02X) " , block ) ) ;
 switch ( block ) {
 case 0xF9 : read_graphic_control_extension ( & gfc , gfi , grr ) ;
 break ;
 case 0xCE : last_name = suck_data ( last_name , 0 , grr ) ;
 break ;
 case 0xFE : if ( ! read_comment_extension ( gfi , grr ) ) goto done ;
 break ;
 case 0xFF : read_application_extension ( & gfc , grr ) ;
 break ;
 default : read_unknown_extension ( & gfc , grr , block , 0 , 0 ) ;
 break ;
 }
 break ;
 default : if ( ! unknown_block_type ) {
 char buf [ 256 ] ;
 sprintf ( buf , "unknown block type %d at file offset %u" , block , grr -> pos - 1 ) ;
 gif_read_error ( & gfc , 1 , buf ) ;
 unknown_block_type = 1 ;
 }
 break ;
 }
 }
 done : if ( gfs && gfi ) {
 Gif_Extension * gfex ;
 gfs -> end_comment = gfi -> comment ;
 gfi -> comment = 0 ;
 gfs -> end_extension_list = gfi -> extension_list ;
 gfi -> extension_list = 0 ;
 for ( gfex = gfs -> end_extension_list ;
 gfex ;
 gfex = gfex -> next ) gfex -> image = NULL ;
 }
 Gif_DeleteImage ( gfi ) ;
 Gif_DeleteArray ( last_name ) ;
 Gif_DeleteArray ( gfc . prefix ) ;
 Gif_DeleteArray ( gfc . suffix ) ;
 Gif_DeleteArray ( gfc . length ) ;
 gfc . gfi = 0 ;
 if ( gfs ) gfs -> errors = gfc . errors [ 1 ] ;
 if ( gfs && gfc . errors [ 1 ] == 0 && ! ( read_flags & GIF_READ_TRAILING_GARBAGE_OK ) && ! grr -> eofer ( grr ) ) gif_read_error ( & gfc , 0 , "trailing garbage after GIF ignored" ) ;
 gif_read_error ( & gfc , - 1 , 0 ) ;
 return gfs ;
 }