diff --git a/ChangeLog b/ChangeLog index 86cc1625..faa8a9fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,6 +22,7 @@ - add @option_string param to thumbnail_buffer [kleisauke] - add XMP, IPCT, ICC, EXIF etc. support to magickload/magicksave - much lower memuse for gifload +- tilecache speedups 4/1/19 started 8.7.4 - magickload with magick6 API did not chain exceptions correctly causing a diff --git a/libvips/conversion/tilecache.c b/libvips/conversion/tilecache.c index c666c580..b91305b8 100644 --- a/libvips/conversion/tilecache.c +++ b/libvips/conversion/tilecache.c @@ -218,6 +218,7 @@ vips_tile_new( VipsBlockCache *cache, int x, int y ) tile->pos.width = cache->tile_width; tile->pos.height = cache->tile_height; g_hash_table_insert( cache->tiles, &tile->pos, tile ); + g_queue_push_tail( tile->cache->recycle, tile ); g_assert( cache->ntiles >= 0 ); cache->ntiles += 1; @@ -318,10 +319,12 @@ vips_tile_unlocked( gpointer key, gpointer value, gpointer user_data ) static void vips_block_cache_minimise( VipsImage *image, VipsBlockCache *cache ) { - /* We can't drop tiles that are in use. - */ + printf( "vips_block_cache_minimise:\n" ); + g_mutex_lock( cache->lock ); + /* We can't drop tiles that are in use. + */ g_hash_table_foreach_remove( cache->tiles, vips_tile_unlocked, NULL ); @@ -434,6 +437,12 @@ vips_tile_destroy( VipsTile *tile ) VIPS_DEBUG_MSG_RED( "vips_tile_destroy: tile %d, %d (%p)\n", tile->pos.left, tile->pos.top, tile ); + /* 0 ref tiles should be on the recycle list. + */ + g_assert( tile->ref_count == 0 ); + g_assert( g_queue_find( tile->cache->recycle, tile ) ); + g_queue_remove( cache->recycle, tile ); + cache->ntiles -= 1; g_assert( cache->ntiles >= 0 ); tile->cache = NULL; diff --git a/libvips/foreign/gifload.c b/libvips/foreign/gifload.c index e7301b37..a9db1ce3 100644 --- a/libvips/foreign/gifload.c +++ b/libvips/foreign/gifload.c @@ -52,9 +52,9 @@ */ /* -#define VIPS_DEBUG #define DEBUG_VERBOSE */ +#define VIPS_DEBUG #ifdef HAVE_CONFIG_H #include @@ -741,23 +741,32 @@ vips_foreign_load_gif_render( VipsForeignLoadGif *gif ) * * Otherwise, we must update previous. */ - if( gif->dispose == DISPOSE_BACKGROUND ) + if( gif->dispose == DISPOSE_BACKGROUND ) { + VIPS_DEBUG_MSG( "vips_foreign_load_gif_render: " + "dispose clear to zero\n" ); memset( VIPS_IMAGE_ADDR( gif->frame, 0, 0 ), 0, VIPS_IMAGE_SIZEOF_IMAGE( gif->frame ) ); - else if( gif->dispose == DISPOSE_PREVIOUS ) + } + else if( gif->dispose == DISPOSE_PREVIOUS ) { + VIPS_DEBUG_MSG( "vips_foreign_load_gif_render: " + "dispose restore from previous\n" ); memcpy( VIPS_IMAGE_ADDR( gif->frame, 0, 0 ), VIPS_IMAGE_ADDR( gif->previous, 0, 0 ), VIPS_IMAGE_SIZEOF_IMAGE( gif->frame ) ); - else + } + else { + VIPS_DEBUG_MSG( "vips_foreign_load_gif_render: " + "dispose copy to previous\n" ); memcpy( VIPS_IMAGE_ADDR( gif->previous, 0, 0 ), VIPS_IMAGE_ADDR( gif->frame, 0, 0 ), VIPS_IMAGE_SIZEOF_IMAGE( gif->frame ) ); + } if( file->Image.Interlace ) { int i; - VIPS_DEBUG_MSG( "gifload: interlaced frame of " - "%d x %d pixels at %d x %d\n", + VIPS_DEBUG_MSG( "vips_foreign_load_gif_render: " + "interlaced frame of %d x %d pixels at %d x %d\n", file->Image.Width, file->Image.Height, file->Image.Left, file->Image.Top ); @@ -784,8 +793,8 @@ vips_foreign_load_gif_render( VipsForeignLoadGif *gif ) else { int y; - VIPS_DEBUG_MSG( "gifload: non-interlaced frame of " - "%d x %d pixels at %d x %d\n", + VIPS_DEBUG_MSG( "vips_foreign_load_gif_render: " + "non-interlaced frame of %d x %d pixels at %d x %d\n", file->Image.Width, file->Image.Height, file->Image.Left, file->Image.Top ); @@ -813,7 +822,7 @@ vips_foreign_load_gif_extension( VipsForeignLoadGif *gif ) GifByteType *extension; int ext_code; - VIPS_DEBUG_MSG( "gifload: EXTENSION_RECORD_TYPE\n" ); + VIPS_DEBUG_MSG( "vips_foreign_load_gif_extension:\n" ); if( DGifGetExtension( gif->file, &ext_code, &extension ) == GIF_ERROR ) { @@ -836,6 +845,8 @@ vips_foreign_load_gif_extension( VipsForeignLoadGif *gif ) * to set the meaning of background and transparent pixels. */ gif->dispose = (extension[1] >> 2) & 0x7; + VIPS_DEBUG_MSG( "vips_foreign_load_gif_extension: " + "dispose = %d\n", gif->dispose ); } while( extension != NULL ) @@ -862,7 +873,8 @@ vips_foreign_load_gif_next_page( VipsForeignLoadGif *gif ) switch( record ) { case IMAGE_DESC_RECORD_TYPE: - VIPS_DEBUG_MSG( "gifload: IMAGE_DESC_RECORD_TYPE\n" ); + VIPS_DEBUG_MSG( "vips_foreign_load_gif_next_page: " + "IMAGE_DESC_RECORD_TYPE\n" ); if( DGifGetImageDesc( gif->file ) == GIF_ERROR ) { vips_foreign_load_gif_error( gif ); @@ -882,16 +894,19 @@ vips_foreign_load_gif_next_page( VipsForeignLoadGif *gif ) break; case TERMINATE_RECORD_TYPE: - VIPS_DEBUG_MSG( "gifload: TERMINATE_RECORD_TYPE\n" ); + VIPS_DEBUG_MSG( "vips_foreign_load_gif_next_page: " + "TERMINATE_RECORD_TYPE\n" ); gif->eof = TRUE; break; case SCREEN_DESC_RECORD_TYPE: - VIPS_DEBUG_MSG( "gifload: SCREEN_DESC_RECORD_TYPE\n" ); + VIPS_DEBUG_MSG( "vips_foreign_load_gif_next_page: " + "SCREEN_DESC_RECORD_TYPE\n" ); break; case UNDEFINED_RECORD_TYPE: - VIPS_DEBUG_MSG( "gifload: UNDEFINED_RECORD_TYPE\n" ); + VIPS_DEBUG_MSG( "vips_foreign_load_gif_next_page: " + "UNDEFINED_RECORD_TYPE\n" ); break; default: @@ -921,7 +936,7 @@ vips_foreign_load_gif_generate( VipsRegion *or, VipsPel *p, *q; int x; - g_assert( line >= 0 && lines < gif->frame->Ysize ); + g_assert( line >= 0 && line < gif->frame->Ysize ); g_assert( page >= 0 && page < gif->n_pages ); /* current_page == 0 means we've not loaded any pages yet. So @@ -997,6 +1012,8 @@ vips_foreign_load_gif_load( VipsForeignLoad *load ) if( class->open( gif ) ) return( -1 ); + printf( "vips_foreign_load_gif_load:\n" ); + /* Make the memory image we accumulate pixels in. We always accumulate * to RGBA, then trim down to whatever the output image needs on * _generate.