From b806659fd596295799678d62d3e8d747797614e6 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 26 Apr 2014 11:21:04 +0100 Subject: [PATCH] fix up filename options all done in vips_foreign_load() / vips_foreign_save() now added vips__filename_split8() --- libvips/foreign/foreign.c | 84 ++++++++++++++++++------------------- libvips/include/vips/util.h | 2 + libvips/iofuncs/object.c | 25 ++++++++--- libvips/iofuncs/util.c | 18 ++++++++ 4 files changed, 79 insertions(+), 50 deletions(-) diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index 3cd66656..df9bbf83 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -514,30 +514,26 @@ vips_foreign_find_load_sub( VipsForeignLoadClass *load_class, * Returns: the name of an operation on success, %NULL on error */ const char * -vips_foreign_find_load( const char *filename ) +vips_foreign_find_load( const char *name ) { - char str[VIPS_PATH_MAX]; - char *p; + char filename[VIPS_PATH_MAX]; + char option_string[VIPS_PATH_MAX]; VipsForeignLoadClass *load_class; - /* Take any [options] off the filename. - */ - vips_strncpy( str, filename, VIPS_PATH_MAX ); - if( (p = (char *) vips__find_rightmost_brackets( str )) ) - *p = '\0'; + vips__filename_split8( name, filename, option_string ); - if( !vips_existsf( "%s", str ) ) { + if( !vips_existsf( "%s", filename ) ) { vips_error( "VipsForeignLoad", - _( "file \"%s\" not found" ), filename ); + _( "file \"%s\" not found" ), name ); return( NULL ); } if( !(load_class = (VipsForeignLoadClass *) vips_foreign_map( "VipsForeignLoad", (VipsSListMap2Fn) vips_foreign_find_load_sub, - (void *) str, NULL )) ) { + (void *) filename, NULL )) ) { vips_error( "VipsForeignLoad", - _( "\"%s\" is not a known file format" ), filename ); + _( "\"%s\" is not a known file format" ), name ); return( NULL ); } @@ -558,17 +554,21 @@ vips_foreign_find_load( const char *filename ) * Returns: 0 on success, -1 on error */ int -vips_foreign_load( const char *filename, VipsImage **out, ... ) +vips_foreign_load( const char *name, VipsImage **out, ... ) { + char filename[VIPS_PATH_MAX]; + char option_string[VIPS_PATH_MAX]; const char *operation_name; va_list ap; int result; + vips__filename_split8( name, filename, option_string ); if( !(operation_name = vips_foreign_find_load( filename )) ) return( -1 ); va_start( ap, out ); - result = vips_call_split( operation_name, ap, filename, out ); + result = vips_call_split_option_string( operation_name, option_string, + ap, filename, out ); va_end( ap ); return( result ); @@ -1481,24 +1481,20 @@ vips_foreign_find_save_sub( VipsForeignSaveClass *save_class, * Returns: the name of an operation on success, %NULL on error */ const char * -vips_foreign_find_save( const char *filename ) +vips_foreign_find_save( const char *name ) { - char str[VIPS_PATH_MAX]; - char *p; + char filename[VIPS_PATH_MAX]; + char option_string[VIPS_PATH_MAX]; VipsForeignSaveClass *save_class; - /* Take any [options] off the filename. - */ - vips_strncpy( str, filename, VIPS_PATH_MAX ); - if( (p = (char *) vips__find_rightmost_brackets( str )) ) - *p = '\0'; + vips__filename_split8( name, filename, option_string ); if( !(save_class = (VipsForeignSaveClass *) vips_foreign_map( "VipsForeignSave", (VipsSListMap2Fn) vips_foreign_find_save_sub, - (void *) str, NULL )) ) { + (void *) filename, NULL )) ) { vips_error( "VipsForeignSave", - _( "\"%s\" is not a known file format" ), filename ); + _( "\"%s\" is not a known file format" ), name ); return( NULL ); } @@ -1521,17 +1517,22 @@ vips_foreign_find_save( const char *filename ) * Returns: 0 on success, -1 on error */ int -vips_foreign_save( VipsImage *in, const char *filename, ... ) +vips_foreign_save( VipsImage *in, const char *name, ... ) { + char filename[VIPS_PATH_MAX]; + char option_string[VIPS_PATH_MAX]; const char *operation_name; va_list ap; int result; + vips__filename_split8( name, filename, option_string ); + if( !(operation_name = vips_foreign_find_save( filename )) ) return( -1 ); - va_start( ap, filename ); - result = vips_call_split( operation_name, ap, in, filename ); + va_start( ap, name ); + result = vips_call_split_option_string( operation_name, option_string, + ap, in, filename ); va_end( ap ); return( result ); @@ -1566,24 +1567,20 @@ vips_foreign_find_save_buffer_sub( VipsForeignSaveClass *save_class, * Returns: the name of an operation on success, %NULL on error */ const char * -vips_foreign_find_save_buffer( const char *suffix ) +vips_foreign_find_save_buffer( const char *name ) { - char str[VIPS_PATH_MAX]; - char *p; + char suffix[VIPS_PATH_MAX]; + char option_string[VIPS_PATH_MAX]; VipsForeignSaveClass *save_class; - /* Take any [options] off the suffix. - */ - vips_strncpy( str, suffix, VIPS_PATH_MAX ); - if( (p = (char *) vips__find_rightmost_brackets( str )) ) - *p = '\0'; + vips__filename_split8( name, suffix, option_string ); if( !(save_class = (VipsForeignSaveClass *) vips_foreign_map( "VipsForeignSave", (VipsSListMap2Fn) vips_foreign_find_save_buffer_sub, - (void *) str, NULL )) ) { + (void *) suffix, NULL )) ) { vips_error( "VipsForeignSave", - _( "\"%s\" is not a known file format" ), suffix ); + _( "\"%s\" is not a known file format" ), name ); return( NULL ); } @@ -1610,24 +1607,23 @@ vips_foreign_find_save_buffer( const char *suffix ) */ int vips_foreign_save_buffer( VipsImage *in, - const char *suffix, void **buf, size_t *len, + const char *name, void **buf, size_t *len, ... ) { - const char *options; + char suffix[VIPS_PATH_MAX]; + char option_string[VIPS_PATH_MAX]; const char *operation_name; VipsArea *area; va_list ap; int result; + vips__filename_split8( name, suffix, option_string ); + if( !(operation_name = vips_foreign_find_save_buffer( suffix )) ) return( -1 ); - /* Extract the options from the suffix, if any. - */ - options = vips__find_rightmost_brackets( suffix ); - va_start( ap, len ); - result = vips_call_split_option_string( operation_name, options, + result = vips_call_split_option_string( operation_name, option_string, ap, in, &area ); va_end( ap ); diff --git a/libvips/include/vips/util.h b/libvips/include/vips/util.h index 152bcb2c..4bd3f069 100644 --- a/libvips/include/vips/util.h +++ b/libvips/include/vips/util.h @@ -257,6 +257,8 @@ const char *vips__token_must( const char *buffer, VipsToken *token, const char *vips__token_need( const char *buffer, VipsToken need_token, char *string, int size ); const char *vips__find_rightmost_brackets( const char *p ); +void vips__filename_split8( const char *name, + char *filename, char *option_string ); int vips_ispoweroftwo( int p ); int vips_amiMSBfirst( void ); diff --git a/libvips/iofuncs/object.c b/libvips/iofuncs/object.c index 0dfc355e..5808da98 100644 --- a/libvips/iofuncs/object.c +++ b/libvips/iofuncs/object.c @@ -2088,10 +2088,18 @@ vips_object_set_args( VipsObject *object, const char *p ) string, VIPS_PATH_MAX )) ) return( -1 ); - do { - if( !(p = vips__token_need( p, VIPS_TOKEN_STRING, - string, VIPS_PATH_MAX )) ) + if( !(p = vips__token_must( p, &token, string, VIPS_PATH_MAX )) ) + return( -1 ); + + for(;;) { + if( token == VIPS_TOKEN_RIGHT ) + break; + if( token != VIPS_TOKEN_STRING ) { + vips_error( class->nickname, + _( "expected string or ), saw %s" ), + vips_enum_nick( VIPS_TYPE_TOKEN, token ) ); return( -1 ); + } /* We have to look for a '=', ')' or a ',' to see if string is * a param name or a value. @@ -2134,14 +2142,19 @@ vips_object_set_args( VipsObject *object, const char *p ) return( -1 ); } - /* Now must be a , or a ). + /* Now must be a , or a ). */ - if( token != VIPS_TOKEN_RIGHT && token != VIPS_TOKEN_COMMA ) { + if( token == VIPS_TOKEN_COMMA ) { + if( !(p = vips__token_must( p, &token, + string, VIPS_PATH_MAX )) ) + return( -1 ); + } + else if( token != VIPS_TOKEN_RIGHT ) { vips_error( class->nickname, "%s", _( "not , or ) after parameter" ) ); return( -1 ); } - } while( token != VIPS_TOKEN_RIGHT ); + } if( (p = vips__token_get( p, &token, string, VIPS_PATH_MAX )) ) { vips_error( class->nickname, diff --git a/libvips/iofuncs/util.c b/libvips/iofuncs/util.c index 59ebc04d..c8840010 100644 --- a/libvips/iofuncs/util.c +++ b/libvips/iofuncs/util.c @@ -1428,6 +1428,24 @@ vips__find_rightmost_brackets( const char *p ) return( start[i] ); } +/* Split a vips8-style filename + options. + * + * filename and options must be VIPS_PATH_MAX in length. + */ +void +vips__filename_split8( const char *name, char *filename, char *option_string ) +{ + char *p; + + vips_strncpy( filename, name, VIPS_PATH_MAX ); + if( (p = (char *) vips__find_rightmost_brackets( filename )) ) { + vips_strncpy( option_string, p, VIPS_PATH_MAX ); + *p = '\0'; + } + else + vips_strncpy( option_string, "", VIPS_PATH_MAX ); +} + /* True if an int is a power of two ... 1, 2, 4, 8, 16, 32, etc. Do with just * integer arithmetic for portability. A previous Nicos version using doubles * and log/log failed on x86 with rounding problems. Return 0 for not