diff --git a/ChangeLog b/ChangeLog index aa041814..f1ae7235 100644 --- a/ChangeLog +++ b/ChangeLog @@ -28,6 +28,8 @@ - added string->double transform for cmdline args - merged class-params branch back into trunk - IM_FREE() can do "const char*" variables +- im_buf_t renamed as VipsBuf +- added vips_object_to_string() 11/9/08 started 7.16.3 - oop typo in manpage for im_project() diff --git a/TODO b/TODO index 2b8b53aa..383637be 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,6 @@ + + + - try making vips_add(), an operator as a class - nickname, description etc need to be properties so nip2 can read them @@ -13,7 +16,7 @@ - update format docs - how to expose things like yafrsmooth's "sharpening" parameter to - nip2/C++/Python? + C++/Python? can we write a find-by-nickname function? eg. @@ -25,24 +28,8 @@ would get us the GType for VipsInterpolatorBicubic - add a g_get_children( "classname" ) -> ["child1-name", ..] to nip2, see old - vips8.c code? - - in nip2, - - inter = g_object_new "yafrsmooth" [$sharpness => 2.4]; - - also need something to return a list of GTypes below a name etc., find class - description:w - - need k - - vips_object_print, set_name etc. need writing -- im_buf_t -> VipsBuf - - now always included in vips.h - - check mosaic1, global_balance, similarity etc. use of im__affine how can we move them to im_affinei ? diff --git a/include/vips/buf.h b/include/vips/buf.h index 54f8b668..45476e34 100644 --- a/include/vips/buf.h +++ b/include/vips/buf.h @@ -27,58 +27,59 @@ */ -#ifndef IM_BUF_H -#define IM_BUF_H +#ifndef VIPS_BUF_H +#define VIPS_BUF_H #ifdef __cplusplus extern "C" { #endif /*__cplusplus*/ /* A string in the process of being written to ... multiple calls to - * buf_append add to it, on overflow append "..." and block further writes. + * vips_buf_append add to it, on overflow append "..." and block further writes. */ typedef struct { - char *base; /* String base */ - int mx; /* Maximum length */ - int i; /* Current write point */ - gboolean full; /* String has filled, block writes */ - int lasti; /* For read-recent */ - gboolean dynamic; /* We own the string with malloc() */ -} im_buf_t; + char *base; /* String base */ + int mx; /* Maximum length */ + int i; /* Current write point */ + gboolean full; /* String has filled, block writes */ + int lasti; /* For read-recent */ + gboolean dynamic; /* We own the string with malloc() */ +} VipsBuf; /* Static init of one of these. */ -#define IM_BUF_STATIC( TEXT, MAX ) \ - { &TEXT[0], MAX, 0, FALSE, 0, FALSE } +#define VIPS_BUF_STATIC( TEXT, MAX ) \ + { &TEXT[0], MAX, 0, FALSE, 0, FALSE } -void im_buf_rewind( im_buf_t *buf ); -void im_buf_destroy( im_buf_t *buf ); -void im_buf_init( im_buf_t *buf ); -void im_buf_set_static( im_buf_t *buf, char *base, int mx ); -void im_buf_set_dynamic( im_buf_t *buf, int mx ); -void im_buf_init_static( im_buf_t *buf, char *base, int mx ); -void im_buf_init_dynamic( im_buf_t *buf, int mx ); -gboolean im_buf_appendns( im_buf_t *buf, const char *str, int sz ); -gboolean im_buf_appends( im_buf_t *buf, const char *str ); -gboolean im_buf_appendline( im_buf_t *buf, const char *str ); -gboolean im_buf_appendf( im_buf_t *buf, const char *fmt, ... ) +/* Init and append to one of the above. + */ +void vips_buf_rewind( VipsBuf *buf ); +void vips_buf_destroy( VipsBuf *buf ); +void vips_buf_init( VipsBuf *buf ); +void vips_buf_set_static( VipsBuf *buf, char *base, int mx ); +void vips_buf_set_dynamic( VipsBuf *buf, int mx ); +void vips_buf_init_static( VipsBuf *buf, char *base, int mx ); +void vips_buf_init_dynamic( VipsBuf *buf, int mx ); +gboolean vips_buf_appendns( VipsBuf *buf, const char *str, int sz ); +gboolean vips_buf_appends( VipsBuf *buf, const char *str ); +gboolean vips_buf_appendf( VipsBuf *buf, const char *fmt, ... ) __attribute__((format(printf, 2, 3))); -gboolean im_buf_vappendf( im_buf_t *buf, const char *fmt, va_list ap ); -gboolean im_buf_appendc( im_buf_t *buf, char ch ); -gboolean im_buf_appendg( im_buf_t *buf, double g ); -gboolean im_buf_appendsc( im_buf_t *buf, const char *str ); -gboolean im_buf_removec( im_buf_t *buf, char ch ); -gboolean im_buf_change( im_buf_t *buf, const char *old, const char * ); -gboolean im_buf_isempty( im_buf_t *buf ); -gboolean im_buf_isfull( im_buf_t *buf ); -const char *im_buf_all( im_buf_t *buf ); -gboolean im_buf_appendd( im_buf_t *buf, int d ); -int im_buf_len( im_buf_t *buf ); +gboolean vips_buf_vappendf( VipsBuf *buf, const char *fmt, va_list ap ); +gboolean vips_buf_appendc( VipsBuf *buf, char ch ); +gboolean vips_buf_appendsc( VipsBuf *buf, gboolean quote, const char *str ); +void vips_buf_appendgv( VipsBuf *buf, GValue *value ); +gboolean vips_buf_removec( VipsBuf *buf, char ch ); +gboolean vips_buf_change( VipsBuf *buf, const char *old, const char * ); +gboolean vips_buf_is_empty( VipsBuf *buf ); +gboolean vips_buf_is_full( VipsBuf *buf ); +const char *vips_buf_all( VipsBuf *buf ); +const char *vips_buf_firstline( VipsBuf *buf ); +gboolean vips_buf_appendg( VipsBuf *buf, double g ); +gboolean vips_buf_appendd( VipsBuf *buf, int d ); +int vips_buf_len( VipsBuf *buf ); + +#endif /*VIPS_BUF_H*/ #ifdef __cplusplus } #endif /*__cplusplus*/ - -#endif /*IM_BUF_H*/ - - diff --git a/include/vips/object.h b/include/vips/object.h index 3190d6cd..23d252f9 100644 --- a/include/vips/object.h +++ b/include/vips/object.h @@ -196,11 +196,11 @@ struct _VipsObjectClass { /* Try to print something about the class, handy for help displays. */ - void (*print_class)( struct _VipsObjectClass *, im_buf_t * ); + void (*print_class)( struct _VipsObjectClass *, VipsBuf * ); /* Try to print something about the object, handy for debugging. */ - void (*print)( VipsObject *, im_buf_t * ); + void (*print)( VipsObject *, VipsBuf * ); /* Class nickname, eg. "VipsInterpolateBicubic" has "bicubic" as a * nickname. Not internationalised. @@ -236,6 +236,7 @@ void vips_object_class_install_argument( VipsObjectClass *, GParamSpec *pspec, VipsArgumentFlags flags, guint offset ); VipsObject *vips_object_new_from_string( const char *base, const char *str ); +void vips_object_to_string( VipsObject *object, VipsBuf *buf ); #ifdef __cplusplus } diff --git a/libsrc/format/format.c b/libsrc/format/format.c index 0aba31f0..e889f5d6 100644 --- a/libsrc/format/format.c +++ b/libsrc/format/format.c @@ -84,7 +84,7 @@ vips_format_map( VSListMap2Fn fn, void *a, void *b ) G_DEFINE_ABSTRACT_TYPE( VipsFormat, vips_format, VIPS_TYPE_OBJECT ); static void -vips_format_print_class( VipsObjectClass *object_class, im_buf_t *buf ) +vips_format_print_class( VipsObjectClass *object_class, VipsBuf *buf ) { VipsFormatClass *class = VIPS_FORMAT_CLASS( object_class ); const char **p; @@ -92,24 +92,24 @@ vips_format_print_class( VipsObjectClass *object_class, im_buf_t *buf ) VIPS_OBJECT_CLASS( vips_format_parent_class )-> print_class( object_class, buf ); - im_buf_appends( buf, ", (" ); + vips_buf_appends( buf, ", (" ); for( p = class->suffs; *p; p++ ) { - im_buf_appendf( buf, "%s", *p ); + vips_buf_appendf( buf, "%s", *p ); if( p[1] ) - im_buf_appends( buf, ", " ); + vips_buf_appends( buf, ", " ); } - im_buf_appends( buf, ") " ); + vips_buf_appends( buf, ") " ); if( class->is_a ) - im_buf_appends( buf, "is_a " ); + vips_buf_appends( buf, "is_a " ); if( class->header ) - im_buf_appends( buf, "header " ); + vips_buf_appends( buf, "header " ); if( class->load ) - im_buf_appends( buf, "load " ); + vips_buf_appends( buf, "load " ); if( class->save ) - im_buf_appends( buf, "save " ); + vips_buf_appends( buf, "save " ); if( class->get_flags ) - im_buf_appends( buf, "get_flags " ); + vips_buf_appends( buf, "get_flags " ); } static void diff --git a/libsrc/format/im_jpeg2vips.c b/libsrc/format/im_jpeg2vips.c index f717cbd3..02a43fe8 100644 --- a/libsrc/format/im_jpeg2vips.c +++ b/libsrc/format/im_jpeg2vips.c @@ -247,16 +247,16 @@ static void attach_exif_entry( ExifEntry *entry, IMAGE *im ) { char name_text[256]; - im_buf_t name; + VipsBuf name; char value_text[256]; - im_buf_t value; + VipsBuf value; char exif_value[256]; - im_buf_init_static( &name, name_text, 256 ); - im_buf_init_static( &value, value_text, 256 ); + vips_buf_init_static( &name, name_text, 256 ); + vips_buf_init_static( &value, value_text, 256 ); - im_buf_appendf( &name, "exif-%s", exif_tag_get_title( entry->tag ) ); - im_buf_appendf( &value, "%s (%s, %d bytes)", + vips_buf_appendf( &name, "exif-%s", exif_tag_get_title( entry->tag ) ); + vips_buf_appendf( &value, "%s (%s, %d bytes)", exif_entry_get_value( entry, exif_value, 256 ), exif_format_get_name( entry->format ), entry->size ); @@ -264,7 +264,7 @@ attach_exif_entry( ExifEntry *entry, IMAGE *im ) /* Can't do anything sensible with the error return. */ (void) im_meta_set_string( im, - im_buf_all( &name ), im_buf_all( &value ) ); + vips_buf_all( &name ), vips_buf_all( &value ) ); } static void diff --git a/libsrc/format/im_magick2vips.c b/libsrc/format/im_magick2vips.c index 90e3db4b..5e96296b 100644 --- a/libsrc/format/im_magick2vips.c +++ b/libsrc/format/im_magick2vips.c @@ -338,11 +338,11 @@ parse_header( Read *read ) #error attributes enabled, but no access funcs found #endif char name_text[256]; - im_buf_t name; + VipsBuf name; - im_buf_init_static( &name, name_text, 256 ); - im_buf_appendf( &name, "magick-%s", attr->key ); - im_meta_set_string( im, im_buf_all( &name ), attr->value ); + vips_buf_init_static( &name, name_text, 256 ); + vips_buf_appendf( &name, "magick-%s", attr->key ); + im_meta_set_string( im, vips_buf_all( &name ), attr->value ); #ifdef DEBUG printf( "key = \"%s\", value = \"%s\"\n", diff --git a/libsrc/iofuncs/buf.c b/libsrc/iofuncs/buf.c index d0cf312c..21bd20b2 100644 --- a/libsrc/iofuncs/buf.c +++ b/libsrc/iofuncs/buf.c @@ -54,7 +54,7 @@ #define MAX_STRSIZE (16000) void -im_buf_rewind( im_buf_t *buf ) +vips_buf_rewind( VipsBuf *buf ) { buf->i = 0; buf->lasti = 0; @@ -67,64 +67,61 @@ im_buf_rewind( im_buf_t *buf ) /* Power on init. */ void -im_buf_init( im_buf_t *buf ) +vips_buf_init( VipsBuf *buf ) { buf->base = NULL; buf->mx = 0; buf->dynamic = FALSE; - im_buf_rewind( buf ); + vips_buf_rewind( buf ); } /* Reset to power on state ... only needed for dynamic bufs. */ void -im_buf_destroy( im_buf_t *buf ) +vips_buf_destroy( VipsBuf *buf ) { if( buf->dynamic ) { - if( buf->base ) { - im_free( buf->base ); - buf->base = NULL; - } + IM_FREE( buf->base ); } - im_buf_init( buf ); + vips_buf_init( buf ); } /* Set to a static string. */ void -im_buf_set_static( im_buf_t *buf, char *base, int mx ) +vips_buf_set_static( VipsBuf *buf, char *base, int mx ) { - assert( mx >= 4 ); + g_assert( mx >= 4 ); - im_buf_destroy( buf ); + vips_buf_destroy( buf ); buf->base = base; buf->mx = mx; buf->dynamic = FALSE; - im_buf_rewind( buf ); + vips_buf_rewind( buf ); } void -im_buf_init_static( im_buf_t *buf, char *base, int mx ) +vips_buf_init_static( VipsBuf *buf, char *base, int mx ) { - im_buf_init( buf ); - im_buf_set_static( buf, base, mx ); + vips_buf_init( buf ); + vips_buf_set_static( buf, base, mx ); } /* Set to a dynamic string. */ void -im_buf_set_dynamic( im_buf_t *buf, int mx ) +vips_buf_set_dynamic( VipsBuf *buf, int mx ) { - assert( mx >= 4 ); + g_assert( mx >= 4 ); if( buf->mx == mx && buf->dynamic ) /* No change? */ - im_buf_rewind( buf ); + vips_buf_rewind( buf ); else { - im_buf_destroy( buf ); + vips_buf_destroy( buf ); if( !(buf->base = IM_ARRAY( NULL, mx, char )) ) /* No error return, so just block writes. @@ -133,23 +130,23 @@ im_buf_set_dynamic( im_buf_t *buf, int mx ) else { buf->mx = mx; buf->dynamic = TRUE; - im_buf_rewind( buf ); + vips_buf_rewind( buf ); } } } void -im_buf_init_dynamic( im_buf_t *buf, int mx ) +vips_buf_init_dynamic( VipsBuf *buf, int mx ) { - im_buf_init( buf ); - im_buf_set_dynamic( buf, mx ); + vips_buf_init( buf ); + vips_buf_set_dynamic( buf, mx ); } /* Append at most sz chars from string to buf. sz < 0 means unlimited. - * FALSE on overflow. + * Error on overflow. */ gboolean -im_buf_appendns( im_buf_t *buf, const char *str, int sz ) +vips_buf_appendns( VipsBuf *buf, const char *str, int sz ) { int len; int n; @@ -191,41 +188,28 @@ im_buf_appendns( im_buf_t *buf, const char *str, int sz ) /* Append a string to a buf. Error on overflow. */ gboolean -im_buf_appends( im_buf_t *buf, const char *str ) +vips_buf_appends( VipsBuf *buf, const char *str ) { - return( im_buf_appendns( buf, str, -1 ) ); + return( vips_buf_appendns( buf, str, -1 ) ); } /* Append a character to a buf. Error on overflow. */ gboolean -im_buf_appendc( im_buf_t *buf, char ch ) +vips_buf_appendc( VipsBuf *buf, char ch ) { char tiny[2]; tiny[0] = ch; tiny[1] = '\0'; - return( im_buf_appendns( buf, tiny, 1 ) ); + return( vips_buf_appendns( buf, tiny, 1 ) ); } -/* Append a double, non-localised. Useful for config files etc. - */ -gboolean -im_buf_appendg( im_buf_t *buf, double g ) -{ - char text[G_ASCII_DTOSTR_BUF_SIZE]; - - g_ascii_dtostr( text, sizeof( text ), g ); - - return( im_buf_appends( buf, text ) ); -} - - /* Swap the rightmost occurence of old for new. */ gboolean -im_buf_change( im_buf_t *buf, const char *old, const char *new ) +vips_buf_change( VipsBuf *buf, const char *old, const char *new ) { int olen = strlen( old ); int nlen = strlen( new ); @@ -243,7 +227,7 @@ im_buf_change( im_buf_t *buf, const char *old, const char *new ) for( i = buf->i - olen; i > 0; i-- ) if( im_isprefix( old, buf->base + i ) ) break; - assert( i >= 0 ); + g_assert( i >= 0 ); /* Move tail of buffer to make right-size space for new. */ @@ -258,75 +242,126 @@ im_buf_change( im_buf_t *buf, const char *old, const char *new ) return( TRUE ); } -/* Remove the last character. +/* Remove the last character, if it's ch. */ gboolean -im_buf_removec( im_buf_t *buf, char ch ) +vips_buf_removec( VipsBuf *buf, char ch ) { if( buf->full ) return( FALSE ); - if( buf->i <= 0 ) return( FALSE ); - buf->i -= 1; - assert( buf->base[buf->i] == ch ); + if( buf->base[buf->i - 1] == ch ) + buf->i -= 1; return( TRUE ); } -/* Append to a buf, args as printf. FALSE on overflow. +/* Append to a buf, args as printf. Error on overflow. */ gboolean -im_buf_appendf( im_buf_t *buf, const char *fmt, ... ) +vips_buf_appendf( VipsBuf *buf, const char *fmt, ... ) { - va_list ap; char str[MAX_STRSIZE]; + va_list ap; va_start( ap, fmt ); (void) im_vsnprintf( str, MAX_STRSIZE, fmt, ap ); va_end( ap ); - return( im_buf_appends( buf, str ) ); + return( vips_buf_appends( buf, str ) ); } /* Append to a buf, args as vprintf. Error on overflow. */ gboolean -im_buf_vappendf( im_buf_t *buf, const char *fmt, va_list ap ) +vips_buf_vappendf( VipsBuf *buf, const char *fmt, va_list ap ) { char str[MAX_STRSIZE]; (void) im_vsnprintf( str, MAX_STRSIZE, fmt, ap ); - return( im_buf_appends( buf, str ) ); + return( vips_buf_appends( buf, str ) ); +} + +/* Append a double, non-localised. Useful for config files etc. + */ +gboolean +vips_buf_appendg( VipsBuf *buf, double g ) +{ + char text[G_ASCII_DTOSTR_BUF_SIZE]; + + g_ascii_dtostr( text, sizeof( text ), g ); + + return( vips_buf_appends( buf, text ) ); +} + +/* Append a number ... if the number is -ve, add brackets. Needed for + * building function arguments. + */ +gboolean +vips_buf_appendd( VipsBuf *buf, int d ) +{ + if( d < 0 ) + return( vips_buf_appendf( buf, " (%d)", d ) ); + else + return( vips_buf_appendf( buf, " %d", d ) ); +} + +void +vips_buf_appendgv( VipsBuf *buf, GValue *value ) +{ + char *str_value; + + str_value = g_strdup_value_contents( value ); + vips_buf_appends( buf, str_value ); + g_free( str_value ); } /* Read all text from buffer. */ const char * -im_buf_all( im_buf_t *buf ) +vips_buf_all( VipsBuf *buf ) { buf->base[buf->i] = '\0'; return( buf->base ); } +/* Trim to just the first line (excluding "\n"). + */ +const char * +vips_buf_firstline( VipsBuf *buf ) +{ + char *p; + + if( (p = strchr( vips_buf_all( buf ), '\n' )) ) + *p = '\0'; + + return( vips_buf_all( buf ) ); +} + +/* Test for buffer empty. + */ gboolean -im_buf_isempty( im_buf_t *buf ) +vips_buf_is_empty( VipsBuf *buf ) { return( buf->i == 0 ); } +/* Test for buffer full. + */ gboolean -im_buf_isfull( im_buf_t *buf ) +vips_buf_is_full( VipsBuf *buf ) { return( buf->full ); } -/* Buffer length ... still need to do im_buf_all(). +/* VipsBuffer length ... still need to do vips_buf_all(). */ int -im_buf_len( im_buf_t *buf ) +vips_buf_len( VipsBuf *buf ) { return( buf->i ); } + diff --git a/libsrc/iofuncs/error.c b/libsrc/iofuncs/error.c index 4fd52eb4..3a670fd0 100644 --- a/libsrc/iofuncs/error.c +++ b/libsrc/iofuncs/error.c @@ -70,8 +70,8 @@ */ #define IM_MAX_ERROR (10240) static char im_error_text[IM_MAX_ERROR] = ""; -static im_buf_t im_error_buf = - IM_BUF_STATIC( im_error_text, IM_MAX_ERROR ); +static VipsBuf im_error_buf = + VIPS_BUF_STATIC( im_error_text, IM_MAX_ERROR ); #define IM_DIAGNOSTICS "IM_DIAGNOSTICS" #define IM_WARNING "IM_WARNING" @@ -82,7 +82,7 @@ im_error_buffer( void ) const char *msg; g_mutex_lock( im__global_lock ); - msg = im_buf_all( &im_error_buf ); + msg = vips_buf_all( &im_error_buf ); g_mutex_unlock( im__global_lock ); return( msg ); @@ -92,9 +92,9 @@ void im_verror( const char *domain, const char *fmt, va_list ap ) { g_mutex_lock( im__global_lock ); - im_buf_appendf( &im_error_buf, "%s: ", domain ); - im_buf_vappendf( &im_error_buf, fmt, ap ); - im_buf_appends( &im_error_buf, "\n" ); + vips_buf_appendf( &im_error_buf, "%s: ", domain ); + vips_buf_vappendf( &im_error_buf, fmt, ap ); + vips_buf_appends( &im_error_buf, "\n" ); g_mutex_unlock( im__global_lock ); } @@ -154,7 +154,7 @@ void im_error_clear( void ) { g_mutex_lock( im__global_lock ); - im_buf_rewind( &im_error_buf ); + vips_buf_rewind( &im_error_buf ); g_mutex_unlock( im__global_lock ); } diff --git a/libsrc/iofuncs/im_updatehist.c b/libsrc/iofuncs/im_updatehist.c index db91cef7..20244c68 100644 --- a/libsrc/iofuncs/im_updatehist.c +++ b/libsrc/iofuncs/im_updatehist.c @@ -63,17 +63,17 @@ im_updatehist( IMAGE *out, const char *name, int argc, char *argv[] ) { int i; char txt[IM_MAX_LINE]; - im_buf_t buf; + VipsBuf buf; - im_buf_init_static( &buf, txt, IM_MAX_LINE ); - im_buf_appends( &buf, name ); + vips_buf_init_static( &buf, txt, IM_MAX_LINE ); + vips_buf_appends( &buf, name ); for( i = 0; i < argc; i++ ) { - im_buf_appends( &buf, " " ); - im_buf_appends( &buf, argv[i] ); + vips_buf_appends( &buf, " " ); + vips_buf_appends( &buf, argv[i] ); } - if( im_histlin( out, "%s", im_buf_all( &buf ) ) ) + if( im_histlin( out, "%s", vips_buf_all( &buf ) ) ) return( -1 ); return( 0 ); diff --git a/libsrc/iofuncs/object.c b/libsrc/iofuncs/object.c index 707fc42d..f40a9cab 100644 --- a/libsrc/iofuncs/object.c +++ b/libsrc/iofuncs/object.c @@ -92,25 +92,25 @@ vips_object_build( VipsObject *object ) void vips_object_print_class( VipsObjectClass *class ) { - im_buf_t buf; + VipsBuf buf; char str[1000]; - im_buf_init_static( &buf, str, 1000 ); + vips_buf_init_static( &buf, str, 1000 ); class->print_class( class, &buf ); - printf( "%s\n", im_buf_all( &buf ) ); + printf( "%s\n", vips_buf_all( &buf ) ); } void vips_object_print( VipsObject *object ) { VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object ); - im_buf_t buf; + VipsBuf buf; char str[1000]; vips_object_print_class( class ); - im_buf_init_static( &buf, str, 1000 ); + vips_buf_init_static( &buf, str, 1000 ); class->print( object, &buf ); - printf( "\n%s (%p)\n", im_buf_all( &buf ), object ); + printf( "\n%s (%p)\n", vips_buf_all( &buf ), object ); } /* Extra stuff we track for properties to do our argument handling. @@ -459,7 +459,7 @@ vips_object_set_property( GObject *gobject, str_value = g_strdup_value_contents( value ); printf( "vips_object_set_property: %s.%s = %s\n", - object->name, pspec->name, str_value ); + object->name, g_param_spec_get_name( pspec ), str_value ); g_free( str_value ); } #endif /*DEBUG*/ @@ -472,8 +472,10 @@ vips_object_set_property( GObject *gobject, */ if( argument_class->flags & VIPS_ARGUMENT_CONSTRUCT && object->constructed ) { - g_warning( "%s: can't assign '%s' after construct", G_STRLOC, - ((VipsArgument *) argument_class)->pspec->name); + g_warning( "%s: %s can't assign '%s' after construct", + G_STRLOC, + G_OBJECT_TYPE_NAME( gobject ), + g_param_spec_get_name( pspec ) ); return; } @@ -481,8 +483,10 @@ vips_object_set_property( GObject *gobject, */ 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 ); + g_warning( "%s: %s can only assign '%s' once", + G_STRLOC, + G_OBJECT_TYPE_NAME( gobject ), + g_param_spec_get_name( pspec ) ); return; } @@ -548,8 +552,10 @@ vips_object_set_property( GObject *gobject, *member = g_value_dup_boxed( value ); } else { - g_warning( "%s: '%s' has unimplemented type", G_STRLOC, - ((VipsArgument *) argument_class)->pspec->name ); + g_warning( "%s: %s unimplemented property type %s", + G_STRLOC, + G_OBJECT_TYPE_NAME( gobject ), + g_type_name( G_PARAM_SPEC_VALUE_TYPE( pspec ) ) ); } /* Note that it's now been set. @@ -612,6 +618,12 @@ vips_object_get_property( GObject *gobject, g_value_set_pointer( value, *member ); } + else if( G_IS_PARAM_SPEC_DOUBLE( pspec ) ) { + double *member = &G_STRUCT_MEMBER( double, object, + argument_class->offset ); + + g_value_set_double( value, *member ); + } else if( G_IS_PARAM_SPEC_BOXED( pspec ) ) { gpointer *member = &G_STRUCT_MEMBER( gpointer, object, argument_class->offset ); @@ -622,7 +634,10 @@ vips_object_get_property( GObject *gobject, g_value_set_boxed( value, *member ); } else { - g_warning( "%s: unimplemented property type", G_STRLOC ); + g_warning( "%s: %s unimplemented property type %s", + G_STRLOC, + G_OBJECT_TYPE_NAME( gobject ), + g_type_name( G_PARAM_SPEC_VALUE_TYPE( pspec ) ) ); } } @@ -639,7 +654,7 @@ vips_object_check_required( VipsObject *object, GParamSpec *pspec, !argument_instance->assigned ) { im_error( "check_required", _( "required construct param %s to %s %s not set" ), - pspec->name, + g_param_spec_get_name( pspec ), G_OBJECT_TYPE_NAME( object ), object->name ); *result = -1; @@ -679,20 +694,20 @@ vips_object_real_changed( VipsObject *object ) } static void -vips_object_real_print_class( VipsObjectClass *class, im_buf_t *buf ) +vips_object_real_print_class( VipsObjectClass *class, VipsBuf *buf ) { - im_buf_appendf( buf, "%s", G_OBJECT_CLASS_NAME( class ) ); + vips_buf_appendf( buf, "%s", G_OBJECT_CLASS_NAME( class ) ); if( class->nickname ) - im_buf_appendf( buf, " (%s)", class->nickname ); + vips_buf_appendf( buf, " (%s)", class->nickname ); if( class->description ) - im_buf_appendf( buf, ", %s", class->description ); + vips_buf_appendf( buf, ", %s", class->description ); } static void -vips_object_real_print( VipsObject *object, im_buf_t *buf ) +vips_object_real_print( VipsObject *object, VipsBuf *buf ) { if( object->name ) - im_buf_appendf( buf, "\"%s\"", object->name ); + vips_buf_appendf( buf, "\"%s\"", object->name ); } static void @@ -910,7 +925,7 @@ vips_object_new_from_string( const char *basename, const char *p ) if( token == VIPS_TOKEN_LEFT && vips_object_set_args( object, p ) ) { im_error( "object_new", "%s", - _( "bad object arguents" ) ); + _( "bad object arguments" ) ); g_object_unref( object ); return( NULL ); } @@ -924,3 +939,94 @@ vips_object_new_from_string( const char *basename, const char *p ) return( object ); } +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, + VipsArgumentClass *argument_class, + VipsArgumentInstance *argument_instance, + void *a, void *b ) +{ + VipsBuf *buf = (VipsBuf *) a; + gboolean *first = (gboolean *) b; + + if( (argument_class->flags & VIPS_ARGUMENT_REQUIRED) ) { + if( *first ) { + vips_buf_appends( buf, "(" ); + *first = FALSE; + } + else { + vips_buf_appends( buf, "," ); + } + + vips_object_print_arg( object, pspec, buf ); + } + + return( NULL ); +} + +static void * +vips_object_to_string_optional( VipsObject *object, + GParamSpec *pspec, + VipsArgumentClass *argument_class, + VipsArgumentInstance *argument_instance, + void *a, void *b ) +{ + VipsBuf *buf = (VipsBuf *) a; + gboolean *first = (gboolean *) b; + + if( !(argument_class->flags & VIPS_ARGUMENT_REQUIRED) && + argument_instance->assigned ) { + if( *first ) { + vips_buf_appends( buf, "(" ); + *first = FALSE; + } + else { + vips_buf_appends( buf, "," ); + } + + vips_buf_appends( buf, g_param_spec_get_name( pspec ) ); + vips_buf_appends( buf, "=" ); + vips_object_print_arg( object, pspec, buf ); + } + + return( NULL ); +} + +/* The inverse of vips_object_new_from_string(): turn an object into eg. + * "VipsInterpolateYafrsmooth(sharpening=12)". + */ +void +vips_object_to_string( VipsObject *object, VipsBuf *buf ) +{ + VipsObjectClass *object_class = VIPS_OBJECT_GET_CLASS( object ); + gboolean first; + + /* Nicknames are not guaranteed to be unique, so use the full type + * name. + */ + vips_buf_appends( buf, G_OBJECT_TYPE_NAME( object ) ); + first = TRUE; + (void) vips_argument_map( object, + vips_object_to_string_required, buf, &first ); + (void) vips_argument_map( object, + vips_object_to_string_optional, buf, &first ); + if( !first ) + vips_buf_appends( buf, ")" ); +} diff --git a/libsrc/mosaicing/mosaic1.c b/libsrc/mosaicing/mosaic1.c index a76926f9..0941350c 100644 --- a/libsrc/mosaicing/mosaic1.c +++ b/libsrc/mosaicing/mosaic1.c @@ -106,7 +106,7 @@ im__lrmerge1( IMAGE *ref, IMAGE *sec, IMAGE *out, { Transformation trn; IMAGE *t1 = im_open_local( out, "im_lrmosaic1:1", "p" ); - im_buf_t buf; + VipsBuf buf; char text[1024]; /* Scale, rotate and displace sec. @@ -123,18 +123,18 @@ im__lrmerge1( IMAGE *ref, IMAGE *sec, IMAGE *out, /* Note parameters in history file ... for global balance to pick up * later. */ - im_buf_init_static( &buf, text, 1024 ); - im_buf_appendf( &buf, "#LRROTSCALE <%s> <%s> <%s> <", + vips_buf_init_static( &buf, text, 1024 ); + vips_buf_appendf( &buf, "#LRROTSCALE <%s> <%s> <%s> <", ref->filename, sec->filename, out->filename ); - im_buf_appendg( &buf, a ); - im_buf_appendf( &buf, "> <" ); - im_buf_appendg( &buf, b ); - im_buf_appendf( &buf, "> <" ); - im_buf_appendg( &buf, dx ); - im_buf_appendf( &buf, "> <" ); - im_buf_appendg( &buf, dy ); - im_buf_appendf( &buf, "> <%d>", mwidth ); - if( im_histlin( out, "%s", im_buf_all( &buf ) ) ) + vips_buf_appendg( &buf, a ); + vips_buf_appendf( &buf, "> <" ); + vips_buf_appendg( &buf, b ); + vips_buf_appendf( &buf, "> <" ); + vips_buf_appendg( &buf, dx ); + vips_buf_appendf( &buf, "> <" ); + vips_buf_appendg( &buf, dy ); + vips_buf_appendf( &buf, "> <%d>", mwidth ); + if( im_histlin( out, "%s", vips_buf_all( &buf ) ) ) return( -1 ); return( 0 ); @@ -148,7 +148,7 @@ im__tbmerge1( IMAGE *ref, IMAGE *sec, IMAGE *out, { Transformation trn; IMAGE *t1 = im_open_local( out, "im_lrmosaic1:2", "p" ); - im_buf_t buf; + VipsBuf buf; char text[1024]; /* Scale, rotate and displace sec. @@ -165,18 +165,18 @@ im__tbmerge1( IMAGE *ref, IMAGE *sec, IMAGE *out, /* Note parameters in history file ... for global balance to pick up * later. */ - im_buf_init_static( &buf, text, 1024 ); - im_buf_appendf( &buf, "#TBROTSCALE <%s> <%s> <%s> <", + vips_buf_init_static( &buf, text, 1024 ); + vips_buf_appendf( &buf, "#TBROTSCALE <%s> <%s> <%s> <", ref->filename, sec->filename, out->filename ); - im_buf_appendg( &buf, a ); - im_buf_appendf( &buf, "> <" ); - im_buf_appendg( &buf, b ); - im_buf_appendf( &buf, "> <" ); - im_buf_appendg( &buf, dx ); - im_buf_appendf( &buf, "> <" ); - im_buf_appendg( &buf, dy ); - im_buf_appendf( &buf, "> <%d>", mwidth ); - if( im_histlin( out, "%s", im_buf_all( &buf ) ) ) + vips_buf_appendg( &buf, a ); + vips_buf_appendf( &buf, "> <" ); + vips_buf_appendg( &buf, b ); + vips_buf_appendf( &buf, "> <" ); + vips_buf_appendg( &buf, dx ); + vips_buf_appendf( &buf, "> <" ); + vips_buf_appendg( &buf, dy ); + vips_buf_appendf( &buf, "> <%d>", mwidth ); + if( im_histlin( out, "%s", vips_buf_all( &buf ) ) ) return( -1 ); return( 0 );