From a93662b8c8ba7fe5f3276f515ba1e0bad759671b Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 21 Oct 2009 08:36:15 +0000 Subject: [PATCH] im_insertplace() fixups --- ChangeLog | 1 + TODO | 10 ---- libvips/include/vips/check.h | 1 + libvips/inplace/im_insertplace.c | 79 +++++++++++++++----------------- libvips/iofuncs/check.c | 26 +++++++++++ 5 files changed, 65 insertions(+), 52 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9e64cb51..0ca6f68f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -68,6 +68,7 @@ function - added im_copy_file() - added im_insertplaceset() +- im_insertplace() allows small to be outside big 25/3/09 started 7.18.0 - revised version numbers diff --git a/TODO b/TODO index bd78da35..768b3359 100644 --- a/TODO +++ b/TODO @@ -1,15 +1,5 @@ - more stuff from util.c? too much to do it all now -- how about an indexed histogram? - - have two images, a 1-band index image and an n-band image to analyze - - for each pixel, add the n-band pixel to the bin indicated by the index image - - - - - - load 500 jpegs, shrink, save VM use is huge, ouch, could we use a bit less? diff --git a/libvips/include/vips/check.h b/libvips/include/vips/check.h index 3c8559ef..85a96e42 100644 --- a/libvips/include/vips/check.h +++ b/libvips/include/vips/check.h @@ -56,6 +56,7 @@ int im_check_u8or16( const char *domain, IMAGE *im ); int im_check_same_size( const char *domain, IMAGE *im1, IMAGE *im2 ); int im_check_same_bands( const char *domain, IMAGE *im1, IMAGE *im2 ); int im_check_same_format( const char *domain, IMAGE *im1, IMAGE *im2 ); +int im_check_same_coding( const char *domain, IMAGE *im1, IMAGE *im2 ); int im_check_vector( const char *domain, int n, IMAGE *im ); gboolean im_isuint( IMAGE *im ); diff --git a/libvips/inplace/im_insertplace.c b/libvips/inplace/im_insertplace.c index 73605377..97bbbcaf 100644 --- a/libvips/inplace/im_insertplace.c +++ b/libvips/inplace/im_insertplace.c @@ -1,12 +1,4 @@ -/* @(#) Insert an image into another. Like im_insert, but an `in-place' - * @(#) operation. small must fit entirely inside big - no clipping is - * @(#) performed. - * @(#) - * @(#) int - * @(#) im_insertplace( big, small, x, y ) - * @(#) IMAGE *big, *small; - * @(#) int x, y; - * @(#) +/* in-place insert * * Copyright: J. Cupitt * Written: 15/06/1992 @@ -21,6 +13,9 @@ * - im_invalidate() after paint * 24/3/09 * - added IM_CODING_RAD support + * 21/10/09 + * - allow small to be outside big + * - gtkdoc */ /* @@ -64,37 +59,41 @@ #include #endif /*WITH_DMALLOC*/ -/* Like im_insert, but perform an in-place insertion. +/** + * im_insertplace: + * @big: main image + * @small: sub-image to insert + * @x: position to insert + * @y: position to insert + * + * Copy @small into @big at position @x, @y. The two images must match in + * format, bands and coding. + * + * This an inplace operation, so @big is changed. It does not thread and will + * not work well as part of a pipeline. + * + * Returns: 0 on success, or -1 on error. + * + * See also: im_insert(). */ int im_insertplace( IMAGE *big, IMAGE *small, int x, int y ) { - Rect br, sr; + Rect br, sr, clip; PEL *p, *q; int z; - /* Check IO. - */ - if( im_rwcheck( big ) || im_incheck( small ) ) - return( -1 ); - /* Check compatibility. */ - if( big->BandFmt != small->BandFmt || big->Bands != small->Bands || - big->Coding != small->Coding ) { - im_error( "im_insertplace", "%s", - _( "inputs differ in format" ) ); - return( -1 ); - } - if( big->Coding != IM_CODING_NONE && - big->Coding != IM_CODING_LABQ && - big->Coding != IM_CODING_RAD ) { - im_error( "im_insertplace", "%s", - _( "Coding should be NONE, LABQ or RAD" ) ); - return( -1 ); - } + if( im_rwcheck( big ) || + im_incheck( small ) || + im_check_known_coded( "im_insertplace", big ) || + im_check_known_coded( "im_insertplace", small ) || + im_check_same_format( "im_insertplace", big, small ) || + im_check_same_bands( "im_insertplace", big, small ) ) + return( -1 ); - /* Make rects for big and small. + /* Make rects for big and small and clip. */ br.left = 0; br.top = 0; @@ -104,21 +103,17 @@ im_insertplace( IMAGE *big, IMAGE *small, int x, int y ) sr.top = y; sr.width = small->Xsize; sr.height = small->Ysize; - - /* Small fits inside big? - */ - if( !im_rect_includesrect( &br, &sr ) ) { - im_error( "im_insertplace", - "%s", _( "small not inside big" ) ); - return( -1 ); - } + im_rect_intersectrect( &br, &sr, &clip ); + if( im_rect_isempty( &clip ) ) + return( 0 ); /* Loop, memcpying small to big. */ - p = (PEL *) IM_IMAGE_ADDR( small, 0, 0 ); - q = (PEL *) IM_IMAGE_ADDR( big, x, y ); - for( z = 0; z < small->Ysize; z++ ) { - memcpy( (char *) q, (char *) p, IM_IMAGE_SIZEOF_LINE( small ) ); + p = (PEL *) IM_IMAGE_ADDR( small, clip.left - x, clip.top - y ); + q = (PEL *) IM_IMAGE_ADDR( big, clip.left, clip.top ); + for( z = 0; z < clip.height; z++ ) { + memcpy( (char *) q, (char *) p, + clip.width * IM_IMAGE_SIZEOF_PEL( small ) ); p += IM_IMAGE_SIZEOF_LINE( small ); q += IM_IMAGE_SIZEOF_LINE( big ); } diff --git a/libvips/iofuncs/check.c b/libvips/iofuncs/check.c index 507640cd..0f0ae1d7 100644 --- a/libvips/iofuncs/check.c +++ b/libvips/iofuncs/check.c @@ -840,6 +840,32 @@ im_check_same_format( const char *domain, IMAGE *im1, IMAGE *im2 ) return( 0 ); } +/** + * im_check_same_coding: + * @domain: the originating domain for the error message + * @im1: first image to check + * @im2: second image to check + * + * Check that the images have the same coding. + * If not, set an error message + * and return non-zero. + * + * Returns: 0 if OK, -1 otherwise. + * + * See also: im_error(). + */ +int +im_check_same_coding( const char *domain, IMAGE *im1, IMAGE *im2 ) +{ + if( im1->Coding != im2->Coding ) { + im_error( domain, "%s", + _( "images must have the same coding" ) ); + return( -1 ); + } + + return( 0 ); +} + /** * im_check_same_vector: * @domain: the originating domain for the error message