added im_INTERPOLATE

This commit is contained in:
John Cupitt 2009-01-13 16:54:22 +00:00
parent 66c81c36bf
commit f476da4e38
12 changed files with 330 additions and 198 deletions

View File

@ -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()

21
TODO
View File

@ -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 ?

View File

@ -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*/

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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",

View File

@ -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 );
}

View File

@ -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 );
}

View File

@ -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 );

View File

@ -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, ")" );
}

View File

@ -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 );