vips8 CLI works

bugs fixed, leaks plugged, hooked up output write
This commit is contained in:
John Cupitt 2011-05-23 17:12:09 +01:00
parent 0514485fa6
commit 8036dda5b7
10 changed files with 184 additions and 46 deletions

View File

@ -59,6 +59,8 @@
- vips.c has new action syntax, knows about vips8 operations
- add now has sizealike
- vips7 binops all do sizealike too, also gbandjoin and ifthenelse
- new API is now functional
- vips.c generates GOption flags for vips8 operations
30/11/10 started 7.24.0
- bump for new stable

7
TODO
View File

@ -1,6 +1,9 @@
- nasty leakage for
- try
$ vips im_add k2.v babe.v out.v
egV
vips add k2.v babe.v out.v

View File

@ -65,8 +65,8 @@
*/
/*
*/
#define DEBUG
*/
#ifdef HAVE_CONFIG_H
#include <config.h>

View File

@ -37,8 +37,8 @@
*/
/*
*/
#define DEBUG
*/
#ifdef HAVE_CONFIG_H
#include <config.h>

View File

@ -33,8 +33,8 @@
*/
/*
*/
#define DEBUG
*/
#ifdef HAVE_CONFIG_H
#include <config.h>

View File

@ -297,6 +297,10 @@ void vips_object_class_install_argument( VipsObjectClass *,
GParamSpec *pspec, VipsArgumentFlags flags, guint offset );
int vips_object_set_argument_from_string( VipsObject *object,
const char *name, const char *value );
gboolean vips_object_get_argument_needs_string( VipsObject *object,
const char *name );
int vips_object_get_argument_to_string( VipsObject *object,
const char *name, const char *arg );
int vips_object_set_required( VipsObject *object, const char *value );
typedef void *(*VipsObjectSetArguments)( VipsObject *, void *, void * );

View File

@ -31,8 +31,8 @@
*/
/*
*/
#define VIPS_DEBUG
*/
#ifdef HAVE_CONFIG_H
#include <config.h>

View File

@ -30,10 +30,10 @@
*/
/*
*/
#define DEBUG
#define VIPS_DEBUG
#define DEBUG_REF
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
@ -463,7 +463,11 @@ vips_object_dispose( GObject *gobject )
vips_argument_free_all( object );
VIPS_FREEF( vips_argument_table_destroy, object->argument_table );
vips_object_close( object );
G_OBJECT_CLASS( vips_object_parent_class )->dispose( gobject );
vips_object_postclose( object );
}
static void
@ -477,15 +481,15 @@ vips_object_finalize( GObject *gobject )
printf( "\n" );
#endif /*DEBUG*/
vips_object_close( object );
/* I'd like to have post-close in here, but you can't emit signals
* from finalize, sadly.
*/
g_mutex_lock( vips__object_all_lock );
g_hash_table_remove( vips__object_all, object );
g_mutex_unlock( vips__object_all_lock );
G_OBJECT_CLASS( vips_object_parent_class )->finalize( gobject );
vips_object_postclose( object );
}
static void
@ -1038,12 +1042,7 @@ vips_object_set_argument_from_string( VipsObject *object,
argument_class = (VipsArgumentClass *)
vips__argument_table_lookup( class->argument_table, pspec );
if( argument_class->flags & VIPS_ARGUMENT_OUTPUT ) {
vips_error( "VipsObject",
_( "can't set output argument %s.%s from string" ),
G_OBJECT_TYPE_NAME( object ), name );
return( -1 );
}
g_assert( argument_class->flags & VIPS_ARGUMENT_INPUT );
if( G_IS_PARAM_SPEC_OBJECT( pspec ) &&
G_PARAM_SPEC_VALUE_TYPE( pspec ) == VIPS_TYPE_IMAGE ) {
@ -1081,6 +1080,114 @@ vips_object_set_argument_from_string( VipsObject *object,
return( 0 );
}
/* Does a named output arg need an argument to write to? For example, an image
* output needs a filename, a double output just prints.
*/
gboolean
vips_object_get_argument_needs_string( VipsObject *object, const char *name )
{
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
GParamSpec *pspec;
VipsArgumentClass *argument_class;
#ifdef DEBUG
printf( "vips_object_get_argument_needs_string: %s\n", name );
#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 );
return( -1 );
}
argument_class = (VipsArgumentClass *)
vips__argument_table_lookup( class->argument_table, pspec );
g_assert( argument_class->flags & VIPS_ARGUMENT_OUTPUT );
/* For now, we just support writing an image to a filename.
*/
if( G_IS_PARAM_SPEC_OBJECT( pspec ) &&
G_PARAM_SPEC_VALUE_TYPE( pspec ) == VIPS_TYPE_IMAGE )
return( TRUE );
else
return( FALSE );
}
static void
vips_object_print_arg( VipsObject *object, GParamSpec *pspec, VipsBuf *buf )
{
GType type = G_PARAM_SPEC_VALUE_TYPE( pspec );
const char *name = g_param_spec_get_name( pspec );
GValue value = { 0 };
char *str_value;
g_value_init( &value, type );
g_object_get_property( G_OBJECT( object ), name, &value );
str_value = g_strdup_value_contents( &value );
vips_buf_appends( buf, str_value );
g_free( str_value );
g_value_unset( &value );
}
/* Write a named arg to the string. If the arg does not need a string (see
* above), arg will be NULL.
*/
int
vips_object_get_argument_to_string( VipsObject *object,
const char *name, const char *arg )
{
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
GParamSpec *pspec;
VipsArgumentClass *argument_class;
#ifdef DEBUG
printf( "vips_object_get_argument_to_string: %s -> %s\n",
name, arg );
#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 );
return( -1 );
}
argument_class = (VipsArgumentClass *)
vips__argument_table_lookup( class->argument_table, pspec );
g_assert( argument_class->flags & VIPS_ARGUMENT_OUTPUT );
if( G_IS_PARAM_SPEC_OBJECT( pspec ) &&
G_PARAM_SPEC_VALUE_TYPE( pspec ) == VIPS_TYPE_IMAGE ) {
VipsImage *value;
VipsImage *image;
if( !(image = vips_image_new_from_file( arg, "w" )) )
return( -1 );
g_object_get( object, name, &value, NULL );
if( im_copy( value, image ) ) {
g_object_unref( value );
g_object_unref( image );
return( -1 );
}
g_object_unref( value );
g_object_unref( image );
}
else {
char str[1000];
VipsBuf buf = VIPS_BUF_STATIC( str );
vips_object_print_arg( object, pspec, &buf );
printf( "%s", vips_buf_all( &buf ) );
}
return( 0 );
}
static void *
vips_argument_is_required( VipsObject *object,
GParamSpec *pspec,
@ -1225,23 +1332,6 @@ vips_object_new_from_string( const char *basename, const char *p )
vips_object_new_from_string_set, (void *) p, NULL ) );
}
static void
vips_object_print_arg( VipsObject *object, GParamSpec *pspec, VipsBuf *buf )
{
GType type = G_PARAM_SPEC_VALUE_TYPE( pspec );
const char *name = g_param_spec_get_name( pspec );
GValue value = { 0 };
char *str_value;
g_value_init( &value, type );
g_object_get_property( G_OBJECT( object ), name, &value );
str_value = g_strdup_value_contents( &value );
vips_buf_appends( buf, str_value );
g_free( str_value );
g_value_unset( &value );
}
static void *
vips_object_to_string_required( VipsObject *object,
GParamSpec *pspec,

View File

@ -28,8 +28,8 @@
*/
/*
*/
#define VIPS_DEBUG
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
@ -551,14 +551,17 @@ vips_call_argv_input( VipsObject *object,
*/
if( (argument_class->flags & VIPS_ARGUMENT_REQUIRED) &&
(argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) ) {
/* Input args get set from argv, we skip output args.
*/
if( (argument_class->flags & VIPS_ARGUMENT_INPUT) )
if( (argument_class->flags & VIPS_ARGUMENT_INPUT) ) {
if( vips_object_set_argument_from_string( object,
g_param_spec_get_name( pspec ), argv[*i] ) )
return( pspec );
*i += 1;
*i += 1;
}
else if( (argument_class->flags & VIPS_ARGUMENT_OUTPUT) ) {
if( vips_object_get_argument_needs_string( object,
g_param_spec_get_name( pspec ) ) )
*i += 1;
}
}
return( NULL );
@ -578,13 +581,46 @@ vips_call_argv_output( VipsObject *object,
*/
if( (argument_class->flags & VIPS_ARGUMENT_REQUIRED) &&
(argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) ) {
/* Output args get written to argv[*i].
*/
if( (argument_class->flags & VIPS_ARGUMENT_OUTPUT) )
printf( "** write %s to %s\n",
g_param_spec_get_name( pspec ), argv[*i] );
if( (argument_class->flags & VIPS_ARGUMENT_INPUT) )
*i += 1;
else if( (argument_class->flags & VIPS_ARGUMENT_OUTPUT) ) {
char *arg;
*i += 1;
arg = NULL;
if( vips_object_get_argument_needs_string( object,
g_param_spec_get_name( pspec ) ) ) {
arg = argv[*i];
*i += 1;
}
if( vips_object_get_argument_to_string( object,
g_param_spec_get_name( pspec ), arg ) )
return( pspec );
}
}
return( NULL );
}
static void *
vips_call_argv_unref_output( VipsObject *object,
GParamSpec *pspec,
VipsArgumentClass *argument_class,
VipsArgumentInstance *argument_instance,
void *a, void *b )
{
if( (argument_class->flags & VIPS_ARGUMENT_OUTPUT) &&
G_IS_PARAM_SPEC_OBJECT( pspec ) ) {
GObject *value;
g_object_get( object,
g_param_spec_get_name( pspec ), &value, NULL );
/* Doing the get refs the object, so unref the get, then unref
* again since this an an output object of the operation.
*/
g_object_unref( value );
g_object_unref( value );
}
return( NULL );
@ -622,6 +658,9 @@ vips_call_argv( VipsOperation *operation, int argc, char **argv )
(void) vips_argument_map( VIPS_OBJECT( operation ),
vips_call_argv_output, argv, &i );
(void) vips_argument_map( VIPS_OBJECT( operation ),
vips_call_argv_unref_output, NULL, NULL );
return( 0 );
}

View File

@ -70,11 +70,11 @@
*/
/*
*/
#define DEBUG_MOVE
#define DEBUG_ENVIRONMENT 1
#define DEBUG_CREATE
#define DEBUG
*/
#ifdef HAVE_CONFIG_H
#include <config.h>