From fd495d36175edfc3cf5921d724ee4dfcc018d41c Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 25 Apr 2014 14:50:58 +0100 Subject: [PATCH 1/7] cleaned up foreign.c need to actually interpret the filename, oops $ vips copy wtc.jpg x.jpg[Q=100] $ ls -l x.jpg\[Q\=100\] -rw-rw-r-- 1 john john 15133033 Apr 25 14:50 x.jpg[Q=100] $ vips copy wtc.jpg x.jpg[Q=1] $ ls -l x.jpg\[Q\=1\] -rw-rw-r-- 1 john john 15133033 Apr 25 14:50 x.jpg[Q=1] --- TODO | 20 +- libvips/foreign/foreign.c | 547 ++++++++++--------------------- libvips/include/vips/foreign.h | 10 +- libvips/include/vips/operation.h | 2 + libvips/iofuncs/image.c | 9 +- libvips/iofuncs/object.c | 8 +- libvips/iofuncs/operation.c | 104 +++--- 7 files changed, 267 insertions(+), 433 deletions(-) diff --git a/TODO b/TODO index e908969c..bb11b09e 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,22 @@ +- when do we apply filename options in vips_foreign_load()? + + should we split the filename and use vips_call_split_option_string()? + + when do we handle filename splitting in vips_pngload()? + + object_new_from_string I guess + + + +- make all + + if( (env = g_getenv( "IM_DISC_THRESHOLD" )) ) + + be eg. + + if( (env = g_getenv( "VIPS_DISC_THRESHOLD" )) || + (env = g_getenv( "IM_DISC_THRESHOLD" )) ) -- use vips_object_set_from_string() for vips_foreign_load_options() and - friends diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index 6d3b03b6..3cd66656 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -466,6 +466,8 @@ vips_foreign_load_summary_class( VipsObjectClass *object_class, VipsBuf *buf ) if( !G_TYPE_IS_ABSTRACT( G_TYPE_FROM_CLASS( class ) ) ) { if( class->is_a ) vips_buf_appends( buf, ", is_a" ); + if( class->is_a_buffer ) + vips_buf_appends( buf, ", is_a_buffer" ); if( class->get_flags ) vips_buf_appends( buf, ", get_flags" ); if( class->get_flags_filename ) @@ -484,7 +486,7 @@ vips_foreign_load_summary_class( VipsObjectClass *object_class, VipsBuf *buf ) /* Can this VipsForeign open this file? */ static void * -vips_foreign_load_new_from_foreign_sub( VipsForeignLoadClass *load_class, +vips_foreign_find_load_sub( VipsForeignLoadClass *load_class, const char *filename ) { VipsForeignClass *class = VIPS_FOREIGN_CLASS( load_class ); @@ -504,7 +506,8 @@ vips_foreign_load_new_from_foreign_sub( VipsForeignLoadClass *load_class, * vips_foreign_find_load: * @filename: file to find a loader for * - * Searches for an operation you could use to load @filename. + * Searches for an operation you could use to load @filename. Any trailing + * options on @filename are stripped and ignored. * * See also: vips_foreign_load(). * @@ -513,9 +516,17 @@ vips_foreign_load_new_from_foreign_sub( VipsForeignLoadClass *load_class, const char * vips_foreign_find_load( const char *filename ) { + char str[VIPS_PATH_MAX]; + char *p; VipsForeignLoadClass *load_class; - if( !vips_existsf( "%s", filename ) ) { + /* Take any [options] off the filename. + */ + vips_strncpy( str, filename, VIPS_PATH_MAX ); + if( (p = (char *) vips__find_rightmost_brackets( str )) ) + *p = '\0'; + + if( !vips_existsf( "%s", str ) ) { vips_error( "VipsForeignLoad", _( "file \"%s\" not found" ), filename ); return( NULL ); @@ -523,8 +534,8 @@ vips_foreign_find_load( const char *filename ) if( !(load_class = (VipsForeignLoadClass *) vips_foreign_map( "VipsForeignLoad", - (VipsSListMap2Fn) vips_foreign_load_new_from_foreign_sub, - (void *) filename, NULL )) ) { + (VipsSListMap2Fn) vips_foreign_find_load_sub, + (void *) str, NULL )) ) { vips_error( "VipsForeignLoad", _( "\"%s\" is not a known file format" ), filename ); return( NULL ); @@ -533,6 +544,36 @@ vips_foreign_find_load( const char *filename ) return( G_OBJECT_CLASS_NAME( load_class ) ); } +/** + * vips_foreign_load: + * @filename: file to load + * @out: output image + * @...: %NULL-terminated list of optional named arguments + * + * Loads @filename into @out using the loader recommended by + * vips_foreign_find_load(). + * + * See also: vips_foreign_save(), vips_foreign_load_options(). + * + * Returns: 0 on success, -1 on error + */ +int +vips_foreign_load( const char *filename, VipsImage **out, ... ) +{ + const char *operation_name; + va_list ap; + int result; + + if( !(operation_name = vips_foreign_find_load( filename )) ) + return( -1 ); + + va_start( ap, out ); + result = vips_call_split( operation_name, ap, filename, out ); + va_end( ap ); + + return( result ); +} + /* Can this VipsForeign open this buffer? */ static void * @@ -547,10 +588,11 @@ vips_foreign_find_load_buffer_sub( VipsForeignLoadClass *load_class, } /** - * vips_foreign_find_load: - * @filename: file to find a loader for + * vips_foreign_find_load_buffer: + * @buf: start of memory buffer + * @len: length of memory buffer * - * Searches for an operation you could use to load @filename. + * Searches for an operation you could use to load a memory buffer. * * See also: vips_foreign_load_buffer(). * @@ -574,37 +616,45 @@ vips_foreign_find_load_buffer( void *buf, size_t len ) } /** - * vips_foreign_find_load_options: - * @filename: file to find a loader for + * vips_foreign_load_buffer: + * @buf: start of memory buffer + * @len: length of memory buffer + * @option_string: set of extra options as a string + * @out: output image + * @...: %NULL-terminated list of optional named arguments * - * Searches for an operation you could use to load @filename. + * Loads @buf, @len into @out using the loader recommended by + * vips_foreign_find_load_buffer(). @option_string can be used to give an + * extra set of load options. * - * Arguments to the loader may be embedded in the filename using the usual - * syntax. - * - * See also: vips_foreign_load(). + * See also: vips_foreign_save(), vips_foreign_load_options(). * * Returns: 0 on success, -1 on error */ -const char * -vips_foreign_find_load_options( const char *filename ) +int +vips_foreign_load_buffer( void *buf, size_t len, const char *option_string, + VipsImage **out, ... ) { - VipsObjectClass *oclass = g_type_class_ref( VIPS_TYPE_FOREIGN_LOAD ); - VipsObject *object; - const char *type_name; + const char *operation_name; + VipsArea *area; + va_list ap; + int result; - /* This will use vips_foreign_load_new_from_string() to pick a loader, - * then set options from the tail of the filename. This is rather slow - * :-( + if( !(operation_name = vips_foreign_find_load_buffer( buf, len )) ) + return( -1 ); + + /* We don't take a copy of the data or free it. */ - if( !(object = vips_object_new_from_string( oclass, filename )) ) - return( NULL ); + area = vips_area_new_blob( NULL, buf, len ); - type_name = G_OBJECT_TYPE_NAME( object ); + va_start( ap, out ); + result = vips_call_split_option_string( operation_name, + option_string, ap, area, out ); + va_end( ap ); - g_object_unref( object ); + vips_area_unref( area ); - return( type_name ); + return( result ); } /** @@ -1039,135 +1089,6 @@ vips_foreign_save_summary_class( VipsObjectClass *object_class, VipsBuf *buf ) vips_enum_nick( VIPS_TYPE_SAVEABLE, class->saveable ) ); } -/* Can we write this filename with this file? - */ -static void * -vips_foreign_find_save_sub( VipsForeignSaveClass *save_class, - const char *filename ) -{ - VipsForeignClass *class = VIPS_FOREIGN_CLASS( save_class ); - - if( class->suffs && - vips_filename_suffix_match( filename, class->suffs ) ) - return( save_class ); - - return( NULL ); -} - -/** - * vips_foreign_find_save: - * @filename: name to find a saver for - * - * Searches for an operation you could use to write to @filename. - * - * @filename may not contain embedded options. See - * vips_foreign_find_save_options() if your filename may have options in. - * - * See also: vips_foreign_save(). - * - * Returns: the name of an operation on success, %NULL on error - */ -const char * -vips_foreign_find_save( const char *filename ) -{ - VipsForeignSaveClass *save_class; - - if( !(save_class = (VipsForeignSaveClass *) vips_foreign_map( - "VipsForeignSave", - (VipsSListMap2Fn) vips_foreign_find_save_sub, - (void *) filename, NULL )) ) { - vips_error( "VipsForeignSave", - _( "\"%s\" is not a known file format" ), filename ); - - return( NULL ); - } - - return( G_OBJECT_CLASS_NAME( save_class ) ); -} - -/* Can we write this buffer with this file type? - */ -static void * -vips_foreign_find_save_buffer_sub( VipsForeignSaveClass *save_class, - const char *suffix ) -{ - VipsObjectClass *object_class = VIPS_OBJECT_CLASS( save_class ); - VipsForeignClass *class = VIPS_FOREIGN_CLASS( save_class ); - - if( class->suffs && - vips_ispostfix( object_class->nickname, "_buffer" ) && - vips_filename_suffix_match( suffix, class->suffs ) ) - return( save_class ); - - return( NULL ); -} - -/** - * vips_foreign_find_save_buffer: - * @suffix: name to find a saver for - * - * Searches for an operation you could use to write to a buffer in @suffix - * format. - * - * @filename may not contain embedded options. See - * vips_foreign_find_save_options() if your filename may have options in. - * - * See also: vips_foreign_save_buffer(). - * - * Returns: the name of an operation on success, %NULL on error - */ -const char * -vips_foreign_find_save_buffer( const char *suffix ) -{ - VipsForeignSaveClass *save_class; - - if( !(save_class = (VipsForeignSaveClass *) vips_foreign_map( - "VipsForeignSave", - (VipsSListMap2Fn) vips_foreign_find_save_buffer_sub, - (void *) suffix, NULL )) ) { - vips_error( "VipsForeignSave", - _( "\"%s\" is not a known file format" ), suffix ); - - return( NULL ); - } - - return( G_OBJECT_CLASS_NAME( save_class ) ); -} - -/** - * vips_foreign_find_save_options: - * @filename: name to find a saver for - * - * Searches for an operation you could use to write to @filename. - * - * @filename may contain embedded options. See - * vips_foreign_find_save() if your filename does not have options in. - * - * See also: vips_foreign_write(). - * - * Returns: 0 on success, -1 on error - */ -const char * -vips_foreign_find_save_options( const char *filename ) -{ - VipsObjectClass *oclass = g_type_class_ref( VIPS_TYPE_FOREIGN_SAVE ); - VipsObject *object; - const char *type_name; - - /* This will use vips_foreign_save_new_from_string() to pick a saver, - * then set options from the tail of the filename. This is rather slow - * :-( - */ - if( !(object = vips_object_new_from_string( oclass, filename )) ) - return( NULL ); - - type_name = G_OBJECT_TYPE_NAME( object ); - - g_object_unref( object ); - - return( type_name ); -} - static VipsObject * vips_foreign_save_new_from_string( const char *string ) { @@ -1533,72 +1454,56 @@ vips_foreign_save_init( VipsForeignSave *object ) { } -/** - * vips_foreign_load: - * @filename: file to load - * @out: output image - * @...: %NULL-terminated list of optional named arguments - * - * Loads @filename into @out using the loader recommended by - * vips_foreign_find_load(). - * - * See also: vips_foreign_save(), vips_foreign_load_options(). - * - * Returns: 0 on success, -1 on error +/* Can we write this filename with this file? */ -int -vips_foreign_load( const char *filename, VipsImage **out, ... ) +static void * +vips_foreign_find_save_sub( VipsForeignSaveClass *save_class, + const char *filename ) { - const char *operation; - va_list ap; - int result; + VipsForeignClass *class = VIPS_FOREIGN_CLASS( save_class ); - if( !(operation = vips_foreign_find_load( filename )) ) - return( -1 ); + if( class->suffs && + vips_filename_suffix_match( filename, class->suffs ) ) + return( save_class ); - va_start( ap, out ); - result = vips_call_split( operation, ap, filename, out ); - va_end( ap ); - - return( result ); + return( NULL ); } /** - * vips_foreign_load_buffer: - * @buf: start of memory buffer - * @len: length of memory buffer - * @out: output image - * @...: %NULL-terminated list of optional named arguments + * vips_foreign_find_save: + * @filename: name to find a saver for * - * Loads @buf, @len into @out using the loader recommended by - * vips_foreign_find_load_buffer(). + * Searches for an operation you could use to write to @filename. + * Any trailing options on @filename are stripped and ignored. * - * See also: vips_foreign_save(), vips_foreign_load_options(). + * See also: vips_foreign_save(). * - * Returns: 0 on success, -1 on error + * Returns: the name of an operation on success, %NULL on error */ -int -vips_foreign_load_buffer( void *buf, size_t len, VipsImage **out, ... ) +const char * +vips_foreign_find_save( const char *filename ) { - const char *operation; - VipsArea *area; - va_list ap; - int result; + char str[VIPS_PATH_MAX]; + char *p; + VipsForeignSaveClass *save_class; - if( !(operation = vips_foreign_find_load_buffer( buf, len )) ) - return( -1 ); - - /* We don't take a copy of the data or free it. + /* Take any [options] off the filename. */ - area = vips_area_new_blob( NULL, buf, len ); + vips_strncpy( str, filename, VIPS_PATH_MAX ); + if( (p = (char *) vips__find_rightmost_brackets( str )) ) + *p = '\0'; - va_start( ap, out ); - result = vips_call_split( operation, ap, area, out ); - va_end( ap ); + if( !(save_class = (VipsForeignSaveClass *) vips_foreign_map( + "VipsForeignSave", + (VipsSListMap2Fn) vips_foreign_find_save_sub, + (void *) str, NULL )) ) { + vips_error( "VipsForeignSave", + _( "\"%s\" is not a known file format" ), filename ); - vips_area_unref( area ); + return( NULL ); + } - return( result ); + return( G_OBJECT_CLASS_NAME( save_class ) ); } /** @@ -1618,20 +1523,74 @@ vips_foreign_load_buffer( void *buf, size_t len, VipsImage **out, ... ) int vips_foreign_save( VipsImage *in, const char *filename, ... ) { - const char *operation; + const char *operation_name; va_list ap; int result; - if( !(operation = vips_foreign_find_save( filename )) ) + if( !(operation_name = vips_foreign_find_save( filename )) ) return( -1 ); va_start( ap, filename ); - result = vips_call_split( operation, ap, in, filename ); + result = vips_call_split( operation_name, ap, in, filename ); va_end( ap ); return( result ); } +/* Can we write this buffer with this file type? + */ +static void * +vips_foreign_find_save_buffer_sub( VipsForeignSaveClass *save_class, + const char *suffix ) +{ + VipsObjectClass *object_class = VIPS_OBJECT_CLASS( save_class ); + VipsForeignClass *class = VIPS_FOREIGN_CLASS( save_class ); + + if( class->suffs && + vips_ispostfix( object_class->nickname, "_buffer" ) && + vips_filename_suffix_match( suffix, class->suffs ) ) + return( save_class ); + + return( NULL ); +} + +/** + * vips_foreign_find_save_buffer: + * @suffix: name to find a saver for + * + * Searches for an operation you could use to write to a buffer in @suffix + * format. + * + * See also: vips_foreign_save_buffer(). + * + * Returns: the name of an operation on success, %NULL on error + */ +const char * +vips_foreign_find_save_buffer( const char *suffix ) +{ + char str[VIPS_PATH_MAX]; + char *p; + 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'; + + if( !(save_class = (VipsForeignSaveClass *) vips_foreign_map( + "VipsForeignSave", + (VipsSListMap2Fn) vips_foreign_find_save_buffer_sub, + (void *) str, NULL )) ) { + vips_error( "VipsForeignSave", + _( "\"%s\" is not a known file format" ), suffix ); + + return( NULL ); + } + + return( G_OBJECT_CLASS_NAME( save_class ) ); +} + /** * vips_foreign_save_buffer: * @in: image to write @@ -1654,63 +1613,24 @@ vips_foreign_save_buffer( VipsImage *in, const char *suffix, void **buf, size_t *len, ... ) { - char str[VIPS_PATH_MAX]; - char *p; + const char *options; const char *operation_name; - VipsOperation *operation; VipsArea *area; va_list ap; int result; - /* Take any [options] off the suffix. - */ - vips_strncpy( str, suffix, VIPS_PATH_MAX ); - if( (p = (char *) vips__find_rightmost_brackets( str )) ) - *p = '\0'; - - if( !(operation_name = vips_foreign_find_save_buffer( str )) ) + if( !(operation_name = vips_foreign_find_save_buffer( suffix )) ) return( -1 ); - if( !(operation = vips_operation_new( operation_name )) ) - return( -1 ); - - g_object_set( operation, "in", in, NULL ); - - /* Now set any operation args from the options list. + /* Extract the options from the suffix, if any. */ - if( (p = (char *) vips__find_rightmost_brackets( suffix )) && - vips_object_set_from_string( VIPS_OBJECT( operation ), p ) ) { - vips_object_unref_outputs( VIPS_OBJECT( operation ) ); - g_object_unref( operation ); - return( -1 ); - } + options = vips__find_rightmost_brackets( suffix ); - /* Set any from varargs. - */ va_start( ap, len ); - result = vips_object_set_valist( VIPS_OBJECT( operation ), ap ); + result = vips_call_split_option_string( operation_name, options, + ap, in, &area ); va_end( ap ); - if( result ) { - vips_object_unref_outputs( VIPS_OBJECT( operation ) ); - g_object_unref( operation ); - return( -1 ); - } - - if( vips_cache_operation_buildp( &operation ) ) { - vips_object_unref_outputs( VIPS_OBJECT( operation ) ); - g_object_unref( operation ); - return( -1 ); - } - - g_object_get( operation, "buffer", &area, NULL ); - - /* Getting @buffer will have upped its count so it'll be safe. - * We can junk all other outputs, - */ - vips_object_unref_outputs( VIPS_OBJECT( operation ) ); - g_object_unref( operation ); - if( area ) { if( buf ) { *buf = area->data; @@ -1722,124 +1642,7 @@ vips_foreign_save_buffer( VipsImage *in, vips_area_unref( area ); } - return( 0 ); -} - -/** - * vips_foreign_load_options: - * @filename: file to load - * @out: output image - * @...: %NULL-terminated list of optional named arguments - * - * Loads @filename into @out using the loader recommended by - * vips_foreign_find_load(). - * - * Arguments to the loader may be embedded in the filename using the usual - * syntax. They may also be given as a set of NULL-terminated optional - * arguments. - * - * See also: vips_foreign_load(). - * - * Returns: 0 on success, -1 on error - */ -int -vips_foreign_load_options( const char *filename, VipsImage **out, ... ) -{ - VipsObjectClass *oclass = g_type_class_ref( VIPS_TYPE_FOREIGN_LOAD ); - - VipsObject *object; - va_list ap; - int result; - - /* This will use vips_foreign_load_new_from_string() to pick a loader, - * then set options from the remains of the string. - */ - if( !(object = vips_object_new_from_string( oclass, filename )) ) - return( -1 ); - - /* Also set options from args. - */ - va_start( ap, out ); - result = vips_object_set_valist( object, ap ); - va_end( ap ); - if( result ) - return( -1 ); - - if( vips_cache_operation_buildp( (VipsOperation **) &object ) ) { - /* The build may have made some output objects before - * failing. - */ - vips_object_unref_outputs( object ); - g_object_unref( object ); - return( -1 ); - } - - g_object_get( object, "out", out, NULL ); - - /* Getting @out will have upped its count so it'll be safe. - * We can junk all other outputs, - */ - vips_object_unref_outputs( object ); - - /* @out holds a ref to new_object, we can drop ours. - */ - g_object_unref( object ); - - return( 0 ); -} - -/** - * vips_foreign_save_options: - * @in: image to write - * @filename: file to write to - * @...: %NULL-terminated list of optional named arguments - * - * Saves @in to @filename using the saver recommended by - * vips_foreign_find_save(). - * - * Arguments to the saver may be embedded in the filename using the usual - * syntax. They may also be given as a set of NULL-terminated optional - * arguments. - * - * See also: vips_foreign_save(). - * - * Returns: 0 on success, -1 on error - */ -int -vips_foreign_save_options( VipsImage *in, const char *filename, ... ) -{ - VipsObjectClass *oclass = g_type_class_ref( VIPS_TYPE_FOREIGN_SAVE ); - - VipsObject *object; - va_list ap; - int result; - - /* This will use vips_foreign_save_new_from_string() to pick a saver, - * then set options from the tail of the filename. - */ - if( !(object = vips_object_new_from_string( oclass, filename )) ) - return( -1 ); - - g_object_set( object, "in", in, NULL ); - - /* Also set options from args. - */ - va_start( ap, filename ); - result = vips_object_set_valist( object, ap ); - va_end( ap ); - if( result ) - return( -1 ); - - /* ... and running _build() should save it. - */ - if( vips_cache_operation_buildp( (VipsOperation **) &object ) ) { - g_object_unref( object ); - return( -1 ); - } - - g_object_unref( object ); - - return( 0 ); + return( result ); } /* Called from iofuncs to init all operations in this dir. Use a plugin system diff --git a/libvips/include/vips/foreign.h b/libvips/include/vips/foreign.h index d539618e..a14899a8 100644 --- a/libvips/include/vips/foreign.h +++ b/libvips/include/vips/foreign.h @@ -215,7 +215,6 @@ GType vips_foreign_load_get_type( void ); const char *vips_foreign_find_load( const char *filename ); const char *vips_foreign_find_load_buffer( void *buf, size_t len ); -const char *vips_foreign_find_load_options( const char *filename ); VipsForeignFlags vips_foreign_flags( const char *loader, const char *filename ); gboolean vips_foreign_is_a( const char *loader, const char *filename ); @@ -309,7 +308,6 @@ GType vips_foreign_save_get_type( void ); const char *vips_foreign_find_save( const char *filename ); const char * vips_foreign_find_save_buffer( const char *suffix ); -const char *vips_foreign_find_save_options( const char *filename ); /* Read/write an image convenience functions. */ @@ -318,12 +316,8 @@ int vips_foreign_load( const char *filename, VipsImage **out, ... ) int vips_foreign_save( VipsImage *in, const char *filename, ... ) __attribute__((sentinel)); -int vips_foreign_load_options( const char *filename, VipsImage **out, ... ) - __attribute__((sentinel)); -int vips_foreign_save_options( VipsImage *in, const char *filename, ... ) - __attribute__((sentinel)); - -int vips_foreign_load_buffer( void *buf, size_t len, VipsImage **out, ... ) +int vips_foreign_load_buffer( void *buf, size_t len, const char *option_string, + VipsImage **out, ... ) __attribute__((sentinel)); int vips_foreign_save_buffer( VipsImage *in, const char *suffix, void **buf, size_t *len, ... ) diff --git a/libvips/include/vips/operation.h b/libvips/include/vips/operation.h index e9697e61..0afb9a9d 100644 --- a/libvips/include/vips/operation.h +++ b/libvips/include/vips/operation.h @@ -104,6 +104,8 @@ VipsOperation *vips_operation_new( const char *name ); int vips_call( const char *operation_name, ... ) __attribute__((sentinel)); int vips_call_split( const char *operation_name, va_list optional, ... ); +int vips_call_split_option_string( const char *operation_name, + const char *option_string, va_list optional, ... ); void vips_call_options( GOptionGroup *group, VipsOperation *operation ); int vips_call_argv( VipsOperation *operation, int argc, char **argv ); diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index d274d83e..9b3b4a56 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -670,7 +670,7 @@ vips_image_rewind( VipsObject *object ) static void vips_image_save_cb( VipsImage *image, int *result ) { - if( vips_foreign_save_options( image, image->filename, NULL ) ) + if( vips_foreign_save( image, image->filename, NULL ) ) *result = -1; } @@ -825,14 +825,13 @@ vips_image_build( VipsObject *object ) VipsImage *t; if( mode[1] == 's' ) { - if( vips_foreign_load_options( filename, &t, + if( vips_foreign_load( filename, &t, "access", VIPS_ACCESS_SEQUENTIAL, NULL ) ) return( -1 ); } else { - if( vips_foreign_load_options( filename, &t, - NULL ) ) + if( vips_foreign_load( filename, &t, NULL ) ) return( -1 ); } @@ -855,7 +854,7 @@ vips_image_build( VipsObject *object ) */ g_assert( g_type_from_name( "VipsForeignSaveVips" ) ); - if( !(file_op = vips_foreign_find_save_options( filename )) ) + if( !(file_op = vips_foreign_find_save( filename )) ) return( -1 ); /* If this is the vips saver, just save directly ourselves. diff --git a/libvips/iofuncs/object.c b/libvips/iofuncs/object.c index 70cf40eb..0dfc355e 100644 --- a/libvips/iofuncs/object.c +++ b/libvips/iofuncs/object.c @@ -1672,8 +1672,7 @@ vips_object_set_argument_from_string( VipsObject *object, return( -1 ); } - /* Read the filename. vips_foreign_load_options() - * handles embedded options. + /* Read the filename. */ if( flags & VIPS_OPERATION_SEQUENTIAL_UNBUFFERED ) access = VIPS_ACCESS_SEQUENTIAL_UNBUFFERED; @@ -1682,7 +1681,7 @@ vips_object_set_argument_from_string( VipsObject *object, else access = VIPS_ACCESS_RANDOM; - if( vips_foreign_load_options( value, &out, + if( vips_foreign_load( value, &out, "access", access, NULL ) ) return( -1 ); @@ -1906,10 +1905,9 @@ vips_object_get_argument_to_string( VipsObject *object, VipsImage *in; /* Pull out the image and write it. - * vips_foreign_save_options() handles embedded options. */ g_object_get( object, name, &in, NULL ); - if( vips_foreign_save_options( in, arg, NULL ) ) { + if( vips_foreign_save( in, arg, NULL ) ) { g_object_unref( in ); return( -1 ); } diff --git a/libvips/iofuncs/operation.c b/libvips/iofuncs/operation.c index 932c9036..de2d2215 100644 --- a/libvips/iofuncs/operation.c +++ b/libvips/iofuncs/operation.c @@ -647,6 +647,50 @@ vips_call_required_optional( VipsOperation **operation, return( result ); } +static int +vips_call_by_name( const char *operation_name, + const char *option_string, va_list required, va_list optional ) +{ + VipsOperation *operation; + int result; + + VIPS_DEBUG_MSG( "vips_call_by_name: starting for %s ...\n", + operation_name ); + + if( !(operation = vips_operation_new( operation_name )) ) + return( -1 ); + + /* Set str options before vargs options, so the user can't override + * thnigs we set deliberately. + */ + if( option_string && + vips_object_set_from_string( VIPS_OBJECT( operation ), + option_string ) ) { + vips_object_unref_outputs( VIPS_OBJECT( operation ) ); + g_object_unref( operation ); + + return( -1 ); + } + + result = vips_call_required_optional( &operation, required, optional ); + + /* Build failed: junk args and back out. + */ + if( result ) { + vips_object_unref_outputs( VIPS_OBJECT( operation ) ); + g_object_unref( operation ); + + return( -1 ); + } + + /* The operation we have built should now have been reffed by one of + * its arguments or have finished its work. Either way, we can unref. + */ + g_object_unref( operation ); + + return( result ); +} + int vips_call( const char *operation_name, ... ) { @@ -655,16 +699,9 @@ vips_call( const char *operation_name, ... ) va_list required; va_list optional; - VIPS_DEBUG_MSG( "vips_call: starting for %s ...\n", operation_name ); - if( !(operation = vips_operation_new( operation_name ) ) ) return( -1 ); -#ifdef VIPS_DEBUG - VIPS_DEBUG_MSG( "where:\n" ); - vips_object_print_dump( VIPS_OBJECT( operation ) ); -#endif /*VIPS_DEBUG*/ - /* We have to break the va_list into separate required and optional * components. * @@ -690,58 +727,43 @@ vips_call( const char *operation_name, ... ) } } VIPS_ARGUMENT_FOR_ALL_END - result = vips_call_required_optional( &operation, required, optional ); + /* We just needed this operation for the arg loop. + */ + g_object_unref( operation ); + + result = vips_call_by_name( operation_name, NULL, required, optional ); va_end( required ); va_end( optional ); - /* Failed: junk args and back out. - */ - if( result ) { - vips_object_unref_outputs( VIPS_OBJECT( operation ) ); - g_object_unref( operation ); - - return( -1 ); - } - - /* The operation we have built should now have been reffed by one of - * its arguments or have finished its work. Either way, we can unref. - */ - g_object_unref( operation ); - return( result ); } int vips_call_split( const char *operation_name, va_list optional, ... ) { - VipsOperation *operation; int result; va_list required; - VIPS_DEBUG_MSG( "vips_call_split: starting for %s ...\n", - operation_name ); - - if( !(operation = vips_operation_new( operation_name )) ) - return( -1 ); - va_start( required, optional ); - result = vips_call_required_optional( &operation, required, optional ); + result = vips_call_by_name( operation_name, NULL, + required, optional ); va_end( required ); - /* Build failed: junk args and back out. - */ - if( result ) { - vips_object_unref_outputs( VIPS_OBJECT( operation ) ); - g_object_unref( operation ); + return( result ); +} - return( -1 ); - } +int +vips_call_split_option_string( const char *operation_name, + const char *option_string, va_list optional, ... ) +{ + int result; + va_list required; - /* The operation we have built should now have been reffed by one of - * its arguments or have finished its work. Either way, we can unref. - */ - g_object_unref( operation ); + va_start( required, optional ); + result = vips_call_by_name( operation_name, option_string, + required, optional ); + va_end( required ); return( result ); } From b806659fd596295799678d62d3e8d747797614e6 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 26 Apr 2014 11:21:04 +0100 Subject: [PATCH 2/7] 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 From 2fd551efc1c85743f221c9707922417c8311a565 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 26 Apr 2014 11:30:00 +0100 Subject: [PATCH 3/7] sync --- TODO | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/TODO b/TODO index bb11b09e..c07c857f 100644 --- a/TODO +++ b/TODO @@ -1,11 +1,7 @@ -- when do we apply filename options in vips_foreign_load()? - should we split the filename and use vips_call_split_option_string()? - - when do we handle filename splitting in vips_pngload()? - - object_new_from_string I guess +- clean in nip2 is broken + looks like the offset in morph embed is wrong - make all From 034df7086656a337a81948710f473ab267c889b4 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 26 Apr 2014 16:53:29 +0100 Subject: [PATCH 4/7] sync --- TODO | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/TODO b/TODO index c07c857f..98e50806 100644 --- a/TODO +++ b/TODO @@ -3,6 +3,16 @@ looks like the offset in morph embed is wrong + no, worse, try + + 0 0 0 + 0 1 0 + 0 0 0 + + erode ... fails badly + + try with vector disabled? + - make all From ee88271d06b8ecc58c777bd4ce1acafe12413872 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 26 Apr 2014 18:45:13 +0100 Subject: [PATCH 5/7] use VIPS_ prefix for env vars stuff --- TODO | 33 ++------------------------------- libvips/foreign/foreign.c | 3 ++- libvips/iofuncs/error.c | 5 +++-- libvips/iofuncs/image.c | 3 ++- libvips/iofuncs/init.c | 3 ++- libvips/iofuncs/threadpool.c | 15 ++++++--------- libvips/iofuncs/vector.c | 3 ++- 7 files changed, 19 insertions(+), 46 deletions(-) diff --git a/TODO b/TODO index 98e50806..4d102e7f 100644 --- a/TODO +++ b/TODO @@ -1,47 +1,18 @@ - clean in nip2 is broken - looks like the offset in morph embed is wrong + works if you use --vips-novector - no, worse, try - - 0 0 0 - 0 1 0 - 0 0 0 - - erode ... fails badly - - try with vector disabled? - - -- make all - - if( (env = g_getenv( "IM_DISC_THRESHOLD" )) ) - - be eg. - - if( (env = g_getenv( "VIPS_DISC_THRESHOLD" )) || - (env = g_getenv( "IM_DISC_THRESHOLD" )) ) + 14.04 is orc-0.4.18, there must have been a change -- use this for dzsave_buffer - - - -- clean up foreign.c, there seems to be some cruft - - vips_filename_suffix_match() is used by vips_foreign_load_new_from_foreign_sub(), but it splits on ':' ... argh! deprecate this thing and stop ':' split - vips_foreign_find_save() should split on [], there's something to find the - start of the rightmost [] pair, use that - - see also vips_foreign_find_save_buffer() - diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index df9bbf83..a8b23b7d 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -744,7 +744,8 @@ vips_get_disc_threshold( void ) */ threshold = 100 * 1024 * 1024; - if( (env = g_getenv( "IM_DISC_THRESHOLD" )) ) + if( (env = g_getenv( "VIPS_DISC_THRESHOLD" )) || + (env = g_getenv( "IM_DISC_THRESHOLD" )) ) threshold = vips__parse_size( env ); if( vips__disc_threshold ) diff --git a/libvips/iofuncs/error.c b/libvips/iofuncs/error.c index 28cc8d99..aff61d58 100644 --- a/libvips/iofuncs/error.c +++ b/libvips/iofuncs/error.c @@ -408,7 +408,7 @@ vips_info( const char *domain, const char *fmt, ... ) * @ap: arguments to the format string * * Sends a formatted warning message to stderr. If you define the - * environment variable IM_WARNING, these message are surpressed. + * environment variable VIPS_WARNING, these message are surpressed. * * Warning messages are used to report things like overflow counts. * @@ -417,7 +417,8 @@ vips_info( const char *domain, const char *fmt, ... ) void vips_vwarn( const char *domain, const char *fmt, va_list ap ) { - if( !g_getenv( "IM_WARNING" ) ) { + if( !g_getenv( "IM_WARNING" ) && + !g_getenv( "VIPS_WARNING" ) ) { g_mutex_lock( vips__global_lock ); (void) fprintf( stderr, _( "%s: " ), _( "vips warning" ) ); if( domain ) diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 9b3b4a56..5a70ddc5 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -737,6 +737,7 @@ static void vips_image_add_progress( VipsImage *image ) { if( vips__progress || + g_getenv( "VIPS_PROGRESS" ) || g_getenv( "IM_PROGRESS" ) ) { /* Keep the %complete we displayed last time here. @@ -1578,7 +1579,7 @@ vips_image_new( void ) * location for the temporary file. * * The disc threshold can be set with the "--vips-disc-threshold" - * command-line argument, or the IM_DISC_THRESHOLD environment variable. + * command-line argument, or the VIPS_DISC_THRESHOLD environment variable. * The value is a simple integer, but can take a unit postfix of "k", * "m" or "g" to indicate kilobytes, megabytes or gigabytes. * diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index ced93528..89fbe645 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c @@ -244,7 +244,8 @@ vips__init( const char *argv0 ) /* Default info setting from env. */ - if( g_getenv( "IM_INFO" ) ) + if( g_getenv( "VIPS_INFO" ) || + g_getenv( "IM_INFO" ) ) vips__info = 1; /* Register base vips types. diff --git a/libvips/iofuncs/threadpool.c b/libvips/iofuncs/threadpool.c index e17d05af..b2396a73 100644 --- a/libvips/iofuncs/threadpool.c +++ b/libvips/iofuncs/threadpool.c @@ -82,14 +82,10 @@ */ /* Maximum number of concurrent threads we allow. No reason for the limit, - * it's just there to stop mad values for IM_CONCURRENCY killing the system. + * it's just there to stop mad values for VIPS_CONCURRENCY killing the system. */ #define MAX_THREADS (1024) -/* Name of environment variable we get concurrency level from. - */ -#define IM_CONCURRENCY "IM_CONCURRENCY" - /* Default tile geometry ... can be set by init_world. */ int vips__tile_width = VIPS__TILE_WIDTH; @@ -220,7 +216,7 @@ vips_g_thread_new( const char *domain, GThreadFunc func, gpointer data ) * #VipsThreadPool. * * The special value 0 means "default". In this case, the number of threads is - * set by the environmnt variable IM_CONCURRENCY, or if that is not set, the + * set by the environmnt variable VIPS_CONCURRENCY, or if that is not set, the * number of threads availble on the hist machine. * * See also: vips_concurrency_get(). @@ -307,9 +303,9 @@ get_num_processors( void ) * "--vips-concurrency" to set this value. * * If vips_concurrency_set() has not been called and no command-line argument - * was used, vips uses the value of the environment variable IM_CONCURRENCY, + * was used, vips uses the value of the environment variable VIPS_CONCURRENCY, * - * If IM_CONCURRENCY has not been set, vips find the number of hardware + * If VIPS_CONCURRENCY has not been set, vips find the number of hardware * threads that the host machine can run in parallel and uses that value. * * The final value is clipped to the range 1 - 1024. @@ -329,7 +325,8 @@ vips_concurrency_get( void ) */ if( vips__concurrency > 0 ) nthr = vips__concurrency; - else if( (str = g_getenv( IM_CONCURRENCY )) && + else if( ((str = g_getenv( "VIPS_CONCURRENCY" )) || + (str = g_getenv( "IM_CONCURRENCY" ))) && (x = atoi( str )) > 0 ) nthr = x; else diff --git a/libvips/iofuncs/vector.c b/libvips/iofuncs/vector.c index 6c772e65..565973f1 100644 --- a/libvips/iofuncs/vector.c +++ b/libvips/iofuncs/vector.c @@ -77,7 +77,8 @@ vips_vector_init( void ) /* Look for the environment variable IM_NOVECTOR and use that to turn * off as well. */ - if( g_getenv( "IM_NOVECTOR" ) ) + if( g_getenv( "VIPS_NOVECTOR" ) || + g_getenv( "IM_NOVECTOR" ) ) vips__vector_enabled = FALSE; #endif /*HAVE_ORC*/ } From 8f6e959133d3c9c692493cc6e1ab03bdcdc7144b Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 28 Apr 2014 12:59:19 +0100 Subject: [PATCH 6/7] include oops --- TODO | 1 + libvips/arithmetic/hough_line.c | 1 + 2 files changed, 2 insertions(+) diff --git a/TODO b/TODO index 4d102e7f..3f6450a6 100644 --- a/TODO +++ b/TODO @@ -5,6 +5,7 @@ 14.04 is orc-0.4.18, there must have been a change + nope, still broken with 0.4.11 diff --git a/libvips/arithmetic/hough_line.c b/libvips/arithmetic/hough_line.c index 6fac6e2f..eaa5b8bd 100644 --- a/libvips/arithmetic/hough_line.c +++ b/libvips/arithmetic/hough_line.c @@ -37,6 +37,7 @@ #include #include +#include #include From 5ec80bf163b39a12d56b4cde3751d185839189ec Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 28 Apr 2014 14:02:35 +0100 Subject: [PATCH 7/7] fix an orc bug --- TODO | 9 --------- libvips/morphology/hitmiss.c | 23 +++++++++++++++-------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/TODO b/TODO index 3f6450a6..4b86a3b1 100644 --- a/TODO +++ b/TODO @@ -1,13 +1,4 @@ -- clean in nip2 is broken - - works if you use --vips-novector - - 14.04 is orc-0.4.18, there must have been a change - - nope, still broken with 0.4.11 - - - vips_filename_suffix_match() is used by vips_foreign_load_new_from_foreign_sub(), but it splits on ':' ... argh! diff --git a/libvips/morphology/hitmiss.c b/libvips/morphology/hitmiss.c index 093b5ea4..fdbe4584 100644 --- a/libvips/morphology/hitmiss.c +++ b/libvips/morphology/hitmiss.c @@ -51,6 +51,7 @@ */ /* +#define DEBUG_VERBOSE #define DEBUG */ @@ -208,8 +209,14 @@ pass_compile_section( Pass *pass, Morph *morph, gboolean first_pass ) ASM3( "orb", "sum", "sum", "value" ); } else { - if( !mask->coeff[i] ) - ASM3( "andnb", "sum", "sum", "value" ); + if( !mask->coeff[i] ) { + /* You'd think we could use andnb, but it + * fails on some machines with some orc + * versions :( + */ + ASM3( "xorb", "value", "value", one ); + ASM3( "andb", "sum", "sum", "value" ); + } else ASM3( "andb", "sum", "sum", "value" ); } @@ -454,10 +461,10 @@ dilate_gen( REGION *or, void *vseq, void *a, void *b ) if( im_prepare( ir, &s ) ) return( -1 ); -#ifdef DEBUG +#ifdef DEBUG_VERBOSE printf( "dilate_gen: preparing %dx%d@%dx%d pixels\n", s.width, s.height, s.left, s.top ); -#endif /*DEBUG*/ +#endif /*DEBUG_VERBOSE*/ /* Scan mask, building offsets we check when processing. Only do this * if the bpl has changed since the previous im_prepare(). @@ -566,10 +573,10 @@ erode_gen( REGION *or, void *vseq, void *a, void *b ) if( im_prepare( ir, &s ) ) return( -1 ); -#ifdef DEBUG +#ifdef DEBUG_VERBOSE printf( "erode_gen: preparing %dx%d@%dx%d pixels\n", s.width, s.height, s.left, s.top ); -#endif /*DEBUG*/ +#endif /*DEBUG_VERBOSE*/ /* Scan mask, building offsets we check when processing. Only do this * if the bpl has changed since the previous im_prepare(). @@ -665,10 +672,10 @@ morph_vector_gen( REGION *or, void *vseq, void *a, void *b ) if( im_prepare( ir, &s ) ) return( -1 ); -#ifdef DEBUG +#ifdef DEBUG_VERBOSE printf( "morph_vector_gen: preparing %dx%d@%dx%d pixels\n", s.width, s.height, s.left, s.top ); -#endif /*DEBUG*/ +#endif /*DEBUG_VERBOSE*/ for( j = 0; j < morph->n_pass; j++ ) vips_executor_set_program( &executor[j],