fix trunk, move class params to branch

This commit is contained in:
John Cupitt 2008-12-08 14:25:17 +00:00
parent 3c28a75ede
commit af7c8651db
6 changed files with 8 additions and 745 deletions

View File

@ -19,7 +19,6 @@
- updated docs
- interpolators use type introspection
- added vips --list classes, does formats too
- copy/pasted some vips8 arg stuff, needs much hacking
11/9/08 started 7.16.3
- oop typo in manpage for im_project()

6
TODO
View File

@ -6,12 +6,8 @@
nickname, description etc need to be properties so nip2 can read them
add a g_get_children( "classname" ) -> ["child1-name", ..] to nip2, see old
vips8.c code?
vips8.c cooe?

View File

@ -34,130 +34,6 @@
extern "C" {
#endif /*__cplusplus*/
typedef struct _VipsObject VipsObject;
typedef struct _VipsObjectClass VipsObjectClass;
/* Track extra stuff for arguments to objects
*/
/* Flags we associate with each argument.
*/
typedef enum _VipsArgumentFlags {
VIPS_ARGUMENT_NONE = 0,
/* Must be set before _build().
*/
VIPS_ARGUMENT_REQUIRED = 1,
/* Can only be set before _build().
*/
VIPS_ARGUMENT_CONSTRUCT = 2,
/* Can only be set once.
*/
VIPS_ARGUMENT_SET_ONCE = 4,
/* Have input & output flags. Both set is an error; neither set is OK.
*/
/* Is an input argument (one we depend on) ... if it's a gobject, we
* should ref it. In our _dispose(), we should unref it.
*/
VIPS_ARGUMENT_INPUT = 8,
/* Is an output argument (one that depends on us) ... if it's a
* gobject, we should ref ourselves. We watch "destroy" on the
* argument: if it goes, we unref ourselves. If we dispose, we
* disconnect the signal.
*/
VIPS_ARGUMENT_OUTPUT = 16
} VipsArgumentFlags;
/* Useful flag combinations. User-visible ones are:
VIPS_ARGUMENT_REQURED_INPUT Eg. the "left" argument for an add operation
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 for an
arithmetic operation
*/
#define VIPS_ARGUMENT_REQUIRED_INPUT \
(VIPS_ARGUMENT_INPUT | VIPS_ARGUMENT_REQUIRED | \
VIPS_ARGUMENT_CONSTRUCT | VIPS_ARGUMENT_SET_ONCE)
#define VIPS_ARGUMENT_OPTIONAL_INPUT \
(VIPS_ARGUMENT_INPUT | \
VIPS_ARGUMENT_CONSTRUCT | VIPS_ARGUMENT_SET_ONCE)
#define VIPS_ARGUMENT_REQUIRED_OUTPUT \
(VIPS_ARGUMENT_OUTPUT | VIPS_ARGUMENT_REQUIRED | \
VIPS_ARGUMENT_SET_ONCE)
#define VIPS_ARGUMENT_OPTIONAL_OUTPUT \
(VIPS_ARGUMENT_OUTPUT | \
VIPS_ARGUMENT_SET_ONCE)
/* Keep one of these for every argument.
*/
typedef struct _VipsArgument {
GParamSpec *pspec; /* pspec for this argument */
/* More stuff, see below */
} VipsArgument;
/* Keep one of these in the class struct for every argument.
*/
typedef struct _VipsArgumentClass {
VipsArgument parent;
/* The class of the object we are an arg for.
*/
VipsObjectClass *object_class;
VipsArgumentFlags flags;
guint offset; /* G_STRUCT_OFFSET of member in object */
} VipsArgumentClass;
/* Keep one of these in the object struct for every argument instance.
*/
typedef struct _VipsArgumentInstance {
VipsArgument parent;
/* The object we are attached to.
*/
VipsObject *object;
/* Has been set.
*/
gboolean assigned;
/* If this is an output argument, keep the id of our "destroy" handler
* here.
*/
gulong destroy_id;
} VipsArgumentInstance;
/* Need to look up our VipsArgument structs from a pspec. Just hash the
* pointer (ie. we assume pspecs are never shared, is this correct?)
*/
typedef GHashTable VipsArgumentTable;
VipsArgumentInstance *vips__argument_get_instance( VipsArgumentClass *,
VipsObject *);
VipsArgument *vips__argument_table_lookup( VipsArgumentTable *,
GParamSpec *);
typedef void *(*VipsArgumentMapFn)( VipsObject *, GParamSpec *,
VipsArgumentClass *, VipsArgumentInstance *, void *a, void *b );
void *vips__argument_map( VipsObject *object,
VipsArgumentMapFn fn, void *a, void *b );
#define VIPS_TYPE_OBJECT (vips_object_get_type())
#define VIPS_OBJECT( obj ) \
(G_TYPE_CHECK_INSTANCE_CAST( (obj), VIPS_TYPE_OBJECT, VipsObject ))
@ -170,17 +46,15 @@ void *vips__argument_map( VipsObject *object,
#define VIPS_OBJECT_GET_CLASS( obj ) \
(G_TYPE_INSTANCE_GET_CLASS( (obj), VIPS_TYPE_OBJECT, VipsObjectClass ))
struct _VipsObject {
typedef struct _VipsObject {
GObject parent_object;
char *name; /* Optional instance name */
/* Table of argument instances for this class and any derived classes.
/* Optional instance name.
*/
VipsArgumentTable *argument_table;
};
char *name;
} VipsObject;
struct _VipsObjectClass {
typedef struct _VipsObjectClass {
GObjectClass parent_class;
/* Something about the object has changed. Should use glib's properties
@ -204,15 +78,7 @@ struct _VipsObjectClass {
/* Class description. Used for help messages, so internationalised.
*/
const char *description;
/* Table of arguments for this class and any derived classes. Order
* is important, so keep a traverse list too. We can't rely on the
* ordering given by g_object_class_list_properties() since it comes
* from a hash :-(
*/
VipsArgumentTable *argument_table;
GSList *argument_table_traverse;
};
} VipsObjectClass;
void *vips_object_changed( VipsObject *object );
void vips_object_print_class( VipsObjectClass *klass );
@ -220,9 +86,6 @@ void vips_object_print( VipsObject *object );
GType vips_object_get_type( void );
void vips_object_class_install_argument( VipsObjectClass *,
GParamSpec *pspec, VipsArgumentFlags flags, guint offset );
#ifdef __cplusplus
}
#endif /*__cplusplus*/

View File

@ -937,4 +937,3 @@ im__meta_init_types( void )
g_value_register_transform_func( IM_TYPE_SAVE_STRING, G_TYPE_DOUBLE,
transform_save_string_double );
}

View File

@ -100,244 +100,16 @@ vips_object_print( VipsObject *object )
printf( "\n%s (%p)\n", im_buf_all( &buf ), object );
}
/* Extra stuff we track for properties to do our argument handling.
*/
/* Free a VipsArgumentInstance ... VipsArgumentClass can just be g_free()d.
*/
static void
vips_argument_instance_free( VipsArgumentInstance *argument_instance )
{
if( argument_instance->destroy_id ) {
g_signal_handler_disconnect( argument_instance->object,
argument_instance->destroy_id );
argument_instance->destroy_id = 0;
}
g_free( argument_instance );
}
VipsArgument *
vips__argument_table_lookup( VipsArgumentTable *table, GParamSpec *pspec )
{
return( g_hash_table_lookup( table, pspec ) );
}
static void
vips_argument_table_replace( VipsArgumentTable *table, VipsArgument *argument )
{
g_hash_table_replace( table, argument->pspec, argument );
}
static void
vips_argument_table_destroy( VipsArgumentTable *table )
{
g_hash_table_destroy( table );
}
static void *
vips_argument_init2( VipsObject *object, GParamSpec *pspec,
VipsArgumentClass *argument_class,
VipsArgumentInstance *argument_instance )
{
VipsArgument *argument;
#ifdef DEBUG
printf ("vips_argument_init_sub: adding instance argument for %s\n",
pspec->name);
#endif /*DEBUG*/
/* argument_instance should be NULL since we've not set it yet.
*/
g_assert( argument_instance == NULL );
argument_instance = g_new( VipsArgumentInstance, 1 );
argument = (VipsArgument *) argument_instance;
argument->pspec = ((VipsArgument *) argument_class)->pspec;
argument_instance->object = object;
argument_instance->assigned = FALSE;
argument_instance->destroy_id = 0;
vips_argument_table_replace( object->argument_table, argument );
return( NULL );
}
/* Create a VipsArgumentInstance for each installed argument property. Ideally
* we'd do this during _init() but g_object_class_find_property() does not seem
* to work then :-( so we have to delay it until first access.
*/
static void
vips_argument_init( VipsObject *object )
{
if( !object->argument_table ) {
object->argument_table = g_hash_table_new_full( g_direct_hash,
g_direct_equal, NULL,
(GDestroyNotify) vips_argument_instance_free );
/* Make a VipsArgumentInstance for each installed argument
* property.
*/
vips__argument_map( object,
(VipsArgumentMapFn) vips_argument_init2, NULL, NULL );
}
}
/* Convenience ... given the VipsArgumentClass, get the VipsArgumentInstance.
*/
VipsArgumentInstance *
vips__argument_get_instance( VipsArgumentClass *argument_class,
VipsObject *object )
{
/* Make sure the instance args are built.
*/
vips_argument_init( object );
return( (VipsArgumentInstance *)
vips__argument_table_lookup( object->argument_table,
((VipsArgument *) argument_class)->pspec ) );
}
/* Loop over the vips_arguments to an object.
*/
void *
vips__argument_map( VipsObject *object, VipsArgumentMapFn fn, void *a, void *b )
{
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
GSList *p;
for( p = class->argument_table_traverse; p; p = p->next ) {
VipsArgumentClass *argument_class =
(VipsArgumentClass *) p->data;
VipsArgument *argument = (VipsArgument *) argument_class;
GParamSpec *pspec = argument->pspec;
VipsArgumentInstance *argument_instance =
vips__argument_get_instance( argument_class, object );
/* We have many props on the arg table ... filter out the ones
* for this class.
*/
if( g_object_class_find_property( G_OBJECT_CLASS( class ),
pspec->name ) == pspec ) {
void *result;
if( (result = fn( object, pspec,
argument_class, argument_instance, a, b )) )
return( result );
}
}
return( NULL );
}
static void
vips_object_clear_object( VipsObject *object, GParamSpec *pspec )
{
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
VipsArgumentClass *argument_class = (VipsArgumentClass *)
vips__argument_table_lookup( class->argument_table, pspec );
VipsArgumentInstance *argument_instance =
vips__argument_get_instance( argument_class, object );
GObject **member = &G_STRUCT_MEMBER( GObject *, object,
argument_class->offset );
if( *member ) {
if( argument_class->flags & VIPS_ARGUMENT_INPUT ) {
#ifdef DEBUG_REF
printf( "vips_object_clear_object: vips object: " );
vips_object_print( object );
printf( " no longer refers to gobject %s (%p)\n",
G_OBJECT_TYPE_NAME( *member ), *member );
printf( " count down to %d\n",
G_OBJECT( *member )->ref_count - 1 );
#endif /*DEBUG_REF*/
/* We reffed the object.
*/
g_object_unref( *member );
}
else if( argument_class->flags & VIPS_ARGUMENT_OUTPUT ) {
#ifdef DEBUG_REF
printf( "vips_object_clear_object: gobject %s (%p)\n",
G_OBJECT_TYPE_NAME( *member ), *member );
printf( " no longer refers to vips object: " );
vips_object_print( object );
printf( " count down to %d\n",
G_OBJECT( object )->ref_count - 1 );
#endif /*DEBUG_REF*/
/* The object reffed us. Stop listening link to the
* object's "destroy" signal. We can come here from
* object being destroyed, in which case the handler
* will already have been disconnected for us.
*/
if( g_signal_handler_is_connected( object,
argument_instance->destroy_id ) )
g_signal_handler_disconnect( object,
argument_instance->destroy_id );
argument_instance->destroy_id = 0;
*member = NULL;
g_object_unref( object );
}
*member = NULL;
}
}
/* Free any args which are holding resources.
*/
static void *
vips_object_dispose_argument( VipsObject *object, GParamSpec *pspec,
VipsArgumentClass *argument_class,
VipsArgumentInstance *argument_instance,
void *a, void *b )
{
#ifdef DEBUG
printf( "vips_object_dispose_argument: %s.%s\n",
object->name, pspec->name );
#endif /*DEBUG*/
g_assert( ((VipsArgument *) argument_class)->pspec == pspec );
g_assert( ((VipsArgument *) argument_instance)->pspec == pspec );
if( G_IS_PARAM_SPEC_STRING( pspec ) ) {
char **member = &G_STRUCT_MEMBER( char *, object,
argument_class->offset );
IM_FREE( *member );
}
else if( G_IS_PARAM_SPEC_OBJECT( pspec ) )
vips_object_clear_object( object, pspec );
else if( G_IS_PARAM_SPEC_BOXED( pspec ) ) {
gpointer *member = &G_STRUCT_MEMBER( gpointer, object,
argument_class->offset );
if( *member ) {
g_boxed_free( G_PARAM_SPEC_VALUE_TYPE( pspec ),
*member );
*member = NULL;
}
}
return( NULL );
}
static void
vips_object_dispose( GObject *gobject )
{
#ifdef DEBUG
VipsObject *object = VIPS_OBJECT( gobject );
#ifdef DEBUG
printf( "vips_object_dispose: " );
vips_object_print( object );
#endif /*DEBUG*/
/* Clear all our arguments: they may be holding refs we should drop.
*/
vips__argument_map( object,
vips_object_dispose_argument, NULL, NULL );
G_OBJECT_CLASS( vips_object_parent_class )->dispose( gobject );
}
@ -351,289 +123,11 @@ vips_object_finalize( GObject *gobject )
vips_object_print( object );
#endif /*DEBUG*/
IM_FREEF( vips_argument_table_destroy, object->argument_table );
IM_FREE( object->name );
G_OBJECT_CLASS( vips_object_parent_class )->finalize( gobject );
}
static void
vips_object_arg_destroy( GObject *argument,
VipsArgumentInstance *argument_instance )
{
VipsObject *object = argument_instance->object;
GParamSpec *pspec = ((VipsArgument *) argument_instance)->pspec;
/* Argument had reffed us ... now it's being destroyed, so we unref.
*/
vips_object_clear_object( object, pspec );
}
static void
vips_object_set_object( VipsObject *object, GParamSpec *pspec,
GObject *argument )
{
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
VipsArgumentClass *argument_class = (VipsArgumentClass *)
vips__argument_table_lookup( class->argument_table, pspec );
VipsArgumentInstance *argument_instance =
vips__argument_get_instance( argument_class, object );
GObject **member = &G_STRUCT_MEMBER( GObject *, object,
argument_class->offset );
g_assert( !*member );
*member = argument;
if( *member ) {
if( argument_class->flags & VIPS_ARGUMENT_INPUT ) {
#ifdef DEBUG_REF
printf( "vips_object_set_object: vips object: " );
vips_object_print( object );
printf( " refers to gobject %s (%p)\n",
G_OBJECT_TYPE_NAME( *member ), *member );
printf( " count up to %d\n",
G_OBJECT( *member )->ref_count );
#endif /*DEBUG_REF*/
/* Ref the argument.
*/
g_object_ref( *member );
}
else if( argument_class->flags & VIPS_ARGUMENT_OUTPUT ) {
#ifdef DEBUG_REF
printf( "vips_object_set_object: gobject %s (%p)\n",
G_OBJECT_TYPE_NAME( *member ), *member );
printf( " refers to vips object: " );
vips_object_print( object );
printf( " count up to %d\n",
G_OBJECT (object)->ref_count );
#endif /*DEBUG_REF*/
/* The argument reffs us.
*/
g_object_ref( object );
argument_instance->destroy_id =
g_signal_connect( *member, "destroy",
G_CALLBACK( vips_object_arg_destroy ),
argument_instance );
}
}
}
static void
vips_object_set_property( GObject *gobject,
guint property_id, const GValue *value, GParamSpec *pspec )
{
VipsObject *object = VIPS_OBJECT( gobject );
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( gobject );
VipsArgumentClass *argument_class = (VipsArgumentClass *)
vips__argument_table_lookup( class->argument_table, pspec );
VipsArgumentInstance *argument_instance =
vips__argument_get_instance( argument_class, object );
if( !argument_class ) {
G_OBJECT_WARN_INVALID_PROPERTY_ID( gobject,
property_id, pspec );
return;
}
#ifdef DEBUG
{
char *str_value;
str_value = g_strdup_value_contents( value );
printf( "vips_object_set_property: %s.%s = %s\n",
object->name, pspec->name, str_value );
g_free( str_value );
}
#endif /*DEBUG*/
g_assert( ((VipsArgument *) argument_class)->pspec == pspec );
g_assert( ((VipsArgument *) argument_instance)->pspec == pspec );
/* If this is a construct-only argument, we can only set before we've
* built.
FIXME ... how do we spot end of construct? put this back
if( argument_class->flags & VIPS_ARGUMENT_CONSTRUCT &&
object->done_build ) {
g_warning( "%s: can't assign '%s' after construct", G_STRLOC,
((VipsArgument *) argument_class)->pspec->name);
return;
}
*/
/* If this is a set-once argument, check we've not set it before.
*/
if( argument_class->flags & VIPS_ARGUMENT_SET_ONCE &&
argument_instance->assigned ) {
g_warning( "%s: can only assign '%s' once", G_STRLOC,
((VipsArgument *)argument_class)->pspec->name );
return;
}
if( G_IS_PARAM_SPEC_STRING( pspec ) ) {
char **member = &G_STRUCT_MEMBER( char *, object,
argument_class->offset );
IM_SETSTR( *member, g_value_get_string( value ) );
}
else if( G_IS_PARAM_SPEC_OBJECT( pspec ) ) {
/* Remove any old object.
*/
vips_object_clear_object( object, pspec );
/* Install the new object.
*/
vips_object_set_object( object, pspec,
g_value_get_object( value ) );
}
else if( G_IS_PARAM_SPEC_INT( pspec ) ) {
int *member = &G_STRUCT_MEMBER( int, object,
argument_class->offset );
*member = g_value_get_int( value );
}
else if( G_IS_PARAM_SPEC_BOOLEAN( pspec ) ) {
gboolean *member = &G_STRUCT_MEMBER( gboolean, object,
argument_class->offset );
*member = g_value_get_boolean( value );
}
else if( G_IS_PARAM_SPEC_ENUM( pspec ) ) {
int *member = &G_STRUCT_MEMBER( int, object,
argument_class->offset );
*member = g_value_get_enum( value );
}
else if( G_IS_PARAM_SPEC_POINTER( pspec ) ) {
gpointer *member = &G_STRUCT_MEMBER( gpointer, object,
argument_class->offset );
*member = g_value_get_pointer( value );
}
else if( G_IS_PARAM_SPEC_BOXED( pspec ) ) {
gpointer *member = &G_STRUCT_MEMBER( gpointer, object,
argument_class->offset );
if( *member ) {
g_boxed_free( G_PARAM_SPEC_VALUE_TYPE( pspec ),
*member );
*member = NULL;
}
/* Copy the boxed into our pointer (will use eg.
* vips__object_vector_dup ()).
*/
*member = g_value_dup_boxed( value );
}
else {
g_warning( "%s: '%s' has unimplemented type", G_STRLOC,
((VipsArgument *) argument_class)->pspec->name );
}
/* Note that it's now been set.
*/
argument_instance->assigned = TRUE;
}
static void
vips_object_get_property( GObject *gobject,
guint property_id, GValue *value, GParamSpec *pspec )
{
VipsObject *object = VIPS_OBJECT( gobject );
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( gobject );
VipsArgumentClass *argument_class = (VipsArgumentClass *)
vips__argument_table_lookup( class->argument_table, pspec );
if( !argument_class ) {
G_OBJECT_WARN_INVALID_PROPERTY_ID( gobject,
property_id, pspec );
return;
}
g_assert( ((VipsArgument *) argument_class)->pspec == pspec );
if( G_IS_PARAM_SPEC_STRING( pspec ) ) {
char *member = G_STRUCT_MEMBER( char *, object,
argument_class->offset );
g_value_set_string( value, member );
}
else if( G_IS_PARAM_SPEC_OBJECT( pspec ) ) {
GObject **member = &G_STRUCT_MEMBER( GObject *, object,
argument_class->offset );
g_value_set_object( value, *member );
}
else if( G_IS_PARAM_SPEC_INT( pspec ) ) {
int *member = &G_STRUCT_MEMBER( int, object,
argument_class->offset );
g_value_set_int( value, *member );
}
else if( G_IS_PARAM_SPEC_BOOLEAN( pspec ) ) {
gboolean *member = &G_STRUCT_MEMBER( gboolean, object,
argument_class->offset );
g_value_set_boolean( value, *member );
}
else if( G_IS_PARAM_SPEC_ENUM( pspec ) ) {
int *member = &G_STRUCT_MEMBER( int, object,
argument_class->offset );
g_value_set_enum( value, *member );
}
else if( G_IS_PARAM_SPEC_POINTER( pspec ) ) {
gpointer *member = &G_STRUCT_MEMBER( gpointer, object,
argument_class->offset );
g_value_set_pointer( value, *member );
}
else if( G_IS_PARAM_SPEC_BOXED( pspec ) ) {
gpointer *member = &G_STRUCT_MEMBER( gpointer, object,
argument_class->offset );
/* Copy the boxed into our pointer (will use eg.
* vips__object_vector_dup ()).
*/
g_value_set_boxed( value, *member );
}
else {
g_warning( "%s: unimplemented property type", G_STRLOC );
}
}
static GObject *
vips_object_constructor( GType gtype,
guint n_properties, GObjectConstructParam *properties )
{
GObject *obj;
#ifdef DEBUG
printf( "vips_object_constructor\n" );
#endif /*DEBUG*/
/* This will build the object and set the constructor params.
*/
obj = G_OBJECT_CLASS( vips_object_parent_class )->constructor(
gtype, n_properties, properties );
/* Check exactly all required params have been set.
*/
#ifdef DEBUG
printf( "vips_object_constructor: checking params\n" );
#endif /*DEBUG*/
/* Set something to indicate that we have constructed, then check that
* in set_property to make sure we only set those during construct.
*/
return( obj );
}
static void
vips_object_real_changed( VipsObject *object )
{
@ -669,9 +163,6 @@ vips_object_class_init( VipsObjectClass *class )
gobject_class->dispose = vips_object_dispose;
gobject_class->finalize = vips_object_finalize;
gobject_class->set_property = vips_object_set_property;
gobject_class->get_property = vips_object_get_property;
gobject_class->constructor = vips_object_constructor;
class->changed = vips_object_real_changed;
class->print_class = vips_object_real_print_class;
@ -704,64 +195,3 @@ vips_object_set_name( VipsObject *object, const char *name )
vips_object_changed( object );
}
/* Add a vipsargument ... automate some stuff with this.
*/
void
vips_object_class_install_argument (VipsObjectClass *object_class,
GParamSpec *pspec, VipsArgumentFlags flags, guint offset)
{
VipsArgumentClass *argument_class = g_new (VipsArgumentClass, 1);
/* Must be a new one.
*/
g_assert (!vips__argument_table_lookup (object_class->argument_table,
pspec));
/* Mustn't have INPUT and OUTPUT both set.
*/
g_assert ((flags & (VIPS_ARGUMENT_INPUT | VIPS_ARGUMENT_OUTPUT)) !=
(VIPS_ARGUMENT_INPUT | VIPS_ARGUMENT_OUTPUT));
((VipsArgument *) argument_class)->pspec = pspec;
argument_class->object_class = object_class;
argument_class->flags = flags;
argument_class->offset = offset;
vips_argument_table_replace (object_class->argument_table,
(VipsArgument *) argument_class);
object_class->argument_table_traverse = g_slist_append (
object_class->argument_table_traverse, argument_class);
}
/* Has a property been set?
*/
gboolean
vips_object_argument_assigned (VipsObject *object, const char *property_name)
{
VipsObjectClass *object_class = VIPS_OBJECT_GET_CLASS (object);
GParamSpec *pspec;
VipsArgumentClass *argument_class;
VipsArgumentInstance *argument_instance;
if (!(pspec = g_object_class_find_property (
G_OBJECT_CLASS (object_class), property_name))) {
g_warning ("property %s not found", property_name);
return (FALSE);
}
if (!(argument_class = (VipsArgumentClass *)
vips__argument_table_lookup (object_class->argument_table,
pspec))) {
g_warning ("vips argument for property %s not found",
property_name);
return (FALSE);
}
if (!(argument_instance = vips__argument_get_instance (
argument_class, object))) {
g_warning ("properties for vips argument %s not found",
property_name);
return (FALSE);
}
return (argument_instance->assigned);
}

View File

@ -128,14 +128,6 @@
*/
#define SMOOTH_SHARPENING_SCALE (0.453125f)
/* Properties.
*/
enum {
PROP_SHARPENING = 1,
PROP_LAST
};
#define VIPS_TYPE_INTERPOLATE_YAFRSMOOTH \
(vips_interpolate_yafrsmooth_get_type())
#define VIPS_INTERPOLATE_YAFRSMOOTH( obj ) \
@ -748,13 +740,10 @@ vips_interpolate_yafrsmooth_interpolate( VipsInterpolate *interpolate,
static void
vips_interpolate_yafrsmooth_class_init( VipsInterpolateYafrsmoothClass *iclass )
{
GObjectClass *gobject_class = G_OBJECT_CLASS( iclass );
VipsObjectClass *object_class = VIPS_OBJECT_CLASS( iclass );
VipsInterpolateClass *interpolate_class =
VIPS_INTERPOLATE_CLASS( iclass );
GParamSpec *pspec;
object_class->nickname = "yafrsmooth";
object_class->description = _( "YAFR smooth interpolation" );
@ -773,19 +762,6 @@ vips_interpolate_yafrsmooth_class_init( VipsInterpolateYafrsmoothClass *iclass )
iclass->matrixi[x][i] =
iclass->matrixf[x][i] * VIPS_INTERPOLATE_SCALE;
}
/* Create properties.
*/
pspec = g_param_spec_double( "sharpening",
_( "Sharpening" ),
_( "Degree of extra edge enhancement" ),
0, 4, 1,
(GParamFlags) G_PARAM_READWRITE );
g_object_class_install_property( gobject_class,
PROP_SHARPENING, pspec );
vips_object_class_install_argument( object_class, pspec,
VIPS_ARGUMENT_SET_ONCE,
G_STRUCT_OFFSET( VipsInterpolateYafrsmooth, sharpening ) );
}
static void