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