use a better name for the dzsave temp dir

see https://github.com/jcupitt/libvips/issues/242

dzsave with deepzoom layout and fs container writes a temp dir called
dzsave-temp-324857 or similar, and makes sure that this directory does
not exist

after write, the foo_files and foo.dzi files are picked out to the
current dir and the temp removed
This commit is contained in:
John Cupitt 2015-02-22 15:59:31 +00:00
parent 98b9214b4c
commit 78acd9b7a0
2 changed files with 58 additions and 26 deletions

8
TODO
View File

@ -1,11 +1,3 @@
- dzsave should write to a mkstemp() temp directory in the output dir
and rename from that, see
https://github.com/jcupitt/libvips/issues/242
- why can't we do - why can't we do
im = Vips.Image.new_from_file(sys.argv[1], access = "sequential") im = Vips.Image.new_from_file(sys.argv[1], access = "sequential")

View File

@ -49,6 +49,8 @@
* - use g_ date funcs, helps Windows * - use g_ date funcs, helps Windows
* 14/2/15 * 14/2/15
* - use vips_region_shrink() * - use vips_region_shrink()
* 22/2/15
* - use a better temp dir name for fs dz output
*/ */
/* /*
@ -417,6 +419,10 @@ struct _VipsForeignSaveDz {
*/ */
char *dirname; char *dirname;
/* For DZ save, we have to write to a temp dir. Track the name here.
*/
char *tempdir;
/* The root directory name ... $basename with perhaps some extra /* The root directory name ... $basename with perhaps some extra
* stuff, eg. $(basename)_files, etc. * stuff, eg. $(basename)_files, etc.
*/ */
@ -459,6 +465,7 @@ vips_foreign_save_dz_dispose( GObject *gobject )
VIPS_FREEF( vips_gsf_tree_free, dz->tree ); VIPS_FREEF( vips_gsf_tree_free, dz->tree );
VIPS_FREE( dz->basename ); VIPS_FREE( dz->basename );
VIPS_FREE( dz->dirname ); VIPS_FREE( dz->dirname );
VIPS_FREE( dz->tempdir );
VIPS_FREE( dz->root_name ); VIPS_FREE( dz->root_name );
VIPS_FREE( dz->file_suffix ); VIPS_FREE( dz->file_suffix );
@ -1445,6 +1452,7 @@ vips_foreign_save_dz_build( VipsObject *object )
{ {
VipsForeignSave *save = (VipsForeignSave *) object; VipsForeignSave *save = (VipsForeignSave *) object;
VipsForeignSaveDz *dz = (VipsForeignSaveDz *) object; VipsForeignSaveDz *dz = (VipsForeignSaveDz *) object;
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( dz );
VipsRect real_pixels; VipsRect real_pixels;
/* Google and zoomify default to zero overlap, ".jpg". /* Google and zoomify default to zero overlap, ".jpg".
@ -1608,21 +1616,53 @@ vips_foreign_save_dz_build( VipsObject *object )
*/ */
switch( dz->container ) { switch( dz->container ) {
case VIPS_FOREIGN_DZ_CONTAINER_FS: case VIPS_FOREIGN_DZ_CONTAINER_FS:
{ if( dz->layout == VIPS_FOREIGN_DZ_LAYOUT_DZ ) {
GsfOutput *out; /* For deepzoom, we have to rearrange the output
GError *error = NULL; * directory after writing it, see the end of this
char name[VIPS_PATH_MAX]; * function. We write to a temporary directory, then
* pull ${basename}_files and ${basename}.dzi out into
* the current directory and remove the temp. The temp
* dir must not clash with another file.
*/
GsfOutput *out;
GError *error = NULL;
int fd;
vips_snprintf( name, VIPS_PATH_MAX, "%s/%s", dz->tempdir = g_build_filename( dz->dirname,
dz->dirname, dz->basename ); "dzsave-temp-XXXXXXX", NULL );
if( !(out = (GsfOutput *) if( (fd = g_mkstemp( dz->tempdir )) == -1 ) {
gsf_outfile_stdio_new( name, &error )) ) { vips_error( class->nickname,
vips_g_error( &error ); _( "unable to make temporary file %s" ),
return( -1 ); dz->tempdir );
return( -1 );
}
close( fd );
g_unlink( dz->tempdir );
if( !(out = (GsfOutput *)
gsf_outfile_stdio_new( dz->tempdir,
&error )) ) {
vips_g_error( &error );
return( -1 );
}
dz->tree = vips_gsf_tree_new( out, FALSE );
} }
else {
GsfOutput *out;
GError *error = NULL;
char name[VIPS_PATH_MAX];
dz->tree = vips_gsf_tree_new( out, FALSE ); vips_snprintf( name, VIPS_PATH_MAX, "%s/%s",
} dz->dirname, dz->basename );
if( !(out = (GsfOutput *)
gsf_outfile_stdio_new( name, &error )) ) {
vips_g_error( &error );
return( -1 );
}
dz->tree = vips_gsf_tree_new( out, FALSE );
}
break; break;
case VIPS_FOREIGN_DZ_CONTAINER_ZIP: case VIPS_FOREIGN_DZ_CONTAINER_ZIP:
@ -1717,21 +1757,21 @@ vips_foreign_save_dz_build( VipsObject *object )
char old_name[VIPS_PATH_MAX]; char old_name[VIPS_PATH_MAX];
char new_name[VIPS_PATH_MAX]; char new_name[VIPS_PATH_MAX];
vips_snprintf( old_name, VIPS_PATH_MAX, "%s/%s/%s.dzi", vips_snprintf( old_name, VIPS_PATH_MAX, "%s/%s.dzi",
dz->dirname, dz->basename, dz->basename ); dz->tempdir, dz->basename );
vips_snprintf( new_name, VIPS_PATH_MAX, "%s/%s.dzi", vips_snprintf( new_name, VIPS_PATH_MAX, "%s/%s.dzi",
dz->dirname, dz->basename ); dz->dirname, dz->basename );
if( vips_rename( old_name, new_name ) ) if( vips_rename( old_name, new_name ) )
return( -1 ); return( -1 );
vips_snprintf( old_name, VIPS_PATH_MAX, "%s/%s/%s_files", vips_snprintf( old_name, VIPS_PATH_MAX, "%s/%s_files",
dz->dirname, dz->basename, dz->basename ); dz->tempdir, dz->basename );
vips_snprintf( new_name, VIPS_PATH_MAX, "%s/%s_files", vips_snprintf( new_name, VIPS_PATH_MAX, "%s/%s_files",
dz->dirname, dz->basename ); dz->dirname, dz->basename );
if( vips_rename( old_name, new_name ) ) if( vips_rename( old_name, new_name ) )
return( -1 ); return( -1 );
if( vips_rmdirf( "%s/%s", dz->dirname, dz->basename ) ) if( vips_rmdirf( "%s", dz->tempdir ) )
return( -1 ); return( -1 );
} }