From dd6f0e8b4dbf19428fa418f921f1761e0f49856b Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 17 May 2011 13:05:45 +0100 Subject: [PATCH] sizealike everywhere all ops now sizealike (I think) and docs are updated to match --- ChangeLog | 3 ++- TODO | 4 ++-- libvips/arithmetic/add.c | 4 +++- libvips/arithmetic/im_divide.c | 7 +++++-- libvips/arithmetic/im_multiply.c | 4 +++- libvips/arithmetic/im_remainder.c | 5 ++++- libvips/arithmetic/im_subtract.c | 4 +++- libvips/boolean/bool_dispatch.c | 7 ++++--- libvips/boolean/boolean.c | 12 ++++++------ libvips/conversion/im_gbandjoin.c | 21 +++++++++++++++------ libvips/include/vips/internal.h | 4 ++++ libvips/relational/im_ifthenelse.c | 22 ++++++++++++++++------ 12 files changed, 67 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index 49803c0d..baf146ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -57,7 +57,8 @@ - updated German translation (thanks Chris) - fixed typo in im_conv() overflow estimation which could cause errors - vips.c has new action syntax, knows about vips8 operations -- add now has sizealike, retrofitted to old vips7 arith as well +- add now has sizealike +- vips7 binops all do sizealike too, also gbandjoin and ifthenelse 30/11/10 started 7.24.0 - bump for new stable diff --git a/TODO b/TODO index 04fcd198..cc53f1b9 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,3 @@ -- old arith now does sizealike, add to bool etc. as well - - vips_object_set_argument_from_string() leaks output images, because it has to, does this matter? @@ -21,6 +19,8 @@ - make something for Python as well + use ctypes and not swig so we get an easy Win version + wrap new API for C++ diff --git a/libvips/arithmetic/add.c b/libvips/arithmetic/add.c index 45cb8ea2..f628f957 100644 --- a/libvips/arithmetic/add.c +++ b/libvips/arithmetic/add.c @@ -93,7 +93,9 @@ * @out: output image * * This operation calculates @in1 + @in2 and writes the result to @out. - * The images must be the same size. They may have any format. + * + * If the images differ in size, the smaller image is enlarged to match the + * larger by adding zero pixels along the bottom and right. * * If the number of bands differs, one of the images * must have one band. In this case, an n-band image is formed from the diff --git a/libvips/arithmetic/im_divide.c b/libvips/arithmetic/im_divide.c index b483f42c..d4df96b0 100644 --- a/libvips/arithmetic/im_divide.c +++ b/libvips/arithmetic/im_divide.c @@ -187,8 +187,11 @@ static int bandfmt_divide[10] = { * @in2: input #IMAGE 2 * @out: output #IMAGE * - * This operation calculates @in1 / @in2 and writes the result to @out. - * The images must be the same size. They may have any format. + * This operation calculates @in1 / @in2 and writes the result to @out. If any + * pixels in @in2 are zero, the corresponding pixel in @out is also zero. + * + * If the images differ in size, the smaller image is enlarged to match the + * larger by adding zero pixels along the bottom and right. * * If the number of bands differs, one of the images * must have one band. In this case, an n-band image is formed from the diff --git a/libvips/arithmetic/im_multiply.c b/libvips/arithmetic/im_multiply.c index 248ef135..5fe0631c 100644 --- a/libvips/arithmetic/im_multiply.c +++ b/libvips/arithmetic/im_multiply.c @@ -158,7 +158,9 @@ static int bandfmt_multiply[10] = { * @out: output #IMAGE * * This operation calculates @in1 * @in2 and writes the result to @out. - * The images must be the same size. They may have any format. + * + * If the images differ in size, the smaller image is enlarged to match the + * larger by adding zero pixels along the bottom and right. * * If the number of bands differs, one of the images * must have one band. In this case, an n-band image is formed from the diff --git a/libvips/arithmetic/im_remainder.c b/libvips/arithmetic/im_remainder.c index 144eb988..531d2d74 100644 --- a/libvips/arithmetic/im_remainder.c +++ b/libvips/arithmetic/im_remainder.c @@ -141,10 +141,13 @@ static int bandfmt_remainder[10] = { * @out: output #IMAGE * * This operation calculates @in1 % @in2 (remainder after division) and writes - * the result to @out. The images must be the same size. They may have any + * the result to @out. The images may have any * non-complex format. For float formats, im_remainder() calculates @in1 - * @in2 * floor (@in1 / @in2). * + * If the images differ in size, the smaller image is enlarged to match the + * larger by adding zero pixels along the bottom and right. + * * If the number of bands differs, one of the images * must have one band. In this case, an n-band image is formed from the * one-band image by joining n copies of the one-band image together, and then diff --git a/libvips/arithmetic/im_subtract.c b/libvips/arithmetic/im_subtract.c index 3a8c0f8a..09f09be8 100644 --- a/libvips/arithmetic/im_subtract.c +++ b/libvips/arithmetic/im_subtract.c @@ -155,7 +155,9 @@ static int bandfmt_subtract[10] = { * @out: output image * * This operation calculates @in1 - @in2 and writes the result to @out. - * The images must be the same size. They may have any format. + * + * If the images differ in size, the smaller image is enlarged to match the + * larger by adding zero pixels along the bottom and right. * * If the number of bands differs, one of the images * must have one band. In this case, an n-band image is formed from the diff --git a/libvips/boolean/bool_dispatch.c b/libvips/boolean/bool_dispatch.c index f567710b..5af60cab 100644 --- a/libvips/boolean/bool_dispatch.c +++ b/libvips/boolean/bool_dispatch.c @@ -54,7 +54,7 @@ * They are useful for combining the results of * the relational and morphological functions. * All will work with - * images of any type or any mixture of types of any size and of any number + * images of any type or any mixture of types, of any size and of any number * of bands. * * For binary operations, if the number of bands differs, one of the images @@ -66,11 +66,12 @@ * im_andimage_vec(), you can mix single-element arrays or single-band images * freely. * + * If the images differ in size, the smaller image is enlarged to match the + * larger by adding zero pixels along the bottom and right. + * * The output type is the same as the input type for integer types. Float and * complex types are cast to signed int. * - * For binary operations on pairs of images, the images must match in size. - * * You might think im_andimage() would be called "im_and", but that causes * problems when we try and make a C++ binding and drop the "im_" prefix. */ diff --git a/libvips/boolean/boolean.c b/libvips/boolean/boolean.c index 466ef359..9442ad12 100644 --- a/libvips/boolean/boolean.c +++ b/libvips/boolean/boolean.c @@ -144,8 +144,8 @@ BINARY_BUFFER( AND, & ) * @out: output #IMAGE * * This operation calculates @in1 & @in2 and writes the result to @out. - * The images must be the same size. They may have any format. They may differ - * in their number of bands, see above. + * The images may have any format. They may differ + * in their number of bands, see above. They may differ in size, see above. * * See also: im_orimage(). * @@ -169,8 +169,8 @@ BINARY_BUFFER( OR, | ) * @out: output #IMAGE * * This operation calculates @in1 | @in2 and writes the result to @out. - * The images must be the same size. They may have any format. They may differ - * in their number of bands, see above. + * The images may have any format. They may differ + * in their number of bands, see above. They may differ in size, see above. * * See also: im_eorimage(). * @@ -194,8 +194,8 @@ BINARY_BUFFER( EOR, ^ ) * @out: output #IMAGE * * This operation calculates @in1 ^ @in2 and writes the result to @out. - * The images must be the same size. They may have any format. They may differ - * in their number of bands, see above. + * The images may have any format. They may differ + * in their number of bands, see above. They may differ in size, see above. * * See also: im_eorimage_vec(), im_andimage(). * diff --git a/libvips/conversion/im_gbandjoin.c b/libvips/conversion/im_gbandjoin.c index 1fca2e8f..0de80b09 100644 --- a/libvips/conversion/im_gbandjoin.c +++ b/libvips/conversion/im_gbandjoin.c @@ -20,6 +20,8 @@ * - works for RAD coding too * 27/1/10 * - formatalike inputs + * 17/5/11 + * - sizealike inputs */ /* @@ -67,6 +69,7 @@ */ typedef struct joins { int n; /* Number of input images */ + IMAGE **t; /* Array of temp images */ IMAGE **in; /* Array of input images, NULL-terminated */ int *is; /* An int for SIZEOF_PEL() for each image */ } Join; @@ -82,14 +85,17 @@ join_new( IMAGE *out, IMAGE **in, int n ) if( !(join = IM_NEW( out, Join )) ) return( NULL ); join->n = n; - if( !(join->in = IM_ARRAY( out, n + 1, IMAGE * )) || + if( !(join->t = IM_ARRAY( out, n, IMAGE * )) || + !(join->in = IM_ARRAY( out, n + 1, IMAGE * )) || !(join->is = IM_ARRAY( out, n, int )) ) return( NULL ); /* Cast inputs up to a common format. */ - if( im_open_local_array( out, join->in, n, "im_gbandjoin", "p" ) || - im__formatalike_vec( in, join->in, n ) ) + if( im_open_local_array( out, join->t, n, "im_gbandjoin", "p" ) || + im_open_local_array( out, join->in, n, "im_gbandjoin", "p" ) || + im__formatalike_vec( in, join->t, n ) || + im__sizealike_vec( join->t, join->in, n ) ) return( NULL ); for( i = 0; i < n; i++ ) @@ -166,7 +172,9 @@ join_bands( REGION *or, void *seq, void *a, void *b ) * bands, with the first n coming from the first image and the last m * from the second. * - * The images must be the same size. + * If the images differ in size, the smaller images are enlarged to match the + * larger by adding zero pixels along the bottom and right. + * * The input images are cast up to the smallest common type (see table * Smallest common format in * arithmetic). @@ -197,7 +205,6 @@ im_gbandjoin( IMAGE **in, IMAGE *out, int n ) return( -1 ); for( i = 0; i < n; i++ ) if( im_pincheck( in[i] ) || - im_check_size_same( "im_gbandjoin", in[i], in[0] ) || im_check_coding_same( "im_gbandjoin", in[i], in[0] ) ) return( -1 ); @@ -235,7 +242,9 @@ im_gbandjoin( IMAGE **in, IMAGE *out, int n ) * bands, with the first n coming from the first image and the last m * from the second. * - * The images must be the same size. + * If the images differ in size, the smaller image is enlarged to match the + * larger by adding zero pixels along the bottom and right. + * * The two input images are cast up to the smallest common type (see table * Smallest common format in * arithmetic). diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index efdabbdb..aef1573c 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -137,6 +137,10 @@ int im__bandalike( const char *domain, VipsImage *in1, VipsImage *in2, VipsImage *out1, VipsImage *out2 ); int im__formatalike_vec( VipsImage **in, VipsImage **out, int n ); int im__formatalike( VipsImage *in1, VipsImage *in2, VipsImage *out1, VipsImage *out2 ); +int im__sizealike_vec( VipsImage **in, VipsImage **out, int n ); +int im__sizealike( VipsImage *in1, VipsImage *in2, + VipsImage *out1, VipsImage *out2 ); + int im__arith_binary( const char *domain, VipsImage *in1, VipsImage *in2, VipsImage *out, int format_table[10], diff --git a/libvips/relational/im_ifthenelse.c b/libvips/relational/im_ifthenelse.c index d03e72ca..8ab1fa9c 100644 --- a/libvips/relational/im_ifthenelse.c +++ b/libvips/relational/im_ifthenelse.c @@ -18,6 +18,8 @@ * 25/6/10 * - let the conditional image be any format by adding a (!=0) if * necessary + * 17/5/11 + * - added sizealike */ /* @@ -198,7 +200,8 @@ ifthenelse( IMAGE *c, IMAGE *a, IMAGE *b, IMAGE *out ) * * Images @a and @b are cast up to the smallest common format. * - * Images @a and @b must match exactly in size. + * If the images differ in size, the smaller image is enlarged to match the + * larger by adding zero pixels along the bottom and right. * * See also: im_blend(), im_equal(). * @@ -207,9 +210,9 @@ ifthenelse( IMAGE *c, IMAGE *a, IMAGE *b, IMAGE *out ) int im_ifthenelse( IMAGE *c, IMAGE *a, IMAGE *b, IMAGE *out ) { - IMAGE *t[7]; + IMAGE *t[9]; - if( im_open_local_array( out, t, 7, "im_ifthenelse", "p" ) ) + if( im_open_local_array( out, t, 9, "im_ifthenelse", "p" ) ) return( -1 ); /* Make a and b match in bands and format. Don't make c match: we @@ -219,16 +222,23 @@ im_ifthenelse( IMAGE *c, IMAGE *a, IMAGE *b, IMAGE *out ) im__bandalike( "im_ifthenelse", t[0], t[1], t[2], t[3] ) ) return( -1 ); + /* All 3 must match in size. + */ + t[4] = c; + if( im__sizealike_vec( t + 2, t + 5, 3 ) ) + return( -1 ); + c = t[5]; + /* If c is not uchar, do (!=0) to make a uchar image. */ if( c->BandFmt != IM_BANDFMT_UCHAR ) { - if( im_notequalconst( c, t[4], 0 ) ) + if( im_notequalconst( c, t[8], 0 ) ) return( -1 ); - c = t[4]; + c = t[8]; } - if( ifthenelse( c, t[2], t[3], out ) ) + if( ifthenelse( c, t[6], t[7], out ) ) return( -1 ); return( 0 );