vips array types are more binding-friendly

this all works now:

```python
from gi.repository import Vips

a = Vips.ArrayDouble.new([1,2,3])
a.get()

a = Vips.ArrayInt.new([1,2,3])
a.get()

a = Vips.ArrayImage.new([c, d, e])
a.get()
```
This commit is contained in:
John Cupitt 2014-08-31 10:41:53 +01:00
parent 42dac9209a
commit a370e5003e
16 changed files with 279 additions and 146 deletions

View File

@ -3,6 +3,7 @@
- fix pngload with libpng >1.6.1 - fix pngload with libpng >1.6.1
- add vips_resize() - add vips_resize()
- return of vips_init(), but just for bindings - return of vips_init(), but just for bindings
- revised type.c to make it more binding-friendly
21/8/14 started 7.40.7 21/8/14 started 7.40.7
- width and height were swapped in matlab load - width and height were swapped in matlab load

42
TODO
View File

@ -2,24 +2,50 @@
- add more constructors - add more constructors
- could import like this:
from gi.repository import Vips
import vips_additions
ie. make it a module, not a package, and make it clear that it
modifies Vips rather than adding anything itself
- need the filename splitter - need the filename splitter
- need more writers - need more writers
- need GBoxed - GBoxed
seems to be almost there! can we write generic array index?
we have: vips_area_index_array( VipsArea *area, int i, GValue *value )
a = Vips.array_double_new([1,2,3]) ie. get element i from array out as a GValue? do we need a
switch for all possible types?
but no VipsArrayDouble type, strangely from gi.repository import GLib
from gi.repository import GObject
VipsThing is there? odd
seems be have spotted that it's just an alias for VipsArea and gint_type = GObject.GType.from_name('gint')
elided the type a = GObject.Value(gint_type)
a.set_value(12)
a.get_value()
12
a.unset()
>>> a
<Value (invalid) None>
a.init(gint_type)
a = GObject.Value(None)
>>> a
<Value (invalid) None>
b = Vips.ArrayDouble.new([1,2,3])
b.area.index_array(1)
segv
- can we pick the vipsthumbnail int shrink factor more intelligently? - can we pick the vipsthumbnail int shrink factor more intelligently?

View File

@ -57,6 +57,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <math.h> #include <math.h>
#include <vips/vips.h> #include <vips/vips.h>
@ -192,8 +193,8 @@ vips_getpoint( VipsImage *in, double **vector, int *n, int x, int y, ... )
{ {
va_list ap; va_list ap;
VipsArrayDouble *out_array; VipsArrayDouble *out_array;
VipsArea *area;
int result; int result;
int i;
va_start( ap, y ); va_start( ap, y );
result = vips_call_split( "getpoint", ap, in, &out_array, x, y ); result = vips_call_split( "getpoint", ap, in, &out_array, x, y );
@ -202,13 +203,14 @@ vips_getpoint( VipsImage *in, double **vector, int *n, int x, int y, ... )
if( !result ) if( !result )
return( -1 ); return( -1 );
if( !(*vector = VIPS_ARRAY( NULL, out_array->n, double )) ) { area = VIPS_AREA( out_array );
vips_area_unref( (VipsArea *) out_array ); *vector = VIPS_ARRAY( NULL, area->n, double );
if( !*vector ) {
vips_area_unref( area );
return( -1 ); return( -1 );
} }
for( i = 0; i < out_array->n; i++ ) memcpy( *vector, area->data, area->n * area->sizeof_type );
(*vector)[i] = ((double *) out_array->data)[i]; *n = area->n;
*n = out_array->n;
return( 0 ); return( 0 );
} }

View File

@ -130,8 +130,8 @@ vips_bandjoin_build( VipsObject *object )
VipsBandjoin *bandjoin = (VipsBandjoin *) object; VipsBandjoin *bandjoin = (VipsBandjoin *) object;
if( bandjoin->in ) { if( bandjoin->in ) {
bandary->in = bandjoin->in->data; bandary->in = VIPS_AREA( bandjoin->in )->data;
bandary->n = bandjoin->in->n; bandary->n = VIPS_AREA( bandjoin->in )->n;
if( bandary->n == 1 ) if( bandary->n == 1 )
return( vips_bandary_copy( bandary ) ); return( vips_bandary_copy( bandary ) );

View File

@ -422,7 +422,8 @@ vips_insert_build( VipsObject *object )
if( !(insert->ink = vips__vector_to_ink( if( !(insert->ink = vips__vector_to_ink(
class->nickname, conversion->out, class->nickname, conversion->out,
insert->background->data, NULL, insert->background->n )) ) (double *) VIPS_ARRAY_ADDR( insert->background, 0 ), NULL,
VIPS_AREA( insert->background )->n )) )
return( -1 ); return( -1 );
if( vips_image_generate( conversion->out, if( vips_image_generate( conversion->out,
@ -503,9 +504,7 @@ vips_insert_init( VipsInsert *insert )
{ {
/* Init our instance fields. /* Init our instance fields.
*/ */
insert->background = insert->background = vips_array_double_newv( 1, 0.0 );
vips_area_new_array( G_TYPE_DOUBLE, sizeof( double ), 1 );
((double *) (insert->background->data))[0] = 0.0;
} }
/** /**

View File

@ -3963,19 +3963,13 @@ im_maxpos_vec( VipsImage *im, int *xpos, int *ypos, double *maxima, int n )
NULL ) ) NULL ) )
return( -1 ); return( -1 );
memcpy( xpos, memcpy( xpos, VIPS_ARRAY_ADDR( x_array, 0 ), n * sizeof( int ) );
vips_area_get_data( x_array, NULL, NULL, NULL, NULL ), memcpy( ypos, VIPS_ARRAY_ADDR( y_array, 0 ), n * sizeof( int ) );
n * sizeof( int ) ); memcpy( maxima, VIPS_ARRAY_ADDR( out_array, 0 ), n * sizeof( double ) );
memcpy( ypos,
vips_area_get_data( y_array, NULL, NULL, NULL, NULL ),
n * sizeof( int ) );
memcpy( maxima,
vips_area_get_data( out_array, NULL, NULL, NULL, NULL ),
n * sizeof( double ) );
vips_area_unref( (VipsArea *) out_array ); vips_area_unref( VIPS_AREA( out_array ) );
vips_area_unref( (VipsArea *) x_array ); vips_area_unref( VIPS_AREA( x_array ) );
vips_area_unref( (VipsArea *) y_array ); vips_area_unref( VIPS_AREA( y_array ) );
return( 0 ); return( 0 );
} }
@ -3996,19 +3990,13 @@ im_minpos_vec( VipsImage *im, int *xpos, int *ypos, double *minima, int n )
NULL ) ) NULL ) )
return( -1 ); return( -1 );
memcpy( xpos, memcpy( xpos, VIPS_ARRAY_ADDR( x_array, 0 ), n * sizeof( int ) );
vips_area_get_data( x_array, NULL, NULL, NULL, NULL ), memcpy( ypos, VIPS_ARRAY_ADDR( y_array, 0 ), n * sizeof( int ) );
n * sizeof( int ) ); memcpy( minima, VIPS_ARRAY_ADDR( out_array, 0 ), n * sizeof( double ) );
memcpy( ypos,
vips_area_get_data( y_array, NULL, NULL, NULL, NULL ),
n * sizeof( int ) );
memcpy( minima,
vips_area_get_data( out_array, NULL, NULL, NULL, NULL ),
n * sizeof( double ) );
vips_area_unref( (VipsArea *) out_array ); vips_area_unref( VIPS_AREA( out_array ) );
vips_area_unref( (VipsArea *) x_array ); vips_area_unref( VIPS_AREA( x_array ) );
vips_area_unref( (VipsArea *) y_array ); vips_area_unref( VIPS_AREA( y_array ) );
return( 0 ); return( 0 );
} }

View File

@ -519,7 +519,8 @@ vips_draw_flood_build( VipsObject *object )
*/ */
if( !(flood.edge = vips__vector_to_ink( class->nickname, if( !(flood.edge = vips__vector_to_ink( class->nickname,
flood.test, flood.test,
drawink->ink->data, NULL, drawink->ink->n )) ) VIPS_ARRAY_ADDR( drawink->ink, 0 ), NULL,
VIPS_AREA( drawink->ink )->n )) )
return( -1 ); return( -1 );
flood_all( &flood, drawflood->x, drawflood->y ); flood_all( &flood, drawflood->x, drawflood->y );

View File

@ -87,6 +87,7 @@ vips_draw_rect_build( VipsObject *object )
{ {
VipsDraw *draw = VIPS_DRAW( object ); VipsDraw *draw = VIPS_DRAW( object );
VipsDrawink *drawink = VIPS_DRAWINK( object ); VipsDrawink *drawink = VIPS_DRAWINK( object );
VipsArea *ink = VIPS_AREA( drawink->ink );
VipsDrawRect *draw_rect = (VipsDrawRect *) object; VipsDrawRect *draw_rect = (VipsDrawRect *) object;
int left = draw_rect->left; int left = draw_rect->left;
int top = draw_rect->top; int top = draw_rect->top;
@ -106,16 +107,16 @@ vips_draw_rect_build( VipsObject *object )
width > 2 && width > 2 &&
height > 2 ) height > 2 )
return( vips_draw_rect( draw->image, return( vips_draw_rect( draw->image,
drawink->ink->data, drawink->ink->n, ink->data, ink->n,
left, top, width, 1, NULL ) || left, top, width, 1, NULL ) ||
vips_draw_rect( draw->image, vips_draw_rect( draw->image,
drawink->ink->data, drawink->ink->n, ink->data, ink->n,
left + width - 1, top, 1, height, NULL ) || left + width - 1, top, 1, height, NULL ) ||
vips_draw_rect( draw->image, vips_draw_rect( draw->image,
drawink->ink->data, drawink->ink->n, ink->data, ink->n,
left, top + height - 1, width, 1, NULL ) || left, top + height - 1, width, 1, NULL ) ||
vips_draw_rect( draw->image, vips_draw_rect( draw->image,
drawink->ink->data, drawink->ink->n, ink->data, ink->n,
left, top, 1, height, NULL ) ); left, top, 1, height, NULL ) );
image.left = 0; image.left = 0;

View File

@ -66,7 +66,8 @@ vips_drawink_build( VipsObject *object )
if( drawink->ink && if( drawink->ink &&
!(drawink->pixel_ink = vips__vector_to_ink( class->nickname, !(drawink->pixel_ink = vips__vector_to_ink( class->nickname,
draw->image, draw->image,
drawink->ink->data, NULL, drawink->ink->n )) ) VIPS_ARRAY_ADDR( drawink->ink, 0 ), NULL,
VIPS_AREA( drawink->ink )->n )) )
return( -1 ); return( -1 );
return( 0 ); return( 0 );
@ -97,9 +98,7 @@ vips_drawink_class_init( VipsDrawinkClass *class )
static void static void
vips_drawink_init( VipsDrawink *drawink ) vips_drawink_init( VipsDrawink *drawink )
{ {
drawink->ink = drawink->ink = vips_array_double_newv( 1, 0.0 );
vips_area_new_array( G_TYPE_DOUBLE, sizeof( double ), 1 );
((double *) (drawink->ink->data))[0] = 0;
} }
/* Fill a scanline between points x1 and x2 inclusive. x1 < x2. /* Fill a scanline between points x1 and x2 inclusive. x1 < x2.

View File

@ -1588,7 +1588,7 @@ vips_foreign_save_dz_build( VipsObject *object )
background = vips_array_double_newv( 1, 255.0 ); background = vips_array_double_newv( 1, 255.0 );
g_object_set( object, "background", background, NULL ); g_object_set( object, "background", background, NULL );
vips_area_unref( background ); vips_area_unref( VIPS_AREA( background ) );
} }
if( dz->overlap >= dz->tile_size ) { if( dz->overlap >= dz->tile_size ) {

View File

@ -461,6 +461,8 @@ int vips_system( const char *cmd_format, ... )
/* Defined in type.c, but declared here since they use VipsImage. /* Defined in type.c, but declared here since they use VipsImage.
*/ */
VipsArrayImage *vips_array_image_new( const VipsImage **array, int n );
VipsImage **vips_array_image_get( VipsArrayImage *array, int *n );
VipsImage **vips_value_get_array_image( const GValue *value, int *n ); VipsImage **vips_value_get_array_image( const GValue *value, int *n );
int vips_value_set_array_image( GValue *value, VipsImage **array, int n ); int vips_value_set_array_image( GValue *value, VipsImage **array, int n );

View File

@ -52,7 +52,6 @@ typedef struct _VipsThing {
#define VIPS_TYPE_THING (vips_thing_get_type()) #define VIPS_TYPE_THING (vips_thing_get_type())
GType vips_thing_get_type( void ); GType vips_thing_get_type( void );
VipsThing *vips_thing_new( int i ); VipsThing *vips_thing_new( int i );
int vips_thing_get_i( VipsThing *thing );
/* A ref-counted area of memory. Can hold arrays of things as well. /* A ref-counted area of memory. Can hold arrays of things as well.
*/ */
@ -97,16 +96,31 @@ VipsArea *vips_area_new_blob( VipsCallbackFn free_fn,
void *data, size_t length ); void *data, size_t length );
VipsArea *vips_area_new_array( GType type, size_t sizeof_type, int n ); VipsArea *vips_area_new_array( GType type, size_t sizeof_type, int n );
VipsArea *vips_area_new_array_object( int n ); VipsArea *vips_area_new_array_object( int n );
void *vips_area_get_data( VipsArea *area, void *vips_area_get_data( VipsArea *area,
size_t *length, int *n, GType *type, size_t *sizeof_type ); size_t *length, int *n, GType *type, size_t *sizeof_type );
#ifdef VIPS_DEBUG
#define VIPS_ARRAY_ADDR( X, I ) \
(((I) >= 0 && (I) < VIPS_AREA( X )->n) ? \
(VIPS_AREA( X )->data + VIPS_AREA( X )->sizeof_type * (I)) : \
(fprintf( stderr, \
"VIPS_ARRAY_ADDR: index out of bounds, " \
"file \"%s\", line %d\n" \
"(index %d should have been within [0,%d])\n", \
__FILE__, __LINE__, \
(I), VIPS_AREA( X )->n ), NULL ))
#else /*!VIPS_DEBUG*/
#define VIPS_ARRAY_ADDR( X, I ) \
(VIPS_AREA( X )->data + VIPS_AREA( X )->sizeof_type * (I))
#endif /*VIPS_DEBUG*/
/** /**
* VIPS_TYPE_AREA: * VIPS_TYPE_AREA:
* *
* The #GType for a #VipsArea. * The #GType for a #VipsArea.
*/ */
#define VIPS_TYPE_AREA (vips_area_get_type()) #define VIPS_TYPE_AREA (vips_area_get_type())
#define VIPS_AREA( X ) ((VipsArea *) (X))
GType vips_area_get_type( void ); GType vips_area_get_type( void );
/** /**
@ -139,9 +153,14 @@ GType vips_blob_get_type( void );
* The #GType for a #VipsArrayDouble. * The #GType for a #VipsArrayDouble.
*/ */
#define VIPS_TYPE_ARRAY_DOUBLE (vips_array_double_get_type()) #define VIPS_TYPE_ARRAY_DOUBLE (vips_array_double_get_type())
typedef VipsArea VipsArrayDouble;
typedef struct _VipsArrayDouble {
VipsArea area;
} VipsArrayDouble;
VipsArrayDouble *vips_array_double_new( const double *array, int n ); VipsArrayDouble *vips_array_double_new( const double *array, int n );
VipsArrayDouble *vips_array_double_newv( int n, ... ); VipsArrayDouble *vips_array_double_newv( int n, ... );
double *vips_array_double_get( VipsArrayDouble *array, int *n );
GType vips_array_double_get_type( void ); GType vips_array_double_get_type( void );
/** /**
@ -150,9 +169,14 @@ GType vips_array_double_get_type( void );
* The #GType for a #VipsArrayInt. * The #GType for a #VipsArrayInt.
*/ */
#define VIPS_TYPE_ARRAY_INT (vips_array_int_get_type()) #define VIPS_TYPE_ARRAY_INT (vips_array_int_get_type())
typedef VipsArea VipsArrayInt;
typedef struct _VipsArrayInt {
VipsArea area;
} VipsArrayInt;
VipsArrayInt *vips_array_int_new( const int *array, int n ); VipsArrayInt *vips_array_int_new( const int *array, int n );
VipsArrayInt *vips_array_int_newv( int n, ... ); VipsArrayInt *vips_array_int_newv( int n, ... );
int *vips_array_int_get( VipsArrayInt *array, int *n );
GType vips_array_int_get_type( void ); GType vips_array_int_get_type( void );
/** /**
@ -161,7 +185,11 @@ GType vips_array_int_get_type( void );
* The #GType for a #VipsArrayImage. * The #GType for a #VipsArrayImage.
*/ */
#define VIPS_TYPE_ARRAY_IMAGE (vips_array_image_get_type()) #define VIPS_TYPE_ARRAY_IMAGE (vips_array_image_get_type())
typedef VipsArea VipsArrayImage;
typedef struct _VipsArrayImage {
VipsArea area;
} VipsArrayImage;
GType vips_array_image_get_type( void ); GType vips_array_image_get_type( void );
void vips_value_set_area( GValue *value, VipsCallbackFn free_fn, void *data ); void vips_value_set_area( GValue *value, VipsCallbackFn free_fn, void *data );
@ -193,8 +221,9 @@ int vips_value_set_array_int( GValue *value, const int *array, int n );
GObject **vips_value_get_array_object( const GValue *value, int *n ); GObject **vips_value_get_array_object( const GValue *value, int *n );
int vips_value_set_array_object( GValue *value, int n ); int vips_value_set_array_object( GValue *value, int n );
/* See also image.h, that has vips_value_get_array_image() and /* See also image.h, that has vips_array_image_get(), vips_array_image_new(),
* vips_value_set_array_image(). They need to be declared after VipsImage. * vips_value_get_array_image() and vips_value_set_array_image(). They need
* to be declared after VipsImage.
*/ */
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -97,7 +97,7 @@ vips_system_dispose( GObject *gobject )
if( system->in_name ) { if( system->in_name ) {
int i; int i;
for( i = 0; i < system->in->n; i++ ) { for( i = 0; i < VIPS_AREA( system->in )->n; i++ ) {
g_unlink( system->in_name[i] ); g_unlink( system->in_name[i] );
VIPS_FREE( system->in_name[i] ); VIPS_FREE( system->in_name[i] );
} }
@ -134,13 +134,13 @@ vips_system_build( VipsObject *object )
if( system->in ) { if( system->in ) {
char *in_format = system->in_format ? char *in_format = system->in_format ?
system->in_format : "%s.tif"; system->in_format : "%s.tif";
VipsImage **in = (VipsImage **) system->in->data; int n;
VipsImage **in = vips_array_image_get( system->in, &n );
if( !(system->in_name = VIPS_ARRAY( object, if( !(system->in_name = VIPS_ARRAY( object, n, char * )) )
system->in->n, char * )) )
return( -1 ); return( -1 );
memset( system->in_name, 0, system->in->n * sizeof( char * ) ); memset( system->in_name, 0, n * sizeof( char * ) );
for( i = 0; i < system->in->n; i++ ) { for( i = 0; i < n; i++ ) {
if( !(system->in_name[i] = if( !(system->in_name[i] =
vips__temp_name( in_format )) ) vips__temp_name( in_format )) )
return( -1 ); return( -1 );
@ -158,7 +158,7 @@ vips_system_build( VipsObject *object )
vips_strncpy( cmd, system->cmd_format, VIPS_PATH_MAX ); vips_strncpy( cmd, system->cmd_format, VIPS_PATH_MAX );
if( system->in ) if( system->in )
for( i = 0; i < system->in->n; i++ ) for( i = 0; i < VIPS_AREA( system->in )->n; i++ )
if( vips__substitute( class->nickname, if( vips__substitute( class->nickname,
cmd, VIPS_PATH_MAX, system->in_name[i] ) ) cmd, VIPS_PATH_MAX, system->in_name[i] ) )
return( -1 ); return( -1 );

View File

@ -66,6 +66,16 @@
*/ */
/* A very simple boxed type for testing. Just an int. /* A very simple boxed type for testing. Just an int.
*
* You can manipulate this thing from Python (for example) with:
*
* from gi.repository import Vips
* a = Vips.Thing.new(12)
* print a.i
* b = a
* del a
* print b.i
* del b
*/ */
/** /**
@ -107,14 +117,6 @@ vips_thing_free( VipsThing *thing )
g_free( thing ); g_free( thing );
} }
int
vips_thing_get_i( VipsThing *thing )
{
printf( "vips_thing_get_i: %d %p\n", thing->i, thing );
return( thing->i );
}
/* /*
* glib-2.26+ only * glib-2.26+ only
@ -599,6 +601,84 @@ vips_blob_get_type( void )
return( type ); return( type );
} }
/**
* vips_array_int_new:
* @array: (array length=n): array of int
* @n: number of ints
*
* Allocate a new array of ints and copy @array into it. Free with
* vips_area_unref().
*
* See also: #VipsArea.
*
* Returns: (transfer full): A new #VipsArrayInt.
*/
VipsArrayInt *
vips_array_int_new( const int *array, int n )
{
VipsArea *area;
int *array_copy;
area = vips_area_new_array( G_TYPE_INT, sizeof( int ), n );
array_copy = vips_area_get_data( area, NULL, NULL, NULL, NULL );
memcpy( array_copy, array, n * sizeof( int ) );
return( (VipsArrayInt *) area );
}
/**
* vips_array_int_newv:
* @n: number of ints
* @...: list of int arguments
*
* Allocate a new array of @n ints and copy @... into it. Free with
* vips_area_unref().
*
* See also: vips_array_int_new()
*
* Returns: (transfer full): A new #VipsArrayInt.
*/
VipsArrayInt *
vips_array_int_newv( int n, ... )
{
va_list ap;
VipsArea *area;
int *array;
int i;
area = vips_area_new_array( G_TYPE_INT, sizeof( int ), n );
array = vips_area_get_data( area, NULL, NULL, NULL, NULL );
va_start( ap, n );
for( i = 0; i < n; i++ )
array[i] = va_arg( ap, int );
va_end( ap );
return( (VipsArrayInt *) area );
}
/**
* vips_array_int_get:
* @array: the #VipsArrayInt to fetch from
* @n: length of array
*
* Fetch an int array from a #VipsArrayInt. Useful for language bindings.
*
* Returns: (array length=n): (transfer none): array of int
*/
int *
vips_array_int_get( VipsArrayInt *array, int *n )
{
VipsArea *area = VIPS_AREA( array );
g_assert( area->type == G_TYPE_INT );
if( n )
*n = area->n;
return( (int *) VIPS_ARRAY_ADDR( array, 0 ) );
}
static void static void
transform_array_int_g_string( const GValue *src_value, GValue *dest_value ) transform_array_int_g_string( const GValue *src_value, GValue *dest_value )
{ {
@ -710,15 +790,7 @@ vips_array_double_new( const double *array, int n )
array_copy = vips_area_get_data( area, NULL, NULL, NULL, NULL ); array_copy = vips_area_get_data( area, NULL, NULL, NULL, NULL );
memcpy( array_copy, array, n * sizeof( double ) ); memcpy( array_copy, array, n * sizeof( double ) );
{ return( (VipsArrayDouble *) area );
int i;
printf( "vips_array_double_new: %p\n", area );
for( i = 0; i < n; i++ )
printf( "\t%d) %g\n", i, array[i] );
}
return( area );
} }
/** /**
@ -749,7 +821,29 @@ vips_array_double_newv( int n, ... )
array[i] = va_arg( ap, double ); array[i] = va_arg( ap, double );
va_end( ap ); va_end( ap );
return( area ); return( (VipsArrayDouble *) area );
}
/**
* vips_array_double_get:
* @array: the #VipsArrayDouble to fetch from
* @n: length of array
*
* Fetch a double array from a #VipsArrayDouble. Useful for language bindings.
*
* Returns: (array length=n): (transfer none): array of double
*/
double *
vips_array_double_get( VipsArrayDouble *array, int *n )
{
VipsArea *area = VIPS_AREA( array );
g_assert( area->type == G_TYPE_DOUBLE );
if( n )
*n = area->n;
return( VIPS_ARRAY_ADDR( array, 0 ) );
} }
static void static void
@ -879,6 +973,53 @@ transform_g_string_array_image( const GValue *src_value, GValue *dest_value )
g_free( str ); g_free( str );
} }
/**
* vips_array_image_new:
* @array: (array length=n): array of #VipsImage
* @n: number of images
*
* Allocate a new array of images and copy @array into it. Free with
* vips_area_unref().
*
* See also: #VipsArea.
*
* Returns: (transfer full): A new #VipsArrayImage.
*/
VipsArrayImage *
vips_array_image_new( const VipsImage **array, int n )
{
VipsArea *area;
VipsImage *array_copy;
area = vips_area_new_array( G_TYPE_DOUBLE, sizeof( double ), n );
array_copy = vips_area_get_data( area, NULL, NULL, NULL, NULL );
memcpy( array_copy, array, n * sizeof( double ) );
return( (VipsArrayImage *) area );
}
/**
* vips_array_image_get:
* @array: the #VipsArrayImage to fetch from
* @n: length of array
*
* Fetch an image array from a #VipsArrayImage. Useful for language bindings.
*
* Returns: (array length=n): (transfer none): array of #VipsImage
*/
VipsImage **
vips_array_image_get( VipsArrayImage *array, int *n )
{
VipsArea *area = VIPS_AREA( array );
g_assert( area->type == VIPS_TYPE_IMAGE );
if( n )
*n = area->n;
return( (VipsImage **) VIPS_ARRAY_ADDR( array, 0 ) );
}
GType GType
vips_array_image_get_type( void ) vips_array_image_get_type( void )
{ {
@ -1144,62 +1285,6 @@ vips_value_get_array( const GValue *value,
return( area->data ); return( area->data );
} }
/**
* vips_array_int_new:
* @array: (array length=n): array of int
* @n: number of ints
*
* Allocate a new array of ints and copy @array into it. Free with
* vips_area_unref().
*
* See also: #VipsArea.
*
* Returns: (transfer full): A new #VipsArrayInt.
*/
VipsArrayInt *
vips_array_int_new( const int *array, int n )
{
VipsArea *area;
int *array_copy;
area = vips_area_new_array( G_TYPE_INT, sizeof( int ), n );
array_copy = vips_area_get_data( area, NULL, NULL, NULL, NULL );
memcpy( array_copy, array, n * sizeof( int ) );
return( area );
}
/**
* vips_array_int_newv:
* @n: number of ints
* @...: list of int arguments
*
* Allocate a new array of @n ints and copy @... into it. Free with
* vips_area_unref().
*
* See also: vips_array_int_new()
*
* Returns: (transfer full): A new #VipsArrayInt.
*/
VipsArrayInt *
vips_array_int_newv( int n, ... )
{
va_list ap;
VipsArea *area;
int *array;
int i;
area = vips_area_new_array( G_TYPE_INT, sizeof( int ), n );
array = vips_area_get_data( area, NULL, NULL, NULL, NULL );
va_start( ap, n );
for( i = 0; i < n; i++ )
array[i] = va_arg( ap, int );
va_end( ap );
return( area );
}
/** /**
* vips_value_get_array_int: * vips_value_get_array_int:
* @value: %GValue to get from * @value: %GValue to get from

View File

@ -173,10 +173,10 @@ vips_match_build( VipsObject *object )
"ody", dy, "ody", dy,
"oarea", oarea, "oarea", oarea,
NULL ) ) { NULL ) ) {
vips_area_unref( oarea ); vips_area_unref( VIPS_AREA( oarea ) );
return( -1 ); return( -1 );
} }
vips_area_unref( oarea ); vips_area_unref( VIPS_AREA( oarea ) );
if( vips_image_write( x, match->out ) ) { if( vips_image_write( x, match->out ) ) {
g_object_unref( x ); g_object_unref( x );

View File

@ -27,8 +27,8 @@ out = a.add(b)
print 'out =', out print 'out =', out
ones = Vips.array_double_new([1]) ones = Vips.ArrayDouble.new([1])
twos = Vips.array_double_new([2]) twos = Vips.ArrayDouble.new([2])
out = out.linear(ones, twos) out = out.linear(ones, twos)