From 827e5311c168ad7eb123efd089a7a077c8cd1918 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 11 Nov 2011 21:54:45 +0000 Subject: [PATCH] finish unaryconst, move relational to it --- ChangeLog | 4 +- TODO | 5 +- libvips/arithmetic/Makefile.am | 2 + libvips/arithmetic/abs.c | 1 - libvips/arithmetic/add.c | 1 - libvips/arithmetic/arithmetic.c | 2 + libvips/arithmetic/binary.c | 1 - libvips/arithmetic/binary.h | 2 + libvips/arithmetic/divide.c | 1 - libvips/arithmetic/invert.c | 1 - libvips/arithmetic/linear.c | 1 - libvips/arithmetic/math.c | 1 - libvips/arithmetic/multiply.c | 1 - libvips/arithmetic/recomb.c | 1 - libvips/arithmetic/relational.c | 61 ++-- libvips/arithmetic/round.c | 1 - libvips/arithmetic/sign.c | 1 - libvips/arithmetic/subtract.c | 1 - libvips/arithmetic/unary.c | 1 - libvips/arithmetic/unary.h | 2 + libvips/arithmetic/unaryconst.c | 506 +++----------------------- libvips/arithmetic/unaryconst.h | 21 +- libvips/deprecated/vips7compat.c | 97 +++++ libvips/include/vips/arithmetic.h | 6 + libvips/include/vips/relational.h | 13 - libvips/include/vips/vips7compat.h | 13 + libvips/relational/Makefile.am | 1 - libvips/relational/relational.c | 548 ----------------------------- 28 files changed, 226 insertions(+), 1070 deletions(-) delete mode 100644 libvips/relational/relational.c diff --git a/ChangeLog b/ChangeLog index 1b0a3b87..17e092c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,8 +9,8 @@ im_atantra(), im_exptra(), im_exp10tra(), im_logtra(), im_log10tra(), im_abs(), im_sign(), im_max(), im_maxpos(), im_deviate(), im_divide(), im_multiply(), im_stats(), im_measure(), im_recomb(), im_floor(), im_ceil(), - im_rint(), im_equal(), im_notequal(), im_less(), im_lesseq(), im_more(), - im_moreeq() + im_rint(), im_equal*(), im_notequal*(), im_less*(), im_lesseq*(), im_more*(), + im_moreeq*() redone as classes - added argument priorites to help control arg ordering - generate has a 'stop' param to signal successful early termination diff --git a/TODO b/TODO index 881d1047..c98bace5 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,9 @@ - test _O_TEMPORARY thing on Windows - * See also: #VipsBoolean, #VipsRelationalConst. + + +- remainder, power move to unary const + diff --git a/libvips/arithmetic/Makefile.am b/libvips/arithmetic/Makefile.am index c4078b36..2fa37e6f 100644 --- a/libvips/arithmetic/Makefile.am +++ b/libvips/arithmetic/Makefile.am @@ -30,6 +30,8 @@ libarithmetic_la_SOURCES = \ binary.h \ unary.c \ unary.h \ + unaryconst.c \ + unaryconst.h \ relational.c \ add.c \ linear.c \ diff --git a/libvips/arithmetic/abs.c b/libvips/arithmetic/abs.c index 8a0f289a..d9de0117 100644 --- a/libvips/arithmetic/abs.c +++ b/libvips/arithmetic/abs.c @@ -67,7 +67,6 @@ #include -#include "arithmetic.h" #include "unary.h" /** diff --git a/libvips/arithmetic/add.c b/libvips/arithmetic/add.c index 8b413275..c5d492f7 100644 --- a/libvips/arithmetic/add.c +++ b/libvips/arithmetic/add.c @@ -79,7 +79,6 @@ #include -#include "arithmetic.h" #include "binary.h" /** diff --git a/libvips/arithmetic/arithmetic.c b/libvips/arithmetic/arithmetic.c index 95b83b93..c9d8d637 100644 --- a/libvips/arithmetic/arithmetic.c +++ b/libvips/arithmetic/arithmetic.c @@ -519,6 +519,7 @@ vips_arithmetic_operation_init( void ) extern GType vips_recomb_get_type( void ); extern GType vips_round_get_type( void ); extern GType vips_relational_get_type( void ); + extern GType vips_relational_const_get_type( void ); vips_add_get_type(); vips_subtract_get_type(); @@ -538,4 +539,5 @@ vips_arithmetic_operation_init( void ) vips_recomb_get_type(); vips_round_get_type(); vips_relational_get_type(); + vips_relational_const_get_type(); } diff --git a/libvips/arithmetic/binary.c b/libvips/arithmetic/binary.c index 281a7447..3d323dcd 100644 --- a/libvips/arithmetic/binary.c +++ b/libvips/arithmetic/binary.c @@ -49,7 +49,6 @@ #include -#include "arithmetic.h" #include "binary.h" G_DEFINE_ABSTRACT_TYPE( VipsBinary, vips_binary, VIPS_TYPE_ARITHMETIC ); diff --git a/libvips/arithmetic/binary.h b/libvips/arithmetic/binary.h index c16b3df9..3d40b5e8 100644 --- a/libvips/arithmetic/binary.h +++ b/libvips/arithmetic/binary.h @@ -34,6 +34,8 @@ extern "C" { #endif /*__cplusplus*/ +#include "arithmetic.h" + #define VIPS_TYPE_BINARY (vips_binary_get_type()) #define VIPS_BINARY( obj ) \ (G_TYPE_CHECK_INSTANCE_CAST( (obj), VIPS_TYPE_BINARY, VipsBinary )) diff --git a/libvips/arithmetic/divide.c b/libvips/arithmetic/divide.c index 0f9f0ace..0d3f1ad1 100644 --- a/libvips/arithmetic/divide.c +++ b/libvips/arithmetic/divide.c @@ -71,7 +71,6 @@ #include -#include "arithmetic.h" #include "binary.h" /** diff --git a/libvips/arithmetic/invert.c b/libvips/arithmetic/invert.c index b709cc4a..5407a466 100644 --- a/libvips/arithmetic/invert.c +++ b/libvips/arithmetic/invert.c @@ -58,7 +58,6 @@ #include -#include "arithmetic.h" #include "unary.h" /** diff --git a/libvips/arithmetic/linear.c b/libvips/arithmetic/linear.c index a44373e7..7a37aa26 100644 --- a/libvips/arithmetic/linear.c +++ b/libvips/arithmetic/linear.c @@ -81,7 +81,6 @@ #include -#include "arithmetic.h" #include "unary.h" /** diff --git a/libvips/arithmetic/math.c b/libvips/arithmetic/math.c index 38aa9d14..0020f430 100644 --- a/libvips/arithmetic/math.c +++ b/libvips/arithmetic/math.c @@ -66,7 +66,6 @@ #include -#include "arithmetic.h" #include "unary.h" /** diff --git a/libvips/arithmetic/multiply.c b/libvips/arithmetic/multiply.c index e27838de..c29e37e0 100644 --- a/libvips/arithmetic/multiply.c +++ b/libvips/arithmetic/multiply.c @@ -70,7 +70,6 @@ #include -#include "arithmetic.h" #include "binary.h" /** diff --git a/libvips/arithmetic/recomb.c b/libvips/arithmetic/recomb.c index d92746c2..0a268f63 100644 --- a/libvips/arithmetic/recomb.c +++ b/libvips/arithmetic/recomb.c @@ -51,7 +51,6 @@ #include -#include "arithmetic.h" #include "unary.h" /** diff --git a/libvips/arithmetic/relational.c b/libvips/arithmetic/relational.c index 41a6bf57..8a5894c1 100644 --- a/libvips/arithmetic/relational.c +++ b/libvips/arithmetic/relational.c @@ -68,7 +68,6 @@ #include -#include "arithmetic.h" #include "binary.h" #include "unaryconst.h" @@ -305,19 +304,21 @@ typedef struct _VipsRelationalConst { VipsOperationRelational relational; } VipsRelationalConst; -typedef VipsUnaryClass VipsRelationalConstClass; +typedef VipsUnaryConstClass VipsRelationalConstClass; G_DEFINE_TYPE( VipsRelationalConst, - vips_relationalconst, VIPS_TYPE_UNARY_CONST ); + vips_relational_const, VIPS_TYPE_UNARY_CONST ); static int -vips_relationalconst_build( VipsObject *object ) +vips_relational_const_build( VipsObject *object ) { - VipsArithmetic *arithmetic = VIPS_ARITHMETIC( object ); - VipsUnaryConst *unaryconst = (VipsUnaryConst *) object; - VipsRelationalConst *relationalconst = (VipsRelationalConst *) object; + VipsUnary *unary = (VipsUnary *) object; + VipsUnaryConst *uconst = (VipsUnaryConst *) object; - if( VIPS_OBJECT_CLASS( vips_relationalconst_parent_class )-> + if( unary->in ) + uconst->const_format = unary->in->BandFmt; + + if( VIPS_OBJECT_CLASS( vips_relational_const_parent_class )-> build( object ) ) return( -1 ); @@ -326,6 +327,7 @@ vips_relationalconst_build( VipsObject *object ) #define RLOOPC( TYPE, OP ) { \ TYPE *p = (TYPE *) in[0]; \ + TYPE *c = (TYPE *) uconst->c_ready; \ \ for( i = 0, x = 0; x < width; x++ ) \ for( b = 0; b < bands; b++, i++ ) \ @@ -336,30 +338,29 @@ vips_relationalconst_build( VipsObject *object ) TYPE *p = (TYPE *) in[0]; \ \ for( i = 0, x = 0; x < width; x++ ) { \ + TYPE *c = (TYPE *) uconst->c_ready; \ + \ for( b = 0; b < bands; b++, i++ ) { \ - out[i] = OP( p[0], p[1], c[i], 0.0) ? 255 : 0; \ + out[i] = OP( p[0], p[1], c[0], c[1]) ? 255 : 0; \ \ p += 2; \ + c += 2; \ } \ } \ } -/* Lintra a buffer, n set of scale/offset. - */ static void -vips_relationalconst_buffer( VipsArithmetic *arithmetic, +vips_relational_const_buffer( VipsArithmetic *arithmetic, PEL *out, PEL **in, int width ) { - VipsUnaryConst *unaryconst = (VipsUnaryConst *) arithmetic; - VipsRelationalConst *relationalconst = (VipsRelationalConst *) - arithmetic; + VipsUnaryConst *uconst = (VipsUnaryConst *) arithmetic; + VipsRelationalConst *rconst = (VipsRelationalConst *) arithmetic; VipsImage *im = arithmetic->ready[0]; int bands = im->Bands; - double *c = unaryconst->c_ready; int i, x, b; - switch( relationalconst->relational ) { + switch( rconst->relational ) { case VIPS_OPERATION_RELATIONAL_EQUAL: SWITCH( RLOOPC, CLOOPC, ==, CEQUAL ); break; @@ -390,7 +391,7 @@ vips_relationalconst_buffer( VipsArithmetic *arithmetic, } static void -vips_relationalconst_class_init( VipsRelationalConstClass *class ) +vips_relational_const_class_init( VipsRelationalConstClass *class ) { GObjectClass *gobject_class = G_OBJECT_CLASS( class ); VipsObjectClass *object_class = (VipsObjectClass *) class; @@ -399,23 +400,31 @@ vips_relationalconst_class_init( VipsRelationalConstClass *class ) gobject_class->set_property = vips_object_set_property; gobject_class->get_property = vips_object_get_property; - object_class->nickname = "relationalconst"; + object_class->nickname = "relational_const"; object_class->description = _( "relational operations against a constant" ); - object_class->build = vips_relationalconst_build; + object_class->build = vips_relational_const_build; vips_arithmetic_set_format_table( aclass, vips_bandfmt_relational ); - aclass->process_line = vips_relationalconst_buffer; + aclass->process_line = vips_relational_const_buffer; + + VIPS_ARG_ENUM( class, "relational", 200, + _( "Operation" ), + _( "relational to perform" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsRelationalConst, relational ), + VIPS_TYPE_OPERATION_RELATIONAL, + VIPS_OPERATION_RELATIONAL_EQUAL ); } static void -vips_relationalconst_init( VipsRelationalConst *relationalconst ) +vips_relational_const_init( VipsRelationalConst *relational_const ) { } int -vips_relationalconst( VipsImage *in, VipsImage **out, +vips_relational_const( VipsImage *in, VipsImage **out, VipsOperationRelational relational, double *c, int n, ... ) { va_list ap; @@ -430,7 +439,7 @@ vips_relationalconst( VipsImage *in, VipsImage **out, array[i] = c[i]; va_start( ap, n ); - result = vips_call_split( "relationalconst", ap, + result = vips_call_split( "relational_const", ap, in, out, relational, area_c ); va_end( ap ); @@ -440,7 +449,7 @@ vips_relationalconst( VipsImage *in, VipsImage **out, } int -vips_relationalconst1( VipsImage *in, VipsImage **out, +vips_relational_const1( VipsImage *in, VipsImage **out, VipsOperationRelational relational, double c, ... ) { va_list ap; @@ -453,7 +462,7 @@ vips_relationalconst1( VipsImage *in, VipsImage **out, array[0] = c; va_start( ap, c ); - result = vips_call_split( "relationalconst", ap, + result = vips_call_split( "relational_const", ap, in, out, relational, area_c ); va_end( ap ); diff --git a/libvips/arithmetic/round.c b/libvips/arithmetic/round.c index 750ace33..8d1a8cd5 100644 --- a/libvips/arithmetic/round.c +++ b/libvips/arithmetic/round.c @@ -52,7 +52,6 @@ #include -#include "arithmetic.h" #include "unary.h" /** diff --git a/libvips/arithmetic/sign.c b/libvips/arithmetic/sign.c index 6f1fdd6f..f631e69e 100644 --- a/libvips/arithmetic/sign.c +++ b/libvips/arithmetic/sign.c @@ -49,7 +49,6 @@ #include -#include "arithmetic.h" #include "unary.h" /** diff --git a/libvips/arithmetic/subtract.c b/libvips/arithmetic/subtract.c index 93650ea7..c1d3587e 100644 --- a/libvips/arithmetic/subtract.c +++ b/libvips/arithmetic/subtract.c @@ -74,7 +74,6 @@ #include -#include "arithmetic.h" #include "binary.h" /** diff --git a/libvips/arithmetic/unary.c b/libvips/arithmetic/unary.c index 7e597b2e..ca14d0dc 100644 --- a/libvips/arithmetic/unary.c +++ b/libvips/arithmetic/unary.c @@ -45,7 +45,6 @@ #include -#include "arithmetic.h" #include "unary.h" G_DEFINE_ABSTRACT_TYPE( VipsUnary, vips_unary, VIPS_TYPE_ARITHMETIC ); diff --git a/libvips/arithmetic/unary.h b/libvips/arithmetic/unary.h index 134fb355..7f9e8db9 100644 --- a/libvips/arithmetic/unary.h +++ b/libvips/arithmetic/unary.h @@ -34,6 +34,8 @@ extern "C" { #endif /*__cplusplus*/ +#include "arithmetic.h" + #define VIPS_TYPE_UNARY (vips_unary_get_type()) #define VIPS_UNARY( obj ) \ (G_TYPE_CHECK_INSTANCE_CAST( (obj), VIPS_TYPE_UNARY, VipsUnary )) diff --git a/libvips/arithmetic/unaryconst.c b/libvips/arithmetic/unaryconst.c index bfbf9a75..fe387e39 100644 --- a/libvips/arithmetic/unaryconst.c +++ b/libvips/arithmetic/unaryconst.c @@ -1,31 +1,7 @@ -/* relational.c --- various relational operations +/* an image plus a constant * - * Modified: - * 26/7/93 JC - * - >,<,>=,<= tests now as (double) to prevent compiler warnings. Should - * split into int/float cases really for speed. - * 25/1/95 JC - * - partialized - * - updated - * 7/2/95 JC - * - oops! bug with doubles fixed - * 3/7/98 JC - * - vector versions added ... im_equal_vec(), im_lesseq_vec() etc - * - small tidies - * - should be a bit faster, lots of *q++ changed to q[x] - * 10/3/03 JC - * - reworked to remove nested #defines: a bit slower, but much smaller - * - all except _vec forms now work on complex - * 31/7/03 JC - * - oops, relational_format was broken for some combinations - * 23/9/09 - * - gtkdoc - * - use new im__arith_binary*() functions - * - more meta-programming - * 23/6/10 - * - oops, moreconst and moreeqconst were the same - * 4/11/11 - * - redone as a class + * 11/11/11 + * - from arith_binary_const */ /* @@ -68,262 +44,20 @@ #include -#include "arithmetic.h" -#include "binary.h" -#include "unary.h" +#include "unaryconst.h" -/** - * VipsRelational: - * @in: input #VipsImage - * @out: output #VipsImage - * @relational: relational operation to perform - * - * Perform various relational operations on pairs of images. - * - * The output type is always uchar, with 0 for FALSE and 255 for TRUE. - * - * Less-than and greater-than for complex images compare the modulus. - * - * 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 - * the two n-band images are operated upon. - * - * The two input images are cast up to the smallest common type (see table - * Smallest common format in - * arithmetic). - * - * See also: #VipsBoolean, #VipsRelationalConst. - */ - -typedef struct _VipsRelational { - VipsBinary parent_instance; - - VipsOperationRelational relational; - -} VipsRelational; - -typedef VipsBinaryClass VipsRelationalClass; - -G_DEFINE_TYPE( VipsRelational, vips_relational, VIPS_TYPE_BINARY ); - -static int -vips_relational_build( VipsObject *object ) -{ - VipsRelational *relational = (VipsRelational *) object; - VipsArithmetic *arithmetic = (VipsArithmetic *) object; - - if( relational->relational == VIPS_OPERATION_RELATIONAL_MORE ) { - relational->relational = VIPS_OPERATION_RELATIONAL_LESS; - VIPS_SWAP( VipsImage *, - arithmetic->ready[0], arithmetic->ready[1] ); - } - - if( relational->relational == VIPS_OPERATION_RELATIONAL_MOREEQ ) { - relational->relational = VIPS_OPERATION_RELATIONAL_LESSEQ; - VIPS_SWAP( VipsImage *, - arithmetic->ready[0], arithmetic->ready[1] ); - } - - if( VIPS_OBJECT_CLASS( vips_relational_parent_class )->build( object ) ) - return( -1 ); - - return( 0 ); -} - -#define RLOOP( TYPE, ROP ) { \ - TYPE *left = (TYPE *) in[0]; \ - TYPE *right = (TYPE *) in[1]; \ - PEL *q = (PEL *) out; \ - \ - for( x = 0; x < sz; x++ ) \ - q[x] = (left[x] ROP right[x]) ? 255 : 0; \ -} - -#define CLOOP( TYPE, COP ) { \ - TYPE *left = (TYPE *) in[0]; \ - TYPE *right = (TYPE *) in[1]; \ - PEL *q = (PEL *) out; \ - \ - for( x = 0; x < sz; x++ ) { \ - q[x] = COP( left[0], left[1], right[0], right[1]) ? 255 : 0; \ - \ - left += 2; \ - right += 2; \ - } \ -} - -#define SWITCH( R, C, ROP, COP ) \ - switch( vips_image_get_format( im ) ) { \ - case VIPS_FORMAT_UCHAR: R( unsigned char, ROP ); break; \ - case VIPS_FORMAT_CHAR: R( signed char, ROP ); break; \ - case VIPS_FORMAT_USHORT: R( unsigned short, ROP ); break; \ - case VIPS_FORMAT_SHORT: R( signed short, ROP ); break; \ - case VIPS_FORMAT_UINT: R( unsigned int, ROP ); break; \ - case VIPS_FORMAT_INT: R( signed int, ROP ); break; \ - case VIPS_FORMAT_FLOAT: R( float, ROP ); break; \ - case VIPS_FORMAT_DOUBLE: R( double, ROP ); break;\ - case VIPS_FORMAT_COMPLEX: C( float, COP ); break; \ - case VIPS_FORMAT_DPCOMPLEX: C( double, COP ); break;\ - \ - default: \ - g_assert( 0 ); \ - } - -#define CEQUAL( x1, y1, x2, y2 ) (x1 == y1 && x2 == y2) -#define CNOTEQUAL( x1, y1, x2, y2 ) (x1 != y1 || x2 != y2) -#define CLESS( x1, y1, x2, y2 ) (x1 * x1 + y1 * y1 < x2 * x2 + y2 * y2) -#define CLESSEQ( x1, y1, x2, y2 ) (x1 * x1 + y1 * y1 <= x2 * x2 + y2 * y2) -#define CMORE( x1, y1, x2, y2 ) (x1 * x1 + y1 * y1 > x2 * x2 + y2 * y2) -#define CMOREEQ( x1, y1, x2, y2 ) (x1 * x1 + y1 * y1 >= x2 * x2 + y2 * y2) - -static void -vips_relational_buffer( VipsArithmetic *arithmetic, - PEL *out, PEL **in, int width ) -{ - VipsRelational *relational = (VipsRelational *) arithmetic; - VipsImage *im = arithmetic->ready[0]; - const int sz = width * vips_image_get_bands( im ); - - int x; - - switch( relational->relational ) { - case VIPS_OPERATION_RELATIONAL_EQUAL: - SWITCH( RLOOP, CLOOP, ==, CEQUAL ); - break; - - case VIPS_OPERATION_RELATIONAL_NOTEQUAL: - SWITCH( RLOOP, CLOOP, !=, CNOTEQUAL ); - break; - - case VIPS_OPERATION_RELATIONAL_LESS: - SWITCH( RLOOP, CLOOP, <, CLESS ); - break; - - case VIPS_OPERATION_RELATIONAL_LESSEQ: - SWITCH( RLOOP, CLOOP, <=, CLESSEQ ); - break; - - default: - g_assert( 0 ); - } -} - -/* Save a bit of typing. - */ -#define UC VIPS_FORMAT_UCHAR -#define C VIPS_FORMAT_CHAR -#define US VIPS_FORMAT_USHORT -#define S VIPS_FORMAT_SHORT -#define UI VIPS_FORMAT_UINT -#define I VIPS_FORMAT_INT -#define F VIPS_FORMAT_FLOAT -#define X VIPS_FORMAT_COMPLEX -#define D VIPS_FORMAT_DOUBLE -#define DX VIPS_FORMAT_DPCOMPLEX - -static const VipsBandFormat vips_bandfmt_relational[10] = { -/* UC C US S UI I F X D DX */ - UC, UC, UC, UC, UC, UC, UC, UC, UC, UC -}; - -static void -vips_relational_class_init( VipsRelationalClass *class ) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS( class ); - VipsObjectClass *object_class = (VipsObjectClass *) class; - VipsArithmeticClass *aclass = VIPS_ARITHMETIC_CLASS( class ); - - gobject_class->set_property = vips_object_set_property; - gobject_class->get_property = vips_object_get_property; - - object_class->nickname = "relational"; - object_class->description = - _( "a relational operation on a pair of images" ); - object_class->build = vips_relational_build; - - vips_arithmetic_set_format_table( aclass, vips_bandfmt_relational ); - - aclass->process_line = vips_relational_buffer; - - VIPS_ARG_ENUM( class, "relational", 200, - _( "Operation" ), - _( "relational to perform" ), - VIPS_ARGUMENT_REQUIRED_INPUT, - G_STRUCT_OFFSET( VipsRelational, relational ), - VIPS_TYPE_OPERATION_RELATIONAL, - VIPS_OPERATION_RELATIONAL_EQUAL ); -} - -static void -vips_relational_init( VipsRelational *relational ) -{ -} - -int -vips_relational( VipsImage *left, VipsImage *right, VipsImage **out, - VipsOperationRelational relational, ... ) -{ - va_list ap; - int result; - - va_start( ap, relational ); - result = vips_call_split( "relational", ap, left, right, out, - relational ); - va_end( ap ); - - return( result ); -} - -/** - * VipsRelationalConst: - * @in: input image - * @out: output image - * @a: array of constants - * @relational: relational operation to perform - * - * Perform various relational operations on an image against a constant. - * - * The output type is always uchar, with 0 for FALSE and 255 for TRUE. - * - * If the array of constants has just one element, that constant is used for - * all image bands. If the array has more than one element and they have - * the same number of elements as there are bands in the image, then - * one array element is used for each band. If the arrays have more than one - * element and the image only has a single band, the result is a many-band - * image where each band corresponds to one array element. - * - * See also: #VipsBoolean, #VipsRelational. - */ - -typedef struct _VipsRelationalConst { - VipsUnary parent_instance; - - /* Our constants. - */ - VipsArea *c; - - /* Our constants expanded to match arith->ready in size. - */ - int n; - double *c_ready; - -} VipsRelationalConst; - -typedef VipsUnaryClass VipsRelationalConstClass; - -G_DEFINE_TYPE( VipsRelationalConst, vips_relationalconst, VIPS_TYPE_UNARY ); +G_DEFINE_ABSTRACT_TYPE( VipsUnaryConst, vips_unary_const, VIPS_TYPE_UNARY ); /* Cast a vector of double to a vector of TYPE, clipping to a range. */ #define CAST_CLIP( TYPE, N, X ) { \ TYPE *tq = (TYPE *) q; \ \ - for( i = 0; i < n; i++ ) \ - tq[i] = (TYPE) IM_CLIP( N, p[i], X ); \ + for( i = 0; i < m; i++ ) { \ + double v = p[VIPS_MIN( n - 1, i )]; \ + \ + tq[i] = (TYPE) VIPS_CLIP( N, v, X ); \ + } \ } /* Cast a vector of double to a vector of TYPE. @@ -331,8 +65,8 @@ G_DEFINE_TYPE( VipsRelationalConst, vips_relationalconst, VIPS_TYPE_UNARY ); #define CAST( TYPE ) { \ TYPE *tq = (TYPE *) q; \ \ - for( i = 0; i < n; i++ ) \ - tq[i] = (TYPE) p[i]; \ + for( i = 0; i < m; i++ ) \ + tq[i] = (TYPE) p[VIPS_MIN( n - 1, i )]; \ } /* Cast a vector of double to a complex vector of TYPE. @@ -340,62 +74,64 @@ G_DEFINE_TYPE( VipsRelationalConst, vips_relationalconst, VIPS_TYPE_UNARY ); #define CASTC( TYPE ) { \ TYPE *tq = (TYPE *) q; \ \ - for( i = 0; i < n; i++ ) { \ - tq[0] = (TYPE) p[i]; \ + for( i = 0; i < m; i++ ) { \ + tq[0] = (TYPE) p[VIPS_MIN( n - 1, i )]; \ tq[1] = 0; \ + \ tq += 2; \ } \ } -/* Cast a vector of double to a passed format. +/* Cast a n-band vector of double to a m-band vector in another format. */ static PEL * -make_pixel( IMAGE *out, VipsBandFmt fmt, int n, double *p ) +make_pixel( VipsObject *obj, int m, VipsBandFmt fmt, int n, double *p ) { PEL *q; int i; - if( !(q = IM_ARRAY( out, n * (im_bits_of_fmt( fmt ) >> 3), PEL )) ) + if( !(q = VIPS_ARRAY( obj, + m * vips__image_sizeof_bandformat[fmt], PEL )) ) return( NULL ); switch( fmt ) { - case IM_BANDFMT_CHAR: + case VIPS_FORMAT_CHAR: CAST_CLIP( signed char, SCHAR_MIN, SCHAR_MAX ); break; - case IM_BANDFMT_UCHAR: + case VIPS_FORMAT_UCHAR: CAST_CLIP( unsigned char, 0, UCHAR_MAX ); break; - case IM_BANDFMT_SHORT: + case VIPS_FORMAT_SHORT: CAST_CLIP( signed short, SCHAR_MIN, SCHAR_MAX ); break; - case IM_BANDFMT_USHORT: + case VIPS_FORMAT_USHORT: CAST_CLIP( unsigned short, 0, USHRT_MAX ); break; - case IM_BANDFMT_INT: + case VIPS_FORMAT_INT: CAST_CLIP( signed int, INT_MIN, INT_MAX ); break; - case IM_BANDFMT_UINT: + case VIPS_FORMAT_UINT: CAST_CLIP( unsigned int, 0, UINT_MAX ); break; - case IM_BANDFMT_FLOAT: + case VIPS_FORMAT_FLOAT: CAST( float ); break; - case IM_BANDFMT_DOUBLE: + case VIPS_FORMAT_DOUBLE: CAST( double ); break; - case IM_BANDFMT_COMPLEX: + case VIPS_FORMAT_COMPLEX: CASTC( float ); break; - case IM_BANDFMT_DPCOMPLEX: + case VIPS_FORMAT_DPCOMPLEX: CASTC( double ); break; @@ -407,45 +143,28 @@ make_pixel( IMAGE *out, VipsBandFmt fmt, int n, double *p ) } static int -vips_relationalconst_build( VipsObject *object ) +vips_unary_const_build( VipsObject *object ) { VipsArithmetic *arithmetic = VIPS_ARITHMETIC( object ); VipsUnary *unary = (VipsUnary *) object; - VipsRelationalConst *relationalconst = (VipsRelationalConst *) object; - - int i; + VipsUnaryConst *uconst = (VipsUnaryConst *) object; /* If we have a three-element vector we need to bandup the image to * match. */ - relationalconst->n = 1; - if( relationalconst->c ) - relationalconst->n = relationalconst->c->n; + uconst->n = 1; + if( uconst->c ) + uconst->n = VIPS_MAX( uconst->n, uconst->c->n ); if( unary->in ) - relationalconst->n = VIPS_MAX( relationalconst->n, - unary->in->Bands ); - arithmetic->base_bands = relationalconst->n; + uconst->n = VIPS_MAX( uconst->n, unary->in->Bands ); + arithmetic->base_bands = uconst->n; - if( unary->in && relational->c ) { + if( unary->in && uconst->c ) { if( vips_check_vector( "VipsRelationalConst", - relationalconst->c->n, unary->in ) ) + uconst->c->n, unary->in ) ) return( -1 ); } - /* Make up-banded versions of our constants. - */ - if( relationalconst->c ) { - double *ary = (double *) relationalconst->c->data; - - relationalconst->c_ready = g_new( double, relationalconst->n ); - - for( i = 0; i < relationalconst->n; i++ ) { - int j = VIPS_MIN( i, relationalconst->c->n - 1 ); - - relationalconst->c_ready[i] = ary[j]; - } - } - /* Some operations need the vector in the input type (eg. * im_equal_vec() where the output type is always uchar and is useless * for comparisons), some need it in the output type (eg. @@ -456,164 +175,41 @@ vips_relationalconst_build( VipsObject *object ) * * Therefore pass in the desired vector type as a param. */ - if( !(vector = make_pixel( out, vfmt, n, c )) ) - return( -1 ); - if( VIPS_OBJECT_CLASS( vips_relationalconst_parent_class )-> + if( uconst->c ) + uconst->c_ready = make_pixel( (VipsObject *) uconst, + uconst->n, uconst->const_format, + uconst->c->n, (double *) uconst->c->data ); + + if( VIPS_OBJECT_CLASS( vips_unary_const_parent_class )-> build( object ) ) return( -1 ); return( 0 ); } -#define RLOOPC( TYPE, OP ) { \ - TYPE *p = (TYPE *) in[0]; \ - \ - for( i = 0, x = 0; x < width; x++ ) \ - for( b = 0; b < bands; b++, i++ ) \ - q[i] = (p[i] OP c[b]) ? 255 : 0; \ -} - -#define CLOOPC( TYPE, OP ) { \ - TYPE *p = (TYPE *) in[0]; \ - \ - for( i = 0, x = 0; x < width; x++ ) { \ - for( b = 0; b < bands; b++, i++ ) { \ - q[i] = COP( p[0], p[1], c[i], 0.0) ? 255 : 0; \ - \ - p += 2; \ - } \ - } \ -} - -/* Lintra a buffer, n set of scale/offset. - */ static void -vips_relationalconst_buffer( VipsArithmetic *arithmetic, - PEL *out, PEL **in, int width ) -{ - VipsRelationalConst *relationalconst = (VipsRelationalConst *) - arithmetic; - VipsImage *im = arithmetic->ready[0]; - int nb = im->Bands; - double *c = relationalconst->c_ready; - - int i, x, k; - - switch( relationalconst->relational ) { - case VIPS_OPERATION_RELATIONAL_EQUAL: - SWITCH( RLOOPC, CLOOPC, ==, CEQUAL ); - break; - - case VIPS_OPERATION_RELATIONAL_NOTEQUAL: - SWITCH( RLOOPC, CLOOPC, !=, CNOTEQUAL ); - break; - - case VIPS_OPERATION_RELATIONAL_LESS: - SWITCH( RLOOPC, CLOOPC, <, CLESS ); - breakC; - - case VIPS_OPERATION_RELATIONAL_LESSEQ: - SWITCH( RLOOPC, CLOOPC, <=, CLESSEQ ); - break; - - case VIPS_OPERATION_RELATIONAL_MORE: - SWITCH( RLOOPC, CLOOPC, >, CMORE ); - breakC; - - case VIPS_OPERATION_RELATIONAL_MOREEQ: - SWITCH( RLOOPC, CLOOPC, >=, CMOREEQ ); - break; - - default: - g_assert( 0 ); - } -} - -static void -vips_relationalconst_class_init( VipsRelationalConstClass *class ) +vips_unary_const_class_init( VipsUnaryConstClass *class ) { GObjectClass *gobject_class = G_OBJECT_CLASS( class ); VipsObjectClass *object_class = (VipsObjectClass *) class; - VipsArithmeticClass *aclass = VIPS_ARITHMETIC_CLASS( class ); gobject_class->set_property = vips_object_set_property; gobject_class->get_property = vips_object_get_property; - object_class->nickname = "relationalconst"; - object_class->description = - _( "relational operations against a constant" ); - object_class->build = vips_relationalconst_build; + object_class->nickname = "unary_const"; + object_class->description = _( "unary operations with a constant" ); + object_class->build = vips_unary_const_build; - vips_arithmetic_set_format_table( aclass, vips_bandfmt_relational ); - - aclass->process_line = vips_relationalconst_buffer; - - VIPS_ARG_ENUM( class, "relational", 200, - _( "Operation" ), - _( "relational operation to perform" ), - VIPS_ARGUMENT_REQUIRED_INPUT, - G_STRUCT_OFFSET( VipsRelational, relational ), - VIPS_TYPE_OPERATION_RELATIONAL, - VIPS_OPERATION_RELATIONAL_EQUAL ); - - VIPS_ARG_BOXED( class, "c", 210, + VIPS_ARG_BOXED( class, "c", 200, _( "c" ), _( "Array of constants" ), VIPS_ARGUMENT_REQUIRED_INPUT, - G_STRUCT_OFFSET( VipsRelationalConst, c ), + G_STRUCT_OFFSET( VipsUnaryConst, c ), VIPS_TYPE_ARRAY_DOUBLE ); } static void -vips_relationalconst_init( VipsRelationalConst *relationalconst ) +vips_unary_const_init( VipsUnaryConst *uconst ) { } - -int -vips_relationalconst( VipsImage *in, VipsImage **out, - VipsOperationRelational relational, double *c, int n, ... ) -{ - va_list ap; - VipsArea *area_c; - double *array; - int result; - int i; - - area_c = vips_area_new_array( G_TYPE_DOUBLE, sizeof( double ), n ); - array = (double *) area_c->data; - for( i = 0; i < n; i++ ) - array[i] = a[i]; - - va_start( ap, n ); - result = vips_call_split( "relationalconst", ap, - in, out, relational, area_c ); - va_end( ap ); - - vips_area_unref( area_c ); - - return( result ); -} - -int -vips_relationalconst1( VipsImage *in, VipsImage **out, - VipsOperationRelational relational, double c, ... ) -{ - va_list ap; - VipsArea *area_c; - double *array; - int result; - - area_c = vips_area_new_array( G_TYPE_DOUBLE, sizeof( double ), 1 ); - array = (double *) area_c->data; - array[0] = c; - - va_start( ap, b ); - result = vips_call_split( "relationalconst", ap, - in, out, relational, area_c ); - va_end( ap ); - - vips_area_unref( area_c ); - - return( result ); -} diff --git a/libvips/arithmetic/unaryconst.h b/libvips/arithmetic/unaryconst.h index c57ccf31..12fa11c6 100644 --- a/libvips/arithmetic/unaryconst.h +++ b/libvips/arithmetic/unaryconst.h @@ -36,7 +36,7 @@ extern "C" { #include "unary.h" -#define VIPS_TYPE_UNARY_CONST (vips_unaryconst_get_type()) +#define VIPS_TYPE_UNARY_CONST (vips_unary_const_get_type()) #define VIPS_UNARY_CONST( obj ) \ (G_TYPE_CHECK_INSTANCE_CAST( (obj), \ VIPS_TYPE_UNARY_CONST, VipsUnaryConst )) @@ -58,26 +58,25 @@ typedef struct _VipsUnaryConst { */ VipsArea *c; - /* Our constants expanded to match arith->ready in size. + /* The format the constant should be cast to. Subclasses set this + * ready for unaryconst's build method. + */ + VipsBandFmt const_format; + + /* Our constant expanded to match arith->ready in size and + * const_format in type. */ int n; - double *c_ready; - - /* Our constants further cast to const_format. - */ - PEL *c_type; + PEL *c_ready; } VipsUnaryConst; typedef struct _VipsUnaryConstClass { VipsUnaryClass parent_class; - /* Cast the const to this format for processing. - */ - VipsBandFormat const_format; } VipsUnaryConstClass; -GType vips_unaryconst_get_type( void ); +GType vips_unary_const_get_type( void ); #ifdef __cplusplus } diff --git a/libvips/deprecated/vips7compat.c b/libvips/deprecated/vips7compat.c index 4e2f42e5..98febb5d 100644 --- a/libvips/deprecated/vips7compat.c +++ b/libvips/deprecated/vips7compat.c @@ -1740,3 +1740,100 @@ im_moreeq( IMAGE *in1, IMAGE *in2, IMAGE *out ) return( vips__relational( in1, in2, out, VIPS_OPERATION_RELATIONAL_MOREEQ ) ); } + +static int +vips__relational_vec( IMAGE *in, IMAGE *out, + VipsOperationRelational relational, double *c, int n ) +{ + VipsImage *t; + + if( vips_relational_const( in, &t, relational, c, n, + NULL ) ) + return( -1 ); + if( vips_image_write( t, out ) ) { + g_object_unref( t ); + return( -1 ); + } + g_object_unref( t ); + + return( 0 ); +} + +int +im_equal_vec( VipsImage *in, VipsImage *out, int n, double *c ) +{ + return( vips__relational_vec( in, out, + VIPS_OPERATION_RELATIONAL_EQUAL, c, n ) ); +} + +int +im_notequal_vec( VipsImage *in, VipsImage *out, int n, double *c ) +{ + return( vips__relational_vec( in, out, + VIPS_OPERATION_RELATIONAL_NOTEQUAL, c, n ) ); +} + +int +im_less_vec( VipsImage *in, VipsImage *out, int n, double *c ) +{ + return( vips__relational_vec( in, out, + VIPS_OPERATION_RELATIONAL_LESS, c, n ) ); +} + +int +im_lesseq_vec( VipsImage *in, VipsImage *out, int n, double *c ) +{ + return( vips__relational_vec( in, out, + VIPS_OPERATION_RELATIONAL_LESSEQ, c, n ) ); +} + +int +im_more_vec( VipsImage *in, VipsImage *out, int n, double *c ) +{ + return( vips__relational_vec( in, out, + VIPS_OPERATION_RELATIONAL_MORE, c, n ) ); +} + +int +im_moreeq_vec( VipsImage *in, VipsImage *out, int n, double *c ) +{ + return( vips__relational_vec( in, out, + VIPS_OPERATION_RELATIONAL_MOREEQ, c, n ) ); +} + +int +im_equalconst( IMAGE *in, IMAGE *out, double c ) +{ + return( im_equal_vec( in, out, 1, &c ) ); +} + +int +im_notequalconst( IMAGE *in, IMAGE *out, double c ) +{ + return( im_notequal_vec( in, out, 1, &c ) ); +} + +int +im_lessconst( IMAGE *in, IMAGE *out, double c ) +{ + return( im_less_vec( in, out, 1, &c ) ); +} + +int +im_lesseqconst( IMAGE *in, IMAGE *out, double c ) +{ + return( im_lesseq_vec( in, out, 1, &c ) ); +} + +int +im_moreconst( IMAGE *in, IMAGE *out, double c ) +{ + return( im_more_vec( in, out, 1, &c ) ); +} + +int +im_moreeqconst( IMAGE *in, IMAGE *out, double c ) +{ + return( im_moreeq_vec( in, out, 1, &c ) ); +} + diff --git a/libvips/include/vips/arithmetic.h b/libvips/include/vips/arithmetic.h index f05eeb29..e9730cd3 100644 --- a/libvips/include/vips/arithmetic.h +++ b/libvips/include/vips/arithmetic.h @@ -143,6 +143,12 @@ int vips_round( VipsImage *in, VipsImage **out, VipsOperationRound round, ... ) int vips_relational( VipsImage *left, VipsImage *right, VipsImage **out, VipsOperationRelational relational, ... ) __attribute__((sentinel)); +int vips_relational_const( VipsImage *in, VipsImage **out, + VipsOperationRelational relational, double *c, int n, ... ) + __attribute__((sentinel)); +int vips_relational_const1( VipsImage *in, VipsImage **out, + VipsOperationRelational relational, double c, ... ) + __attribute__((sentinel)); diff --git a/libvips/include/vips/relational.h b/libvips/include/vips/relational.h index 999ffb7f..65d96ca0 100644 --- a/libvips/include/vips/relational.h +++ b/libvips/include/vips/relational.h @@ -37,19 +37,6 @@ extern "C" { #endif /*__cplusplus*/ -int im_equal_vec( VipsImage *in, VipsImage *out, int n, double *c ); -int im_notequal_vec( VipsImage *in, VipsImage *out, int n, double *c ); -int im_less_vec( VipsImage *in, VipsImage *out, int n, double *c ); -int im_lesseq_vec( VipsImage *in, VipsImage *out, int n, double *c ); -int im_more_vec( VipsImage *in, VipsImage *out, int n, double *c ); -int im_moreeq_vec( VipsImage *in, VipsImage *out, int n, double *c ); -int im_equalconst( VipsImage *in, VipsImage *out, double c ); -int im_notequalconst( VipsImage *in, VipsImage *out, double c ); -int im_lessconst( VipsImage *in, VipsImage *out, double c ); -int im_lesseqconst( VipsImage *in, VipsImage *out, double c ); -int im_moreconst( VipsImage *in, VipsImage *out, double c ); -int im_moreeqconst( VipsImage *in, VipsImage *out, double c ); - int im_ifthenelse( VipsImage *c, VipsImage *a, VipsImage *b, VipsImage *out ); int im_blend( VipsImage *c, VipsImage *a, VipsImage *b, VipsImage *out ); diff --git a/libvips/include/vips/vips7compat.h b/libvips/include/vips/vips7compat.h index 1f15b9b4..e44fedae 100644 --- a/libvips/include/vips/vips7compat.h +++ b/libvips/include/vips/vips7compat.h @@ -564,6 +564,19 @@ int im_lesseq( VipsImage *in1, VipsImage *in2, VipsImage *out ); int im_more( VipsImage *in1, VipsImage *in2, VipsImage *out ); int im_moreeq( VipsImage *in1, VipsImage *in2, VipsImage *out ); +int im_equal_vec( VipsImage *in, VipsImage *out, int n, double *c ); +int im_notequal_vec( VipsImage *in, VipsImage *out, int n, double *c ); +int im_less_vec( VipsImage *in, VipsImage *out, int n, double *c ); +int im_lesseq_vec( VipsImage *in, VipsImage *out, int n, double *c ); +int im_more_vec( VipsImage *in, VipsImage *out, int n, double *c ); +int im_moreeq_vec( VipsImage *in, VipsImage *out, int n, double *c ); +int im_equalconst( VipsImage *in, VipsImage *out, double c ); +int im_notequalconst( VipsImage *in, VipsImage *out, double c ); +int im_lessconst( VipsImage *in, VipsImage *out, double c ); +int im_lesseqconst( VipsImage *in, VipsImage *out, double c ); +int im_moreconst( VipsImage *in, VipsImage *out, double c ); +int im_moreeqconst( VipsImage *in, VipsImage *out, double c ); + int im_copy( VipsImage *in, VipsImage *out ); int im_copy_set( VipsImage *in, VipsImage *out, VipsInterpretation interpretation, diff --git a/libvips/relational/Makefile.am b/libvips/relational/Makefile.am index 9eca7265..1ee05237 100644 --- a/libvips/relational/Makefile.am +++ b/libvips/relational/Makefile.am @@ -3,7 +3,6 @@ noinst_LTLIBRARIES = librelational.la librelational_la_SOURCES = \ im_ifthenelse.c \ im_blend.c \ - relational.c \ relational_dispatch.c INCLUDES = -I${top_srcdir}/libvips/include @VIPS_CFLAGS@ @VIPS_INCLUDES@ diff --git a/libvips/relational/relational.c b/libvips/relational/relational.c deleted file mode 100644 index fe524fd9..00000000 --- a/libvips/relational/relational.c +++ /dev/null @@ -1,548 +0,0 @@ -/* relational.c --- various relational operation - * - * Modified: - * 26/7/93 JC - * - >,<,>=,<= tests now as (double) to prevent compiler warnings. Should - * split into int/float cases really for speed. - * 25/1/95 JC - * - partialized - * - updated - * 7/2/95 JC - * - oops! bug with doubles fixed - * 3/7/98 JC - * - vector versions added ... im_equal_vec(), im_lesseq_vec() etc - * - small tidies - * - should be a bit faster, lots of *q++ changed to q[x] - * 10/3/03 JC - * - reworked to remove nested #defines: a bit slower, but much smaller - * - all except _vec forms now work on complex - * 31/7/03 JC - * - oops, relational_format was broken for some combinations - * 23/9/09 - * - gtkdoc - * - use new im__arith_binary*() functions - * - more meta-programming - * 23/6/10 - * - oops, moreconst and moreeqconst were the same - */ - -/* - - This file is part of VIPS. - - VIPS is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - */ - -/* - - These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk - - */ - -#ifdef HAVE_CONFIG_H -#include -#endif /*HAVE_CONFIG_H*/ -#include - -#include -#include - -#include -#include - -#define UC IM_BANDFMT_UCHAR - -/* Type conversions for relational: everything goes to uchar. - */ -static int bandfmt_relational[10] = { -/* UC C US S UI I F X D DX */ - UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, -}; - -#define EQUAL_REAL( Q, A, B ) { \ - if( (A) == (B) ) \ - Q = 255; \ - else \ - Q = 0; \ -} - -#define EQUAL_COMPLEX( Q, A, B ) { \ - if( (A)[0] == (B)[0] && (A)[1] == (B)[1] ) \ - Q = 255; \ - else \ - Q = 0; \ -} - -#define NOTEQUAL_REAL( Q, A, B ) { \ - if( (A) != (B) ) \ - Q = 255; \ - else \ - Q = 0; \ -} - -#define NOTEQUAL_COMPLEX( Q, A, B ) { \ - if( (A)[0] != (B)[0] || (A)[1] != (B)[1] ) \ - Q = 255; \ - else \ - Q = 0; \ -} - -#define LESS_REAL( Q, A, B ) { \ - if( (A) < (B) ) \ - Q = 255; \ - else \ - Q = 0; \ -} - -#define LESS_COMPLEX( Q, A, B ) { \ - double m1 = (A)[0] * (A)[0] + (A)[1] * (A)[1]; \ - double m2 = (B)[0] * (B)[0] + (B)[1] * (B)[1]; \ - \ - if( m1 < m2 ) \ - Q = 255; \ - else \ - Q = 0; \ -} - -#define LESSEQ_REAL( Q, A, B ) { \ - if( (A) <= (B) ) \ - Q = 255; \ - else \ - Q = 0; \ -} - -#define LESSEQ_COMPLEX( Q, A, B ) { \ - double m1 = (A)[0] * (A)[0] + (A)[1] * (A)[1]; \ - double m2 = (B)[0] * (B)[0] + (B)[1] * (B)[1]; \ - \ - if( m1 <= m2 ) \ - Q = 255; \ - else \ - Q = 0; \ -} - -#define RCONST1( IN, FUN ) { \ - IN *tp = (IN *) p; \ - IN tc = *((IN *) vector); \ - \ - for( i = 0; i < ne; i++ ) \ - FUN( q[i], tp[i], tc ); \ -} - -#define CCONST1( IN, FUN ) { \ - IN *tp = (IN *) p; \ - IN *tc = ((IN *) vector); \ - \ - for( i = 0; i < ne; i++ ) { \ - FUN( q[i], tp, tc ); \ - \ - tp += 2; \ - } \ -} - -#define CONST1_BUFFER( NAME, RFUN, CFUN ) \ -static void \ -NAME ## 1_buffer( PEL *p, PEL *q, int n, PEL *vector, IMAGE *im ) \ -{ \ - const int ne = n * im->Bands; \ - \ - int i; \ - \ - switch( im->BandFmt ) { \ - case IM_BANDFMT_CHAR: RCONST1( signed char, RFUN ); break; \ - case IM_BANDFMT_UCHAR: RCONST1( unsigned char, RFUN ); break; \ - case IM_BANDFMT_SHORT: RCONST1( signed short, RFUN ); break; \ - case IM_BANDFMT_USHORT: RCONST1( unsigned short, RFUN ); break; \ - case IM_BANDFMT_INT: RCONST1( signed int, RFUN ); break; \ - case IM_BANDFMT_UINT: RCONST1( unsigned int, RFUN ); break; \ - case IM_BANDFMT_FLOAT: RCONST1( float, RFUN ); break; \ - case IM_BANDFMT_COMPLEX: CCONST1( float, CFUN ); break; \ - case IM_BANDFMT_DOUBLE: RCONST1( double, RFUN ); break; \ - case IM_BANDFMT_DPCOMPLEX: CCONST1( double, CFUN ); break; \ - \ - default: \ - g_assert( 0 ); \ - } \ -} - -#define RCONSTN( IN, FUN ) { \ - IN *tp = (IN *) p; \ - IN *tc = (IN *) vector; \ - \ - for( i = 0, x = 0; x < n; x++ ) \ - for( b = 0; b < bands; b++, i++ ) \ - FUN( q[i], tp[i], tc[b] ); \ -} - -#define CCONSTN( IN, FUN ) { \ - IN *tp = (IN *) p; \ - \ - for( i = 0, x = 0; x < n; x++ ) { \ - IN *tc = ((IN *) vector); \ - \ - for( b = 0; b < bands; b++, i++ ) { \ - FUN( q[i], tp, tc ); \ - \ - tp += 2; \ - tc += 2; \ - } \ - } \ -} - -#define CONSTN_BUFFER( NAME, RFUN, CFUN ) \ -static void \ -NAME ## n_buffer( PEL *p, PEL *q, int n, PEL *vector, IMAGE *im ) \ -{ \ - const int bands = im->Bands; \ - \ - int i, x, b; \ - \ - switch( im->BandFmt ) { \ - case IM_BANDFMT_CHAR: RCONSTN( signed char, RFUN ); break; \ - case IM_BANDFMT_UCHAR: RCONSTN( unsigned char, RFUN ); break; \ - case IM_BANDFMT_SHORT: RCONSTN( signed short, RFUN ); break; \ - case IM_BANDFMT_USHORT: RCONSTN( unsigned short, RFUN ); break; \ - case IM_BANDFMT_INT: RCONSTN( signed int, RFUN ); break; \ - case IM_BANDFMT_UINT: RCONSTN( unsigned int, RFUN ); break; \ - case IM_BANDFMT_FLOAT: RCONSTN( float, RFUN ); break; \ - case IM_BANDFMT_COMPLEX: CCONSTN( float, CFUN ); break; \ - case IM_BANDFMT_DOUBLE: RCONSTN( double, RFUN ); break; \ - case IM_BANDFMT_DPCOMPLEX: CCONSTN( double, CFUN ); break; \ - \ - default: \ - g_assert( 0 ); \ - } \ -} - -CONST1_BUFFER( EQUAL, EQUAL_REAL, EQUAL_COMPLEX ) - -CONSTN_BUFFER( EQUAL, EQUAL_REAL, EQUAL_COMPLEX ) - -/** - * im_equal_vec: - * @in: input #IMAGE - * @out: output #IMAGE - * @n: array length - * @c: array of constants - * - * This operation calculates @in == @c (image element equals constant array - * @c) and writes the result to @out. - * - * See also: im_equal(), im_equalconst(). - * - * Returns: 0 on success, -1 on error - */ -int -im_equal_vec( IMAGE *in, IMAGE *out, int n, double *c ) -{ - return( im__arith_binary_const( "im_equal", - in, out, n, c, in->BandFmt, - bandfmt_relational, - (im_wrapone_fn) EQUAL1_buffer, - (im_wrapone_fn) EQUALn_buffer ) ); -} - -CONST1_BUFFER( NOTEQUAL, NOTEQUAL_REAL, NOTEQUAL_COMPLEX ) - -CONSTN_BUFFER( NOTEQUAL, NOTEQUAL_REAL, NOTEQUAL_COMPLEX ) - -/** - * im_notequal_vec: - * @in: input #IMAGE - * @out: output #IMAGE - * @n: array length - * @c: array of constants - * - * This operation calculates @in != @c (image element is not equal to constant - * array @c) and writes the result to @out. - * - * See also: im_equal(), im_equal_vec(). - * - * Returns: 0 on success, -1 on error - */ -int -im_notequal_vec( IMAGE *in, IMAGE *out, int n, double *c ) -{ - return( im__arith_binary_const( "im_notequal", - in, out, n, c, in->BandFmt, - bandfmt_relational, - (im_wrapone_fn) NOTEQUAL1_buffer, - (im_wrapone_fn) NOTEQUALn_buffer ) ); -} - -CONST1_BUFFER( LESS, LESS_REAL, LESS_COMPLEX ) - -CONSTN_BUFFER( LESS, LESS_REAL, LESS_COMPLEX ) - -/** - * im_less_vec: - * @in: input #IMAGE - * @out: output #IMAGE - * @n: array length - * @c: array of constants - * - * This operation calculates @in < @c (image element is less than constant - * array @c) and writes the result to @out. - * - * See also: im_less(), im_lessconst(). - * - * Returns: 0 on success, -1 on error - */ -int -im_less_vec( IMAGE *in, IMAGE *out, int n, double *c ) -{ - return( im__arith_binary_const( "im_less", - in, out, n, c, in->BandFmt, - bandfmt_relational, - (im_wrapone_fn) LESS1_buffer, - (im_wrapone_fn) LESSn_buffer ) ); -} - -CONST1_BUFFER( LESSEQ, LESSEQ_REAL, LESSEQ_COMPLEX ) - -CONSTN_BUFFER( LESSEQ, LESSEQ_REAL, LESSEQ_COMPLEX ) - -/** - * im_lesseq_vec: - * @in: input #IMAGE - * @out: output #IMAGE - * @n: array length - * @c: array of constants - * - * This operation calculates @in <= @c (image element is less than or equal to - * constant array @c) and writes the result to @out. - * - * See also: im_lesseq(), im_lesseqconst(). - * - * Returns: 0 on success, -1 on error - */ -int -im_lesseq_vec( IMAGE *in, IMAGE *out, int n, double *c ) -{ - return( im__arith_binary_const( "im_lesseq", - in, out, n, c, in->BandFmt, - bandfmt_relational, - (im_wrapone_fn) LESSEQ1_buffer, - (im_wrapone_fn) LESSEQn_buffer ) ); -} - -#define MORE_REAL( Q, A, B ) { \ - if( (A) > (B) ) \ - Q = 255; \ - else \ - Q = 0; \ -} - -#define MORE_COMPLEX( Q, A, B ) { \ - double m1 = (A)[0] * (A)[0] + (A)[1] * (A)[1]; \ - double m2 = (B)[0] * (B)[0] + (B)[1] * (B)[1]; \ - \ - if( m1 > m2 ) \ - Q = 255; \ - else \ - Q = 0; \ -} - -CONST1_BUFFER( MORE, MORE_REAL, MORE_COMPLEX ) - -CONSTN_BUFFER( MORE, MORE_REAL, MORE_COMPLEX ) - -/** - * im_more_vec: - * @in: input #IMAGE - * @out: output #IMAGE - * @n: array length - * @c: array of constants - * - * This operation calculates @in > @c (image element is greater than - * constant array @c) and writes the result to @out. - * - * See also: im_lesseq(), im_lesseqconst(). - * - * Returns: 0 on success, -1 on error - */ -int -im_more_vec( IMAGE *in, IMAGE *out, int n, double *c ) -{ - return( im__arith_binary_const( "im_more", - in, out, n, c, in->BandFmt, - bandfmt_relational, - (im_wrapone_fn) MORE1_buffer, - (im_wrapone_fn) MOREn_buffer ) ); -} - -#define MOREEQ_REAL( Q, A, B ) { \ - if( (A) >= (B) ) \ - Q = 255; \ - else \ - Q = 0; \ -} - -#define MOREEQ_COMPLEX( Q, A, B ) { \ - double m1 = (A)[0] * (A)[0] + (A)[1] * (A)[1]; \ - double m2 = (B)[0] * (B)[0] + (B)[1] * (B)[1]; \ - \ - if( m1 >= m2 ) \ - Q = 255; \ - else \ - Q = 0; \ -} - -CONST1_BUFFER( MOREEQ, MOREEQ_REAL, MOREEQ_COMPLEX ) - -CONSTN_BUFFER( MOREEQ, MOREEQ_REAL, MOREEQ_COMPLEX ) - -/** - * im_moreeq_vec: - * @in: input #IMAGE - * @out: output #IMAGE - * @n: array length - * @c: array of constants - * - * This operation calculates @in >= @c (image element is greater than or - * equal to - * constant array @c) and writes the result to @out. - * - * See also: im_lesseq(), im_lesseqconst(). - * - * Returns: 0 on success, -1 on error - */ -int -im_moreeq_vec( IMAGE *in, IMAGE *out, int n, double *c ) -{ - return( im__arith_binary_const( "im_moreeq", - in, out, n, c, in->BandFmt, - bandfmt_relational, - (im_wrapone_fn) MOREEQ1_buffer, - (im_wrapone_fn) MOREEQn_buffer ) ); -} - -/** - * im_equalconst: - * @in: input #IMAGE - * @out: output #IMAGE - * @c: constant - * - * This operation calculates @in == @c (image element is - * equal to constant @c) and writes the result to @out. - * - * See also: im_lesseq(), im_lesseqconst(). - * - * Returns: 0 on success, -1 on error - */ -int -im_equalconst( IMAGE *in, IMAGE *out, double c ) -{ - return( im_equal_vec( in, out, 1, &c ) ); -} - -/** - * im_notequalconst: - * @in: input #IMAGE - * @out: output #IMAGE - * @c: constant - * - * This operation calculates @in != @c (image element is not equal to - * constant @c) and writes the result to @out. - * - * See also: im_lesseq(), im_lesseqconst(). - * - * Returns: 0 on success, -1 on error - */ -int -im_notequalconst( IMAGE *in, IMAGE *out, double c ) -{ - return( im_notequal_vec( in, out, 1, &c ) ); -} - -/** - * im_lessconst: - * @in: input #IMAGE - * @out: output #IMAGE - * @c: constant - * - * This operation calculates @in < @c (image element is less than - * constant @c) and writes the result to @out. - * - * See also: im_lesseq(), im_lesseqconst(). - * - * Returns: 0 on success, -1 on error - */ -int -im_lessconst( IMAGE *in, IMAGE *out, double c ) -{ - return( im_less_vec( in, out, 1, &c ) ); -} - -/** - * im_lesseqconst: - * @in: input #IMAGE - * @out: output #IMAGE - * @c: constant - * - * This operation calculates @in = @c (image element is less than - * or equal to - * constant @c) and writes the result to @out. - * - * See also: im_lesseq(), im_lesseqconst(). - * - * Returns: 0 on success, -1 on error - */ -int -im_lesseqconst( IMAGE *in, IMAGE *out, double c ) -{ - return( im_lesseq_vec( in, out, 1, &c ) ); -} - -/** - * im_moreconst: - * @in: input #IMAGE - * @out: output #IMAGE - * @c: constant - * - * This operation calculates @in = @c (image element is more than - * constant @c) and writes the result to @out. - * - * See also: im_lesseq(), im_lesseqconst(). - * - * Returns: 0 on success, -1 on error - */ -int -im_moreconst( IMAGE *in, IMAGE *out, double c ) -{ - return( im_more_vec( in, out, 1, &c ) ); -} - -/** - * im_moreeqconst: - * @in: input #IMAGE - * @out: output #IMAGE - * @c: constant - * - * This operation calculates @in = @c (image element is more than - * or equal to - * constant @c) and writes the result to @out. - * - * See also: im_lesseq(), im_lesseqconst(). - * - * Returns: 0 on success, -1 on error - */ -int -im_moreeqconst( IMAGE *in, IMAGE *out, double c ) -{ - return( im_moreeq_vec( in, out, 1, &c ) ); -} -