tuned a bit too
This commit is contained in:
John Cupitt 2019-02-14 15:22:51 +00:00
parent b02a50aaed
commit bfa1f22520
2 changed files with 78 additions and 61 deletions

View File

@ -21,6 +21,7 @@
- add @reduction_effort param to webpsave [lovell]
- add @option_string param to thumbnail_buffer [kleisauke]
- add XMP, IPCT, ICC, EXIF etc. support to magickload/magicksave
- much lower memuse for gifload
4/1/19 started 8.7.4
- magickload with magick6 API did not chain exceptions correctly causing a

View File

@ -20,6 +20,8 @@
* - add dispose handling
* 13/8/18
* - init pages to 0 before load
* 14/2/19
* - rework as a sequential loader ... smaller, less mem use
*/
/*
@ -51,6 +53,7 @@
/*
#define VIPS_DEBUG
#define DEBUG_VERBOSE
*/
#ifdef HAVE_CONFIG_H
@ -312,8 +315,9 @@ vips_foreign_load_gif_dispose( GObject *gobject )
vips_foreign_load_gif_close( gif );
VIPS_FREE( gif->comment );
VIPS_UNREF( gif->frame );
VIPS_FREE( gif->comment );
VIPS_FREE( gif->line )
G_OBJECT_CLASS( vips_foreign_load_gif_parent_class )->
dispose( gobject );
@ -424,7 +428,6 @@ vips_foreign_load_gif_scan_image_record( VipsForeignLoadGif *gif )
for( i = 0; i < map->ColorCount; i++ )
if( map->Colors[i].Red != map->Colors[i].Green ||
map->Colors[i].Green != map->Colors[i].Blue ) {
printf( "gifload: not mono\n" );
gif->has_colour = TRUE;
break;
}
@ -446,8 +449,6 @@ vips_foreign_load_gif_scan_application_ext( VipsForeignLoadGif *gif,
{
gboolean have_netscape;
printf( "gifload: type: application\n" );
/* The 11-byte NETSCAPE extension.
*/
have_netscape = FALSE;
@ -462,11 +463,8 @@ vips_foreign_load_gif_scan_application_ext( VipsForeignLoadGif *gif,
if( have_netscape &&
extension &&
extension[0] == 3 &&
extension[1] == 1 ) {
extension[1] == 1 )
gif->loop = extension[2] | (extension[3] << 8);
printf( "gifload: seen loop %d\n",
gif->loop );
}
}
return( 0 );
@ -501,8 +499,6 @@ vips_foreign_load_gif_scan_extension( VipsForeignLoadGif *gif )
GifByteType *extension;
int ext_code;
printf( "gifload: EXTENSION_RECORD_TYPE\n" );
if( DGifGetExtension( gif->file, &ext_code, &extension ) ==
GIF_ERROR ) {
vips_foreign_load_gif_error( gif );
@ -566,7 +562,7 @@ vips_foreign_load_gif_set_header( VipsForeignLoadGif *gif, VipsImage *image )
gif->has_colour ?
VIPS_INTERPRETATION_sRGB : VIPS_INTERPRETATION_B_W,
1.0, 1.0 );
vips_image_pipelinev( image, VIPS_DEMAND_STYLE_THINSTRIP, NULL );
vips_image_pipelinev( image, VIPS_DEMAND_STYLE_FATSTRIP, NULL );
if( gif->n_pages > 1 ) {
vips_image_set_int( image,
@ -594,13 +590,9 @@ vips_foreign_load_gif_header( VipsForeignLoad *load )
GifRecordType record;
printf( "vips_foreign_load_gif_header:\n" );
if( gif_class->open( gif ) )
return( -1 );
printf( "vips_foreign_load_gif_header: starting page scan\n" );
gif->n_pages = 0;
do {
@ -611,8 +603,6 @@ vips_foreign_load_gif_header( VipsForeignLoad *load )
switch( record ) {
case IMAGE_DESC_RECORD_TYPE:
printf( "gifload: IMAGE_DESC_RECORD_TYPE\n" );
if( DGifGetImageDesc( gif->file ) == GIF_ERROR ) {
vips_foreign_load_gif_error( gif );
return( -1 );
@ -636,16 +626,11 @@ vips_foreign_load_gif_header( VipsForeignLoad *load )
break;
case TERMINATE_RECORD_TYPE:
printf( "gifload: TERMINATE_RECORD_TYPE\n" );
gif->eof = TRUE;
break;
case SCREEN_DESC_RECORD_TYPE:
printf( "gifload: SCREEN_DESC_RECORD_TYPE\n" );
break;
case UNDEFINED_RECORD_TYPE:
printf( "gifload: UNDEFINED_RECORD_TYPE\n" );
break;
default:
@ -653,9 +638,6 @@ vips_foreign_load_gif_header( VipsForeignLoad *load )
}
} while( !gif->eof );
printf( "vips_foreign_load_gif_header: found %d pages\n",
gif->n_pages );
if( gif->n == -1 )
gif->n = gif->n_pages - gif->page;
@ -728,8 +710,6 @@ vips_foreign_load_gif_render( VipsForeignLoadGif *gif )
{
GifFileType *file = gif->file;
printf( "vips_foreign_load_gif_render:\n" );
if( file->Image.Interlace ) {
int i;
@ -830,8 +810,6 @@ vips_foreign_load_gif_next_page( VipsForeignLoadGif *gif )
GifRecordType record;
gboolean have_read_frame;
printf( "vips_foreign_load_gif_next_page:\n" );
have_read_frame = FALSE;
do {
if( DGifGetRecordType( gif->file, &record ) == GIF_ERROR ) {
@ -889,33 +867,76 @@ vips_foreign_load_gif_generate( VipsRegion *or,
VipsRect *r = &or->valid;
VipsForeignLoadGif *gif = (VipsForeignLoadGif *) a;
/* The page for this generate, and the line number in page.
*/
int page = r->top / gif->file->SHeight + gif->page;
int line = r->top % gif->file->SHeight;
int y;
#ifdef DEBUG_VERBOSE
#endif /*DEBUG_VERBOSE*/
printf( "vips_foreign_load_gif_generate: line %d\n", r->top );
for( y = 0; y < r->height; y++ ) {
/* The page for this output line, and the line number in page.
*/
int page = (r->top + y) / gif->file->SHeight + gif->page;
int line = (r->top + y) % gif->file->SHeight;
g_assert( r->height == 1 );
g_assert( line >= 0 && lines < gif->frame->Ysize );
g_assert( page >= 0 && page < gif->n_pages );
VipsPel *p, *q;
int x;
/* current_page == 0 means we've not loaded any pages yet. So we need
* to have loaded the page beyond the page we want.
*/
while( gif->current_page <= page ) {
if( vips_foreign_load_gif_next_page( gif ) )
return( -1 );
g_assert( line >= 0 && lines < gif->frame->Ysize );
g_assert( page >= 0 && page < gif->n_pages );
gif->current_page += 1;
/* current_page == 0 means we've not loaded any pages yet. So
* we need to have loaded the page beyond the page we want.
*/
while( gif->current_page <= page ) {
if( vips_foreign_load_gif_next_page( gif ) )
return( -1 );
gif->current_page += 1;
}
/* @frame is always RGBA, but or may be G, GA, RGB or RGBA.
* We have to pick out the values we want.
*/
p = VIPS_IMAGE_ADDR( gif->frame, 0, line );
q = VIPS_REGION_ADDR( or, 0, r->top + y );
switch( or->im->Bands ) {
case 1:
for( x = 0; x < gif->frame->Xsize; x++ ) {
q[0] = p[1];
q += 1;
p += 4;
}
break;
case 2:
for( x = 0; x < gif->frame->Xsize; x++ ) {
q[0] = p[1];
q[1] = p[3];
q += 2;
p += 4;
}
break;
case 3:
for( x = 0; x < gif->frame->Xsize; x++ ) {
q[0] = p[0];
q[1] = p[1];
q[2] = p[2];
q += 3;
p += 4;
}
break;
case 4:
memcpy( q, p, VIPS_IMAGE_SIZEOF_LINE( gif->frame ) );
break;
default:
g_assert_not_reached();
break;
}
}
memcpy( VIPS_REGION_ADDR( or, 0, r->top ),
VIPS_IMAGE_ADDR( gif->frame, 0, line ),
VIPS_IMAGE_SIZEOF_LINE( gif->frame ) );
return( 0 );
}
@ -928,8 +949,6 @@ vips_foreign_load_gif_load( VipsForeignLoad *load )
VipsImage **t = (VipsImage **)
vips_object_local_array( VIPS_OBJECT( load ), 4 );
printf( "vips_foreign_load_gif_load:\n" );
/* Rewind.
*/
if( class->open( gif ) )
@ -953,9 +972,13 @@ vips_foreign_load_gif_load( VipsForeignLoad *load )
if( vips_foreign_load_gif_set_header( gif, t[0] ) )
return( -1 );
/* Strips 8 pixels high to avoid too many tiny regions.
*/
if( vips_image_generate( t[0],
NULL, vips_foreign_load_gif_generate, NULL, gif, NULL ) ||
vips_sequential( t[0], &t[1], NULL ) ||
vips_sequential( t[0], &t[1],
"tile_height", VIPS__FATSTRIP_HEIGHT,
NULL ) ||
vips_image_write( t[1], load->real ) )
return( -1 );
@ -965,8 +988,6 @@ vips_foreign_load_gif_load( VipsForeignLoad *load )
static int
vips_foreign_load_gif_open( VipsForeignLoadGif *gif )
{
printf( "vips_foreign_load_gif_open:\n" );
#ifdef HAVE_GIFLIB_5
{
int error;
@ -989,8 +1010,7 @@ vips_foreign_load_gif_open( VipsForeignLoadGif *gif )
/* Allocate a line buffer now that we have the GIF width.
*/
VIPS_FREE( gif->line )
if( !(gif->line = VIPS_ARRAY( gif,
gif->file->SWidth, GifPixelType )) )
if( !(gif->line = VIPS_ARRAY( NULL, gif->file->SWidth, GifPixelType )) )
return( -1 );
return( 0 );
@ -1094,8 +1114,6 @@ vips_foreign_load_gif_file_open( VipsForeignLoadGif *gif )
VipsForeignLoad *load = (VipsForeignLoad *) gif;
VipsForeignLoadGifFile *file = (VipsForeignLoadGifFile *) gif;
printf( "vips_foreign_load_gif_file_open:\n" );
if( !file->fp ) {
if( !(file->fp =
vips__file_open_read( file->filename, NULL, FALSE )) )
@ -1198,8 +1216,6 @@ vips_foreign_load_gif_buffer_open( VipsForeignLoadGif *gif )
{
VipsForeignLoadGifBuffer *buffer = (VipsForeignLoadGifBuffer *) gif;
printf( "vips_foreign_load_gif_buffer_open:\n" );
vips_foreign_load_gif_close( gif );
buffer->p = buffer->buf->data;
buffer->bytes_to_go = buffer->buf->length;