1 /* relational.c --- various relational operations
2 *
3 * Modified:
4 * 26/7/93 JC
5 * - >,<,>=,<= tests now as (double) to prevent compiler warnings. Should
6 * split into int/float cases really for speed.
7 * 25/1/95 JC
8 * - partialized
9 * - updated
10 * 7/2/95 JC
11 * - oops! bug with doubles fixed
12 * 3/7/98 JC
13 * - vector versions added ... im_equal_vec(), im_lesseq_vec() etc
14 * - small tidies
15 * - should be a bit faster, lots of *q++ changed to q[x]
16 * 10/3/03 JC
17 * - reworked to remove nested #defines: a bit slower, but much smaller
18 * - all except _vec forms now work on complex
19 * 31/7/03 JC
20 * - oops, relational_format was broken for some combinations
21 * 23/9/09
22 * - gtkdoc
23 * - use new im__arith_binary*() functions
24 * - more meta-programming
25 * 23/6/10
26 * - oops, moreconst and moreeqconst were the same
27 * 4/11/11
28 * - redone as a class
29 * 1/2/12
30 * - complex ==, != were broken
31 * 16/7/12
32 * - im1 > im2, im1 >= im2 were broken
33 * 17/9/14
34 * - im1 > im2, im1 >= im2 were still broken, but in a more subtle way
35 */
36
37 /*
38
39 Copyright (C) 1991-2005 The National Gallery
40
41 This library is free software; you can redistribute it and/or
42 modify it under the terms of the GNU Lesser General Public
43 License as published by the Free Software Foundation; either
44 version 2.1 of the License, or (at your option) any later version.
45
46 This library is distributed in the hope that it will be useful,
47 but WITHOUT ANY WARRANTY; without even the implied warranty of
48 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
49 Lesser General Public License for more details.
50
51 You should have received a copy of the GNU Lesser General Public
52 License along with this library; if not, write to the Free Software
53 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
54 02110-1301 USA
55
56 */
57
58 /*
59
60 These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
61
62 */
63
64 /*
65 #define DEBUG
66 */
67
68 #ifdef HAVE_CONFIG_H
69 #include <config.h>
70 #endif /*HAVE_CONFIG_H*/
71 #include <vips/intl.h>
72
73 #include <stdio.h>
74 #include <stdlib.h>
75
76 #include <vips/vips.h>
77
78 #include "binary.h"
79 #include "unaryconst.h"
80
81 typedef struct _VipsRelational {
82 VipsBinary parent_instance;
83
84 VipsOperationRelational relational;
85
86 } VipsRelational;
87
88 typedef VipsBinaryClass VipsRelationalClass;
89
90 G_DEFINE_TYPE( VipsRelational, vips_relational, VIPS_TYPE_BINARY );
91
92 #define RLOOP( TYPE, ROP ) { \
93 TYPE * restrict left = (TYPE *) in0; \
94 TYPE * restrict right = (TYPE *) in1; \
95 VipsPel * restrict q = (VipsPel *) out; \
96 \
97 for( x = 0; x < sz; x++ ) \
98 q[x] = (left[x] ROP right[x]) ? 255 : 0; \
99 }
100
101 #define CLOOP( TYPE, COP ) { \
102 TYPE * restrict left = (TYPE *) in0; \
103 TYPE * restrict right = (TYPE *) in1; \
104 VipsPel * restrict q = (VipsPel *) out; \
105 \
106 for( x = 0; x < sz; x++ ) { \
107 q[x] = COP( left[0], left[1], right[0], right[1]) ? 255 : 0; \
108 \
109 left += 2; \
110 right += 2; \
111 } \
112 }
113
114 #define SWITCH( R, C, ROP, COP ) \
115 switch( vips_image_get_format( im ) ) { \
116 case VIPS_FORMAT_UCHAR: R( unsigned char, ROP ); break; \
117 case VIPS_FORMAT_CHAR: R( signed char, ROP ); break; \
118 case VIPS_FORMAT_USHORT: R( unsigned short, ROP ); break; \
119 case VIPS_FORMAT_SHORT: R( signed short, ROP ); break; \
120 case VIPS_FORMAT_UINT: R( unsigned int, ROP ); break; \
121 case VIPS_FORMAT_INT: R( signed int, ROP ); break; \
122 case VIPS_FORMAT_FLOAT: R( float, ROP ); break; \
123 case VIPS_FORMAT_DOUBLE: R( double, ROP ); break;\
124 case VIPS_FORMAT_COMPLEX: C( float, COP ); break; \
125 case VIPS_FORMAT_DPCOMPLEX: C( double, COP ); break;\
126 \
127 default: \
128 g_assert_not_reached(); \
129 }
130
131 #define CEQUAL( x1, y1, x2, y2 ) (x1 == x2 && y1 == y2)
132 #define CNOTEQ( x1, y1, x2, y2 ) (x1 != x2 || y1 != y2)
133 #define CLESS( x1, y1, x2, y2 ) (x1 * x1 + y1 * y1 < x2 * x2 + y2 * y2)
134 #define CLESSEQ( x1, y1, x2, y2 ) (x1 * x1 + y1 * y1 <= x2 * x2 + y2 * y2)
135 #define CMORE( x1, y1, x2, y2 ) (x1 * x1 + y1 * y1 > x2 * x2 + y2 * y2)
136 #define CMOREEQ( x1, y1, x2, y2 ) (x1 * x1 + y1 * y1 >= x2 * x2 + y2 * y2)
137
138 static void
vips_relational_buffer(VipsArithmetic * arithmetic,VipsPel * out,VipsPel ** in,int width)139 vips_relational_buffer( VipsArithmetic *arithmetic,
140 VipsPel *out, VipsPel **in, int width )
141 {
142 VipsRelational *relational = (VipsRelational *) arithmetic;
143 VipsImage *im = arithmetic->ready[0];
144 const int sz = width * vips_image_get_bands( im );
145
146 VipsOperationRelational op;
147 VipsPel *in0;
148 VipsPel *in1;
149 int x;
150
151 in0 = in[0];
152 in1 = in[1];
153 op = relational->relational;
154
155 if( op == VIPS_OPERATION_RELATIONAL_MORE ) {
156 op = VIPS_OPERATION_RELATIONAL_LESS;
157 VIPS_SWAP( VipsPel *, in0, in1 );
158 }
159
160 if( op == VIPS_OPERATION_RELATIONAL_MOREEQ ) {
161 op = VIPS_OPERATION_RELATIONAL_LESSEQ;
162 VIPS_SWAP( VipsPel *, in0, in1 );
163 }
164
165 switch( op ) {
166 case VIPS_OPERATION_RELATIONAL_EQUAL:
167 SWITCH( RLOOP, CLOOP, ==, CEQUAL );
168 break;
169
170 case VIPS_OPERATION_RELATIONAL_NOTEQ:
171 SWITCH( RLOOP, CLOOP, !=, CNOTEQ );
172 break;
173
174 case VIPS_OPERATION_RELATIONAL_LESS:
175 SWITCH( RLOOP, CLOOP, <, CLESS );
176 break;
177
178 case VIPS_OPERATION_RELATIONAL_LESSEQ:
179 SWITCH( RLOOP, CLOOP, <=, CLESSEQ );
180 break;
181
182 default:
183 g_assert_not_reached();
184 }
185 }
186
187 /* Save a bit of typing.
188 */
189 #define UC VIPS_FORMAT_UCHAR
190 #define C VIPS_FORMAT_CHAR
191 #define US VIPS_FORMAT_USHORT
192 #define S VIPS_FORMAT_SHORT
193 #define UI VIPS_FORMAT_UINT
194 #define I VIPS_FORMAT_INT
195 #define F VIPS_FORMAT_FLOAT
196 #define X VIPS_FORMAT_COMPLEX
197 #define D VIPS_FORMAT_DOUBLE
198 #define DX VIPS_FORMAT_DPCOMPLEX
199
200 static const VipsBandFormat vips_relational_format_table[10] = {
201 /* UC C US S UI I F X D DX */
202 UC, UC, UC, UC, UC, UC, UC, UC, UC, UC
203 };
204
205 static void
vips_relational_class_init(VipsRelationalClass * class)206 vips_relational_class_init( VipsRelationalClass *class )
207 {
208 GObjectClass *gobject_class = G_OBJECT_CLASS( class );
209 VipsObjectClass *object_class = (VipsObjectClass *) class;
210 VipsArithmeticClass *aclass = VIPS_ARITHMETIC_CLASS( class );
211
212 gobject_class->set_property = vips_object_set_property;
213 gobject_class->get_property = vips_object_get_property;
214
215 object_class->nickname = "relational";
216 object_class->description = _( "relational operation on two images" );
217
218 aclass->process_line = vips_relational_buffer;
219
220 vips_arithmetic_set_format_table( aclass,
221 vips_relational_format_table );
222
223 VIPS_ARG_ENUM( class, "relational", 200,
224 _( "Operation" ),
225 _( "relational to perform" ),
226 VIPS_ARGUMENT_REQUIRED_INPUT,
227 G_STRUCT_OFFSET( VipsRelational, relational ),
228 VIPS_TYPE_OPERATION_RELATIONAL,
229 VIPS_OPERATION_RELATIONAL_EQUAL );
230 }
231
232 static void
vips_relational_init(VipsRelational * relational)233 vips_relational_init( VipsRelational *relational )
234 {
235 }
236
237 static int
vips_relationalv(VipsImage * left,VipsImage * right,VipsImage ** out,VipsOperationRelational relational,va_list ap)238 vips_relationalv( VipsImage *left, VipsImage *right, VipsImage **out,
239 VipsOperationRelational relational, va_list ap )
240 {
241 return( vips_call_split( "relational", ap, left, right, out,
242 relational ) );
243 }
244
245 /**
246 * vips_relational:
247 * @left: left-hand input #VipsImage
248 * @right: right-hand input #VipsImage
249 * @out: (out): output #VipsImage
250 * @relational: relational operation to perform
251 * @...: %NULL-terminated list of optional named arguments
252 *
253 * Perform various relational operations on pairs of images.
254 *
255 * The output type is always uchar, with 0 for FALSE and 255 for TRUE.
256 *
257 * Less-than and greater-than for complex images compare the modulus.
258 *
259 * If the images differ in size, the smaller image is enlarged to match the
260 * larger by adding zero pixels along the bottom and right.
261 *
262 * If the number of bands differs, one of the images
263 * must have one band. In this case, an n-band image is formed from the
264 * one-band image by joining n copies of the one-band image together, and then
265 * the two n-band images are operated upon.
266 *
267 * The two input images are cast up to the smallest common format (see table
268 * Smallest common format in
269 * <link linkend="libvips-arithmetic">arithmetic</link>).
270 *
271 * To decide if pixels match exactly, that is have the same value in every
272 * band, use vips_bandbool() after this operation to AND or OR image bands
273 * together.
274 *
275 * See also: vips_boolean(), vips_bandbool(), vips_relational_const().
276 *
277 * Returns: 0 on success, -1 on error
278 */
279 int
vips_relational(VipsImage * left,VipsImage * right,VipsImage ** out,VipsOperationRelational relational,...)280 vips_relational( VipsImage *left, VipsImage *right, VipsImage **out,
281 VipsOperationRelational relational, ... )
282 {
283 va_list ap;
284 int result;
285
286 va_start( ap, relational );
287 result = vips_relationalv( left, right, out, relational, ap );
288 va_end( ap );
289
290 return( result );
291 }
292
293 /**
294 * vips_equal:
295 * @left: left-hand input #VipsImage
296 * @right: right-hand input #VipsImage
297 * @out: (out): output #VipsImage
298 * @...: %NULL-terminated list of optional named arguments
299 *
300 * Perform #VIPS_OPERATION_RELATIONAL_EQUAL on a pair of images. See
301 * vips_relational().
302 *
303 * Returns: 0 on success, -1 on error
304 */
305 int
vips_equal(VipsImage * left,VipsImage * right,VipsImage ** out,...)306 vips_equal( VipsImage *left, VipsImage *right, VipsImage **out, ... )
307 {
308 va_list ap;
309 int result;
310
311 va_start( ap, out );
312 result = vips_relationalv( left, right, out,
313 VIPS_OPERATION_RELATIONAL_EQUAL, ap );
314 va_end( ap );
315
316 return( result );
317 }
318
319 /**
320 * vips_notequal:
321 * @left: left-hand input #VipsImage
322 * @right: right-hand input #VipsImage
323 * @out: (out): output #VipsImage
324 * @...: %NULL-terminated list of optional named arguments
325 *
326 * Perform #VIPS_OPERATION_RELATIONAL_NOTEQ on a pair of images. See
327 * vips_relational().
328 *
329 * Returns: 0 on success, -1 on error
330 */
331 int
vips_notequal(VipsImage * left,VipsImage * right,VipsImage ** out,...)332 vips_notequal( VipsImage *left, VipsImage *right, VipsImage **out, ... )
333 {
334 va_list ap;
335 int result;
336
337 va_start( ap, out );
338 result = vips_relationalv( left, right, out,
339 VIPS_OPERATION_RELATIONAL_NOTEQ, ap );
340 va_end( ap );
341
342 return( result );
343 }
344
345 /**
346 * vips_more:
347 * @left: left-hand input #VipsImage
348 * @right: right-hand input #VipsImage
349 * @out: (out): output #VipsImage
350 * @...: %NULL-terminated list of optional named arguments
351 *
352 * Perform #VIPS_OPERATION_RELATIONAL_MORE on a pair of images. See
353 * vips_relational().
354 *
355 * Returns: 0 on success, -1 on error
356 */
357 int
vips_more(VipsImage * left,VipsImage * right,VipsImage ** out,...)358 vips_more( VipsImage *left, VipsImage *right, VipsImage **out, ... )
359 {
360 va_list ap;
361 int result;
362
363 va_start( ap, out );
364 result = vips_relationalv( left, right, out,
365 VIPS_OPERATION_RELATIONAL_MORE, ap );
366 va_end( ap );
367
368 return( result );
369 }
370
371 /**
372 * vips_moreeq:
373 * @left: left-hand input #VipsImage
374 * @right: right-hand input #VipsImage
375 * @out: (out): output #VipsImage
376 * @...: %NULL-terminated list of optional named arguments
377 *
378 * Perform #VIPS_OPERATION_RELATIONAL_MOREEQ on a pair of images. See
379 * vips_relational().
380 *
381 * Returns: 0 on success, -1 on error
382 */
383 int
vips_moreeq(VipsImage * left,VipsImage * right,VipsImage ** out,...)384 vips_moreeq( VipsImage *left, VipsImage *right, VipsImage **out, ... )
385 {
386 va_list ap;
387 int result;
388
389 va_start( ap, out );
390 result = vips_relationalv( left, right, out,
391 VIPS_OPERATION_RELATIONAL_MOREEQ, ap );
392 va_end( ap );
393
394 return( result );
395 }
396
397 /**
398 * vips_less:
399 * @left: left-hand input #VipsImage
400 * @right: right-hand input #VipsImage
401 * @out: (out): output #VipsImage
402 * @...: %NULL-terminated list of optional named arguments
403 *
404 * Perform #VIPS_OPERATION_RELATIONAL_LESS on a pair of images. See
405 * vips_relational().
406 *
407 * Returns: 0 on success, -1 on error
408 */
409 int
vips_less(VipsImage * left,VipsImage * right,VipsImage ** out,...)410 vips_less( VipsImage *left, VipsImage *right, VipsImage **out, ... )
411 {
412 va_list ap;
413 int result;
414
415 va_start( ap, out );
416 result = vips_relationalv( left, right, out,
417 VIPS_OPERATION_RELATIONAL_LESS, ap );
418 va_end( ap );
419
420 return( result );
421 }
422
423 /**
424 * vips_lesseq:
425 * @left: left-hand input #VipsImage
426 * @right: right-hand input #VipsImage
427 * @out: (out): output #VipsImage
428 * @...: %NULL-terminated list of optional named arguments
429 *
430 * Perform #VIPS_OPERATION_RELATIONAL_LESSEQ on a pair of images. See
431 * vips_relational().
432 *
433 * Returns: 0 on success, -1 on error
434 */
435 int
vips_lesseq(VipsImage * left,VipsImage * right,VipsImage ** out,...)436 vips_lesseq( VipsImage *left, VipsImage *right, VipsImage **out, ... )
437 {
438 va_list ap;
439 int result;
440
441 va_start( ap, out );
442 result = vips_relationalv( left, right, out,
443 VIPS_OPERATION_RELATIONAL_LESSEQ, ap );
444 va_end( ap );
445
446 return( result );
447 }
448
449 typedef struct _VipsRelationalConst {
450 VipsUnaryConst parent_instance;
451
452 VipsOperationRelational relational;
453 } VipsRelationalConst;
454
455 typedef VipsUnaryConstClass VipsRelationalConstClass;
456
457 G_DEFINE_TYPE( VipsRelationalConst,
458 vips_relational_const, VIPS_TYPE_UNARY_CONST );
459
460 #define RLOOPCI( TYPE, OP ) { \
461 TYPE * restrict p = (TYPE *) in[0]; \
462 int * restrict c = uconst->c_int; \
463 \
464 for( i = 0, x = 0; x < width; x++ ) \
465 for( b = 0; b < bands; b++, i++ ) \
466 out[i] = (p[i] OP c[b]) ? 255 : 0; \
467 }
468
469 #define RLOOPCF( TYPE, OP ) { \
470 TYPE * restrict p = (TYPE *) in[0]; \
471 double * restrict c = uconst->c_double; \
472 \
473 for( i = 0, x = 0; x < width; x++ ) \
474 for( b = 0; b < bands; b++, i++ ) \
475 out[i] = (p[i] OP c[b]) ? 255 : 0; \
476 }
477
478 #define CLOOPC( TYPE, OP ) { \
479 TYPE * restrict p = (TYPE *) in[0]; \
480 \
481 for( i = 0, x = 0; x < width; x++ ) { \
482 double * restrict c = uconst->c_double; \
483 \
484 for( b = 0; b < bands; b++, i++ ) { \
485 out[i] = OP( p[0], p[1], c[0], c[1]) ? 255 : 0; \
486 \
487 p += 2; \
488 c += 2; \
489 } \
490 } \
491 }
492
493 static void
vips_relational_const_buffer(VipsArithmetic * arithmetic,VipsPel * out,VipsPel ** in,int width)494 vips_relational_const_buffer( VipsArithmetic *arithmetic,
495 VipsPel *out, VipsPel **in, int width )
496 {
497 VipsUnaryConst *uconst = (VipsUnaryConst *) arithmetic;
498 VipsRelationalConst *rconst = (VipsRelationalConst *) arithmetic;
499 VipsImage *im = arithmetic->ready[0];
500 int bands = im->Bands;
501 gboolean is_int = uconst->is_int &&
502 vips_band_format_isint( im->BandFmt );
503
504 int i, x, b;
505
506 switch( rconst->relational ) {
507 case VIPS_OPERATION_RELATIONAL_EQUAL:
508 if( is_int ) {
509 SWITCH( RLOOPCI, CLOOPC, ==, CEQUAL );
510 }
511 else {
512 SWITCH( RLOOPCF, CLOOPC, ==, CEQUAL );
513 }
514 break;
515
516 case VIPS_OPERATION_RELATIONAL_NOTEQ:
517 if( is_int ) {
518 SWITCH( RLOOPCI, CLOOPC, !=, CNOTEQ );
519 }
520 else {
521 SWITCH( RLOOPCF, CLOOPC, !=, CNOTEQ );
522 }
523 break;
524
525 case VIPS_OPERATION_RELATIONAL_LESS:
526 if( is_int ) {
527 SWITCH( RLOOPCI, CLOOPC, <, CLESS );
528 }
529 else {
530 SWITCH( RLOOPCF, CLOOPC, <, CLESS );
531 }
532 break;
533
534 case VIPS_OPERATION_RELATIONAL_LESSEQ:
535 if( is_int ) {
536 SWITCH( RLOOPCI, CLOOPC, <=, CLESSEQ );
537 }
538 else {
539 SWITCH( RLOOPCF, CLOOPC, <=, CLESSEQ );
540 }
541 break;
542
543 case VIPS_OPERATION_RELATIONAL_MORE:
544 if( is_int ) {
545 SWITCH( RLOOPCI, CLOOPC, >, CMORE );
546 }
547 else {
548 SWITCH( RLOOPCF, CLOOPC, >, CMORE );
549 }
550 break;
551
552 case VIPS_OPERATION_RELATIONAL_MOREEQ:
553 if( is_int ) {
554 SWITCH( RLOOPCI, CLOOPC, >=, CMOREEQ );
555 }
556 else {
557 SWITCH( RLOOPCF, CLOOPC, >=, CMOREEQ );
558 }
559 break;
560
561 default:
562 g_assert_not_reached();
563 }
564 }
565
566 static void
vips_relational_const_class_init(VipsRelationalConstClass * class)567 vips_relational_const_class_init( VipsRelationalConstClass *class )
568 {
569 GObjectClass *gobject_class = G_OBJECT_CLASS( class );
570 VipsObjectClass *object_class = (VipsObjectClass *) class;
571 VipsArithmeticClass *aclass = VIPS_ARITHMETIC_CLASS( class );
572
573 gobject_class->set_property = vips_object_set_property;
574 gobject_class->get_property = vips_object_get_property;
575
576 object_class->nickname = "relational_const";
577 object_class->description =
578 _( "relational operations against a constant" );
579
580 aclass->process_line = vips_relational_const_buffer;
581
582 vips_arithmetic_set_format_table( aclass,
583 vips_relational_format_table );
584
585 VIPS_ARG_ENUM( class, "relational", 200,
586 _( "Operation" ),
587 _( "relational to perform" ),
588 VIPS_ARGUMENT_REQUIRED_INPUT,
589 G_STRUCT_OFFSET( VipsRelationalConst, relational ),
590 VIPS_TYPE_OPERATION_RELATIONAL,
591 VIPS_OPERATION_RELATIONAL_EQUAL );
592 }
593
594 static void
vips_relational_const_init(VipsRelationalConst * relational_const)595 vips_relational_const_init( VipsRelationalConst *relational_const )
596 {
597 }
598
599 static int
vips_relational_constv(VipsImage * in,VipsImage ** out,VipsOperationRelational relational,const double * c,int n,va_list ap)600 vips_relational_constv( VipsImage *in, VipsImage **out,
601 VipsOperationRelational relational, const double *c, int n, va_list ap )
602 {
603 VipsArea *area_c;
604 double *array;
605 int result;
606 int i;
607
608 area_c = vips_area_new_array( G_TYPE_DOUBLE, sizeof( double ), n );
609 array = (double *) area_c->data;
610 for( i = 0; i < n; i++ )
611 array[i] = c[i];
612
613 result = vips_call_split( "relational_const", ap,
614 in, out, relational, area_c );
615
616 vips_area_unref( area_c );
617
618 return( result );
619 }
620
621 /**
622 * vips_relational_const: (method)
623 * @in: input image
624 * @out: (out): output image
625 * @relational: relational operation to perform
626 * @c: (array length=n): array of constants
627 * @n: number of constants in @c
628 * @...: %NULL-terminated list of optional named arguments
629 *
630 * Perform various relational operations on an image and an array of
631 * constants.
632 *
633 * The output type is always uchar, with 0 for FALSE and 255 for TRUE.
634 *
635 * If the array of constants has just one element, that constant is used for
636 * all image bands. If the array has more than one element and they have
637 * the same number of elements as there are bands in the image, then
638 * one array element is used for each band. If the arrays have more than one
639 * element and the image only has a single band, the result is a many-band
640 * image where each band corresponds to one array element.
641 *
642 * See also: vips_boolean(), vips_relational().
643 *
644 * Returns: 0 on success, -1 on error
645 */
646 int
vips_relational_const(VipsImage * in,VipsImage ** out,VipsOperationRelational relational,const double * c,int n,...)647 vips_relational_const( VipsImage *in, VipsImage **out,
648 VipsOperationRelational relational, const double *c, int n, ... )
649 {
650 va_list ap;
651 int result;
652
653 va_start( ap, n );
654 result = vips_relational_constv( in, out, relational, c, n, ap );
655 va_end( ap );
656
657 return( result );
658 }
659
660 /**
661 * vips_equal_const: (method)
662 * @in: input #VipsImage
663 * @out: (out): output #VipsImage
664 * @c: (array length=n): array of constants
665 * @n: number of constants in @c
666 * @...: %NULL-terminated list of optional named arguments
667 *
668 * Perform #VIPS_OPERATION_RELATIONAL_EQUAL on an image and a constant. See
669 * vips_relational_const().
670 *
671 * Returns: 0 on success, -1 on error
672 */
673 int
vips_equal_const(VipsImage * in,VipsImage ** out,const double * c,int n,...)674 vips_equal_const( VipsImage *in, VipsImage **out, const double *c, int n, ... )
675 {
676 va_list ap;
677 int result;
678
679 va_start( ap, n );
680 result = vips_relational_constv( in, out,
681 VIPS_OPERATION_RELATIONAL_EQUAL, c, n, ap );
682 va_end( ap );
683
684 return( result );
685 }
686
687 /**
688 * vips_notequal_const: (method)
689 * @in: input #VipsImage
690 * @out: (out): output #VipsImage
691 * @c: (array length=n): array of constants
692 * @n: number of constants in @c
693 * @...: %NULL-terminated list of optional named arguments
694 *
695 * Perform #VIPS_OPERATION_RELATIONAL_NOTEQ on an image and a constant. See
696 * vips_relational_const().
697 *
698 * Returns: 0 on success, -1 on error
699 */
700 int
vips_notequal_const(VipsImage * in,VipsImage ** out,const double * c,int n,...)701 vips_notequal_const( VipsImage *in, VipsImage **out,
702 const double *c, int n, ... )
703 {
704 va_list ap;
705 int result;
706
707 va_start( ap, n );
708 result = vips_relational_constv( in, out,
709 VIPS_OPERATION_RELATIONAL_NOTEQ, c, n, ap );
710 va_end( ap );
711
712 return( result );
713 }
714
715 /**
716 * vips_less_const: (method)
717 * @in: input #VipsImage
718 * @out: (out): output #VipsImage
719 * @c: (array length=n): array of constants
720 * @n: number of constants in @c
721 * @...: %NULL-terminated list of optional named arguments
722 *
723 * Perform #VIPS_OPERATION_RELATIONAL_LESS on an image and a constant. See
724 * vips_relational_const().
725 *
726 * Returns: 0 on success, -1 on error
727 */
728 int
vips_less_const(VipsImage * in,VipsImage ** out,const double * c,int n,...)729 vips_less_const( VipsImage *in, VipsImage **out, const double *c, int n, ... )
730 {
731 va_list ap;
732 int result;
733
734 va_start( ap, n );
735 result = vips_relational_constv( in, out,
736 VIPS_OPERATION_RELATIONAL_LESS, c, n, ap );
737 va_end( ap );
738
739 return( result );
740 }
741
742 /**
743 * vips_lesseq_const: (method)
744 * @in: input #VipsImage
745 * @out: (out): output #VipsImage
746 * @c: (array length=n): array of constants
747 * @n: number of constants in @c
748 * @...: %NULL-terminated list of optional named arguments
749 *
750 * Perform #VIPS_OPERATION_RELATIONAL_LESSEQ on an image and a constant. See
751 * vips_relational_const().
752 *
753 * Returns: 0 on success, -1 on error
754 */
755 int
vips_lesseq_const(VipsImage * in,VipsImage ** out,const double * c,int n,...)756 vips_lesseq_const( VipsImage *in, VipsImage **out, const double *c, int n, ... )
757 {
758 va_list ap;
759 int result;
760
761 va_start( ap, n );
762 result = vips_relational_constv( in, out,
763 VIPS_OPERATION_RELATIONAL_LESSEQ, c, n, ap );
764 va_end( ap );
765
766 return( result );
767 }
768
769 /**
770 * vips_more_const: (method)
771 * @in: input #VipsImage
772 * @out: (out): output #VipsImage
773 * @c: (array length=n): array of constants
774 * @n: number of constants in @c
775 * @...: %NULL-terminated list of optional named arguments
776 *
777 * Perform #VIPS_OPERATION_RELATIONAL_MORE on an image and a constant. See
778 * vips_relational_const().
779 *
780 * Returns: 0 on success, -1 on error
781 */
782 int
vips_more_const(VipsImage * in,VipsImage ** out,const double * c,int n,...)783 vips_more_const( VipsImage *in, VipsImage **out, const double *c, int n, ... )
784 {
785 va_list ap;
786 int result;
787
788 va_start( ap, n );
789 result = vips_relational_constv( in, out,
790 VIPS_OPERATION_RELATIONAL_MORE, c, n, ap );
791 va_end( ap );
792
793 return( result );
794 }
795
796 /**
797 * vips_moreeq_const: (method)
798 * @in: input #VipsImage
799 * @out: (out): output #VipsImage
800 * @c: (array length=n): array of constants
801 * @n: number of constants in @c
802 * @...: %NULL-terminated list of optional named arguments
803 *
804 * Perform #VIPS_OPERATION_RELATIONAL_MOREEQ on an image and a constant. See
805 * vips_relational_const().
806 *
807 * Returns: 0 on success, -1 on error
808 */
809 int
vips_moreeq_const(VipsImage * in,VipsImage ** out,const double * c,int n,...)810 vips_moreeq_const( VipsImage *in, VipsImage **out, const double *c, int n, ... )
811 {
812 va_list ap;
813 int result;
814
815 va_start( ap, n );
816 result = vips_relational_constv( in, out,
817 VIPS_OPERATION_RELATIONAL_MOREEQ, c, n, ap );
818 va_end( ap );
819
820 return( result );
821 }
822
823 /**
824 * vips_relational_const1: (method)
825 * @in: input image
826 * @out: (out): output image
827 * @relational: relational operation to perform
828 * @c: constant
829 * @...: %NULL-terminated list of optional named arguments
830 *
831 * Perform various relational operations on an image and a constant. See
832 * vips_relational_const().
833 *
834 * See also: vips_boolean(), vips_relational().
835 *
836 * Returns: 0 on success, -1 on error
837 */
838 int
vips_relational_const1(VipsImage * in,VipsImage ** out,VipsOperationRelational relational,double c,...)839 vips_relational_const1( VipsImage *in, VipsImage **out,
840 VipsOperationRelational relational, double c, ... )
841 {
842 va_list ap;
843 int result;
844
845 va_start( ap, c );
846 result = vips_relational_constv( in, out, relational, &c, 1, ap );
847 va_end( ap );
848
849 return( result );
850 }
851
852 /**
853 * vips_equal_const1: (method)
854 * @in: input image
855 * @out: (out): output image
856 * @c: constant
857 * @...: %NULL-terminated list of optional named arguments
858 *
859 * Perform #VIPS_OPERATION_RELATIONAL_EQUAL on an image and a constant. See
860 * vips_relational_const().
861 *
862 * Returns: 0 on success, -1 on error
863 */
864 int
vips_equal_const1(VipsImage * in,VipsImage ** out,double c,...)865 vips_equal_const1( VipsImage *in, VipsImage **out, double c, ... )
866 {
867 va_list ap;
868 int result;
869
870 va_start( ap, c );
871 result = vips_relational_constv( in, out,
872 VIPS_OPERATION_RELATIONAL_EQUAL, &c, 1, ap );
873 va_end( ap );
874
875 return( result );
876 }
877
878 /**
879 * vips_notequal_const1: (method)
880 * @in: input image
881 * @out: (out): output image
882 * @c: constant
883 * @...: %NULL-terminated list of optional named arguments
884 *
885 * Perform #VIPS_OPERATION_RELATIONAL_NOTEQ on an image and a constant. See
886 * vips_relational_const().
887 *
888 * Returns: 0 on success, -1 on error
889 */
890 int
vips_notequal_const1(VipsImage * in,VipsImage ** out,double c,...)891 vips_notequal_const1( VipsImage *in, VipsImage **out, double c, ... )
892 {
893 va_list ap;
894 int result;
895
896 va_start( ap, c );
897 result = vips_relational_constv( in, out,
898 VIPS_OPERATION_RELATIONAL_NOTEQ, &c, 1, ap );
899 va_end( ap );
900
901 return( result );
902 }
903
904 /**
905 * vips_less_const1: (method)
906 * @in: input image
907 * @out: (out): output image
908 * @c: constant
909 * @...: %NULL-terminated list of optional named arguments
910 *
911 * Perform #VIPS_OPERATION_RELATIONAL_LESS on an image and a constant. See
912 * vips_relational_const().
913 *
914 * Returns: 0 on success, -1 on error
915 */
916 int
vips_less_const1(VipsImage * in,VipsImage ** out,double c,...)917 vips_less_const1( VipsImage *in, VipsImage **out, double c, ... )
918 {
919 va_list ap;
920 int result;
921
922 va_start( ap, c );
923 result = vips_relational_constv( in, out,
924 VIPS_OPERATION_RELATIONAL_LESS, &c, 1, ap );
925 va_end( ap );
926
927 return( result );
928 }
929
930 /**
931 * vips_lesseq_const1: (method)
932 * @in: input image
933 * @out: (out): output image
934 * @c: constant
935 * @...: %NULL-terminated list of optional named arguments
936 *
937 * Perform #VIPS_OPERATION_RELATIONAL_LESSEQ on an image and a constant. See
938 * vips_relational_const().
939 *
940 * Returns: 0 on success, -1 on error
941 */
942 int
vips_lesseq_const1(VipsImage * in,VipsImage ** out,double c,...)943 vips_lesseq_const1( VipsImage *in, VipsImage **out, double c, ... )
944 {
945 va_list ap;
946 int result;
947
948 va_start( ap, c );
949 result = vips_relational_constv( in, out,
950 VIPS_OPERATION_RELATIONAL_LESSEQ, &c, 1, ap );
951 va_end( ap );
952
953 return( result );
954 }
955
956 /**
957 * vips_more_const1: (method)
958 * @in: input image
959 * @out: (out): output image
960 * @c: constant
961 * @...: %NULL-terminated list of optional named arguments
962 *
963 * Perform #VIPS_OPERATION_RELATIONAL_MORE on an image and a constant. See
964 * vips_relational_const().
965 *
966 * Returns: 0 on success, -1 on error
967 */
968 int
vips_more_const1(VipsImage * in,VipsImage ** out,double c,...)969 vips_more_const1( VipsImage *in, VipsImage **out, double c, ... )
970 {
971 va_list ap;
972 int result;
973
974 va_start( ap, c );
975 result = vips_relational_constv( in, out,
976 VIPS_OPERATION_RELATIONAL_MORE, &c, 1, ap );
977 va_end( ap );
978
979 return( result );
980 }
981
982 /**
983 * vips_moreeq_const1: (method)
984 * @in: input image
985 * @out: (out): output image
986 * @c: constant
987 * @...: %NULL-terminated list of optional named arguments
988 *
989 * Perform #VIPS_OPERATION_RELATIONAL_MOREEQ on an image and a constant. See
990 * vips_relational_const().
991 *
992 * Returns: 0 on success, -1 on error
993 */
994 int
vips_moreeq_const1(VipsImage * in,VipsImage ** out,double c,...)995 vips_moreeq_const1( VipsImage *in, VipsImage **out, double c, ... )
996 {
997 va_list ap;
998 int result;
999
1000 va_start( ap, c );
1001 result = vips_relational_constv( in, out,
1002 VIPS_OPERATION_RELATIONAL_MOREEQ, &c, 1, ap );
1003 va_end( ap );
1004
1005 return( result );
1006 }
1007
1008