/src/libvips/libvips/arithmetic/math2.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* math2.c --- 2ary math funcs |
2 | | * |
3 | | * Copyright: 1990, N. Dessipris |
4 | | * |
5 | | * Author: Nicos Dessipris |
6 | | * Written on: 02/05/1990 |
7 | | * Modified on: |
8 | | * 10/12/93 JC |
9 | | * - now reports total number of x/0, rather than each one. |
10 | | * 1/2/95 JC |
11 | | * - rewritten for PIO with im_wrapone() |
12 | | * - incorrect complex code removed |
13 | | * - /0 reporting removed for ease of programming |
14 | | * 15/4/97 JC |
15 | | * - return( 0 ) missing, oops! |
16 | | * 6/7/98 JC |
17 | | * - _vec form added |
18 | | * 30/8/09 |
19 | | * - gtkdoc |
20 | | * - tiny cleanups |
21 | | * 20/9/09 |
22 | | * - im_powtra() adapted to make math2.c |
23 | | * 12/11/11 |
24 | | * - redone as a class |
25 | | * 17/7/12 |
26 | | * - wopconst was broken |
27 | | * 20/10/21 indus |
28 | | * - add atan2 |
29 | | */ |
30 | | |
31 | | /* |
32 | | |
33 | | Copyright (C) 1991-2005 The National Gallery |
34 | | |
35 | | This library is free software; you can redistribute it and/or |
36 | | modify it under the terms of the GNU Lesser General Public |
37 | | License as published by the Free Software Foundation; either |
38 | | version 2.1 of the License, or (at your option) any later version. |
39 | | |
40 | | This library is distributed in the hope that it will be useful, |
41 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
42 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
43 | | Lesser General Public License for more details. |
44 | | |
45 | | You should have received a copy of the GNU Lesser General Public |
46 | | License along with this library; if not, write to the Free Software |
47 | | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
48 | | 02110-1301 USA |
49 | | |
50 | | */ |
51 | | |
52 | | /* |
53 | | |
54 | | These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk |
55 | | |
56 | | */ |
57 | | |
58 | | /* |
59 | | #define DEBUG |
60 | | */ |
61 | | |
62 | | #ifdef HAVE_CONFIG_H |
63 | | #include <config.h> |
64 | | #endif /*HAVE_CONFIG_H*/ |
65 | | #include <glib/gi18n-lib.h> |
66 | | |
67 | | #include <stdio.h> |
68 | | #include <stdlib.h> |
69 | | #include <math.h> |
70 | | |
71 | | #include <vips/vips.h> |
72 | | |
73 | | #include "binary.h" |
74 | | #include "unaryconst.h" |
75 | | |
76 | | typedef struct _VipsMath2 { |
77 | | VipsBinary parent_instance; |
78 | | |
79 | | VipsOperationMath2 math2; |
80 | | |
81 | | } VipsMath2; |
82 | | |
83 | | typedef VipsBinaryClass VipsMath2Class; |
84 | | |
85 | | G_DEFINE_TYPE(VipsMath2, vips_math2, VIPS_TYPE_BINARY); |
86 | | |
87 | | static int |
88 | | vips_math2_build(VipsObject *object) |
89 | 0 | { |
90 | 0 | VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(object); |
91 | 0 | VipsBinary *binary = (VipsBinary *) object; |
92 | |
|
93 | 0 | if (binary->left && |
94 | 0 | vips_check_noncomplex(class->nickname, binary->left)) |
95 | 0 | return -1; |
96 | 0 | if (binary->right && |
97 | 0 | vips_check_noncomplex(class->nickname, binary->right)) |
98 | 0 | return -1; |
99 | | |
100 | 0 | if (VIPS_OBJECT_CLASS(vips_math2_parent_class)->build(object)) |
101 | 0 | return -1; |
102 | | |
103 | 0 | return 0; |
104 | 0 | } |
105 | | |
106 | | #define LOOP(IN, OUT, OP) \ |
107 | 0 | { \ |
108 | 0 | IN *restrict p1 = (IN *) in[0]; \ |
109 | 0 | IN *restrict p2 = (IN *) in[1]; \ |
110 | 0 | OUT *restrict q = (OUT *) out; \ |
111 | 0 | \ |
112 | 0 | for (x = 0; x < sz; x++) \ |
113 | 0 | OP(q[x], p1[x], p2[x]); \ |
114 | 0 | } |
115 | | |
116 | | #define SWITCH(L, OP) \ |
117 | 0 | switch (vips_image_get_format(im)) { \ |
118 | 0 | case VIPS_FORMAT_UCHAR: \ |
119 | 0 | L(unsigned char, float, OP); \ |
120 | 0 | break; \ |
121 | 0 | case VIPS_FORMAT_CHAR: \ |
122 | 0 | L(signed char, float, OP); \ |
123 | 0 | break; \ |
124 | 0 | case VIPS_FORMAT_USHORT: \ |
125 | 0 | L(unsigned short, float, OP); \ |
126 | 0 | break; \ |
127 | 0 | case VIPS_FORMAT_SHORT: \ |
128 | 0 | L(signed short, float, OP); \ |
129 | 0 | break; \ |
130 | 0 | case VIPS_FORMAT_UINT: \ |
131 | 0 | L(unsigned int, float, OP); \ |
132 | 0 | break; \ |
133 | 0 | case VIPS_FORMAT_INT: \ |
134 | 0 | L(signed int, float, OP); \ |
135 | 0 | break; \ |
136 | 0 | case VIPS_FORMAT_FLOAT: \ |
137 | 0 | L(float, float, OP); \ |
138 | 0 | break; \ |
139 | 0 | case VIPS_FORMAT_DOUBLE: \ |
140 | 0 | L(double, double, OP); \ |
141 | 0 | break; \ |
142 | 0 | \ |
143 | 0 | default: \ |
144 | 0 | g_assert_not_reached(); \ |
145 | 0 | } |
146 | | |
147 | | #define POW(Y, X, E) \ |
148 | 0 | { \ |
149 | 0 | double left = (double) (X); \ |
150 | 0 | double right = (double) (E); \ |
151 | 0 | \ |
152 | 0 | /* Special case for **-1 and **0.5, since they are so common. Also \ |
153 | 0 | * watch for /0. \ |
154 | 0 | */ \ |
155 | 0 | (Y) = (left == 0.0) \ |
156 | 0 | ? 0.0 \ |
157 | 0 | : (right == -1) \ |
158 | 0 | ? 1.0 / left \ |
159 | 0 | : (right == 0.5) \ |
160 | 0 | ? sqrt(left) \ |
161 | 0 | : pow(left, right); \ |
162 | 0 | } |
163 | | |
164 | 0 | #define WOP(Y, X, E) POW(Y, E, X) |
165 | | |
166 | | #define ATAN2(Y, L, R) \ |
167 | 0 | { \ |
168 | 0 | double left = (double) (L); \ |
169 | 0 | double right = (double) (R); \ |
170 | 0 | \ |
171 | 0 | (Y) = VIPS_DEG(atan2(left, right)); \ |
172 | 0 | if ((Y) < 0.0) \ |
173 | 0 | (Y) += 360; \ |
174 | 0 | } |
175 | | |
176 | | static void |
177 | | vips_math2_buffer(VipsArithmetic *arithmetic, |
178 | | VipsPel *out, VipsPel **in, int width) |
179 | 0 | { |
180 | 0 | VipsMath2 *math2 = (VipsMath2 *) arithmetic; |
181 | 0 | VipsImage *im = arithmetic->ready[0]; |
182 | 0 | const int sz = width * vips_image_get_bands(im); |
183 | |
|
184 | 0 | int x; |
185 | |
|
186 | 0 | switch (math2->math2) { |
187 | 0 | case VIPS_OPERATION_MATH2_POW: |
188 | 0 | SWITCH(LOOP, POW); |
189 | 0 | break; |
190 | 0 | case VIPS_OPERATION_MATH2_WOP: |
191 | 0 | SWITCH(LOOP, WOP); |
192 | 0 | break; |
193 | 0 | case VIPS_OPERATION_MATH2_ATAN2: |
194 | 0 | SWITCH(LOOP, ATAN2); |
195 | 0 | break; |
196 | | |
197 | 0 | default: |
198 | 0 | g_assert_not_reached(); |
199 | 0 | } |
200 | 0 | } |
201 | | |
202 | | /* Save a bit of typing. |
203 | | */ |
204 | | #define UC VIPS_FORMAT_UCHAR |
205 | | #define C VIPS_FORMAT_CHAR |
206 | | #define US VIPS_FORMAT_USHORT |
207 | | #define S VIPS_FORMAT_SHORT |
208 | | #define UI VIPS_FORMAT_UINT |
209 | | #define I VIPS_FORMAT_INT |
210 | | #define F VIPS_FORMAT_FLOAT |
211 | | #define X VIPS_FORMAT_COMPLEX |
212 | | #define D VIPS_FORMAT_DOUBLE |
213 | | #define DX VIPS_FORMAT_DPCOMPLEX |
214 | | |
215 | | /* Type promotion for math2. Keep in sync with math2_buffer() above. |
216 | | */ |
217 | | static const VipsBandFormat vips_math2_format_table[10] = { |
218 | | /* Band format: UC C US S UI I F X D DX */ |
219 | | /* Promotion: */ F, F, F, F, F, F, F, X, D, DX |
220 | | }; |
221 | | |
222 | | static void |
223 | | vips_math2_class_init(VipsMath2Class *class) |
224 | 1 | { |
225 | 1 | GObjectClass *gobject_class = G_OBJECT_CLASS(class); |
226 | 1 | VipsObjectClass *object_class = (VipsObjectClass *) class; |
227 | 1 | VipsArithmeticClass *aclass = VIPS_ARITHMETIC_CLASS(class); |
228 | | |
229 | 1 | gobject_class->set_property = vips_object_set_property; |
230 | 1 | gobject_class->get_property = vips_object_get_property; |
231 | | |
232 | 1 | object_class->nickname = "math2"; |
233 | 1 | object_class->description = _("binary math operations"); |
234 | 1 | object_class->build = vips_math2_build; |
235 | | |
236 | 1 | aclass->process_line = vips_math2_buffer; |
237 | | |
238 | 1 | vips_arithmetic_set_format_table(aclass, vips_math2_format_table); |
239 | | |
240 | 1 | VIPS_ARG_ENUM(class, "math2", 200, |
241 | 1 | _("Operation"), |
242 | 1 | _("Math to perform"), |
243 | 1 | VIPS_ARGUMENT_REQUIRED_INPUT, |
244 | 1 | G_STRUCT_OFFSET(VipsMath2, math2), |
245 | 1 | VIPS_TYPE_OPERATION_MATH2, VIPS_OPERATION_MATH2_POW); |
246 | 1 | } |
247 | | |
248 | | static void |
249 | | vips_math2_init(VipsMath2 *math2) |
250 | 0 | { |
251 | 0 | } |
252 | | |
253 | | static int |
254 | | vips_math2v(VipsImage *left, VipsImage *right, VipsImage **out, |
255 | | VipsOperationMath2 math2, va_list ap) |
256 | 0 | { |
257 | 0 | return vips_call_split("math2", ap, left, right, out, math2); |
258 | 0 | } |
259 | | |
260 | | /** |
261 | | * vips_math2: |
262 | | * @left: left-hand input #VipsImage |
263 | | * @right: right-hand input #VipsImage |
264 | | * @out: (out): output #VipsImage |
265 | | * @math2: math operation to perform |
266 | | * @...: %NULL-terminated list of optional named arguments |
267 | | * |
268 | | * This operation calculates a 2-ary maths operation on a pair of images |
269 | | * and writes the result to @out. The images may have any |
270 | | * non-complex format. @out is float except in the case that either of @left |
271 | | * or @right are double, in which case @out is also double. |
272 | | * |
273 | | * It detects division by zero, setting those pixels to zero in the output. |
274 | | * Beware: it does this silently! |
275 | | * |
276 | | * If the images differ in size, the smaller image is enlarged to match the |
277 | | * larger by adding zero pixels along the bottom and right. |
278 | | * |
279 | | * If the number of bands differs, one of the images |
280 | | * must have one band. In this case, an n-band image is formed from the |
281 | | * one-band image by joining n copies of the one-band image together, and then |
282 | | * the two n-band images are operated upon. |
283 | | * |
284 | | * The two input images are cast up to the smallest common format (see table |
285 | | * Smallest common format in |
286 | | * <link linkend="libvips-arithmetic">arithmetic</link>), and that format is the |
287 | | * result type. |
288 | | * |
289 | | * See also: vips_math2_const(). |
290 | | * |
291 | | * Returns: 0 on success, -1 on error |
292 | | */ |
293 | | int |
294 | | vips_math2(VipsImage *left, VipsImage *right, VipsImage **out, |
295 | | VipsOperationMath2 math2, ...) |
296 | 0 | { |
297 | 0 | va_list ap; |
298 | 0 | int result; |
299 | |
|
300 | 0 | va_start(ap, math2); |
301 | 0 | result = vips_math2v(left, right, out, math2, ap); |
302 | 0 | va_end(ap); |
303 | |
|
304 | 0 | return result; |
305 | 0 | } |
306 | | |
307 | | /** |
308 | | * vips_pow: |
309 | | * @left: left-hand input #VipsImage |
310 | | * @right: right-hand input #VipsImage |
311 | | * @out: (out): output #VipsImage |
312 | | * @...: %NULL-terminated list of optional named arguments |
313 | | * |
314 | | * Perform #VIPS_OPERATION_MATH2_POW on a pair of images. See |
315 | | * vips_math2(). |
316 | | * |
317 | | * Returns: 0 on success, -1 on error |
318 | | */ |
319 | | int |
320 | | vips_pow(VipsImage *left, VipsImage *right, VipsImage **out, ...) |
321 | 0 | { |
322 | 0 | va_list ap; |
323 | 0 | int result; |
324 | |
|
325 | 0 | va_start(ap, out); |
326 | 0 | result = vips_math2v(left, right, out, VIPS_OPERATION_MATH2_POW, ap); |
327 | 0 | va_end(ap); |
328 | |
|
329 | 0 | return result; |
330 | 0 | } |
331 | | |
332 | | /** |
333 | | * vips_wop: |
334 | | * @left: left-hand input #VipsImage |
335 | | * @right: right-hand input #VipsImage |
336 | | * @out: (out): output #VipsImage |
337 | | * @...: %NULL-terminated list of optional named arguments |
338 | | * |
339 | | * Perform #VIPS_OPERATION_MATH2_WOP on a pair of images. See |
340 | | * vips_math2(). |
341 | | * |
342 | | * Returns: 0 on success, -1 on error |
343 | | */ |
344 | | int |
345 | | vips_wop(VipsImage *left, VipsImage *right, VipsImage **out, ...) |
346 | 0 | { |
347 | 0 | va_list ap; |
348 | 0 | int result; |
349 | |
|
350 | 0 | va_start(ap, out); |
351 | 0 | result = vips_math2v(left, right, out, VIPS_OPERATION_MATH2_WOP, ap); |
352 | 0 | va_end(ap); |
353 | |
|
354 | 0 | return result; |
355 | 0 | } |
356 | | |
357 | | /** |
358 | | * vips_atan2: |
359 | | * @left: left-hand input #VipsImage |
360 | | * @right: right-hand input #VipsImage |
361 | | * @out: (out): output #VipsImage |
362 | | * @...: %NULL-terminated list of optional named arguments |
363 | | * |
364 | | * Perform #VIPS_OPERATION_MATH2_ATAN2 on a pair of images. See |
365 | | * vips_math2(). |
366 | | * |
367 | | * Returns: 0 on success, -1 on error |
368 | | */ |
369 | | int |
370 | | vips_atan2(VipsImage *left, VipsImage *right, VipsImage **out, ...) |
371 | 0 | { |
372 | 0 | va_list ap; |
373 | 0 | int result; |
374 | |
|
375 | 0 | va_start(ap, out); |
376 | 0 | result = vips_math2v(left, right, out, VIPS_OPERATION_MATH2_ATAN2, ap); |
377 | 0 | va_end(ap); |
378 | |
|
379 | 0 | return result; |
380 | 0 | } |
381 | | |
382 | | typedef struct _VipsMath2Const { |
383 | | VipsUnaryConst parent_instance; |
384 | | |
385 | | VipsOperationMath2 math2; |
386 | | |
387 | | } VipsMath2Const; |
388 | | |
389 | | typedef VipsUnaryConstClass VipsMath2ConstClass; |
390 | | |
391 | | G_DEFINE_TYPE(VipsMath2Const, |
392 | | vips_math2_const, VIPS_TYPE_UNARY_CONST); |
393 | | |
394 | | static int |
395 | | vips_math2_const_build(VipsObject *object) |
396 | 0 | { |
397 | 0 | VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(object); |
398 | 0 | VipsUnary *unary = (VipsUnary *) object; |
399 | |
|
400 | 0 | if (unary->in && |
401 | 0 | vips_check_noncomplex(class->nickname, unary->in)) |
402 | 0 | return -1; |
403 | | |
404 | 0 | if (VIPS_OBJECT_CLASS(vips_math2_const_parent_class)->build(object)) |
405 | 0 | return -1; |
406 | | |
407 | 0 | return 0; |
408 | 0 | } |
409 | | |
410 | | #define LOOPC(IN, OUT, OP) \ |
411 | 0 | { \ |
412 | 0 | IN *restrict p = (IN *) in[0]; \ |
413 | 0 | OUT *restrict q = (OUT *) out; \ |
414 | 0 | double *restrict c = uconst->c_double; \ |
415 | 0 | \ |
416 | 0 | for (i = 0, x = 0; x < width; x++) \ |
417 | 0 | for (b = 0; b < bands; b++, i++) \ |
418 | 0 | OP(q[i], p[i], c[b]); \ |
419 | 0 | } |
420 | | |
421 | | static void |
422 | | vips_math2_const_buffer(VipsArithmetic *arithmetic, |
423 | | VipsPel *out, VipsPel **in, int width) |
424 | 0 | { |
425 | 0 | VipsUnaryConst *uconst = (VipsUnaryConst *) arithmetic; |
426 | 0 | VipsMath2Const *math2 = (VipsMath2Const *) arithmetic; |
427 | 0 | VipsImage *im = arithmetic->ready[0]; |
428 | 0 | int bands = im->Bands; |
429 | |
|
430 | 0 | int i, x, b; |
431 | |
|
432 | 0 | switch (math2->math2) { |
433 | 0 | case VIPS_OPERATION_MATH2_POW: |
434 | 0 | SWITCH(LOOPC, POW); |
435 | 0 | break; |
436 | | |
437 | 0 | case VIPS_OPERATION_MATH2_WOP: |
438 | 0 | SWITCH(LOOPC, WOP); |
439 | 0 | break; |
440 | | |
441 | 0 | case VIPS_OPERATION_MATH2_ATAN2: |
442 | 0 | SWITCH(LOOPC, ATAN2); |
443 | 0 | break; |
444 | | |
445 | 0 | default: |
446 | 0 | g_assert_not_reached(); |
447 | 0 | break; |
448 | 0 | } |
449 | 0 | } |
450 | | |
451 | | static void |
452 | | vips_math2_const_class_init(VipsMath2ConstClass *class) |
453 | 1 | { |
454 | 1 | GObjectClass *gobject_class = G_OBJECT_CLASS(class); |
455 | 1 | VipsObjectClass *object_class = (VipsObjectClass *) class; |
456 | 1 | VipsArithmeticClass *aclass = VIPS_ARITHMETIC_CLASS(class); |
457 | | |
458 | 1 | gobject_class->set_property = vips_object_set_property; |
459 | 1 | gobject_class->get_property = vips_object_get_property; |
460 | | |
461 | 1 | object_class->nickname = "math2_const"; |
462 | 1 | object_class->description = |
463 | 1 | _("binary math operations with a constant"); |
464 | 1 | object_class->build = vips_math2_const_build; |
465 | | |
466 | 1 | aclass->process_line = vips_math2_const_buffer; |
467 | | |
468 | 1 | vips_arithmetic_set_format_table(aclass, vips_math2_format_table); |
469 | | |
470 | 1 | VIPS_ARG_ENUM(class, "math2", 200, |
471 | 1 | _("Operation"), |
472 | 1 | _("Math to perform"), |
473 | 1 | VIPS_ARGUMENT_REQUIRED_INPUT, |
474 | 1 | G_STRUCT_OFFSET(VipsMath2Const, math2), |
475 | 1 | VIPS_TYPE_OPERATION_MATH2, VIPS_OPERATION_MATH2_POW); |
476 | 1 | } |
477 | | |
478 | | static void |
479 | | vips_math2_const_init(VipsMath2Const *math2_const) |
480 | 0 | { |
481 | 0 | } |
482 | | |
483 | | static int |
484 | | vips_math2_constv(VipsImage *in, VipsImage **out, |
485 | | VipsOperationMath2 math2, const double *c, int n, va_list ap) |
486 | 0 | { |
487 | 0 | VipsArea *area_c; |
488 | 0 | double *array; |
489 | 0 | int result; |
490 | 0 | int i; |
491 | |
|
492 | 0 | area_c = vips_area_new_array(G_TYPE_DOUBLE, sizeof(double), n); |
493 | 0 | array = (double *) area_c->data; |
494 | 0 | for (i = 0; i < n; i++) |
495 | 0 | array[i] = c[i]; |
496 | |
|
497 | 0 | result = vips_call_split("math2_const", ap, in, out, math2, area_c); |
498 | |
|
499 | 0 | vips_area_unref(area_c); |
500 | |
|
501 | 0 | return result; |
502 | 0 | } |
503 | | |
504 | | /** |
505 | | * vips_math2_const: (method) |
506 | | * @in: input image |
507 | | * @out: (out): output image |
508 | | * @math2: math operation to perform |
509 | | * @c: (array length=n): array of constants |
510 | | * @n: number of constants in @c |
511 | | * @...: %NULL-terminated list of optional named arguments |
512 | | * |
513 | | * This operation calculates various 2-ary maths operations on an image and |
514 | | * an array of constants and writes the result to @out. |
515 | | * The image may have any |
516 | | * non-complex format. @out is float except in the case that @in |
517 | | * is double, in which case @out is also double. |
518 | | * |
519 | | * It detects division by zero, setting those pixels to zero in the output. |
520 | | * Beware: it does this silently! |
521 | | * |
522 | | * If the array of constants has just one element, that constant is used for |
523 | | * all image bands. If the array has more than one element and they have |
524 | | * the same number of elements as there are bands in the image, then |
525 | | * one array element is used for each band. If the arrays have more than one |
526 | | * element and the image only has a single band, the result is a many-band |
527 | | * image where each band corresponds to one array element. |
528 | | * |
529 | | * See also: vips_math2(), vips_math(). |
530 | | * |
531 | | * Returns: 0 on success, -1 on error |
532 | | */ |
533 | | int |
534 | | vips_math2_const(VipsImage *in, VipsImage **out, |
535 | | VipsOperationMath2 math2, const double *c, int n, ...) |
536 | 0 | { |
537 | 0 | va_list ap; |
538 | 0 | int result; |
539 | |
|
540 | 0 | va_start(ap, n); |
541 | 0 | result = vips_math2_constv(in, out, math2, c, n, ap); |
542 | 0 | va_end(ap); |
543 | |
|
544 | 0 | return result; |
545 | 0 | } |
546 | | |
547 | | /** |
548 | | * vips_pow_const: (method) |
549 | | * @in: left-hand input #VipsImage |
550 | | * @out: (out): output #VipsImage |
551 | | * @c: (array length=n): array of constants |
552 | | * @n: number of constants in @c |
553 | | * @...: %NULL-terminated list of optional named arguments |
554 | | * |
555 | | * Perform #VIPS_OPERATION_MATH2_POW on an image and a constant. See |
556 | | * vips_math2_const(). |
557 | | * |
558 | | * Returns: 0 on success, -1 on error |
559 | | */ |
560 | | int |
561 | | vips_pow_const(VipsImage *in, VipsImage **out, const double *c, int n, ...) |
562 | 0 | { |
563 | 0 | va_list ap; |
564 | 0 | int result; |
565 | |
|
566 | 0 | va_start(ap, n); |
567 | 0 | result = vips_math2_constv(in, out, |
568 | 0 | VIPS_OPERATION_MATH2_POW, c, n, ap); |
569 | 0 | va_end(ap); |
570 | |
|
571 | 0 | return result; |
572 | 0 | } |
573 | | |
574 | | /** |
575 | | * vips_wop_const: (method) |
576 | | * @in: left-hand input #VipsImage |
577 | | * @out: (out): output #VipsImage |
578 | | * @c: (array length=n): array of constants |
579 | | * @n: number of constants in @c |
580 | | * @...: %NULL-terminated list of optional named arguments |
581 | | * |
582 | | * Perform #VIPS_OPERATION_MATH2_WOP on an image and a constant. See |
583 | | * vips_math2_const(). |
584 | | * |
585 | | * Returns: 0 on success, -1 on error |
586 | | */ |
587 | | int |
588 | | vips_wop_const(VipsImage *in, VipsImage **out, const double *c, int n, ...) |
589 | 0 | { |
590 | 0 | va_list ap; |
591 | 0 | int result; |
592 | |
|
593 | 0 | va_start(ap, n); |
594 | 0 | result = vips_math2_constv(in, out, |
595 | 0 | VIPS_OPERATION_MATH2_WOP, c, n, ap); |
596 | 0 | va_end(ap); |
597 | |
|
598 | 0 | return result; |
599 | 0 | } |
600 | | |
601 | | /** |
602 | | * vips_atan2_const: (method) |
603 | | * @in: left-hand input #VipsImage |
604 | | * @out: (out): output #VipsImage |
605 | | * @c: (array length=n): array of constants |
606 | | * @n: number of constants in @c |
607 | | * @...: %NULL-terminated list of optional named arguments |
608 | | * |
609 | | * Perform #VIPS_OPERATION_MATH2_ATAN2 on an image and a constant. See |
610 | | * vips_math2_const(). |
611 | | * |
612 | | * Returns: 0 on success, -1 on error |
613 | | */ |
614 | | int |
615 | | vips_atan2_const(VipsImage *in, VipsImage **out, const double *c, int n, ...) |
616 | 0 | { |
617 | 0 | va_list ap; |
618 | 0 | int result; |
619 | |
|
620 | 0 | va_start(ap, n); |
621 | 0 | result = vips_math2_constv(in, out, |
622 | 0 | VIPS_OPERATION_MATH2_ATAN2, c, n, ap); |
623 | 0 | va_end(ap); |
624 | |
|
625 | 0 | return result; |
626 | 0 | } |
627 | | |
628 | | /** |
629 | | * vips_math2_const1: (method) |
630 | | * @in: input image |
631 | | * @out: (out): output image |
632 | | * @math2: math operation to perform |
633 | | * @c: constant |
634 | | * @...: %NULL-terminated list of optional named arguments |
635 | | * |
636 | | * This operation calculates various 2-ary maths operations on an image and |
637 | | * a constant. See vips_math2_const(). |
638 | | * |
639 | | * Returns: 0 on success, -1 on error |
640 | | */ |
641 | | int |
642 | | vips_math2_const1(VipsImage *in, VipsImage **out, |
643 | | VipsOperationMath2 math2, double c, ...) |
644 | 0 | { |
645 | 0 | va_list ap; |
646 | 0 | int result; |
647 | |
|
648 | 0 | va_start(ap, c); |
649 | 0 | result = vips_math2_constv(in, out, math2, &c, 1, ap); |
650 | 0 | va_end(ap); |
651 | |
|
652 | 0 | return result; |
653 | 0 | } |
654 | | |
655 | | /** |
656 | | * vips_pow_const1: (method) |
657 | | * @in: left-hand input #VipsImage |
658 | | * @out: (out): output #VipsImage |
659 | | * @c: constant |
660 | | * @...: %NULL-terminated list of optional named arguments |
661 | | * |
662 | | * Perform #VIPS_OPERATION_MATH2_POW on an image and a constant. See |
663 | | * vips_math2_const(). |
664 | | * |
665 | | * Returns: 0 on success, -1 on error |
666 | | */ |
667 | | int |
668 | | vips_pow_const1(VipsImage *in, VipsImage **out, double c, ...) |
669 | 0 | { |
670 | 0 | va_list ap; |
671 | 0 | int result; |
672 | |
|
673 | 0 | va_start(ap, c); |
674 | 0 | result = vips_math2_constv(in, out, |
675 | 0 | VIPS_OPERATION_MATH2_POW, &c, 1, ap); |
676 | 0 | va_end(ap); |
677 | |
|
678 | 0 | return result; |
679 | 0 | } |
680 | | |
681 | | /** |
682 | | * vips_wop_const1: (method) |
683 | | * @in: left-hand input #VipsImage |
684 | | * @out: (out): output #VipsImage |
685 | | * @c: constant |
686 | | * @...: %NULL-terminated list of optional named arguments |
687 | | * |
688 | | * Perform #VIPS_OPERATION_MATH2_WOP on an image and a constant. See |
689 | | * vips_math2_const(). |
690 | | * |
691 | | * Returns: 0 on success, -1 on error |
692 | | */ |
693 | | int |
694 | | vips_wop_const1(VipsImage *in, VipsImage **out, double c, ...) |
695 | 0 | { |
696 | 0 | va_list ap; |
697 | 0 | int result; |
698 | |
|
699 | 0 | va_start(ap, c); |
700 | 0 | result = vips_math2_constv(in, out, |
701 | 0 | VIPS_OPERATION_MATH2_WOP, &c, 1, ap); |
702 | 0 | va_end(ap); |
703 | |
|
704 | 0 | return result; |
705 | 0 | } |
706 | | |
707 | | /** |
708 | | * vips_atan2_const1: (method) |
709 | | * @in: left-hand input #VipsImage |
710 | | * @out: (out): output #VipsImage |
711 | | * @c: constant |
712 | | * @...: %NULL-terminated list of optional named arguments |
713 | | * |
714 | | * Perform #VIPS_OPERATION_MATH2_ATAN2 on an image and a constant. See |
715 | | * vips_math2_const(). |
716 | | * |
717 | | * Returns: 0 on success, -1 on error |
718 | | */ |
719 | | int |
720 | | vips_atan2_const1(VipsImage *in, VipsImage **out, double c, ...) |
721 | 0 | { |
722 | 0 | va_list ap; |
723 | 0 | int result; |
724 | |
|
725 | 0 | va_start(ap, c); |
726 | 0 | result = vips_math2_constv(in, out, |
727 | 0 | VIPS_OPERATION_MATH2_ATAN2, &c, 1, ap); |
728 | 0 | va_end(ap); |
729 | |
|
730 | 0 | return result; |
731 | 0 | } |