diff --git a/ChangeLog b/ChangeLog index 97530390..6b044594 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,7 @@ - revised version numbers - updated vipsmanual - revised manpages +- removed name and "changed" from vipsobject since we don't use them yet 6/3/09 started 7.17.3 - revised nohalo diff --git a/TODO b/TODO index 12477fec..770de6bb 100644 --- a/TODO +++ b/TODO @@ -1,10 +1,9 @@ +- writing man page for VipsInterpolate - wrap im_gauss_mask_line or whatever it's called in C++/Python? - need man pages for im_affinei, im_affinei_all - page for VipsInterpolate.3? along the lines of VipsFormat - - Mention vips --list-classes or whatever in VipsFormat man page also in VipsInterpolate diff --git a/include/vips/object.h b/include/vips/object.h index b20f1a3d..60229209 100644 --- a/include/vips/object.h +++ b/include/vips/object.h @@ -173,7 +173,6 @@ void *vips_argument_map( VipsObject *object, struct _VipsObject { GObject parent_object; - char *name; /* Optional instance name */ gboolean constructed; /* Construct done and checked */ /* Table of argument instances for this class and any derived classes. @@ -195,11 +194,6 @@ struct _VipsObjectClass { */ int (*build)( VipsObject *object ); - /* Something about the object has changed. Should use glib's properties - * but fix this later. - */ - void (*changed)( VipsObject * ); - /* Try to print something about the class, handy for help displays. */ void (*print_class)( struct _VipsObjectClass *, VipsBuf * ); @@ -232,7 +226,6 @@ void vips_object_get_property( GObject *gobject, guint property_id, GValue *value, GParamSpec *pspec ); int vips_object_build( VipsObject *object ); -void *vips_object_changed( VipsObject *object ); void vips_object_print_class( VipsObjectClass *klass ); void vips_object_print( VipsObject *object ); diff --git a/libsrc/iofuncs/object.c b/libsrc/iofuncs/object.c index a68d7442..a8a22863 100644 --- a/libsrc/iofuncs/object.c +++ b/libsrc/iofuncs/object.c @@ -48,13 +48,6 @@ #include #endif /*WITH_DMALLOC*/ -/* Our signals. - */ -enum { - SIG_CHANGED, /* VipsObject has changed somehow */ - SIG_LAST -}; - /* Properties. */ enum { @@ -63,27 +56,8 @@ enum { PROP_LAST }; -static guint vips_object_signals[SIG_LAST] = { 0 }; - G_DEFINE_ABSTRACT_TYPE( VipsObject, vips_object, G_TYPE_OBJECT ); -void * -vips_object_changed( VipsObject *object ) -{ - g_return_val_if_fail( object != NULL, NULL ); - g_return_val_if_fail( VIPS_IS_OBJECT( object ), NULL ); - -#ifdef DEBUG - printf( "vips_object_changed: " ); - vips_object_print( object ); -#endif /*DEBUG*/ - - g_signal_emit( G_OBJECT( object ), - vips_object_signals[SIG_CHANGED], 0 ); - - return( NULL ); -} - int vips_object_build( VipsObject *object ) { @@ -317,8 +291,9 @@ vips_object_dispose_argument( VipsObject *object, GParamSpec *pspec, void *a, void *b ) { #ifdef DEBUG - printf( "vips_object_dispose_argument: %s.%s\n", - object->name, pspec->name ); + printf( "vips_object_dispose_argument: " ); + vips_object_print( object ); + printf( ".%s\n", pspec->name ); #endif /*DEBUG*/ g_assert( ((VipsArgument *) argument_class)->pspec == pspec ); @@ -374,7 +349,6 @@ vips_object_finalize( GObject *gobject ) #endif /*DEBUG*/ IM_FREEF( vips_argument_table_destroy, object->argument_table ); - IM_FREE( object->name ); G_OBJECT_CLASS( vips_object_parent_class )->finalize( gobject ); } @@ -467,8 +441,9 @@ vips_object_set_property( GObject *gobject, char *str_value; str_value = g_strdup_value_contents( value ); - printf( "vips_object_set_property: %s.%s = %s\n", - object->name, g_param_spec_get_name( pspec ), str_value ); + printf( "vips_object_set_property: " ); + vips_object_print( object ); + printf( ".%s = %s\n", g_param_spec_get_name( pspec ), str_value ); g_free( str_value ); } #endif /*DEBUG*/ @@ -662,10 +637,9 @@ vips_object_check_required( VipsObject *object, GParamSpec *pspec, (argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) && !argument_instance->assigned ) { im_error( "check_required", - _( "required construct param %s to %s %s not set" ), + _( "required construct param %s to %s not set" ), g_param_spec_get_name( pspec ), - G_OBJECT_TYPE_NAME( object ), - object->name ); + G_OBJECT_TYPE_NAME( object ) ); *result = -1; } @@ -700,22 +674,9 @@ vips_object_real_build( VipsObject *object ) "nickname", object_class->nickname, "description", object_class->description, NULL ); - /* Signal changed, since all properties should now be set. - */ - vips_object_changed( object ); - return( result ); } -static void -vips_object_real_changed( VipsObject *object ) -{ -#ifdef DEBUG - printf( "vips_object_real_changed: " ); - vips_object_print( object ); -#endif /*DEBUG*/ -} - static void vips_object_real_print_class( VipsObjectClass *class, VipsBuf *buf ) { @@ -729,8 +690,7 @@ vips_object_real_print_class( VipsObjectClass *class, VipsBuf *buf ) static void vips_object_real_print( VipsObject *object, VipsBuf *buf ) { - if( object->name ) - vips_buf_appendf( buf, "\"%s\"", object->name ); + vips_buf_appendf( buf, " (%p)", object ); } static void @@ -753,7 +713,6 @@ vips_object_class_init( VipsObjectClass *object_class ) gobject_class->get_property = vips_object_get_property; object_class->build = vips_object_real_build; - object_class->changed = vips_object_real_changed; object_class->print_class = vips_object_real_print_class; object_class->print = vips_object_real_print; object_class->nickname = "object"; @@ -765,14 +724,6 @@ vips_object_class_init( VipsObjectClass *object_class ) g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) g_free ); object_class->argument_table_traverse = NULL; - vips_object_signals[SIG_CHANGED] = g_signal_new( "changed", - G_OBJECT_CLASS_TYPE( gobject_class ), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET( VipsObjectClass, changed ), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0 ); - /* For setting double arguments from the command-line. */ g_value_register_transform_func( G_TYPE_STRING, G_TYPE_DOUBLE, @@ -813,13 +764,6 @@ vips_object_init( VipsObject *object ) #endif /*DEBUG*/ } -void -vips_object_set_name( VipsObject *object, const char *name ) -{ - IM_SETSTR( object->name, name ); - vips_object_changed( object ); -} - /* Add a vipsargument ... automate some stuff with this. */ void diff --git a/man/Makefile.am b/man/Makefile.am index 5f3ceed4..e043413c 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -183,7 +183,9 @@ man_MANS = \ im_flood_blob.3 \ im_floor.3 \ im_flt_imag_freq.3 \ + VipsObject.3 \ VipsFormat.3 \ + VipsInterpolate.3 \ vips_format_for_file.3 \ vips_format_for_name.3 \ vips_format_map.3 \ diff --git a/man/VipsInterpolate.3 b/man/VipsInterpolate.3 new file mode 100644 index 00000000..7b52d60f --- /dev/null +++ b/man/VipsInterpolate.3 @@ -0,0 +1,56 @@ +.TH VIPS_INTERPOLATE 3 "28 March 2009" +.SH NAME +VipsInterpolate, +vips_interpolate, +vips_interpolate_get_method, +vips_interpolate_get_window_size +\- +base class for VIPS interpolators +.SH SYNOPSIS +#include + +typedef void (*VipsInterpolateMethod)( VipsInterpolate *, +.br + PEL *out, REGION *in, double x, double y ); + +typedef struct _VipsInterpolateClass { +.br + VipsObjectClass parent_class; + + VipsInterpolateMethod interpolate; +.br + int (*get_window_size)( VipsInterpolate * ); +.br + int window_size; +.br +} VipsInterpolateClass; + +void vips_interpolate( VipsInterpolate *interpolate, +.br + PEL *out, REGION *in, double x, double y ); +.br +VipsInterpolateMethod vips_interpolate_get_method( VipsInterpolate * ); +.br +int vips_interpolate_get_window_size( VipsInterpolate *interpolate ); + +.SH DESCRIPTION +.B VipsInterpolate +is the base class for VIPS interpolators. It provides a simple framework that +subclasses use to implement the various interpolators that VIPS ships with. +You can add new interpolators by subclassing +.B VipsInterpolate. +You can use any interpolator in your code via the methods of +.B VipsInterpolate. + +.B vips_interpolate(3) + + +.SH SUPPORTED INTERPOLATORS + +.SH RETURN VALUE +Unless otherwise noted, functions return 0 success and -1 on error. +.SH SEE ALSO +VipsFormat(3), VipsInterpolate(3), +vips_type_find(3). +.SH AUTHOR +John Cupitt diff --git a/man/VipsObject.3 b/man/VipsObject.3 new file mode 100644 index 00000000..5524fb7c --- /dev/null +++ b/man/VipsObject.3 @@ -0,0 +1,317 @@ +.TH VIPS_OBJECT 3 "28 March 2009" +.SH NAME +VipsObject, +vips_object_build, vips_object_print_class, +vips_object_print, +vips_object_class_install_argument, +vips_argument_map, +vips_object_set_property, +vips_object_get_property, +vips_object_new, +vips_object_new_from_string, +vips_object_to_string +\- +VIPS base class +.SH SYNOPSIS +#include + +/* Flags we associate with each argument. +.br + */ +.br +typedef enum _VipsArgumentFlags { +.br + VIPS_ARGUMENT_NONE = 0, + + /* Must be set in the constructor. +.br + */ +.br + VIPS_ARGUMENT_REQUIRED = 1, + + /* Can only be set in the constructor. +.br + */ +.br + VIPS_ARGUMENT_CONSTRUCT = 2, + + /* Can only be set once. +.br + */ +.br + VIPS_ARGUMENT_SET_ONCE = 4, + + /* Have input & output flags. Both set is an error; neither set +.br + * is OK. +.br + */ + + /* Is an input argument (one we depend on) ... if it's a gobject, we +.br + * should ref it. In our _dispose(), we should unref it. +.br + */ +.br + VIPS_ARGUMENT_INPUT = 8, + + /* Is an output argument (one that depends on us) ... if it's a +.br + * gobject, we should ref ourselves. We watch "destroy" on the +.br + * argument: if it goes, we unref ourselves. If we dispose, we +.br + * disconnect the signal. +.br + */ +.br + VIPS_ARGUMENT_OUTPUT = 16 +.br +} VipsArgumentFlags; + +/* Useful flag combinations. User-visible ones are: + +VIPS_ARGUMENT_REQURED_INPUT Eg. the "left" argument for add + +VIPS_ARGUMENT_OPTIONAL_INPUT Eg. the "caption" for an object + +VIPS_ARGUMENT_REQURED_OUTPUT Eg. the "result" of an add operation + +VIPS_ARGUMENT_OPTIONAL_OUTPUT Eg. the "width" of an image + + Other combinations are used internally, eg. supplying the cast-table +.br + for an arithmetic operation + + */ + +#define VIPS_ARGUMENT_REQUIRED_INPUT \ +.br + (VIPS_ARGUMENT_INPUT | VIPS_ARGUMENT_REQUIRED | \ +.br + VIPS_ARGUMENT_CONSTRUCT | VIPS_ARGUMENT_SET_ONCE) + +#define VIPS_ARGUMENT_OPTIONAL_INPUT \ +.br + (VIPS_ARGUMENT_INPUT | \ +.br + VIPS_ARGUMENT_CONSTRUCT | VIPS_ARGUMENT_SET_ONCE) + +#define VIPS_ARGUMENT_REQUIRED_OUTPUT \ +.br + (VIPS_ARGUMENT_OUTPUT | VIPS_ARGUMENT_REQUIRED | \ +.br + VIPS_ARGUMENT_SET_ONCE) + +#define VIPS_ARGUMENT_OPTIONAL_OUTPUT \ +.br + (VIPS_ARGUMENT_OUTPUT | \ +.br + VIPS_ARGUMENT_SET_ONCE) + +/* Keep one of these for every argument. +.br + */ +.br +typedef struct _VipsArgument { +.br + GParamSpec *pspec; /* pspec for this argument */ + + /* More stuff, see below */ +.br +} VipsArgument; + +typedef void *(*VipsArgumentMapFn)( VipsObject *, GParamSpec *, +.br + VipsArgumentClass *, VipsArgumentInstance *, void *a, void *b ); +.br +void *vips_argument_map( VipsObject *object, +.br + VipsArgumentMapFn fn, void *a, void *b ); + +struct _VipsObject { +.br + GObject parent_object; + +}; + +struct _VipsObjectClass { +.br + GObjectClass parent_class; + + /* Build the object ... all argument properties have been set, +.br + * now build the thing. +.br + */ +.br + int (*build)( VipsObject *object ); + + /* Try to print something about the class, handy for help displays. +.br + */ +.br + void (*print_class)( struct _VipsObjectClass *, VipsBuf * ); + + /* Try to print something about the object, handy for debugging. +.br + */ +.br + void (*print)( VipsObject *, VipsBuf * ); + + /* Class nickname, eg. "VipsInterpolateBicubic" has "bicubic" as a +.br + * nickname. Not internationalised. +.br + */ +.br + const char *nickname; + + /* Class description. Used for help messages, so internationalised. +.br + */ +.br + const char *description; + +}; + +void vips_object_set_property( GObject *gobject, +.br + guint property_id, const GValue *value, GParamSpec *pspec ); +.br +void vips_object_get_property( GObject *gobject, +.br + guint property_id, GValue *value, GParamSpec *pspec ); + +int vips_object_build( VipsObject *object ); +.br +void vips_object_print_class( VipsObjectClass *klass ); +.br +void vips_object_print( VipsObject *object ); + +void vips_object_class_install_argument( VipsObjectClass *, +.br + GParamSpec *pspec, VipsArgumentFlags flags, guint offset ); + +typedef void *(*VipsObjectSetArguments)( VipsObject *, +.br + void *, void * ); +.br +VipsObject *vips_object_new( GType type, +.br + VipsObjectSetArguments set, void *a, void *b ); + +VipsObject *vips_object_new_from_string( const char *base, +.br + const char *str ); +.br +void vips_object_to_string( VipsObject *object, VipsBuf *buf ); + +.SH DESCRIPTION +.B VipsObject +is the base class for VIPS. It provides some common features, like class +nicknames, and implements an extension to +.B GObject +for properties to let them be used more like function arguments. + +.B VipsObject +is still being developed, so this documentation only covers enough of the +interface to let you use the classes that have been built on top of +.B VipsObject: +.B VipsInterpolate +and +.B VipsFormat. +Hopefully the next version will be more fleshed out. + +.B VipsObject +adds two properties: +.B nickname +and +.B description. +They are actually class properties, but are available as instance properties +too for convenience. + +.B nickname +is the non-internationalised nickname of the class and is used to simplify +lookup. For example, the +.B VipsInterpolateBicubic +class has the nickname "bicubic". + +.B description +is the internationalised short description of the class. +For example, the +.B VipsInterpolateBicubic +class might have the description "bicubic interpolation (Catmull-Rom)". + +Like the rest of VIPS, +.B VipsObject +is a functional type. You can set +properties during object construction, but not after that point. You may read +properties at any time after construction, but not before. + +To enforce these rules, VIPS extends the standard +.B GObject +property +system and adds a new phase to object creation. + +In class_init, after creating a property, you make it into an argument by +adding a call to +.B vips_object_class_install_argument(3). +This takes a set of flags, used to tell VIPS what sort of argument this is, +and an offset for the data value in the class instance. For example: + + pspec = g_param_spec_string( "description", + _( "Description" ), + _( "Class description" ), + "", + (GParamFlags) G_PARAM_READWRITE ); + g_object_class_install_property( gobject_class, + PROP_DESCRIPTION, pspec ); + vips_object_class_install_argument( object_class, pspec, + VIPS_ARGUMENT_SET_ONCE, + G_STRUCT_OFFSET( VipsObject, description ) ); + +After +.B g_object_new(3) +you can continue to set arguments. After you have set all the ones you want to +set, call +.B vips_object_build(3) +to check that required arguments have been set, no arguments have been set +many times, and so on. + +Once a +.B VipsObject +has been built, you can no longer set arguments, but you can read them. + +Use +.B vips_argument_map(3) +to iterate over the arguments for an object in the correct order. You can use +this to discover the arguments any class takes at runtime. + +.B vips_object_set_property(3) +and +.B vips_object_get_property(3) +are used in subclasses of +.B VipsObject +to get and set object arguments. You don't need to implement your own get/set +methods. + +.B vips_object_new(3) +is a convenience function which encapsulates the new/set/build sequence +outlined above. + +.B vips_object_new_from_string(3) +is a convenience function which builds an object from a set of arguments +encoded as a string. It used used by the VIPS command-line program to generate +operation arguments. + +.B vips_object_to_string(3) +is the exact inverse: it prints the string that would construct an object. + +.SH RETURN VALUE +Unless otherwise noted, functions return 0 success and -1 on error. +.SH SEE ALSO +VipsFormat(3), VipsInterpolate(3), +vips_type_find(3). +.SH AUTHOR +John Cupitt