im_inserplace() hacking

This commit is contained in:
John Cupitt 2010-08-25 11:15:36 +00:00
parent 38dde13826
commit d215ef4a33
8 changed files with 192 additions and 124 deletions

View File

@ -15,6 +15,8 @@
benchmark
- rewritten im_circle as im_draw_circle, im_circle moved to almostdeprecated
- special-case 3x3 makss in im_conv() for a 20% speedup
- add IM_TYPE_RW flag for im__rw_image, helps nip2 auto-wrap inplace ops
- im_insertplace() casts and bandalikes
12/5/10 started 7.22.2
- the conditional image of ifthenelse can be any format, a (!=0) is added if

4
TODO
View File

@ -1,6 +1,8 @@
- rename most of the inplace ops as im_draw_line() etc.
nip2 should be able to call RW image ops by copying them, see
- use im__inplace_base() in more places
- nip2 should be able to call RW image ops by copying them, see
im_draw_circle_copy()
- use D65 in cmsCreateLab4Profile() ? not sure

View File

@ -53,6 +53,7 @@ int im_check_mono( const char *domain, IMAGE *im );
int im_check_bands_1or3( const char *domain, IMAGE *in );
int im_check_bands( const char *domain, IMAGE *im, int bands );
int im_check_bands_1orn( const char *domain, IMAGE *im1, IMAGE *im2 );
int im_check_bands_1orn_unary( const char *domain, IMAGE *im, int n );
int im_check_bands_same( const char *domain, IMAGE *im1, IMAGE *im2 );
int im_check_bandno( const char *domain, IMAGE *im, int bandno );
int im_check_int( const char *domain, IMAGE *im );

View File

@ -75,7 +75,8 @@ typedef void *im_object;
typedef enum {
IM_TYPE_NONE = 0, /* No flags */
IM_TYPE_OUTPUT = 0x1, /* Output/input object */
IM_TYPE_ARG = 0x2 /* Uses a str arg in construction */
IM_TYPE_ARG = 0x2, /* Uses a str arg in construction */
IM_TYPE_RW = 0x4 /* Read-write */
} im_type_flags;
/* Initialise, destroy and write objects. The "str" argument to the

View File

@ -274,6 +274,12 @@ int im_convsep_f_raw( IMAGE *in, IMAGE *out, DOUBLEMASK *mask );
int im__fmaskcir( IMAGE *out, VipsMaskType flag, va_list ap );
/* inplace
*/
IMAGE *im__inplace_base( const char *domain,
IMAGE *main, IMAGE *sub, IMAGE *out );
#ifdef __cplusplus
}
#endif /*__cplusplus*/

View File

@ -19,6 +19,8 @@
* 6/3/10
* - don't im_invalidate() after paint, this now needs to be at a higher
* level
* 25/8/10
* - cast and bandalike sub to main
*/
/*
@ -57,11 +59,40 @@
#include <string.h>
#include <vips/vips.h>
#include <vips/internal.h>
#ifdef WITH_DMALLOC
#include <dmalloc.h>
#endif /*WITH_DMALLOC*/
/* The common part of most binary inplace operators.
*
* Unlike im__formatalike() and friends, we can only change one of the images,
* since the other is being updated.
*/
IMAGE *
im__inplace_base( const char *domain,
IMAGE *main, IMAGE *sub, IMAGE *out )
{
IMAGE *t[2];
if( im_rwcheck( main ) ||
im_pincheck( sub ) ||
im_check_coding_known( domain, main ) ||
im_check_coding_same( domain, main, sub ) ||
im_check_bands_1orn_unary( domain, sub, main->Bands ) )
return( NULL );
/* Cast sub to match main in bands and format.
*/
if( im_open_local_array( out, t, 2, domain, "p" ) ||
im__bandup( sub, t[0], main->Bands ) ||
im_clip2fmt( t[0], t[1], main->BandFmt ) )
return( NULL );
return( t[1] );
}
/**
* im_insertplace:
* @main: main image
@ -69,8 +100,10 @@
* @x: position to insert
* @y: position to insert
*
* Copy @sub into @main at position @x, @y. The two images must match in
* format, bands and coding.
* Copy @sub into @main at position @x, @y. The two images must have the same
* Coding. If @sub has 1 band, the bands will be duplicated to match the
* number of bands in @main. @sub will be converted to @main's format, see
* im_clip2fmt().
*
* This an inplace operation, so @main is changed. It does not thread and will
* not work well as part of a pipeline.
@ -86,16 +119,6 @@ im_insertplace( IMAGE *main, IMAGE *sub, int x, int y )
PEL *p, *q;
int z;
/* Check compatibility.
*/
if( im_rwcheck( main ) ||
im_incheck( sub ) ||
im_check_coding_known( "im_insertplace", main ) ||
im_check_coding_known( "im_insertplace", sub ) ||
im_check_format_same( "im_insertplace", main, sub ) ||
im_check_bands_same( "im_insertplace", main, sub ) )
return( -1 );
/* Make rects for main and sub and clip.
*/
br.left = 0;
@ -110,6 +133,11 @@ im_insertplace( IMAGE *main, IMAGE *sub, int x, int y )
if( im_rect_isempty( &clip ) )
return( 0 );
if( !(sub = im__inplace_base( "im_insertplace", main, sub, main )) ||
im_rwcheck( main ) ||
im_incheck( sub ) )
return( -1 );
/* Loop, memcpying sub to main.
*/
p = (PEL *) IM_IMAGE_ADDR( sub, clip.left - x, clip.top - y );

View File

@ -743,6 +743,32 @@ im_check_bands_1orn( const char *domain, IMAGE *im1, IMAGE *im2 )
return( 0 );
}
/**
* im_check_bands_1orn_unary:
* @domain: the originating domain for the error message
* @im1: image to check
* @n: number of bands, or 1
*
* Check that an image has 1 or @n bands. Handy for unary operations, cf.
* im_check_bands_1orn().
* If not, set an error message
* and return non-zero.
*
* See also: im_check_bands_1orn().
*
* Returns: 0 on OK, or -1 on error.
*/
int
im_check_bands_1orn_unary( const char *domain, IMAGE *im, int n )
{
if( im->Bands != 1 && im->Bands != n ) {
im_error( domain, _( "image must have 1 or %d bands" ), n );
return( -1 );
}
return( 0 );
}
/**
* im_check_noncomplex:
* @domain: the originating domain for the error message

View File

@ -5,6 +5,8 @@
* Modified:
* 21/5/07
* - any length vector (Tom)
* 23/8/10
* - add IM_TYPE_RW flag for im__rw_image
*/
/*
@ -87,21 +89,21 @@ input_display_init( im_object *obj, char *str )
/* Input display type.
*/
im_type_desc im__input_display = {
IM_TYPE_DISPLAY, /* Its a display */
0, /* No storage needed */
IM_TYPE_ARG, /* It requires a command-line arg */
input_display_init, /* Init function */
NULL /* Destroy function */
IM_TYPE_DISPLAY, /* It's a display */
0, /* No storage needed */
IM_TYPE_ARG, /* It requires a command-line arg */
input_display_init, /* Init function */
NULL /* Destroy function */
};
/* Output display type.
*/
im_type_desc im__output_display = {
IM_TYPE_DISPLAY, /* Its a display */
IM_TYPE_DISPLAY, /* It's a display */
sizeof( struct im_col_display ),/* Memory to allocate */
IM_TYPE_OUTPUT, /* Output object */
NULL, /* Init function */
NULL /* Destroy function */
IM_TYPE_OUTPUT, /* Output object */
NULL, /* Init function */
NULL /* Destroy function */
};
/* Init function for input images.
@ -117,11 +119,11 @@ input_image_init( im_object *obj, char *str )
/* Input image type.
*/
im_type_desc im__input_image = {
IM_TYPE_IMAGE, /* Its an image */
0, /* No storage needed */
IM_TYPE_ARG, /* It requires a command-line arg */
IM_TYPE_IMAGE, /* It's an image */
0, /* No storage needed */
IM_TYPE_ARG, /* It requires a command-line arg */
(im_init_obj_fn) input_image_init,/* Init function */
(im_dest_obj_fn) im_close/* Destroy function */
(im_dest_obj_fn) im_close /* Destroy function */
};
/* Init function for output images.
@ -137,11 +139,11 @@ output_image_init( im_object *obj, char *str )
/* Output image type.
*/
im_type_desc im__output_image = {
IM_TYPE_IMAGE, /* Its an image */
0, /* No storage to be allocated */
IM_TYPE_OUTPUT | IM_TYPE_ARG, /* Flags! */
(im_init_obj_fn) output_image_init, /* Init function */
(im_dest_obj_fn) im_close /* Destroy function */
IM_TYPE_IMAGE, /* It's an image */
0, /* No storage to be allocated */
IM_TYPE_OUTPUT | IM_TYPE_ARG, /* Flags! */
(im_init_obj_fn) output_image_init,/* Init function */
(im_dest_obj_fn) im_close /* Destroy function */
};
/* Init function for RW images.
@ -157,9 +159,9 @@ rw_image_init( im_object *obj, char *str )
/* RW image type.
*/
im_type_desc im__rw_image = {
IM_TYPE_IMAGE, /* Its an image */
0, /* No storage to be allocated */
IM_TYPE_ARG, /* Flags! Pretend its an input type */
IM_TYPE_IMAGE, /* It's an image */
0, /* No storage to be allocated */
IM_TYPE_ARG | IM_TYPE_RW, /* Read-write object, needs an arg */
(im_init_obj_fn) rw_image_init, /* Init function */
(im_dest_obj_fn) im_close /* Destroy function */
};
@ -226,11 +228,11 @@ input_imagevec_init( im_object *obj, char *str )
/* Input image vector type.
*/
im_type_desc im__input_imagevec = {
IM_TYPE_IMAGEVEC, /* Its an array of IMAGE */
sizeof( im_imagevec_object ), /* Memory to allocate in vec build */
IM_TYPE_ARG, /* It requires a command-line arg */
input_imagevec_init, /* Init function */
imagevec_dest /* Destroy function */
IM_TYPE_IMAGEVEC, /* It's an array of IMAGE */
sizeof( im_imagevec_object ), /* Memory to allocate in vec build */
IM_TYPE_ARG, /* It requires a command-line arg */
input_imagevec_init, /* Init function */
imagevec_dest /* Destroy function */
};
/* Init function for masks. "str" can be NULL for output masks.
@ -344,52 +346,52 @@ save_imask_dest( im_object obj )
/* Output dmask type.
*/
im_type_desc im__output_dmask = {
IM_TYPE_DMASK, /* Its a mask */
sizeof( im_mask_object ),/* Storage for mask object */
IM_TYPE_DMASK, /* It's a mask */
sizeof( im_mask_object ), /* Storage for mask object */
IM_TYPE_OUTPUT | IM_TYPE_ARG, /* Flags */
mask_init, /* Init function */
save_dmask_dest /* Save and destroy function */
mask_init, /* Init function */
save_dmask_dest /* Save and destroy function */
};
/* Input dmask type.
*/
im_type_desc im__input_dmask = {
IM_TYPE_DMASK, /* Its a mask */
sizeof( im_mask_object ),/* Storage for mask object */
IM_TYPE_ARG, /* It requires a command-line arg */
dmask_init, /* Init function */
dmask_dest /* Destroy function */
IM_TYPE_DMASK, /* It's a mask */
sizeof( im_mask_object ), /* Storage for mask object */
IM_TYPE_ARG, /* It requires a command-line arg */
dmask_init, /* Init function */
dmask_dest /* Destroy function */
};
/* Output imask type.
*/
im_type_desc im__output_imask = {
IM_TYPE_IMASK, /* Its a mask */
sizeof( im_mask_object ),/* Storage for mask object */
IM_TYPE_IMASK, /* It's a mask */
sizeof( im_mask_object ), /* Storage for mask object */
IM_TYPE_OUTPUT | IM_TYPE_ARG, /* Flags */
mask_init, /* Init function */
save_imask_dest /* Save and destroy function */
mask_init, /* Init function */
save_imask_dest /* Save and destroy function */
};
/* Input imask type.
*/
im_type_desc im__input_imask = {
IM_TYPE_IMASK, /* Its a mask */
sizeof( im_mask_object ),/* Storage for mask object */
IM_TYPE_ARG, /* It requires a command-line arg */
imask_init, /* Init function */
imask_dest /* Destroy function */
IM_TYPE_IMASK, /* It's a mask */
sizeof( im_mask_object ), /* Storage for mask object */
IM_TYPE_ARG, /* It requires a command-line arg */
imask_init, /* Init function */
imask_dest /* Destroy function */
};
/* Output dmask to screen type. Set a `print' function to get actual output.
* Used for things like "stats".
*/
im_type_desc im__output_dmask_screen = {
IM_TYPE_DMASK, /* Its a mask */
sizeof( im_mask_object ),/* Storage for mask object */
IM_TYPE_OUTPUT, /* Its an output argument */
mask_init, /* Init function */
dmask_dest /* Destroy function */
IM_TYPE_DMASK, /* It's a mask */
sizeof( im_mask_object ), /* Storage for mask object */
IM_TYPE_OUTPUT, /* It's an output argument */
mask_init, /* Init function */
dmask_dest /* Destroy function */
};
/* Init function for double input.
@ -407,11 +409,11 @@ input_double_init( im_object *obj, char *str )
/* Input double type.
*/
im_type_desc im__input_double = {
IM_TYPE_DOUBLE, /* Its a double */
sizeof( double ), /* Memory to allocate */
IM_TYPE_ARG, /* It requires a command-line arg */
input_double_init, /* Init function */
NULL /* Destroy function */
IM_TYPE_DOUBLE, /* It's a double */
sizeof( double ), /* Memory to allocate */
IM_TYPE_ARG, /* It requires a command-line arg */
input_double_init, /* Init function */
NULL /* Destroy function */
};
/* im_doublevec_object destroy function.
@ -467,11 +469,11 @@ input_doublevec_init( im_object *obj, char *str )
/* Input double vector type.
*/
im_type_desc im__input_doublevec = {
IM_TYPE_DOUBLEVEC, /* Its an array of double */
sizeof( im_doublevec_object ), /* Memory to allocate in vec build */
IM_TYPE_ARG, /* It requires a command-line arg */
input_doublevec_init, /* Init function */
doublevec_dest /* Destroy function */
IM_TYPE_DOUBLEVEC, /* It's an array of double */
sizeof( im_doublevec_object ), /* Memory to allocate in vec build */
IM_TYPE_ARG, /* It requires a command-line arg */
input_doublevec_init, /* Init function */
doublevec_dest /* Destroy function */
};
/* Print function for doublevec output.
@ -492,11 +494,11 @@ im__dvprint( im_object obj )
/* Output double vector type.
*/
im_type_desc im__output_doublevec = {
IM_TYPE_DOUBLEVEC, /* Its an array of double */
sizeof( im_doublevec_object ), /* Memory to allocate in vec build */
IM_TYPE_OUTPUT, /* Output type */
NULL, /* Init function */
doublevec_dest /* Destroy function */
IM_TYPE_DOUBLEVEC, /* It's an array of double */
sizeof( im_doublevec_object ), /* Memory to allocate in vec build */
IM_TYPE_OUTPUT, /* Output type */
NULL, /* Init function */
doublevec_dest /* Destroy function */
};
/* im_intvec_object destroy function.
@ -558,11 +560,11 @@ input_intvec_init( im_object *obj, char *str )
/* Input int vector type.
*/
im_type_desc im__input_intvec = {
IM_TYPE_INTVEC, /* It's an array of int */
sizeof( im_intvec_object ), /* Memory to allocate in vec build */
IM_TYPE_ARG, /* It requires a command-line arg */
input_intvec_init, /* Init function */
intvec_dest /* Destroy function */
IM_TYPE_INTVEC, /* It's an array of int */
sizeof( im_intvec_object ), /* Memory to allocate in vec build */
IM_TYPE_ARG, /* It requires a command-line arg */
input_intvec_init, /* Init function */
intvec_dest /* Destroy function */
};
/* Print function for intvec output.
@ -583,11 +585,11 @@ im__ivprint( im_object obj )
/* Output int vector type.
*/
im_type_desc im__output_intvec = {
IM_TYPE_INTVEC, /* It's an array of int */
sizeof( im_intvec_object ), /* Memory to allocate in vec build */
IM_TYPE_OUTPUT, /* Output arg */
(im_init_obj_fn)NULL, /* Init function */
(im_dest_obj_fn)intvec_dest /* Destroy function */
IM_TYPE_INTVEC, /* It's an array of int */
sizeof( im_intvec_object ), /* Memory to allocate in vec build */
IM_TYPE_OUTPUT, /* Output arg */
(im_init_obj_fn)NULL, /* Init function */
(im_dest_obj_fn)intvec_dest /* Destroy function */
};
/* Init function for int input.
@ -609,11 +611,11 @@ input_int_init( im_object *obj, char *str )
/* Input int type.
*/
im_type_desc im__input_int = {
IM_TYPE_INT, /* Its an int */
sizeof( int ), /* Memory to allocate */
IM_TYPE_ARG, /* It requires a command-line arg */
input_int_init, /* Init function */
NULL /* Destroy function */
IM_TYPE_INT, /* It's an int */
sizeof( int ), /* Memory to allocate */
IM_TYPE_ARG, /* It requires a command-line arg */
input_int_init, /* Init function */
NULL /* Destroy function */
};
/* Init function for string input.
@ -630,51 +632,51 @@ input_string_init( im_object *obj, char *str )
/* Input string type.
*/
im_type_desc im__input_string = {
IM_TYPE_STRING, /* Its a string */
0, /* Memory to allocate */
IM_TYPE_ARG, /* It requires a command-line arg */
input_string_init, /* Init function */
im_free /* Destroy function */
IM_TYPE_STRING, /* It's a string */
0, /* Memory to allocate */
IM_TYPE_ARG, /* It requires a command-line arg */
input_string_init, /* Init function */
im_free /* Destroy function */
};
/* Output string type.
*/
im_type_desc im__output_string = {
IM_TYPE_STRING, /* Its a string */
0, /* Memory to allocate */
IM_TYPE_OUTPUT, /* Its an output argument */
NULL, /* Init function */
im_free /* Destroy function */
IM_TYPE_STRING, /* It's a string */
0, /* Memory to allocate */
IM_TYPE_OUTPUT, /* It's an output argument */
NULL, /* Init function */
im_free /* Destroy function */
};
/* Output double type.
*/
im_type_desc im__output_double = {
IM_TYPE_DOUBLE, /* Its a double */
sizeof( double ), /* Memory to allocate */
IM_TYPE_OUTPUT, /* Its an output argument */
NULL, /* Init function */
NULL /* Destroy function */
IM_TYPE_DOUBLE, /* It's a double */
sizeof( double ), /* Memory to allocate */
IM_TYPE_OUTPUT, /* It's an output argument */
NULL, /* Init function */
NULL /* Destroy function */
};
/* Output complex type.
*/
im_type_desc im__output_complex = {
IM_TYPE_COMPLEX, /* Its a complex */
2 * sizeof( double ), /* Memory to allocate */
IM_TYPE_OUTPUT, /* Its an output argument */
NULL, /* Init function */
NULL /* Destroy function */
IM_TYPE_COMPLEX, /* It's a complex */
2 * sizeof( double ), /* Memory to allocate */
IM_TYPE_OUTPUT, /* It's an output argument */
NULL, /* Init function */
NULL /* Destroy function */
};
/* Output int type.
*/
im_type_desc im__output_int = {
IM_TYPE_INT, /* Its an int */
sizeof( int ), /* Memory to allocate */
IM_TYPE_OUTPUT, /* Its an output argument */
NULL, /* Init function */
NULL /* Destroy function */
IM_TYPE_INT, /* It's an int */
sizeof( int ), /* Memory to allocate */
IM_TYPE_OUTPUT, /* It's an output argument */
NULL, /* Init function */
NULL /* Destroy function */
};
/* Print function for int output.
@ -841,8 +843,8 @@ gvalue_free( im_object obj )
*/
im_type_desc im__input_gvalue = {
IM_TYPE_GVALUE,
sizeof( GValue ), /* Need some storage */
IM_TYPE_ARG, /* It requires a command-line arg */
sizeof( GValue ), /* Need some storage */
IM_TYPE_ARG, /* It requires a command-line arg */
(im_init_obj_fn) input_gvalue_init, /* Init function */
(im_dest_obj_fn) gvalue_free /* Destroy function */
};
@ -904,9 +906,9 @@ input_interpolate_dest( im_object obj )
im_type_desc im__input_interpolate = {
IM_TYPE_INTERPOLATE,
0, /* No storage required */
IM_TYPE_ARG, /* It requires a command-line arg */
input_interpolate_init, /* Init function */
input_interpolate_dest /* Destroy function */
0, /* No storage required */
IM_TYPE_ARG, /* It requires a command-line arg */
input_interpolate_init, /* Init function */
input_interpolate_dest /* Destroy function */
};