remove wrap7 class
and pyvips8 now knows about deprecated args and ops
This commit is contained in:
parent
b40bad04bb
commit
d25beeddac
4
TODO
4
TODO
@ -8,13 +8,11 @@
|
||||
|
||||
- why don't we get gtk-doc expansions in the leading chapters? we turn them on
|
||||
|
||||
- does Vips.py need to hide deprecated operations?
|
||||
|
||||
- note we automatically copy modified args in Vips.py
|
||||
|
||||
- does cplusplus need to hide deprecated args and operations?
|
||||
|
||||
- test other arg types
|
||||
- test other cpp arg types
|
||||
|
||||
input int works
|
||||
input double
|
||||
|
@ -22,7 +22,6 @@ libdeprecated_la_SOURCES = \
|
||||
hist_dispatch.c \
|
||||
other_dispatch.c \
|
||||
im_maxpos_avg.c \
|
||||
wrapvips7.c \
|
||||
lazy.c \
|
||||
im_dif_std.c \
|
||||
im_simcontr.c \
|
||||
|
@ -1,877 +0,0 @@
|
||||
/* wrap a vips7 operation as a vips8 class
|
||||
*
|
||||
* 12/7/11
|
||||
* - quick hack
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
This file is part of VIPS.
|
||||
|
||||
VIPS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
TODO:
|
||||
|
||||
- masks would be hard, vips8 won't really have these
|
||||
- keep for testing, mostly ... iofuncs/init.c has a commented-out
|
||||
call to init this thing
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
#define DEBUG
|
||||
#define VIPS_DEBUG
|
||||
#define DEBUG_REF
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/internal.h>
|
||||
#include <vips/debug.h>
|
||||
#include <vips/vector.h>
|
||||
|
||||
#define VIPS_WRAP7_PREFIX "VipsWrap7_"
|
||||
|
||||
static GHashTable *vips_wrap7_subclass_types = NULL;
|
||||
|
||||
/* VipsWrap7 is an abstract type ... subclass for each operation we wrap with
|
||||
* no extra members.
|
||||
*/
|
||||
|
||||
typedef struct _VipsWrap7 {
|
||||
VipsOperation parent_object;
|
||||
|
||||
/* vips7 dispatch spine we build.
|
||||
*/
|
||||
im_object *vargv;
|
||||
|
||||
/* Set if we get an error during construct.
|
||||
*/
|
||||
gboolean error;
|
||||
|
||||
} VipsWrap7;
|
||||
|
||||
typedef struct _VipsWrap7Class {
|
||||
VipsOperationClass parent_class;
|
||||
|
||||
/* Look this up from the class name.
|
||||
*/
|
||||
im_function *fn;
|
||||
|
||||
/* Set if we can't wrap this im_function for some reason.
|
||||
*/
|
||||
gboolean not_supported;
|
||||
|
||||
} VipsWrap7Class;
|
||||
|
||||
#define VIPS_TYPE_WRAP7 (vips_wrap7_get_type())
|
||||
#define VIPS_WRAP7( obj ) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST( (obj), VIPS_TYPE_WRAP7, VipsWrap7 ))
|
||||
#define VIPS_WRAP7_CLASS( klass ) \
|
||||
(G_TYPE_CHECK_CLASS_CAST( (klass), VIPS_TYPE_WRAP7, VipsWrap7Class))
|
||||
#define VIPS_IS_WRAP7( obj ) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_WRAP7 ))
|
||||
#define VIPS_IS_WRAP7_CLASS( klass ) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_WRAP7 ))
|
||||
#define VIPS_WRAP7_GET_CLASS( obj ) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS( (obj), VIPS_TYPE_WRAP7, VipsWrap7Class ))
|
||||
|
||||
typedef enum {
|
||||
VIPS_WRAP7_NONE = -1,
|
||||
VIPS_WRAP7_DOUBLE = 0,
|
||||
VIPS_WRAP7_INT,
|
||||
VIPS_WRAP7_COMPLEX,
|
||||
VIPS_WRAP7_STRING,
|
||||
VIPS_WRAP7_IMAGE,
|
||||
VIPS_WRAP7_DOUBLEVEC,
|
||||
VIPS_WRAP7_DMASK,
|
||||
VIPS_WRAP7_IMASK,
|
||||
VIPS_WRAP7_IMAGEVEC,
|
||||
VIPS_WRAP7_INTVEC,
|
||||
VIPS_WRAP7_GVALUE,
|
||||
VIPS_WRAP7_INTERPOLATE
|
||||
} VipsWrap7Type;
|
||||
|
||||
/* Order must match VipsWrap7Type enums.
|
||||
*/
|
||||
static char *vips_wrap7_supported[] = {
|
||||
IM_TYPE_DOUBLE,
|
||||
IM_TYPE_INT,
|
||||
IM_TYPE_COMPLEX,
|
||||
IM_TYPE_STRING,
|
||||
IM_TYPE_IMAGE,
|
||||
IM_TYPE_DOUBLEVEC,
|
||||
IM_TYPE_DMASK,
|
||||
IM_TYPE_IMASK,
|
||||
IM_TYPE_IMAGEVEC,
|
||||
IM_TYPE_INTVEC,
|
||||
IM_TYPE_GVALUE,
|
||||
IM_TYPE_INTERPOLATE
|
||||
};
|
||||
|
||||
/* Turn a vips7 type name to an enum.
|
||||
*/
|
||||
static VipsWrap7Type
|
||||
vips_wrap7_lookup_type( im_arg_type type )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < VIPS_NUMBER( vips_wrap7_supported ); i++ )
|
||||
if( strcmp( type, vips_wrap7_supported[i] ) == 0 )
|
||||
return( (VipsWrap7Type) i );
|
||||
|
||||
return( VIPS_WRAP7_NONE );
|
||||
}
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE( VipsWrap7, vips_wrap7, VIPS_TYPE_OPERATION );
|
||||
|
||||
/* Drop any refs vargv may hold.
|
||||
*/
|
||||
static void
|
||||
vips_wrap7_vargv_dispose( im_function *fn, im_object *vargv )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < fn->argc; i++ ) {
|
||||
im_arg_desc *arg = &fn->argv[i];
|
||||
im_type_desc *type = arg->desc;
|
||||
im_arg_type vt = type->type;
|
||||
|
||||
switch( vips_wrap7_lookup_type( vt ) ) {
|
||||
case VIPS_WRAP7_NONE: /* IM_TYPE_DISPLAY */
|
||||
case VIPS_WRAP7_DOUBLE:
|
||||
case VIPS_WRAP7_INT:
|
||||
case VIPS_WRAP7_COMPLEX:
|
||||
case VIPS_WRAP7_DOUBLEVEC:
|
||||
case VIPS_WRAP7_INTVEC:
|
||||
case VIPS_WRAP7_DMASK:
|
||||
case VIPS_WRAP7_IMASK:
|
||||
/* Do nothing.
|
||||
*/
|
||||
break;
|
||||
|
||||
case VIPS_WRAP7_INTERPOLATE:
|
||||
case VIPS_WRAP7_IMAGE:
|
||||
VIPS_UNREF( vargv[i] );
|
||||
break;
|
||||
|
||||
case VIPS_WRAP7_IMAGEVEC:
|
||||
{
|
||||
im_imagevec_object *iv = vargv[i];
|
||||
int j;
|
||||
|
||||
for( j = 0; j < iv->n; j++ )
|
||||
VIPS_UNREF( iv->vec[j] );
|
||||
}
|
||||
break;
|
||||
|
||||
case VIPS_WRAP7_GVALUE:
|
||||
if( vargv[i] ) {
|
||||
GValue *value = (GValue *) vargv[i];
|
||||
|
||||
if( G_VALUE_TYPE( value ) )
|
||||
g_value_unset( value );
|
||||
}
|
||||
break;
|
||||
|
||||
case VIPS_WRAP7_STRING:
|
||||
VIPS_FREE( vargv[i] );
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert( FALSE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vips_wrap7_dispose( GObject *gobject )
|
||||
{
|
||||
VipsWrap7 *wrap7 = VIPS_WRAP7( gobject );
|
||||
VipsWrap7Class *class = VIPS_WRAP7_GET_CLASS( wrap7 );
|
||||
|
||||
#ifdef DEBUG
|
||||
printf( "vips_wrap7_dispose: " );
|
||||
vips_object_print_name( VIPS_OBJECT( wrap7 ) );
|
||||
printf( "\n" );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
vips_wrap7_vargv_dispose( class->fn, wrap7->vargv );
|
||||
|
||||
G_OBJECT_CLASS( vips_wrap7_parent_class )->dispose( gobject );
|
||||
}
|
||||
|
||||
/* Junk stuff we may have attached to vargv.
|
||||
*/
|
||||
static void
|
||||
vips_wrap7_vargv_finalize( im_function *fn, im_object *vargv )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < fn->argc; i++ ) {
|
||||
im_arg_desc *arg = &fn->argv[i];
|
||||
im_type_desc *type = arg->desc;
|
||||
im_arg_type vt = type->type;
|
||||
|
||||
switch( vips_wrap7_lookup_type( vt ) ) {
|
||||
case VIPS_WRAP7_NONE: /* IM_TYPE_DISPLAY */
|
||||
case VIPS_WRAP7_DOUBLE:
|
||||
case VIPS_WRAP7_INT:
|
||||
case VIPS_WRAP7_COMPLEX:
|
||||
case VIPS_WRAP7_GVALUE:
|
||||
case VIPS_WRAP7_INTERPOLATE:
|
||||
case VIPS_WRAP7_IMAGE:
|
||||
/* Do nothing.
|
||||
*/
|
||||
break;
|
||||
|
||||
case VIPS_WRAP7_STRING:
|
||||
VIPS_FREE( vargv[i] );
|
||||
break;
|
||||
|
||||
case VIPS_WRAP7_IMAGEVEC:
|
||||
VIPS_FREE( ((im_imagevec_object *) vargv[i])->vec );
|
||||
break;
|
||||
|
||||
case VIPS_WRAP7_DOUBLEVEC:
|
||||
VIPS_FREE( ((im_doublevec_object *) vargv[i])->vec );
|
||||
break;
|
||||
|
||||
case VIPS_WRAP7_INTVEC:
|
||||
VIPS_FREE( ((im_intvec_object *) vargv[i])->vec );
|
||||
break;
|
||||
|
||||
case VIPS_WRAP7_DMASK:
|
||||
VIPS_FREE( ((im_mask_object *) vargv[i])->name );
|
||||
VIPS_FREEF( im_free_dmask,
|
||||
((im_mask_object *) vargv[i])->mask );
|
||||
break;
|
||||
|
||||
case VIPS_WRAP7_IMASK:
|
||||
VIPS_FREE( ((im_mask_object *) vargv[i])->name );
|
||||
VIPS_FREEF( im_free_imask,
|
||||
((im_mask_object *) vargv[i])->mask );
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert( FALSE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vips_wrap7_finalize( GObject *gobject )
|
||||
{
|
||||
VipsWrap7 *wrap7 = VIPS_WRAP7( gobject );
|
||||
VipsWrap7Class *class = VIPS_WRAP7_GET_CLASS( wrap7 );
|
||||
|
||||
#ifdef DEBUG
|
||||
printf( "vips_wrap7_finalize: " );
|
||||
vips_object_print_name( VIPS_OBJECT( wrap7 ) );
|
||||
printf( "\n" );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
if( wrap7->vargv ) {
|
||||
vips_wrap7_vargv_finalize( class->fn, wrap7->vargv );
|
||||
im_free_vargv( class->fn, wrap7->vargv );
|
||||
VIPS_FREE( wrap7->vargv );
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS( vips_wrap7_parent_class )->finalize( gobject );
|
||||
}
|
||||
|
||||
/* Like the one in object.c, but write to vargv instead. Use offset to record
|
||||
* the index in vargv we set.
|
||||
*/
|
||||
static void
|
||||
vips_wrap7_object_set_property( GObject *gobject,
|
||||
guint property_id, const GValue *value, GParamSpec *pspec )
|
||||
{
|
||||
VipsObject *object = VIPS_OBJECT( gobject );
|
||||
VipsObjectClass *oclass = VIPS_OBJECT_GET_CLASS( gobject );
|
||||
VipsArgumentClass *argument_class = (VipsArgumentClass *)
|
||||
vips__argument_table_lookup( oclass->argument_table, pspec );
|
||||
VipsArgumentInstance *argument_instance =
|
||||
vips__argument_get_instance( argument_class, object );
|
||||
VipsWrap7 *wrap7 = VIPS_WRAP7( gobject );
|
||||
VipsWrap7Class *class = VIPS_WRAP7_GET_CLASS( wrap7 );
|
||||
|
||||
int i;
|
||||
im_arg_desc *arg;
|
||||
im_type_desc *type;
|
||||
im_arg_type vt;
|
||||
|
||||
g_assert( argument_instance );
|
||||
|
||||
if( !argument_class ) {
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID( gobject,
|
||||
property_id, pspec );
|
||||
return;
|
||||
}
|
||||
|
||||
i = argument_class->offset;
|
||||
arg = &class->fn->argv[i];
|
||||
type = arg->desc;
|
||||
vt = type->type;
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
char *str_value;
|
||||
|
||||
str_value = g_strdup_value_contents( value );
|
||||
printf( "vips_object_set_property: " );
|
||||
vips_object_print_name( object );
|
||||
printf( ".%s = %s\n", g_param_spec_get_name( pspec ), 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.
|
||||
*/
|
||||
if( argument_class->flags & VIPS_ARGUMENT_CONSTRUCT &&
|
||||
object->constructed &&
|
||||
!vips_value_is_null( pspec, value ) ) {
|
||||
g_warning( "%s: %s can't assign '%s' after construct",
|
||||
G_STRLOC,
|
||||
G_OBJECT_TYPE_NAME( gobject ),
|
||||
g_param_spec_get_name( pspec ) );
|
||||
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 &&
|
||||
!vips_value_is_null( pspec, value ) ) {
|
||||
g_warning( "%s: %s can only assign '%s' once",
|
||||
G_STRLOC,
|
||||
G_OBJECT_TYPE_NAME( gobject ),
|
||||
g_param_spec_get_name( pspec ) );
|
||||
return;
|
||||
}
|
||||
|
||||
switch( vips_wrap7_lookup_type( vt ) ) {
|
||||
case VIPS_WRAP7_DOUBLE:
|
||||
*((double*)wrap7->vargv[i]) = g_value_get_double( value );
|
||||
break;
|
||||
|
||||
case VIPS_WRAP7_INT:
|
||||
*((int*)wrap7->vargv[i]) = g_value_get_int( value );
|
||||
break;
|
||||
|
||||
case VIPS_WRAP7_STRING:
|
||||
IM_SETSTR( wrap7->vargv[i], g_value_get_string( value ) );
|
||||
break;
|
||||
|
||||
case VIPS_WRAP7_GVALUE:
|
||||
g_value_init( wrap7->vargv[i], G_VALUE_TYPE( value ) );
|
||||
g_value_copy( value, wrap7->vargv[i] );
|
||||
break;
|
||||
|
||||
case VIPS_WRAP7_IMAGE:
|
||||
case VIPS_WRAP7_INTERPOLATE:
|
||||
vips__object_set_member( object, pspec,
|
||||
(GObject **) &wrap7->vargv[i],
|
||||
g_value_get_object( value ) );
|
||||
break;
|
||||
|
||||
default:
|
||||
wrap7->error = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Note that it's now been set.
|
||||
*/
|
||||
argument_instance->assigned = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
vips_wrap7_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 );
|
||||
VipsArgumentInstance *argument_instance =
|
||||
vips__argument_get_instance( argument_class, object );
|
||||
VipsWrap7 *wrap7 = VIPS_WRAP7( gobject );
|
||||
VipsWrap7Class *wclass = VIPS_WRAP7_GET_CLASS( wrap7 );
|
||||
|
||||
int i;
|
||||
im_arg_desc *arg;
|
||||
im_type_desc *type;
|
||||
im_arg_type vt;
|
||||
|
||||
if( !argument_class ) {
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID( gobject,
|
||||
property_id, pspec );
|
||||
return;
|
||||
}
|
||||
|
||||
i = argument_class->offset;
|
||||
arg = &wclass->fn->argv[i];
|
||||
type = arg->desc;
|
||||
vt = type->type;
|
||||
|
||||
g_assert( ((VipsArgument *) argument_class)->pspec == pspec );
|
||||
|
||||
if( !argument_instance->assigned ) {
|
||||
g_warning( "%s: %s attempt to read unset property %s",
|
||||
G_STRLOC,
|
||||
G_OBJECT_TYPE_NAME( gobject ),
|
||||
g_type_name( G_PARAM_SPEC_VALUE_TYPE( pspec ) ) );
|
||||
return;
|
||||
}
|
||||
|
||||
switch( vips_wrap7_lookup_type( vt ) ) {
|
||||
case VIPS_WRAP7_DOUBLE:
|
||||
g_value_set_double( value, *((double*)wrap7->vargv[i]) );
|
||||
break;
|
||||
|
||||
case VIPS_WRAP7_INT:
|
||||
g_value_set_int( value, *((int*)wrap7->vargv[i]) );
|
||||
break;
|
||||
|
||||
case VIPS_WRAP7_STRING:
|
||||
g_value_set_string( value, wrap7->vargv[i] );
|
||||
break;
|
||||
|
||||
case VIPS_WRAP7_IMAGE:
|
||||
case VIPS_WRAP7_INTERPOLATE:
|
||||
case VIPS_WRAP7_GVALUE:
|
||||
g_value_set_object( value, wrap7->vargv[i] );
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning( "%s: %s unimplemented property type %s",
|
||||
G_STRLOC,
|
||||
G_OBJECT_TYPE_NAME( gobject ),
|
||||
g_type_name( G_PARAM_SPEC_VALUE_TYPE( pspec ) ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Init an output slot in vargv.
|
||||
*/
|
||||
static void *
|
||||
vips_wrap7_build_output( VipsObject *object,
|
||||
GParamSpec *pspec,
|
||||
VipsArgumentClass *argument_class,
|
||||
VipsArgumentInstance *argument_instance,
|
||||
void *a, void *b )
|
||||
{
|
||||
VipsWrap7 *wrap7 = VIPS_WRAP7( object );
|
||||
VipsWrap7Class *class = VIPS_WRAP7_GET_CLASS( wrap7 );
|
||||
|
||||
int i;
|
||||
im_arg_desc *arg;
|
||||
im_type_desc *type;
|
||||
im_arg_type vt;
|
||||
|
||||
/* We want required, construct-time, unassigned output args.
|
||||
*/
|
||||
if( !(argument_class->flags & VIPS_ARGUMENT_REQUIRED) ||
|
||||
!(argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) ||
|
||||
argument_instance->assigned ||
|
||||
!(argument_class->flags & VIPS_ARGUMENT_OUTPUT) )
|
||||
return( NULL );
|
||||
|
||||
/* argument_class->offset is only the argv slot for true params. We
|
||||
* can't do this before we've tested the arg class.
|
||||
*/
|
||||
i = argument_class->offset;
|
||||
arg = &class->fn->argv[i];
|
||||
type = arg->desc;
|
||||
vt = type->type;
|
||||
|
||||
/* Provide output objects for the operation to write to.
|
||||
*/
|
||||
switch( vips_wrap7_lookup_type( vt ) ) {
|
||||
case VIPS_WRAP7_DOUBLE:
|
||||
case VIPS_WRAP7_INT:
|
||||
case VIPS_WRAP7_COMPLEX:
|
||||
case VIPS_WRAP7_STRING:
|
||||
break;
|
||||
|
||||
case VIPS_WRAP7_IMAGE:
|
||||
g_object_set( object, arg->name, vips_image_new(), NULL );
|
||||
break;
|
||||
|
||||
case VIPS_WRAP7_DMASK:
|
||||
case VIPS_WRAP7_IMASK:
|
||||
break;
|
||||
|
||||
case VIPS_WRAP7_GVALUE:
|
||||
{
|
||||
GValue *value = wrap7->vargv[i];
|
||||
|
||||
memset( value, 0, sizeof( GValue ) );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case VIPS_WRAP7_DOUBLEVEC:
|
||||
case VIPS_WRAP7_INTVEC:
|
||||
default:
|
||||
wrap7->error = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
/* Mark an output as assigned.
|
||||
*/
|
||||
static void *
|
||||
vips_wrap7_note_assigned( VipsObject *object,
|
||||
GParamSpec *pspec,
|
||||
VipsArgumentClass *argument_class,
|
||||
VipsArgumentInstance *argument_instance,
|
||||
void *a, void *b )
|
||||
{
|
||||
/* We want required, construct-time, output args.
|
||||
*/
|
||||
if( !(argument_class->flags & VIPS_ARGUMENT_REQUIRED) ||
|
||||
!(argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) ||
|
||||
!(argument_class->flags & VIPS_ARGUMENT_OUTPUT) )
|
||||
return( NULL );
|
||||
|
||||
if( !argument_instance->assigned ) {
|
||||
argument_instance->assigned = TRUE;
|
||||
|
||||
VIPS_DEBUG_MSG( "vips_wrap7_note_assigned: "
|
||||
"marking %s as assigned\n",
|
||||
g_param_spec_get_name( pspec ) );
|
||||
}
|
||||
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
static int
|
||||
vips_wrap7_build( VipsObject *object )
|
||||
{
|
||||
VipsWrap7 *wrap7 = VIPS_WRAP7( object );
|
||||
VipsWrap7Class *class = VIPS_WRAP7_GET_CLASS( wrap7 );
|
||||
VipsObjectClass *oclass = VIPS_OBJECT_CLASS( class );
|
||||
|
||||
if( wrap7->error ) {
|
||||
vips_error( "wrap7",
|
||||
_( "error constructing vips7 operation %s" ),
|
||||
oclass->nickname );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( class->not_supported ) {
|
||||
vips_error( "wrap7",
|
||||
_( "vips7 operation %s not supported by vips8" ),
|
||||
oclass->nickname );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf( "vips_wrap7_build: " );
|
||||
vips_object_print_name( VIPS_OBJECT( wrap7 ) );
|
||||
printf( " building output\n" );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
/* Init all the output args.
|
||||
*/
|
||||
(void) vips_argument_map( VIPS_OBJECT( wrap7 ),
|
||||
vips_wrap7_build_output,
|
||||
NULL, NULL );
|
||||
|
||||
if( VIPS_OBJECT_CLASS( vips_wrap7_parent_class )->build( object ) )
|
||||
return( -1 );
|
||||
|
||||
/* Run the operation.
|
||||
*/
|
||||
if( class->fn->disp( wrap7->vargv ) )
|
||||
return( -1 );
|
||||
|
||||
/* The vips7 operation will have written any outputs (such as the
|
||||
* output double for im_max(), for example) to varg. g_object_get()
|
||||
* fetches directly from vargv (see vips_wrap7_object_get_property())
|
||||
* so we don't need to do any copying, we just need to tell vips that
|
||||
* all outputs now have values.
|
||||
*/
|
||||
(void) vips_argument_map( VIPS_OBJECT( wrap7 ),
|
||||
vips_wrap7_note_assigned,
|
||||
NULL, NULL );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_wrap7_summary_class( VipsObjectClass *oclass, VipsBuf *buf )
|
||||
{
|
||||
VipsWrap7Class *class = VIPS_WRAP7_CLASS( oclass );
|
||||
im_function *fn = class->fn;
|
||||
|
||||
if( fn )
|
||||
vips_buf_appends( buf, fn->name );
|
||||
else
|
||||
vips_buf_appends( buf, G_OBJECT_CLASS_NAME( class ) );
|
||||
|
||||
if( oclass->description )
|
||||
vips_buf_appendf( buf, " - %s", oclass->description );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_wrap7_dump( VipsObject *object, VipsBuf *buf )
|
||||
{
|
||||
VipsWrap7Class *class = VIPS_WRAP7_GET_CLASS( object );
|
||||
im_function *fn = class->fn;
|
||||
im_package *pack = im_package_of_function( fn->name );
|
||||
|
||||
VIPS_OBJECT_CLASS( vips_wrap7_parent_class )->dump( object, buf );
|
||||
|
||||
if( pack )
|
||||
vips_buf_appendf( buf, "from package \"%s\"", pack->name );
|
||||
vips_buf_appendf( buf, "\n" );
|
||||
|
||||
/* Print any flags this function has.
|
||||
*/
|
||||
vips_buf_appendf( buf, "flags: " );
|
||||
if( fn->flags & IM_FN_PIO )
|
||||
vips_buf_appendf( buf, "(PIO function) " );
|
||||
else
|
||||
vips_buf_appendf( buf, "(WIO function) " );
|
||||
if( fn->flags & IM_FN_TRANSFORM )
|
||||
vips_buf_appendf( buf, "(coordinate transformer) " );
|
||||
else
|
||||
vips_buf_appendf( buf, "(no coordinate transformation) " );
|
||||
if( fn->flags & IM_FN_PTOP )
|
||||
vips_buf_appendf( buf, "(point-to-point operation) " );
|
||||
else
|
||||
vips_buf_appendf( buf, "(area operation) " );
|
||||
if( fn->flags & IM_FN_NOCACHE )
|
||||
vips_buf_appendf( buf, "(nocache operation) " );
|
||||
else
|
||||
vips_buf_appendf( buf, "(result can be cached) " );
|
||||
|
||||
vips_buf_appendf( buf, "\n" );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_wrap7_class_init( VipsWrap7Class *class )
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) class;
|
||||
VipsObjectClass *vobject_class = (VipsObjectClass *) class;
|
||||
VipsOperationClass *operation_class = (VipsOperationClass *) class;
|
||||
|
||||
gobject_class->dispose = vips_wrap7_dispose;
|
||||
gobject_class->finalize = vips_wrap7_finalize;
|
||||
|
||||
vobject_class->nickname = "wrap7";
|
||||
vobject_class->description = _( "vips7 operations as vips8 classes" );
|
||||
vobject_class->build = vips_wrap7_build;
|
||||
vobject_class->summary_class = vips_wrap7_summary_class;
|
||||
vobject_class->dump = vips_wrap7_dump;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_DEPRECATED;
|
||||
}
|
||||
|
||||
static void
|
||||
vips_wrap7_init( VipsWrap7 *wrap7 )
|
||||
{
|
||||
}
|
||||
|
||||
/* Build a subclass of vips7 for every vips7 operation.
|
||||
*/
|
||||
|
||||
static void
|
||||
vips_wrap7_subclass_class_init( VipsWrap7Class *class )
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) class;
|
||||
VipsObjectClass *vobject_class = (VipsObjectClass *) class;
|
||||
|
||||
/* The name of the vips operation we wrap is hidden in our class name.
|
||||
*/
|
||||
const char *name = G_OBJECT_CLASS_NAME( class ) +
|
||||
strlen( VIPS_WRAP7_PREFIX );
|
||||
im_function *fn = im_find_function( name );
|
||||
|
||||
int i;
|
||||
|
||||
g_assert( !class->fn );
|
||||
g_assert( fn );
|
||||
|
||||
gobject_class->set_property = vips_wrap7_object_set_property;
|
||||
gobject_class->get_property = vips_wrap7_object_get_property;
|
||||
|
||||
vobject_class->nickname = im_strdup( NULL, name );
|
||||
vobject_class->description = fn->desc;
|
||||
|
||||
class->fn = fn;
|
||||
|
||||
for( i = fn->argc - 1; i >= 0; i-- ) {
|
||||
im_arg_desc *arg = &fn->argv[i];
|
||||
im_type_desc *type = arg->desc;
|
||||
im_arg_type vt = type->type;
|
||||
|
||||
GParamSpec *pspec;
|
||||
|
||||
switch( vips_wrap7_lookup_type( vt ) ) {
|
||||
case VIPS_WRAP7_DOUBLEVEC:
|
||||
case VIPS_WRAP7_DMASK:
|
||||
case VIPS_WRAP7_IMASK:
|
||||
case VIPS_WRAP7_IMAGEVEC:
|
||||
case VIPS_WRAP7_INTVEC:
|
||||
case VIPS_WRAP7_GVALUE:
|
||||
case VIPS_WRAP7_INTERPOLATE:
|
||||
case VIPS_WRAP7_COMPLEX:
|
||||
case VIPS_WRAP7_STRING:
|
||||
case VIPS_WRAP7_NONE:
|
||||
/* Can't wrap this function. class_init can't fail, so
|
||||
* set a flag to block _build().
|
||||
*/
|
||||
class->not_supported = TRUE;
|
||||
pspec = NULL;
|
||||
break;
|
||||
|
||||
case VIPS_WRAP7_INT:
|
||||
pspec = g_param_spec_int( arg->name,
|
||||
arg->name,
|
||||
arg->name,
|
||||
-G_MAXINT, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE );
|
||||
break;
|
||||
|
||||
case VIPS_WRAP7_DOUBLE:
|
||||
pspec = g_param_spec_double( arg->name,
|
||||
arg->name,
|
||||
arg->name,
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
|
||||
G_PARAM_READWRITE );
|
||||
break;
|
||||
|
||||
case VIPS_WRAP7_IMAGE:
|
||||
pspec = g_param_spec_object( arg->name,
|
||||
arg->name,
|
||||
arg->name,
|
||||
VIPS_TYPE_IMAGE,
|
||||
G_PARAM_READWRITE );
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert( 0 );
|
||||
|
||||
/* Keep -Wall happy.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if( pspec ) {
|
||||
g_object_class_install_property( gobject_class,
|
||||
i + 1, pspec );
|
||||
vips_object_class_install_argument( vobject_class,
|
||||
pspec,
|
||||
(type->flags & IM_TYPE_OUTPUT) ?
|
||||
VIPS_ARGUMENT_REQUIRED_OUTPUT :
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
i, i );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vips_wrap7_subclass_init( VipsWrap7 *wrap7 )
|
||||
{
|
||||
VipsWrap7Class *class = VIPS_WRAP7_GET_CLASS( wrap7 );
|
||||
im_function *fn = class->fn;
|
||||
|
||||
if( !(wrap7->vargv = IM_ARRAY( NULL, fn->argc + 1, im_object )) ||
|
||||
im_allocate_vargv( fn, wrap7->vargv ) ) {
|
||||
wrap7->error = TRUE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static GType
|
||||
vips_wrap7_subclass_get_type( im_function *fn )
|
||||
{
|
||||
static const GTypeInfo info = {
|
||||
sizeof( VipsWrap7Class ),
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc) vips_wrap7_subclass_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof( VipsWrap7 ),
|
||||
32, /* n_preallocs */
|
||||
(GInstanceInitFunc) vips_wrap7_subclass_init,
|
||||
};
|
||||
|
||||
char name[256];
|
||||
GType type;
|
||||
|
||||
if( !vips_wrap7_subclass_types )
|
||||
vips_wrap7_subclass_types =
|
||||
g_hash_table_new( g_direct_hash, g_direct_equal );
|
||||
|
||||
if( (type = (GType)
|
||||
g_hash_table_lookup( vips_wrap7_subclass_types, fn )) )
|
||||
return( type );
|
||||
|
||||
im_snprintf( name, 256, VIPS_WRAP7_PREFIX "%s", fn->name );
|
||||
type = g_type_register_static( VIPS_TYPE_WRAP7, name, &info, 0 );
|
||||
g_hash_table_insert( vips_wrap7_subclass_types, fn, (gpointer) type );
|
||||
|
||||
return( type );
|
||||
}
|
||||
|
||||
static void *
|
||||
vips_wrap7_build_package( im_package *package )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < package->nfuncs; i++ )
|
||||
(void) vips_wrap7_subclass_get_type( package->table[i] );
|
||||
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
/* Walk the whole of the vips7 operation table building classes.
|
||||
*/
|
||||
void
|
||||
vips__init_wrap7_classes( void )
|
||||
{
|
||||
(void) im_map_packages( (VSListMap2Fn) vips_wrap7_build_package, NULL );
|
||||
}
|
||||
|
@ -198,10 +198,6 @@ void vips__draw_circle_direct( VipsImage *image, int cx, int cy, int r,
|
||||
*/
|
||||
void vips__interpolate_init( void );
|
||||
|
||||
/* Register wrappers for all the vips7 operations.
|
||||
*/
|
||||
void vips__init_wrap7_classes( void );
|
||||
|
||||
/* Start up various packages.
|
||||
*/
|
||||
void vips_arithmetic_operation_init( void );
|
||||
|
@ -367,10 +367,6 @@ vips_init( const char *argv0 )
|
||||
vips_error_clear();
|
||||
}
|
||||
|
||||
/* Build classes which wrap old vips7 operations.
|
||||
*/
|
||||
vips__init_wrap7_classes();
|
||||
|
||||
/* Start up the buffer cache.
|
||||
*/
|
||||
vips__buffer_init();
|
||||
|
@ -174,7 +174,7 @@ class Operation(Vips.Operation):
|
||||
def get_args(self):
|
||||
args = [Argument(self, x) for x in self.props]
|
||||
args = [y for y in args
|
||||
if not (y.flags & Vips.ArgumentFlags.DEPRECATED)]
|
||||
if not y.flags & Vips.ArgumentFlags.DEPRECATED]
|
||||
args.sort(lambda a, b: a.priority - b.priority)
|
||||
|
||||
return args
|
||||
@ -205,6 +205,8 @@ def _call_base(name, required, optional, self = None, option_string = None):
|
||||
op = Vips.Operation.new(name)
|
||||
except TypeError, e:
|
||||
raise Error('No such operator.')
|
||||
if op.get_flags() & Vips.OperationFlags.DEPRECATED:
|
||||
raise Error('No such operator.', 'operator "%s" is deprecated' % name)
|
||||
|
||||
# set str options first so the user can't override things we set
|
||||
# deliberately and break stuff
|
||||
@ -412,7 +414,9 @@ def generate_docstring(name):
|
||||
try:
|
||||
op = Vips.Operation.new(name)
|
||||
except TypeError, e:
|
||||
return 'No such operator ' + name
|
||||
raise Error('No such operator.')
|
||||
if op.get_flags() & Vips.OperationFlags.DEPRECATED:
|
||||
raise Error('No such operator.', 'operator "%s" is deprecated' % name)
|
||||
|
||||
# find all the args for this op, sort into priority order
|
||||
args = op.get_args()
|
||||
|
Loading…
Reference in New Issue
Block a user