sort out dzsave paths, auto-enable zip

rationalised output paths for dzsave

enable zip automatically if output name ends in .zip
This commit is contained in:
John Cupitt 2014-05-06 14:28:41 +01:00
parent 1384f9d4e0
commit 30808f70a5
3 changed files with 61 additions and 39 deletions

13
TODO
View File

@ -1,3 +1,14 @@
- argh oh dear sort out zip / non-zip paths
container FS zip
layout
deepzoom x/x_files/ x.zip/x/x_files/
google x/0 x.zip/x/0
zoomify x/Imag.. x.zip/x/Imag..
- how do we keep compat with old behaviour? gsf won't let us write to "." - how do we keep compat with old behaviour? gsf won't let us write to "."
@ -5,8 +16,6 @@
- auto-enable zip output?
- try - try
vips vips vips vips

View File

@ -41,28 +41,6 @@
* filesystem * filesystem
*/ */
/*
TODO
- need some way to pass save options to the jpeg tile writer
- and to pick a tile writer!
- need some way to select a container format
- are the rules for naming objects correct? eg.
vips dzsave fred.tif /my/output/file.zip
will create file.zip containing
file.zip:file_files
file.zip:file_files/0/0_0.jpg
file.zip:file.dzi
*/
/* /*
This file is part of VIPS. This file is part of VIPS.
@ -176,6 +154,10 @@ typedef struct _VipsGsfDirectory {
*/ */
gboolean no_compression; gboolean no_compression;
/* The root node holds the enclosing zip file or FS root ... finish
* this on cleanup.
*/
GsfOutput *container;
} VipsGsfDirectory; } VipsGsfDirectory;
/* Close all dirs, non-NULL on error. /* Close all dirs, non-NULL on error.
@ -185,12 +167,19 @@ vips_gsf_tree_close( VipsGsfDirectory *tree )
{ {
vips_slist_map2( tree->children, vips_slist_map2( tree->children,
(VipsSListMap2Fn) vips_gsf_tree_close, NULL, NULL ); (VipsSListMap2Fn) vips_gsf_tree_close, NULL, NULL );
if( tree->out && if( tree->out &&
!gsf_output_is_closed( tree->out ) && !gsf_output_is_closed( tree->out ) &&
!gsf_output_close( tree->out ) ) { !gsf_output_close( tree->out ) ) {
vips_error( "vips_gsf", "%s", _( "unable to close stream" ) ); vips_error( "vips_gsf", "%s", _( "unable to close stream" ) );
return( tree ); 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 );
}
return( NULL ); return( NULL );
} }
@ -205,11 +194,19 @@ vips_gsf_tree_free( VipsGsfDirectory *tree )
(VipsSListMap2Fn) vips_gsf_tree_free, NULL, NULL ); (VipsSListMap2Fn) vips_gsf_tree_free, NULL, NULL );
g_slist_free( tree->children ); g_slist_free( tree->children );
g_free( (char *) tree->name ); g_free( (char *) tree->name );
if( tree->out ) { if( tree->out ) {
if( !gsf_output_is_closed( tree->out ) ) if( !gsf_output_is_closed( tree->out ) )
(void) gsf_output_close( tree->out ); (void) gsf_output_close( tree->out );
g_object_unref( tree->out ); g_object_unref( tree->out );
} }
if( tree->container ) {
if( !gsf_output_is_closed( tree->container ) )
(void) gsf_output_close( tree->container );
g_object_unref( tree->container );
}
g_free( tree ); g_free( tree );
return( NULL ); return( NULL );
@ -227,6 +224,7 @@ vips_gsf_tree_new( GsfOutput *out, gboolean no_compression )
tree->children = NULL; tree->children = NULL;
tree->out = out; tree->out = out;
tree->no_compression = no_compression; tree->no_compression = no_compression;
tree->container = NULL;
return( tree ); return( tree );
} }
@ -263,6 +261,7 @@ vips_gsf_dir_new( VipsGsfDirectory *parent, const char *name )
dir->name = g_strdup( name ); dir->name = g_strdup( name );
dir->children = NULL; dir->children = NULL;
dir->no_compression = parent->no_compression; dir->no_compression = parent->no_compression;
dir->container = NULL;
if( dir->no_compression ) if( dir->no_compression )
dir->out = gsf_outfile_new_child_full( dir->out = gsf_outfile_new_child_full(
@ -404,8 +403,8 @@ struct _VipsForeignSaveDz {
*/ */
char *dirname; char *dirname;
/* The root directory name ... used to form /* The root directory name ... $basename with perhaps some extra
* $(root_name)_files, $(root_name), etc. * stuff, eg. $(basename)_files, etc.
*/ */
char *root_name; char *root_name;
}; };
@ -588,7 +587,7 @@ write_dzi( VipsForeignSaveDz *dz )
char buf[VIPS_PATH_MAX]; char buf[VIPS_PATH_MAX];
char *p; char *p;
vips_snprintf( buf, VIPS_PATH_MAX, "%s.dzi", dz->name ); vips_snprintf( buf, VIPS_PATH_MAX, "%s.dzi", dz->basename );
out = vips_gsf_path( dz->tree, buf, NULL ); out = vips_gsf_path( dz->tree, buf, NULL );
vips_snprintf( buf, VIPS_PATH_MAX, "%s", dz->suffix + 1 ); vips_snprintf( buf, VIPS_PATH_MAX, "%s", dz->suffix + 1 );
@ -675,7 +674,7 @@ write_blank( VipsForeignSaveDz *dz )
} }
g_object_unref( x ); g_object_unref( x );
out = vips_gsf_path( dz->tree, "blank.png", dz->root_name, NULL ); out = vips_gsf_path( dz->tree, "blank.png", NULL );
gsf_output_write( out, len, buf ); gsf_output_write( out, len, buf );
gsf_output_close( out ); gsf_output_close( out );
g_object_unref( out ); g_object_unref( out );
@ -955,8 +954,7 @@ tile_name( Layer *layer, int x, int y )
*/ */
dz->tile_count += 1; dz->tile_count += 1;
out = vips_gsf_path( dz->tree, name, out = vips_gsf_path( dz->tree, name, dirname, NULL );
dz->root_name, dirname, NULL );
break; break;
@ -965,8 +963,7 @@ tile_name( Layer *layer, int x, int y )
vips_snprintf( dirname2, VIPS_PATH_MAX, "%d", y ); vips_snprintf( dirname2, VIPS_PATH_MAX, "%d", y );
vips_snprintf( name, VIPS_PATH_MAX, "%d%s", x, dz->suffix ); vips_snprintf( name, VIPS_PATH_MAX, "%d%s", x, dz->suffix );
out = vips_gsf_path( dz->tree, name, out = vips_gsf_path( dz->tree, name, dirname, dirname2, NULL );
dz->root_name, dirname, dirname2, NULL );
break; break;
@ -1490,10 +1487,17 @@ vips_foreign_save_dz_build( VipsObject *object )
char *p; char *p;
dz->basename = g_path_get_basename( dz->name ); dz->basename = g_path_get_basename( dz->name );
if( (p = (char *) vips__find_rightmost_brackets( dz->name )) ) if( (p = (char *) vips__find_rightmost_brackets( dz->basename )) )
*p = '\0'; *p = '\0';
if( (p = strrchr( dz->name, '.' )) ) if( (p = strrchr( dz->basename, '.' )) ) {
*p = '\0'; *p = '\0';
/* If we're writing to thing.zip, default to zip container.
*/
if( strcasecmp( p + 1, "zip" ) == 0 &&
!vips_object_argument_isset( object, "container" ) )
dz->container = VIPS_FOREIGN_DZ_CONTAINER_ZIP;
}
} }
dz->dirname = g_path_get_dirname( dz->name ); dz->dirname = g_path_get_dirname( dz->name );
@ -1528,6 +1532,7 @@ vips_foreign_save_dz_build( VipsObject *object )
{ {
GsfOutput *out; GsfOutput *out;
GsfOutput *zip; GsfOutput *zip;
GsfOutput *out2;
GError *error = NULL; GError *error = NULL;
/* This is the zip we are building. /* This is the zip we are building.
@ -1547,7 +1552,19 @@ vips_foreign_save_dz_build( VipsObject *object )
*/ */
g_object_unref( out ); g_object_unref( out );
dz->tree = vips_gsf_tree_new( zip, TRUE ); /* Make the base directory inside the zip. All stuff goes into
* this.
*/
out2 = gsf_outfile_new_child_full( (GsfOutfile *) zip,
dz->basename, TRUE,
"compression-level", 0,
NULL );
dz->tree = vips_gsf_tree_new( out2, TRUE );
/* Note the thing that will need closing up on exit.
*/
dz->tree->container = zip;
} }
break; break;

View File

@ -118,10 +118,6 @@ vips_system_build( VipsObject *object )
char cmd[VIPS_PATH_MAX]; char cmd[VIPS_PATH_MAX];
FILE *fp;
char line[VIPS_PATH_MAX];
char txt[VIPS_PATH_MAX];
VipsBuf buf = VIPS_BUF_STATIC( txt );
char *p; char *p;
char *std_output; char *std_output;
char *std_error; char *std_error;