much better handling of arrayimage cli args

we were not setting the access hint on arrayimage args, so

arrayjoin "$(echo *.jpg)" x.tif[bigtiff] --across 10

would open all the jpg images to memory, usually, in random mode

now arrayimage args see the operation's access hint (seq in this case),
for much better behaviour

also, we allow any whitespace as an arg separator in arrayimage from
string
This commit is contained in:
John Cupitt 2016-02-27 20:37:20 +00:00
parent 35650c2244
commit ee1874c5ca
5 changed files with 124 additions and 42 deletions

View File

@ -10,6 +10,7 @@
- sharpen has a new @sigma param, @radius is deprecated
- sharpen allows a much greater range of parameters
- better handling of deprecated args in python
- much better handling of arrayimage command-line args
27/1/16 started 8.2.3
- fix a crash with SPARC byte-order labq vips images

View File

@ -134,6 +134,10 @@ vips_arrayjoin_build( VipsObject *object )
return( -1 );
in = vips_array_image_get( join->in, &n );
/* Array length zero means error.
*/
if( n == 0 )
return( -1 );
/* Move all input images to a common format and number of bands.
*/
@ -291,6 +295,7 @@ vips_arrayjoin_class_init( VipsArrayjoinClass *class )
{
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class );
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
VIPS_DEBUG_MSG( "vips_arrayjoin_class_init\n" );
@ -301,6 +306,8 @@ vips_arrayjoin_class_init( VipsArrayjoinClass *class )
vobject_class->description = _( "join an array of images" );
vobject_class->build = vips_arrayjoin_build;
operation_class->flags = VIPS_OPERATION_SEQUENTIAL_UNBUFFERED;
VIPS_ARG_BOXED( class, "in", -1,
_( "Input" ),
_( "Array of input images" ),

View File

@ -493,6 +493,8 @@ int vips_system( const char *cmd_format, ... )
*/
VipsArrayImage *vips_array_image_new( VipsImage **array, int n );
VipsArrayImage *vips_array_image_newv( int n, ... );
VipsArrayImage *vips_array_image_new_from_string( const char *string,
VipsAccess flags );
VipsArrayImage *vips_array_image_empty( void );
VipsArrayImage *vips_array_image_append( VipsArrayImage *array,
VipsImage *image );

View File

@ -1818,16 +1818,16 @@ vips_object_set_argument_from_string( VipsObject *object,
VipsOperationFlags flags;
VipsAccess access;
flags = 0;
if( VIPS_IS_OPERATION( object ) )
flags = vips_operation_get_flags(
VIPS_OPERATION( object ) );
if( !value ) {
vips_object_no_value( object, name );
return( -1 );
}
flags = 0;
if( VIPS_IS_OPERATION( object ) )
flags = vips_operation_get_flags(
VIPS_OPERATION( object ) );
/* Read the filename.
*/
if( flags & VIPS_OPERATION_SEQUENTIAL_UNBUFFERED )
@ -1850,6 +1850,44 @@ vips_object_set_argument_from_string( VipsObject *object,
*/
g_object_unref( out );
}
else if( g_type_is_a( otype, VIPS_TYPE_ARRAY_IMAGE ) ) {
/* We have to have a special case for this, we can't just rely
* on transform_g_string_array_image(), since we need to be
* able to set the access hint on the image.
*/
VipsArrayImage *array_image;
VipsOperationFlags flags;
VipsAccess access;
if( !value ) {
vips_object_no_value( object, name );
return( -1 );
}
flags = 0;
if( VIPS_IS_OPERATION( object ) )
flags = vips_operation_get_flags(
VIPS_OPERATION( object ) );
if( flags & VIPS_OPERATION_SEQUENTIAL_UNBUFFERED )
access = VIPS_ACCESS_SEQUENTIAL_UNBUFFERED;
else if( flags & VIPS_OPERATION_SEQUENTIAL )
access = VIPS_ACCESS_SEQUENTIAL;
else
access = VIPS_ACCESS_RANDOM;
if( !(array_image =
vips_array_image_new_from_string( value, access )) )
return( -1 );
g_value_init( &gvalue, VIPS_TYPE_ARRAY_IMAGE );
g_value_set_boxed( &gvalue, array_image );
/* Setting gvalue will have upped @array_image's count again,
* go back to 1 so that gvalue has the only ref.
*/
vips_area_unref( (VipsArea *) array_image );
}
else if( g_type_is_a( otype, VIPS_TYPE_OBJECT ) &&
(oclass = g_type_class_ref( otype )) ) {
VipsObject *new_object;

View File

@ -1089,43 +1089,6 @@ vips_array_double_get_type( void )
return( type );
}
static void
transform_g_string_array_image( const GValue *src_value, GValue *dest_value )
{
char *str;
int n;
char *p, *q;
int i;
VipsImage **array;
/* We need a copy of the string, since we insert \0 during
* scan.
*/
str = g_value_dup_string( src_value );
n = 0;
for( p = str; (q = vips_break_token( p, " " )); p = q )
n += 1;
g_free( str );
vips_value_set_array_image( dest_value, n );
array = vips_value_get_array_image( dest_value, NULL );
str = g_value_dup_string( src_value );
for( i = 0, p = str; (q = vips_break_token( p, " " )); i++, p = q )
if( !(array[i] = vips_image_new_from_file( p, NULL )) ) {
/* Set the dest to length zero to indicate error.
*/
vips_value_set_array_image( dest_value, 0 );
g_free( str );
return;
}
g_free( str );
}
/**
* vips_array_image_new:
* @array: (array length=n): array of #VipsImage
@ -1205,6 +1168,52 @@ vips_array_image_newv( int n, ... )
return( (VipsArrayImage *) area );
}
VipsArrayImage *
vips_array_image_new_from_string( const char *string, VipsAccess access )
{
char *str;
int n;
VipsArea *area;
VipsImage **array;
char *p, *q;
int i;
/* We need a copy of the string, since we insert \0 during
* scan.
*/
str = g_strdup( string );
n = 0;
for( p = str; (q = vips_break_token( p, " \n\t\r" )); p = q )
n += 1;
g_free( str );
area = vips_area_new_array_object( n );
area->type = VIPS_TYPE_IMAGE;
array = vips_area_get_data( area, NULL, NULL, NULL, NULL );
str = g_strdup( string );
i = 0;
for( p = str; (q = vips_break_token( p, " \n\t\r" )); p = q ) {
if( !(array[i] = vips_image_new_from_file( p,
"access", access,
NULL )) ) {
vips_area_unref( area );
g_free( str );
return( NULL );
}
i += 1;
}
g_free( str );
return( (VipsArrayImage *) area );
}
/**
* vips_array_image_empty:
*
@ -1284,6 +1293,31 @@ vips_array_image_get( VipsArrayImage *array, int *n )
return( (VipsImage **) VIPS_ARRAY_ADDR( array, 0 ) );
}
static void
transform_g_string_array_image( const GValue *src_value, GValue *dest_value )
{
char *str;
VipsArrayImage *array_image;
str = g_value_dup_string( src_value );
/* We can't get access here, just assume nothing. See the special case
* in vips_object_new_from_string() for how we usually get this right.
*/
if( !(array_image = vips_array_image_new_from_string( str, 0 )) ) {
/* Set the dest to length zero to indicate error.
*/
vips_value_set_array_image( dest_value, 0 );
g_free( str );
return;
}
g_free( str );
g_value_set_boxed( dest_value, array_image );
vips_area_unref( (VipsArea *) array_image );
}
GType
vips_array_image_get_type( void )
{