From f2c55e80feaad3362ddf369ac34bdc608aaa6298 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 18 Aug 2017 12:31:24 +0100 Subject: [PATCH] better dzsave with zip output to a file close down output earlier to help mark-sweep bindings --- ChangeLog | 1 + libvips/foreign/dzsave.c | 67 ++++++++++++++++++---------------------- 2 files changed, 31 insertions(+), 37 deletions(-) diff --git a/ChangeLog b/ChangeLog index aa5ee3d8..02917137 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 2/8/17 started 8.5.8 - fix transparency detection in merge, thanks Haida - define env var VIPS_WARNING to hide warning messages +- shut down dzsave output earlier to help mark-sweep bindings 9/6/17 started 8.5.7 - better smartcrop diff --git a/libvips/foreign/dzsave.c b/libvips/foreign/dzsave.c index 4beeeb31..d02dfc79 100644 --- a/libvips/foreign/dzsave.c +++ b/libvips/foreign/dzsave.c @@ -71,6 +71,8 @@ * - add dzsave_buffer * 11/11/16 Felix Bünemann * - better >4gb detection for zip output on older libgsfs + * 18/8/17 + * - shut down the output earlier to flush zip output */ /* @@ -210,47 +212,28 @@ vips_gsf_tree_close( VipsGsfDirectory *tree ) vips_slist_map2( tree->children, (VipsSListMap2Fn) vips_gsf_tree_close, NULL, NULL ); - if( tree->out && - !gsf_output_is_closed( tree->out ) && - !gsf_output_close( tree->out ) ) { - vips_error( "vips_gsf", "%s", _( "unable to close stream" ) ); - return( tree ); - } - if( tree->container && - !gsf_output_is_closed( tree->container ) && - !gsf_output_close( tree->container ) ) { - vips_error( "vips_gsf", "%s", _( "unable to close stream" ) ); - return( tree ); - } + if( tree->out ) { + if( !gsf_output_is_closed( tree->out ) && + !gsf_output_close( tree->out ) ) { + vips_error( "vips_gsf", + "%s", _( "unable to close stream" ) ); + return( tree ); + } - return( NULL ); -} - -/* Close and unref everything, can't fail. Call vips_gsf_tree_close() to get - * an error return. - */ -static void * -vips_gsf_tree_free( VipsGsfDirectory *tree ) -{ - vips_slist_map2( tree->children, - (VipsSListMap2Fn) vips_gsf_tree_free, NULL, NULL ); - g_slist_free( tree->children ); - g_free( (char *) tree->name ); - - if( tree->out ) { - if( !gsf_output_is_closed( tree->out ) ) - (void) gsf_output_close( tree->out ); g_object_unref( tree->out ); } if( tree->container ) { - if( !gsf_output_is_closed( tree->container ) ) - (void) gsf_output_close( tree->container ); + if( !gsf_output_is_closed( tree->container ) && + !gsf_output_close( tree->container ) ) { + vips_error( "vips_gsf", + "%s", _( "unable to close stream" ) ); + return( tree ); + } + g_object_unref( tree->container ); } - g_free( tree ); - return( NULL ); } @@ -562,7 +545,7 @@ vips_foreign_save_dz_dispose( GObject *gobject ) VipsForeignSaveDz *dz = (VipsForeignSaveDz *) gobject; VIPS_FREEF( layer_free, dz->layer ); - VIPS_FREEF( vips_gsf_tree_free, dz->tree ); + VIPS_FREEF( vips_gsf_tree_close, dz->tree ); VIPS_FREEF( g_object_unref, dz->out ); VIPS_FREE( dz->basename ); VIPS_FREE( dz->dirname ); @@ -1908,9 +1891,6 @@ vips_foreign_save_dz_build( VipsObject *object ) write_vips_meta( dz ) ) return( -1 ); - if( vips_gsf_tree_close( dz->tree ) ) - return( -1 ); - /* This is so ugly. In earlier versions of dzsave, we wrote x.dzi and * x_files. Now we write x/x.dzi and x/x_files to make it possible to * create zip files. @@ -1942,6 +1922,19 @@ vips_foreign_save_dz_build( VipsObject *object ) return( -1 ); } + /* Shut down the output to flush everything. + */ + if( vips_gsf_tree_close( dz->tree ) ) + return( -1 ); + dz->tree = NULL; + + /* If we are writing a zip to the filesystem, we must unref out to + * force it to disc. + */ + if( dz->container == VIPS_FOREIGN_DZ_CONTAINER_ZIP && + dz->dirname != NULL ) + VIPS_FREEF( g_object_unref, dz->out ); + return( 0 ); }