diff --git a/TODO b/TODO index 690c7012..261522eb 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,4 @@ + - need a thing to test overloads - test other arg types diff --git a/cplusplus/VImage.cc b/cplusplus/VImage.cc index c4909984..c3ec06d6 100644 --- a/cplusplus/VImage.cc +++ b/cplusplus/VImage.cc @@ -167,7 +167,6 @@ VOption::set( const char *name, VImage value ) pair->input = true; g_value_init( &pair->value, VIPS_TYPE_IMAGE ); - // we need to unbox g_value_set_object( &pair->value, value.get_image() ); options.push_back( pair ); @@ -185,6 +184,7 @@ VOption::set( const char *name, std::vector value ) pair->input = true; + g_value_init( &pair->value, VIPS_TYPE_ARRAY_DOUBLE ); vips_value_set_array_double( &pair->value, NULL, value.size() ); array = vips_value_get_array_double( &pair->value, NULL ); @@ -207,6 +207,7 @@ VOption::set( const char *name, std::vector value ) pair->input = true; + g_value_init( &pair->value, VIPS_TYPE_ARRAY_IMAGE ); vips_value_set_array_image( &pair->value, value.size() ); array = vips_value_get_array_image( &pair->value, NULL ); @@ -242,10 +243,9 @@ VOption::set( const char *name, bool *value ) { Pair *pair = new Pair( name ); - // note where we will write the VImage on success pair->input = false; pair->vbool = value; - g_value_init( &pair->value, G_TYPE_BOOLEAN ); + g_value_init( &pair->value, G_TYPE_BOOLEAN ); options.push_back( pair ); @@ -258,10 +258,9 @@ VOption::set( const char *name, int *value ) { Pair *pair = new Pair( name ); - // note where we will write the VImage on success pair->input = false; pair->vint = value; - g_value_init( &pair->value, G_TYPE_INT ); + g_value_init( &pair->value, G_TYPE_INT ); options.push_back( pair ); @@ -274,10 +273,9 @@ VOption::set( const char *name, double *value ) { Pair *pair = new Pair( name ); - // note where we will write the VImage on success pair->input = false; pair->vdouble = value; - g_value_init( &pair->value, G_TYPE_DOUBLE ); + g_value_init( &pair->value, G_TYPE_DOUBLE ); options.push_back( pair ); @@ -290,7 +288,6 @@ VOption::set( const char *name, VImage *value ) { Pair *pair = new Pair( name ); - // note where we will write the VImage on success pair->input = false; pair->vimage = value; g_value_init( &pair->value, VIPS_TYPE_IMAGE ); @@ -306,9 +303,9 @@ VOption::set( const char *name, std::vector *value ) { Pair *pair = new Pair( name ); - // note where we will write the VImage on success pair->input = false; pair->vvector = value; + g_value_init( &pair->value, VIPS_TYPE_ARRAY_DOUBLE ); options.push_back( pair ); @@ -323,6 +320,7 @@ VOption::set( const char *name, VipsBlob **value ) pair->input = false; pair->vblob = value; + g_value_init( &pair->value, VIPS_TYPE_BLOB ); options.push_back( pair ); @@ -340,8 +338,7 @@ VOption::set_operation( VipsOperation *operation ) #ifdef DEBUG printf( "set_operation: " ); vips_object_print_name( VIPS_OBJECT( operation ) ); - char *str_value = - g_strdup_value_contents( &(*i)->value ); + char *str_value = g_strdup_value_contents( &(*i)->value ); printf( ".%s = %s\n", (*i)->name, str_value ); g_free( str_value ); #endif /*DEBUG*/ @@ -351,7 +348,7 @@ VOption::set_operation( VipsOperation *operation ) } } -// walk the options and do any processing needed for output objects +// walk the options and fetch any requested outputs void VOption::get_operation( VipsOperation *operation ) { @@ -360,20 +357,22 @@ VOption::get_operation( VipsOperation *operation ) for( i = options.begin(); i != options.end(); i++ ) if( not (*i)->input ) { const char *name = (*i)->name; - GValue *value = &(*i)->value; g_object_get_property( G_OBJECT( operation ), - name, value ); + name, &(*i)->value ); #ifdef DEBUG printf( "get_operation: " ); vips_object_print_name( VIPS_OBJECT( operation ) ); - char *str_value = g_strdup_value_contents( value ); + char *str_value = g_strdup_value_contents( + &(*i)->value ); printf( ".%s = %s\n", name, str_value ); g_free( str_value ); #endif /*DEBUG*/ + GValue *value = &(*i)->value; GType type = G_VALUE_TYPE( value ); + if( type == VIPS_TYPE_IMAGE ) { // rebox object VipsImage *image = VIPS_IMAGE( diff --git a/cplusplus/examples/test_overloads.cc b/cplusplus/examples/test_overloads.cc index ed108601..357a53c2 100644 --- a/cplusplus/examples/test_overloads.cc +++ b/cplusplus/examples/test_overloads.cc @@ -11,6 +11,31 @@ using namespace vips8; +template +C test_add( T left, T right ) +{ + return( left + right ); +} + +std::vector +get_pixel( VImage x, int x, int y ) +{ + VImage pixel = x.extract_area( x, y, 1, 1 ); + std::vector split = pixel.bandsplit() + std::vector values( split.bands() ); + + for( int i = 0; i < split.bands(); i++ ) + values[i] = split.avg(); + + return( values ); +} + +void +test_binary +{ + +} + int main( int argc, char **argv ) { @@ -47,46 +72,5 @@ main( int argc, char **argv ) printf( "avg = %g\n", avg ); } -{ - VImage in = VImage::new_from_file( argv[1], - VImage::option()->set( "access", VIPS_ACCESS_SEQUENTIAL_UNBUFFERED ) ); - - VImage out = in.embed( 10, 10, 1000, 1000, - VImage::option()->set( "extend", VIPS_EXTEND_COPY ) ); - - out.write_to_file( "embed.jpg" ); -} - -{ - VImage in = VImage::new_from_file( argv[1], - VImage::option()->set( "access", VIPS_ACCESS_SEQUENTIAL_UNBUFFERED ) ); - double a[] = { 1.0, 2.0, 3.0 }; - double b[] = { 4.0, 5.0, 6.0 }; - - std::vector avec( a, a + VIPS_NUMBER( a ) ); - std::vector bvec( b, b + VIPS_NUMBER( b ) ); - - VImage out = in.linear( avec, bvec ); - - out.write_to_file( "linear.jpg" ); -} - -{ - VImage in = VImage::new_from_file( argv[1], - VImage::option()->set( "access", VIPS_ACCESS_SEQUENTIAL_UNBUFFERED ) ); - VImage out = in.linear( 1, 2 ); - - out.write_to_file( "linear1.jpg" ); -} - -{ - VImage in = VImage::new_from_file( argv[1] ); - VImage out = in.new_from_image( 128 ); - - out.write_to_file( "const.jpg" ); -} - - vips_shutdown(); - return( 0 ); } diff --git a/cplusplus/examples/try.cc b/cplusplus/examples/try.cc index ed108601..78ee40cb 100644 --- a/cplusplus/examples/try.cc +++ b/cplusplus/examples/try.cc @@ -52,7 +52,8 @@ main( int argc, char **argv ) VImage::option()->set( "access", VIPS_ACCESS_SEQUENTIAL_UNBUFFERED ) ); VImage out = in.embed( 10, 10, 1000, 1000, - VImage::option()->set( "extend", VIPS_EXTEND_COPY ) ); + VImage::option()->set( "extend", VIPS_EXTEND_BACKGROUND )-> + set( "background", 128 ) ); out.write_to_file( "embed.jpg" ); } diff --git a/cplusplus/include/vips/VImage8.h b/cplusplus/include/vips/VImage8.h index fb400833..1c8f72d8 100644 --- a/cplusplus/include/vips/VImage8.h +++ b/cplusplus/include/vips/VImage8.h @@ -34,6 +34,8 @@ #include #include +#include + #include VIPS_NAMESPACE_START @@ -169,38 +171,28 @@ private: struct Pair { const char *name; - // the thing we pass to VipsOperation - GValue value; + // the thing we pass to and from our caller + GValue value; // an input or output parameter ... we guess the direction // from the arg to set() bool input; + // the pointer we write output values to union { - // we need to box and unbox VImage ... keep a pointer - // to the VImage from C++ here - VImage *vimage; - - // output double - double *vdouble; - - // output int - int *vint; - - // output doublearray - std::vector *vvector; - - // output Blob - VipsBlob **vblob; - - // output bool bool *vbool; + int *vint; + double *vdouble; + VImage *vimage; + std::vector *vvector; + VipsBlob **vblob; }; Pair( const char *name ) : name( name ), input( false ), vimage( 0 ) { - G_VALUE_TYPE( &value ) = 0; + // argh = {0} won't work wil vanilla C++ + memset( &value, 0, sizeof( GValue ) ); } ~Pair() diff --git a/libvips/iofuncs/type.c b/libvips/iofuncs/type.c index 8a7011c1..e64e7879 100644 --- a/libvips/iofuncs/type.c +++ b/libvips/iofuncs/type.c @@ -749,8 +749,8 @@ transform_g_string_array_int( const GValue *src_value, GValue *dest_value ) g_free( str ); - vips_value_set_array( dest_value, n, G_TYPE_INT, sizeof( int ) ); - array = (int *) vips_value_get_array( dest_value, NULL, NULL, NULL ); + vips_value_set_array_int( dest_value, NULL, n ); + array = vips_value_get_array_int( dest_value, NULL ); str = g_value_dup_string( src_value ); @@ -773,6 +773,28 @@ transform_g_string_array_int( const GValue *src_value, GValue *dest_value ) g_free( str ); } +/* We need a arrayint, we have an int, make a one-element array. + */ +static void +transform_int_array_int( const GValue *src_value, GValue *dest_value ) +{ + int *array; + + vips_value_set_array_int( dest_value, NULL, 1 ); + array = vips_value_get_array_int( dest_value, NULL ); + array[0] = g_value_get_int( src_value ); +} + +static void +transform_double_array_int( const GValue *src_value, GValue *dest_value ) +{ + int *array; + + vips_value_set_array_int( dest_value, NULL, 1 ); + array = vips_value_get_array_int( dest_value, NULL ); + array[0] = g_value_get_double( src_value ); +} + GType vips_array_int_get_type( void ) { @@ -786,6 +808,10 @@ vips_array_int_get_type( void ) transform_array_int_g_string ); g_value_register_transform_func( G_TYPE_STRING, type, transform_g_string_array_int ); + g_value_register_transform_func( G_TYPE_INT, type, + transform_int_array_int ); + g_value_register_transform_func( G_TYPE_DOUBLE, type, + transform_double_array_int ); } return( type ); @@ -902,8 +928,7 @@ transform_g_string_array_double( const GValue *src_value, GValue *dest_value ) double *array; /* Walk the string to get the number of elements. - * We need a copy of the string since we insert \0 during - * scan. + * We need a copy of the string, since we insert \0 during scan. * * We can't allow ',' as a separator since some locales use it as a * decimal point. @@ -916,8 +941,8 @@ transform_g_string_array_double( const GValue *src_value, GValue *dest_value ) g_free( str ); - vips_value_set_array( dest_value, n, G_TYPE_DOUBLE, sizeof( double ) ); - array = (double *) vips_value_get_array( dest_value, NULL, NULL, NULL ); + vips_value_set_array_double( dest_value, NULL, n ); + array = vips_value_get_array_double( dest_value, NULL ); str = g_value_dup_string( src_value ); @@ -928,8 +953,7 @@ transform_g_string_array_double( const GValue *src_value, GValue *dest_value ) */ vips_error( "vipstype", _( "unable to convert \"%s\" to float" ), p ); - vips_value_set_array( dest_value, - 0, G_TYPE_DOUBLE, sizeof( double ) ); + vips_value_set_array_double( dest_value, NULL, 0 ); g_free( str ); return; } @@ -940,6 +964,28 @@ transform_g_string_array_double( const GValue *src_value, GValue *dest_value ) g_free( str ); } +/* We need a arraydouble, we have a double, make a one-element array. + */ +static void +transform_double_array_double( const GValue *src_value, GValue *dest_value ) +{ + double *array; + + vips_value_set_array_double( dest_value, NULL, 1 ); + array = vips_value_get_array_double( dest_value, NULL ); + array[0] = g_value_get_double( src_value ); +} + +static void +transform_int_array_double( const GValue *src_value, GValue *dest_value ) +{ + double *array; + + vips_value_set_array_double( dest_value, NULL, 1 ); + array = vips_value_get_array_double( dest_value, NULL ); + array[0] = g_value_get_int( src_value ); +} + GType vips_array_double_get_type( void ) { @@ -953,6 +999,10 @@ vips_array_double_get_type( void ) transform_array_double_g_string ); g_value_register_transform_func( G_TYPE_STRING, type, transform_g_string_array_double ); + g_value_register_transform_func( G_TYPE_DOUBLE, type, + transform_double_array_double ); + g_value_register_transform_func( G_TYPE_INT, type, + transform_int_array_double ); } return( type ); @@ -1388,7 +1438,6 @@ vips_value_get_array_int( const GValue *value, int *n ) void vips_value_set_array_int( GValue *value, const int *array, int n ) { - g_value_init( value, VIPS_TYPE_ARRAY_INT ); vips_value_set_array( value, n, G_TYPE_INT, sizeof( int ) ); if( array ) { @@ -1430,7 +1479,6 @@ vips_value_get_array_double( const GValue *value, int *n ) void vips_value_set_array_double( GValue *value, const double *array, int n ) { - g_value_init( value, VIPS_TYPE_ARRAY_DOUBLE ); vips_value_set_array( value, n, G_TYPE_DOUBLE, sizeof( double ) ); if( array ) {