add arg lookup

convenience function to look up vipsargs
This commit is contained in:
John Cupitt 2011-09-29 23:26:10 +01:00
parent db9118369a
commit 45b2a9a525
4 changed files with 177 additions and 15 deletions

10
TODO
View File

@ -1,5 +1,15 @@
- VipsCopy needs optional params for all header fields it can change
need a vips_argument_lookup(), see vips_argument_map(), since we need to
be able to find out if an optional arg has been set
added vips_object_get_argument(), look for use of
g_object_class_find_property() and swap for new thing, then back to copy.c
operation.c could use it too in places
copy.c things to set interpretation etc. could go into image.c
how would we do meta sets?
copy_swap needs doing too, a separate class I guess

View File

@ -89,8 +89,8 @@
/**
* VipsCopy:
* @in: input image
* @out: output image
* @input: input image
* @output: output image
*
* Copy an image, optionally modifying the header. VIPS copies images by
* copying pointers, so this operation is fast, even for very large images.
@ -102,6 +102,18 @@
*/
enum {
PROP_INPUT = 1,
PROP_INTERPRETATION,
PROP_XRES,
PROP_YRES,
PROP_XOFFSET,
PROP_YOFFSET,
PROP_BANDS,
PROP_FORMAT,
PROP_CODING,
PROP_WIDTH,
PROP_HEIGHT,
PROP_LAST
};
@ -111,6 +123,20 @@ typedef struct _VipsCopy {
/* The input image.
*/
VipsImage *input;
/* Fields we can optionally set on the way through.
*/
VipsInterpretation interpretation;
double xres;
double yres;
int xoffset;
int yoffset;
int bands;
VipsBandFormat format;
VipsCoding coding;
int width;
int height;
} VipsCopy;
typedef VipsConversionClass VipsCopyClass;
@ -180,8 +206,6 @@ vips_copy_class_init( VipsCopyClass *class )
vobject_class->description = _( "copy an image" );
vobject_class->build = vips_copy_build;
/* Create properties.
*/
pspec = g_param_spec_object( "input",
"Input", "Input image argument",
VIPS_TYPE_IMAGE,
@ -192,6 +216,97 @@ vips_copy_class_init( VipsCopyClass *class )
VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsCopy, input ) );
pspec = g_param_spec_enum( "interpretation", "Interpretation",
_( "Pixel interpretation" ),
VIPS_TYPE_INTERPRETATION, VIPS_INTERPRETATION_MULTIBAND,
G_PARAM_READWRITE );
g_object_class_install_property( gobject_class,
PROP_INTERPRETATION, pspec );
vips_object_class_install_argument( vobject_class, pspec,
VIPS_ARGUMENT_SET_ONCE,
G_STRUCT_OFFSET( VipsCopy, interpretation ) );
pspec = g_param_spec_double( "xres", "XRes",
_( "Horizontal resolution in pixels/mm" ),
0, 1000000, 0,
G_PARAM_READWRITE );
g_object_class_install_property( gobject_class, PROP_XRES, pspec );
vips_object_class_install_argument( vobject_class, pspec,
VIPS_ARGUMENT_SET_ONCE,
G_STRUCT_OFFSET( VipsCopy, xres ) );
pspec = g_param_spec_double( "yres", "YRes",
_( "Vertical resolution in pixels/mm" ),
0, 1000000, 0,
G_PARAM_READWRITE );
g_object_class_install_property( gobject_class, PROP_YRES, pspec );
vips_object_class_install_argument( vobject_class, pspec,
VIPS_ARGUMENT_SET_ONCE,
G_STRUCT_OFFSET( VipsCopy, yres ) );
pspec = g_param_spec_int( "xoffset", "XOffset",
_( "Horizontal offset of origin" ),
-10000000, 1000000, 0,
G_PARAM_READWRITE );
g_object_class_install_property( gobject_class, PROP_XOFFSET, pspec );
vips_object_class_install_argument( vobject_class, pspec,
VIPS_ARGUMENT_SET_ONCE,
G_STRUCT_OFFSET( VipsCopy, xoffset ) );
pspec = g_param_spec_int( "yoffset", "YOffset",
_( "Vertical offset of origin" ),
-10000000, 1000000, 0,
G_PARAM_READWRITE );
g_object_class_install_property( gobject_class, PROP_YOFFSET, pspec );
vips_object_class_install_argument( vobject_class, pspec,
VIPS_ARGUMENT_SET_ONCE,
G_STRUCT_OFFSET( VipsCopy, yoffset ) );
pspec = g_param_spec_int( "bands", "Bands",
_( "Number of bands in image" ),
0, 1000000, 0,
G_PARAM_READWRITE );
g_object_class_install_property( gobject_class, PROP_BANDS, pspec );
vips_object_class_install_argument( vobject_class, pspec,
VIPS_ARGUMENT_SET_ONCE,
G_STRUCT_OFFSET( VipsCopy, bands ) );
pspec = g_param_spec_enum( "format", "Format",
_( "Pixel format in image" ),
VIPS_TYPE_BAND_FORMAT, VIPS_FORMAT_UCHAR,
G_PARAM_READWRITE );
g_object_class_install_property( gobject_class, PROP_FORMAT, pspec );
vips_object_class_install_argument( vobject_class, pspec,
VIPS_ARGUMENT_SET_ONCE,
G_STRUCT_OFFSET( VipsCopy, format ) );
pspec = g_param_spec_enum( "coding", "Coding",
_( "Pixel coding" ),
VIPS_TYPE_CODING, VIPS_CODING_NONE,
G_PARAM_READWRITE );
g_object_class_install_property( gobject_class, PROP_FORMAT, pspec );
vips_object_class_install_argument( vobject_class, pspec,
VIPS_ARGUMENT_SET_ONCE,
G_STRUCT_OFFSET( VipsCopy, coding ) );
pspec = g_param_spec_int( "width", "Width",
_( "Image width in pixels" ),
0, 1000000, 0,
G_PARAM_READWRITE );
g_object_class_install_property( gobject_class, PROP_WIDTH, pspec );
vips_object_class_install_argument( vobject_class, pspec,
VIPS_ARGUMENT_SET_ONCE,
G_STRUCT_OFFSET( VipsCopy, width ) );
pspec = g_param_spec_int( "height", "Height",
_( "Image height in pixels" ),
0, 1000000, 0,
G_PARAM_READWRITE );
g_object_class_install_property( gobject_class, PROP_HEIGHT, pspec );
vips_object_class_install_argument( vobject_class, pspec,
VIPS_ARGUMENT_SET_ONCE,
G_STRUCT_OFFSET( VipsCopy, height ) );
}
static void

View File

@ -168,6 +168,10 @@ typedef void *(*VipsArgumentMapFn)( VipsObject *, GParamSpec *,
void *vips_argument_map( VipsObject *object,
VipsArgumentMapFn fn, void *a, void *b );
void vips_argument_dispose_all( VipsObject *object );
int vips_object_get_argument( VipsObject *object, const char *name,
GParamSpec **pspec,
VipsArgumentClass **argument_class,
VipsArgumentInstance **argument_instance );
/* We have to loop over an objects args in several places, and we can't always
* use vips_argument_map(), the preferred looper. Have the loop code as a

View File

@ -388,6 +388,44 @@ vips__argument_get_instance( VipsArgumentClass *argument_class,
((VipsArgument *) argument_class)->pspec ) );
}
/* Look up the three things you need to work with a vips argument.
*/
int
vips_object_get_argument( VipsObject *object, const char *name,
GParamSpec **pspec,
VipsArgumentClass **argument_class,
VipsArgumentInstance **argument_instance )
{
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
if( !(*pspec = g_object_class_find_property(
G_OBJECT_CLASS( class ), name )) ) {
vips_error( VIPS_OBJECT_CLASS( class )->description,
_( "class `%s' has no property named `%s'" ),
G_OBJECT_TYPE_NAME( object ), name );
return( -1 );
}
if( !(*argument_class = (VipsArgumentClass *)
vips__argument_table_lookup( class->argument_table,
*pspec )) ) {
vips_error( VIPS_OBJECT_CLASS( class )->description,
_( "class `%s' has no vips argument named `%s'" ),
G_OBJECT_TYPE_NAME( object ), name );
return( -1 );
}
if( argument_class &&
!(*argument_instance = vips__argument_get_instance(
*argument_class, object )) ) {
vips_error( VIPS_OBJECT_CLASS( class )->description,
_( "vips argument `%s' has no instance" ),
G_OBJECT_TYPE_NAME( object ), name );
return( -1 );
}
return( 0 );
}
static void
vips_object_clear_member( VipsObject *object, GParamSpec *pspec,
GObject **member )
@ -1158,12 +1196,12 @@ int
vips_object_set_argument_from_string( VipsObject *object,
const char *name, const char *value )
{
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
GParamSpec *pspec;
GType otype;
VipsArgumentClass *argument_class;
VipsArgumentInstance *argument_instance;
GType otype;
VipsObjectClass *oclass;
GValue gvalue = { 0 };
#ifdef DEBUG
@ -1171,16 +1209,11 @@ vips_object_set_argument_from_string( VipsObject *object,
name, value );
#endif /*DEBUG*/
pspec = g_object_class_find_property( G_OBJECT_CLASS( class ), name );
if( !pspec ) {
vips_error( "VipsObject", _( "%s.%s does not exist" ),
G_OBJECT_TYPE_NAME( object ), name );
if( vips_object_get_argument( object, name,
&pspec, &argument_class, &argument_instance ) )
return( -1 );
}
otype = G_PARAM_SPEC_VALUE_TYPE( pspec );
argument_class = (VipsArgumentClass *)
vips__argument_table_lookup( class->argument_table, pspec );
otype = G_PARAM_SPEC_VALUE_TYPE( pspec );
g_assert( argument_class->flags & VIPS_ARGUMENT_INPUT );