add more type conversions

so we automatically do int and double -> doublevec and intvec
This commit is contained in:
John Cupitt 2014-10-31 18:11:26 +00:00
parent 35bcd4eaa0
commit 2a992375fe
6 changed files with 112 additions and 87 deletions

1
TODO
View File

@ -1,3 +1,4 @@
- need a thing to test overloads
- test other arg types

View File

@ -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<double> 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<VImage> 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<double> *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(

View File

@ -11,6 +11,31 @@
using namespace vips8;
template <typename A, typename B, typename C>
C test_add( T left, T right )
{
return( left + right );
}
std::vector<double>
get_pixel( VImage x, int x, int y )
{
VImage pixel = x.extract_area( x, y, 1, 1 );
std::vector<VImage> split = pixel.bandsplit()
std::vector<double> 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<double> avec( a, a + VIPS_NUMBER( a ) );
std::vector<double> 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 );
}

View File

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

View File

@ -34,6 +34,8 @@
#include <complex>
#include <vector>
#include <string.h>
#include <vips/vips.h>
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<double> *vvector;
// output Blob
VipsBlob **vblob;
// output bool
bool *vbool;
int *vint;
double *vdouble;
VImage *vimage;
std::vector<double> *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()

View File

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