insert.c compiles

and we have VipsArea as a public struct for array arguments
This commit is contained in:
John Cupitt 2011-10-22 13:10:47 +01:00
parent 210668edc2
commit 2c4cbedc70
10 changed files with 121 additions and 110 deletions

View File

@ -1,7 +1,8 @@
20/8/11 started 7.27.0
- version bump for new dev cycle
- im_subtract(), im_avg(), im_min(), im_minpos(), im_copy(), im_embed(),
im_flophor(), im_flipver() redone as classes
im_flophor(), im_flipver(), im_insert(), im_insert_noexpand() redone as
classes
- added VIPS_ARGUMENT_APPEND to help control arg ordering
- generate has a 'stop' param to signal successful early termination
- added optional output args, eg. x/y for min
@ -22,6 +23,8 @@
- more VipsImage props
- added vips_image_write(), old one becomes vips_image_write_to_file()
- added vips_region_paint_pel()
- added VipsArea as a public struct
- added array members and arguments
12/10/11 started 7.26.6
- NOCACHE was not being set correctly on OS X causing performance

9
TODO
View File

@ -1,12 +1,3 @@
- what should the member of VipsInsert be? what does get_member do for boxed?
just the pointer I guess
does that mean VipsInsert sees an Area?
yes, vips_object_set_property() writes g_value_dup_boxed() to the member
argh do we have to expose Area now?

View File

@ -6,6 +6,7 @@ libconversion_la_SOURCES = \
copy.c \
embed.c \
flip.c \
insert.c \
conver_dispatch.c \
im_black.c \
im_c2amph.c \

View File

@ -105,9 +105,11 @@ vips_conversion_operation_init( void )
extern GType vips_copy_get_type( void );
extern GType vips_embed_get_type( void );
extern GType vips_flip_get_type( void );
extern GType vips_insert_get_type( void );
vips_copy_get_type();
vips_embed_get_type();
vips_flip_get_type();
vips_insert_get_type();
}

View File

@ -120,7 +120,7 @@ typedef struct _VipsInsert {
int x;
int y;
gboolean expand;
GArray *background;
VipsArea *background;
/* Pixel we paint calculated from background.
*/
@ -147,7 +147,7 @@ G_DEFINE_TYPE( VipsInsert, vips_insert, VIPS_TYPE_CONVERSION );
static int
vips_insert_just_one( VipsRegion *or, VipsRegion *ir, int x, int y )
{
VIpsRect need;
VipsRect need;
/* Find the part of pos we need.
*/
@ -204,43 +204,38 @@ vips_insert_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop )
Rect ovl;
/* Ask for input we need.
*/
if( vips_region_prepare( ir, r ) )
return( -1 );
/* Does the rect we have been asked for fall entirely inside the
* sub-image?
*/
if( vips_rect_includesrect( &ins->rsub, &or->valid ) )
if( vips_rect_includesrect( &insert->rsub, &or->valid ) )
return( vips_insert_just_one( or, ir[1],
ins->rsub.left, ins->rsub.top ) );
insert->rsub.left, insert->rsub.top ) );
/* Does it fall entirely inside the main, and not at all inside the
* sub?
*/
vips_rect_intersectrect( &or->valid, &ins->rsub, &ovl );
if( vips_rect_includesrect( &ins->rmain, &or->valid ) &&
vips_rect_intersectrect( &or->valid, &insert->rsub, &ovl );
if( vips_rect_includesrect( &insert->rmain, &or->valid ) &&
vips_rect_isempty( &ovl ) )
return( vips_insert_just_one( or, ir[0],
ins->rmain.left, ins->rmain.top ) );
insert->rmain.left, insert->rmain.top ) );
/* Output requires both (or neither) input. If it is not entirely
* inside both the main and the sub, then there is going to be some
* background.
*/
if( !(vips_rect_includesrect( &ins->rsub, &or->valid ) &&
vips_rect_includesrect( &ins->rmain, &or->valid )) )
if( !(vips_rect_includesrect( &insert->rsub, &or->valid ) &&
vips_rect_includesrect( &insert->rmain, &or->valid )) )
vips_region_paint_pel( or, r, insert->ink );
/* Paste from main.
*/
if( vips_insert_paste_region( or, ir[0], &ins->rmain ) )
if( vips_insert_paste_region( or, ir[0], &insert->rmain ) )
return( -1 );
/* Paste from sub.
*/
if( vips_insert_paste_region( or, ir[1], &ins->rsub ) )
if( vips_insert_paste_region( or, ir[1], &insert->rsub ) )
return( -1 );
return( 0 );
@ -250,7 +245,7 @@ vips_insert_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop )
* valid.
*/
PEL *
vips__vector_to_ink( const char *domain, VipsImage *im, int n, double *vec )
vips__vector_to_ink( const char *domain, VipsImage *im, double *vec, int n )
{
VipsImage *t[3];
double *zeros;
@ -258,7 +253,7 @@ vips__vector_to_ink( const char *domain, VipsImage *im, int n, double *vec )
if( vips_check_vector( domain, n, im ) )
return( NULL );
if( vips_open_local_array( im, t, 3, domain, "t" ) ||
if( vips_image_new_array( VIPS_OBJECT( im ), t, 3 ) ||
!(zeros = VIPS_ARRAY( im, n, double )) )
return( NULL );
for( i = 0; i < n; i++ )
@ -285,7 +280,6 @@ vips_insert_build( VipsObject *object )
VipsImage *t[4];
VipsImage **arry;
int i;
/* Check args.
*/
@ -301,9 +295,11 @@ vips_insert_build( VipsObject *object )
if( vips_image_pio_input( insert->main ) ||
vips_image_pio_input( insert->sub ) ||
vips_image_pio_output( conversion->output ) ||
vips_check_bands_1orn( domain, in1, in2 ) ||
vips_check_coding_known( domain, in1 ) ||
vips_check_coding_same( domain, in1, in2 ) )
vips_check_bands_1orn( "VipsInsert",
insert->main, insert->sub ) ||
vips_check_coding_known( "VipsInsert", insert->main ) ||
vips_check_coding_same( "VipsInsert",
insert->main, insert->sub ) )
return( -1 );
if( vips_image_new_array( object, t, 4 ) )
@ -312,7 +308,7 @@ vips_insert_build( VipsObject *object )
/* Cast our input images up to a common format and bands.
*/
if( vips__formatalike( insert->main, insert->sub, t[0], t[1] ) ||
vips__bandalike( domain, t[0], t[1], t[2], t[3] ) )
vips__bandalike( "VipsInsert", t[0], t[1], t[2], t[3] ) )
return( -1 );
insert->main_processed = t[2];
insert->sub_processed = t[3];
@ -322,7 +318,7 @@ vips_insert_build( VipsObject *object )
if( vips_image_copy_fields_array( conversion->output, arry ) )
return( -1 );
vips_demand_hint_array( arithmetic->output,
vips_demand_hint_array( conversion->output,
VIPS_DEMAND_STYLE_SMALLTILE, arry );
/* Calculate geometry.
@ -331,8 +327,8 @@ vips_insert_build( VipsObject *object )
insert->rmain.top = 0;
insert->rmain.width = insert->main_processed->Xsize;
insert->rmain.height = insert->main_processed->Ysize;
insert->rsub.left = x;
insert->rsub.top = y;
insert->rsub.left = insert->x;
insert->rsub.top = insert->y;
insert->rsub.width = insert->sub_processed->Xsize;
insert->rsub.height = insert->sub_processed->Ysize;
@ -352,14 +348,14 @@ vips_insert_build( VipsObject *object )
insert->rout.top = 0;
}
else
ins->rout = ins->rmain;
insert->rout = insert->rmain;
conversion->output->Xsize = insert->rout.width;
conversion->output->Ysize = insert->rout.height;
if( !(insert->ink = vips__vector_to_ink(
"VipsInsert", conversion->output,
insert->background, insert->n )) )
insert->background->data, insert->background->n )) )
return( -1 );
if( vips_image_generate( conversion->output,
@ -440,7 +436,7 @@ vips_insert( VipsImage *main, VipsImage *sub, VipsImage **out,
va_list ap;
int result;
va_start( ap, out );
va_start( ap, y );
result = vips_call_split( "insert", ap, main, sub, out, x, y );
va_end( ap );

View File

@ -77,6 +77,41 @@ extern "C" {
*/
#define VIPS_META_RESOLUTION_UNIT "resolution-unit"
/* Also used for eg. vips_local() and friends.
*/
typedef int (*VipsCallbackFn)( void *a, void *b );
/* A ref-counted area of memory.
*/
typedef struct _VipsArea {
void *data;
size_t length; /* 0 if not known */
/* If this area represents an array, the number of elements in the
* array. Equal to length / sizeof(element).
*/
int n;
/*< private >*/
/* Reference count.
*/
int count;
/* Things like ICC profiles need their own free functions.
*/
VipsCallbackFn free_fn;
/* If we are holding an array (for exmaple, an array of double), the
* GType of the elements and their size. 0 for not known.
*
* n is always length / sizeof_type, we keep it as a member for
* convenience.
*/
GType type;
size_t sizeof_type;
} VipsArea;
int vips_format_sizeof( VipsBandFormat format );
int vips_image_get_width( const VipsImage *image );
@ -150,10 +185,6 @@ size_t vips_ref_string_get_length( const GValue *value );
* The #GType for an #vips_blob.
*/
/* Also used for eg. vips_local() and friends.
*/
typedef int (*VipsCallbackFn)( void *a, void *b );
#define VIPS_TYPE_BLOB (vips_blob_get_type())
GType vips_blob_get_type( void );
void *vips_blob_get( const GValue *value, size_t *length );
@ -168,8 +199,8 @@ int vips_blob_set( GValue *value, VipsCallbackFn free_fn,
#define VIPS_TYPE_ARRAY_DOUBLE (vips_array_double_get_type())
GType vips_array_double_get_type( void );
double *vips_array_double_get( const GValue *value, int *length );
int vips_array_double_set( GValue *value, double *array, int length );
double *vips_array_double_get( const GValue *value, int *n );
int vips_array_double_set( GValue *value, const double *array, int n );
void vips_image_set_area( VipsImage *image,
const char *field, VipsCallbackFn free_fn, void *data );

View File

@ -115,6 +115,22 @@ int vips__write_header_bytes( VipsImage *im, unsigned char *to );
extern GMutex *vips__global_lock;
int vips__formatalike_vec( VipsImage **in, VipsImage **out, int n );
int vips__formatalike( VipsImage *in1, VipsImage *in2,
VipsImage *out1, VipsImage *out2 );
int vips__sizealike_vec( VipsImage **in, VipsImage **out, int n );
int vips__sizealike( VipsImage *in1, VipsImage *in2,
VipsImage *out1, VipsImage *out2 );
int vips__bandup( const char *domain, VipsImage *in, VipsImage *out, int n );
int vips__bandalike_vec( const char *domain,
VipsImage **in, VipsImage **out, int n );
int vips__bandalike( const char *domain,
VipsImage *in1, VipsImage *in2, VipsImage *out1, VipsImage *out2 );
void im__format_init( void );
void im__tiff_register( void );

View File

@ -147,7 +147,7 @@ extern int _vips__argument_id;
}
#define VIPS_ARG_BOXED( CLASS, NAME, PRIORITY, LONG, DESC, \
FLAGS, OFFSET, TYPE ) \
FLAGS, OFFSET, TYPE ) { \
GParamSpec *pspec; \
\
pspec = g_param_spec_boxed( (NAME), (LONG), (DESC), \

View File

@ -1014,24 +1014,6 @@ transform_save_string_double( const GValue *src_value, GValue *dest_value )
g_ascii_strtod( vips_save_string_get( src_value ), NULL ) );
}
/* A GType for a ref-counted area of memory.
*/
typedef struct _Area {
int count;
size_t length; /* 0 if not known */
void *data;
VipsCallbackFn free_fn;
/* If we are holding an array (for exmaple, an array of double), the
* GType of elements and their size. Calculate the number of elements
* in the array from this.
*/
GType type;
size_t sizeof_type;
} Area;
#ifdef DEBUG
static int area_number = 0;
#endif /*DEBUG*/
@ -1039,12 +1021,12 @@ static int area_number = 0;
/* An area of mem with a free func. (eg. \0-terminated string, or a struct).
* Inital count == 1, so _unref() after attaching somewhere.
*/
static Area *
static VipsArea *
area_new( VipsCallbackFn free_fn, void *data )
{
Area *area;
VipsArea *area;
if( !(area = VIPS_NEW( NULL, Area )) )
if( !(area = VIPS_NEW( NULL, VipsArea )) )
return( NULL );
area->count = 1;
area->length = 0;
@ -1065,10 +1047,10 @@ area_new( VipsCallbackFn free_fn, void *data )
/* An area of mem with a free func and a length (some sort of binary object,
* like an ICC profile).
*/
static Area *
static VipsArea *
area_new_blob( VipsCallbackFn free_fn, void *blob, size_t blob_length )
{
Area *area;
VipsArea *area;
if( !(area = area_new( free_fn, blob )) )
return( NULL );
@ -1077,8 +1059,8 @@ area_new_blob( VipsCallbackFn free_fn, void *blob, size_t blob_length )
return( area );
}
static Area *
area_copy( Area *area )
static VipsArea *
area_copy( VipsArea *area )
{
g_assert( area->count >= 0 );
@ -1092,7 +1074,7 @@ area_copy( Area *area )
}
static void
area_unref( Area *area )
area_unref( VipsArea *area )
{
g_assert( area->count > 0 );
@ -1119,7 +1101,7 @@ area_unref( Area *area )
static void
transform_area_g_string( const GValue *src_value, GValue *dest_value )
{
Area *area;
VipsArea *area;
char buf[256];
area = g_value_get_boxed( src_value );
@ -1151,7 +1133,7 @@ vips_area_get_type( void )
static int
value_set_area( VipsCallbackFn free_fn, void *data, GValue *value )
{
Area *area;
VipsArea *area;
if( !(area = area_new( free_fn, data )) )
return( -1 );
@ -1168,7 +1150,7 @@ value_set_area( VipsCallbackFn free_fn, void *data, GValue *value )
static void *
value_get_area_data( const GValue *value )
{
Area *area;
VipsArea *area;
area = g_value_get_boxed( value );
@ -1178,7 +1160,7 @@ value_get_area_data( const GValue *value )
static size_t
value_get_area_length( const GValue *value )
{
Area *area;
VipsArea *area;
area = g_value_get_boxed( value );
@ -1300,7 +1282,7 @@ vips_ref_string_get_length( const GValue *value )
int
vips_ref_string_set( GValue *value, const char *str )
{
Area *area;
VipsArea *area;
char *str_copy;
g_assert( G_VALUE_TYPE( value ) == VIPS_TYPE_REF_STRING );
@ -1387,7 +1369,7 @@ vips_ref_string_get_type( void )
void *
vips_blob_get( const GValue *value, size_t *length )
{
Area *area;
VipsArea *area;
/* Can't check value type, because we may get called from
* vips_blob_get_type().
@ -1487,7 +1469,7 @@ int
vips_blob_set( GValue *value,
VipsCallbackFn free_fn, void *data, size_t length )
{
Area *area;
VipsArea *area;
g_assert( G_VALUE_TYPE( value ) == VIPS_TYPE_BLOB );
@ -1502,15 +1484,16 @@ vips_blob_set( GValue *value,
/* An area which holds a copy of an array of GType.
*/
static Area *
static VipsArea *
area_new_array( GType type, size_t sizeof_type, int n )
{
Area *area;
VipsArea *area;
void *array;
array = g_malloc( n * sizeof_type );
if( !(area = area_new( g_free, array )) )
if( !(area = area_new( (VipsCallbackFn) g_free, array )) )
return( NULL );
area->n = n;
area->length = n * sizeof_type;
area->type = G_TYPE_DOUBLE;
area->sizeof_type = sizeof_type;
@ -1524,9 +1507,7 @@ area_new_array( GType type, size_t sizeof_type, int n )
static int
vips_array_set( GValue *value, GType type, size_t sizeof_type, int n )
{
Area *area;
g_assert( G_VALUE_TYPE( value ) == VIPS_TYPE_ARRAY );
VipsArea *area;
if( !(area = area_new_array( type, sizeof_type, n )) )
return( -1 );
@ -1538,17 +1519,17 @@ vips_array_set( GValue *value, GType type, size_t sizeof_type, int n )
static void *
vips_array_get( const GValue *value,
int *length, GType *type, size_t *sizeof_type )
int *n, GType *type, size_t *sizeof_type )
{
Area *area;
VipsArea *area;
/* Can't check value type, because we may get called from
* vips_*_get_type().
*/
area = g_value_get_boxed( value );
if( length )
*length = area->length;
if( n )
*n = area->n;
if( type )
*type = area->type;
if( sizeof_type )
@ -1561,20 +1542,19 @@ static void
transform_array_g_string( const GValue *src_value, GValue *dest_value )
{
char *array;
int length;
int n;
GType type;
size_t sizeof_type;
int n;
char txt[1024];
VipsBuf buf = VIPS_BUF_STATIC( txt );
int i;
array = (char *) vips_array_get( src_value,
&length, &type, &sizeof_type );
n = length / sizeof_type;
&n, &type, &sizeof_type );
for( i = 0; i < n; i++ ) {
GValue value = { 0, };
char *str;
if( i > 0 )
vips_buf_appends( &buf, ", " );
@ -1609,8 +1589,8 @@ vips_array_double_get_type( void )
if( !type ) {
type = g_boxed_type_register_static( "vips_array_double",
(GBoxedCopyFunc) area_ref,
(GBoxedFreeFunc) area_copy );
(GBoxedCopyFunc) area_copy,
(GBoxedFreeFunc) area_unref );
g_value_register_transform_func( type, G_TYPE_STRING,
transform_array_g_string );
}
@ -1633,15 +1613,7 @@ vips_array_double_get_type( void )
double *
vips_array_double_get( const GValue *value, int *n )
{
double *array;
size_t &length;
array = vips_array_get( value, &length, NULL, NULL );
if( n )
*n = length / sizeof( double );
return( array );
return( vips_array_get( value, n, NULL, NULL ) );
}
/**
@ -1657,12 +1629,11 @@ vips_array_double_get( const GValue *value, int *n )
* Returns: 0 on success, -1 otherwise.
*/
int
vips_array_double_set( const GValue *value, double *array, int n )
vips_array_double_set( GValue *value, const double *array, int n )
{
double *array_copy;
vips_array_set( value,
G_TYPE_DOUBLE, sizeof( double ), n * sizeof( double ) );
vips_array_set( value, G_TYPE_DOUBLE, sizeof( double ), n );
array_copy = vips_array_double_get( value, NULL );
memcpy( array_copy, array, n * sizeof( double ) );
@ -1879,7 +1850,7 @@ vips_image_get_string( VipsImage *image, const char *field, char **out )
{
int i;
GValue value_copy = { 0 };
Area *area;
VipsArea *area;
for( i = 0; i < VIPS_NUMBER( string_field ); i++ )
if( strcmp( field, string_field[i].field ) == 0 ) {

View File

@ -886,8 +886,8 @@ vips_region_paint_pel( VipsRegion *reg, VipsRect *r, PEL *ink )
for( x = 0; x < ovl.width; x++ ) {
/* Faster than memcpy() for about n<20.
*/
for( j = 0; j < ps; j++ )
q[j] = ink[j];
for( z = 0; z < ps; z++ )
q[z] = ink[z];
q += ps;
}