/* Looking for construct-time optional output args. Append them to out. */ static void * vo_get_optional_arg( const char *name, PElement *value, Vo *vo, PElement *out ) { GParamSpec *pspec; VipsArgumentClass *argument_class; VipsArgumentInstance *argument_instance; if( vips_object_get_argument( vo->object, name, &pspec, &argument_class, &argument_instance ) ) return( NULL ); if( !(argument_class->flags & VIPS_ARGUMENT_REQUIRED) && (argument_class->flags & VIPS_ARGUMENT_OUTPUT) && argument_instance->assigned ) { GType type = G_PARAM_SPEC_VALUE_TYPE( pspec ); GValue gvalue = { 0 }; PElement lhs; if( !heap_list_add( vo->rc->heap, out, &lhs ) ) return( value ); g_value_init( &gvalue, type ); g_object_get_property( G_OBJECT( vo->object ), name, &gvalue ); if( !heap_gvalue_to_ip( &gvalue, &lhs ) ) { g_value_unset( &gvalue ); return( value ); } g_value_unset( &gvalue ); (void) heap_list_next( out ); } return( NULL ); }
// just g_object_set_property(), except we allow set enum from string static void set_property( VipsObject *object, const char *name, const GValue *value ) { VipsObjectClass *object_class = VIPS_OBJECT_GET_CLASS( object ); GType type = G_VALUE_TYPE( value ); GParamSpec *pspec; VipsArgumentClass *argument_class; VipsArgumentInstance *argument_instance; if( vips_object_get_argument( object, name, &pspec, &argument_class, &argument_instance ) ) { g_warning( "%s", vips_error_buffer() ); vips_error_clear(); return; } if( G_IS_PARAM_SPEC_ENUM( pspec ) && type == G_TYPE_STRING ) { GType pspec_type = G_PARAM_SPEC_VALUE_TYPE( pspec ); int enum_value; GValue value2 = { 0 }; if( (enum_value = vips_enum_from_nick( object_class->nickname, pspec_type, g_value_get_string( value ) )) < 0 ) { g_warning( "%s", vips_error_buffer() ); vips_error_clear(); return; } g_value_init( &value2, pspec_type ); g_value_set_enum( &value2, enum_value ); g_object_set_property( G_OBJECT( object ), name, &value2 ); g_value_unset( &value2 ); } else g_object_set_property( G_OBJECT( object ), name, value ); }
static void * vo_set_optional_arg( const char *name, PElement *value, Vo *vo ) { GParamSpec *pspec; VipsArgumentClass *argument_class; VipsArgumentInstance *argument_instance; /* Looking for construct-time optional input args. */ /* For optional args, we should ignore properties that don't exist. For * example, we might supply ($sharpening => 12) to all interpolators, * though only one interpolator uses this property. */ if( vips_object_get_argument( vo->object, name, &pspec, &argument_class, &argument_instance ) ) return( NULL ); if( !(argument_class->flags & VIPS_ARGUMENT_REQUIRED) && (argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) && (argument_class->flags & VIPS_ARGUMENT_INPUT) && !argument_instance->assigned ) { GValue gvalue = { 0 }; if( !heap_ip_to_gvalue( value, &gvalue ) ) { g_value_unset( &gvalue ); return( value ); } if( vo_set_property( vo, name, pspec, &gvalue ) ) { g_value_unset( &gvalue ); return( value ); } g_value_unset( &gvalue ); } return( NULL ); }
static int vips_copy_build( VipsObject *object ) { VipsConversion *conversion = VIPS_CONVERSION( object ); VipsCopy *copy = (VipsCopy *) object; int i; if( VIPS_OBJECT_CLASS( vips_copy_parent_class )->build( object ) ) return( -1 ); if( vips_image_pio_input( copy->in ) ) return( -1 ); if( vips_image_pipelinev( conversion->out, VIPS_DEMAND_STYLE_THINSTRIP, copy->in, NULL ) ) return( -1 ); /* Use props to adjust header fields. */ for( i = 0; i < VIPS_NUMBER( vips_copy_names ); i++ ) { const char *name = vips_copy_names[i]; GParamSpec *pspec; VipsArgumentClass *argument_class; VipsArgumentInstance *argument_instance; if( vips_object_get_argument( object, name, &pspec, &argument_class, &argument_instance ) ) return( -1 ); if( argument_instance->assigned ) { GType type = G_PARAM_SPEC_VALUE_TYPE( pspec ); GValue value = { 0, }; g_value_init( &value, type ); g_object_get_property( G_OBJECT( object ), name, &value ); #ifdef VIPS_DEBUG { char *str; str = g_strdup_value_contents( &value ); printf( "vips_copy_build: %s = %s\n", name, str ); g_free( str ); } #endif /* VIPS_DEBUG */ g_object_set_property( G_OBJECT( conversion->out ), name, &value ); g_value_unset( &value ); } } if( vips_image_generate( conversion->out, vips_start_one, vips_copy_gen, vips_stop_one, copy->in, copy ) ) return( -1 ); return( 0 ); }