Coverage Report

Created: 2025-01-28 06:32

/src/libvips/libvips/conversion/cast.c
Line
Count
Source (jump to first uncovered line)
1
/* cast an image to a numerical format
2
 *
3
 * Author: Nicos Dessipris
4
 * Written on: 07/03/1991
5
 * Modified on:
6
 * 04/05/1992 JC
7
 *  - works for char, uchar too
8
 *  - floating point code removed from integer clip operations
9
 *  - uses nint() instead of own rounding code
10
 *  - calculated the number of >255 clips for float/double input
11
 *    incorrectly
12
 *  - rejects complex input correctly now
13
 * 27/4/93 JC
14
 *  - adapted to work with partial images
15
 *  - nint() removed, now just +0.5
16
 *  - im_warning code removed
17
 * 30/6/93 JC
18
 *  - adapted for partial v2
19
 * 31/8/93 JC
20
 *  - now detects and prints over/underflows
21
 * 27/10/93 JC
22
 *  - unsigned integer clips now faster!
23
 *  - falls back to im_copy() correctly
24
 * 5/5/94 JC
25
 *  - switched to rint()
26
 * 18/8/94 JC
27
 *  - now uses evalend callback
28
 * 9/5/95 JC
29
 *  - now does complex too
30
 * 11/7/95 JC
31
 *  - now uses IM_RINT() macro
32
 * 10/3/01 JC
33
 *  - slightly faster and simpler
34
 *  - generalised to im_clip2fmt(), all other clippers now just call
35
 *    this
36
 * 21/4/04 JC
37
 *  - now does floor(), not rint() ... you'll need to round yourself
38
 *    before calling this if you want round-to-nearest
39
 * 7/11/07
40
 *  - use new evalstart/evalend system
41
 * 26/8/08
42
 *  - oops, complex->complex conversion was broken
43
 * 27/1/10
44
 *  - modernised
45
 *  - gtk-doc
46
 * 27/10/11
47
 *  - redone as a class
48
 * 10/4/12
49
 *  - cast to uint now removes <0 values
50
 * 11/2/15
51
 *  - add @shift option
52
 * 1/3/16
53
 *  - better behaviour for shift of non-int types (thanks apacheark)
54
 * 14/11/18
55
 *  - revise for better uint/int clipping [erdmann]
56
 *  - remove old overflow/underflow detect
57
 * 8/12/20
58
 *  - fix range clip in int32 -> unsigned casts [ewelot]
59
 */
60
61
/*
62
63
  This file is part of VIPS.
64
65
  VIPS is free software; you can redistribute it and/or modify
66
  it under the terms of the GNU Lesser General Public License as published by
67
  the Free Software Foundation; either version 2 of the License, or
68
  (at your option) any later version.
69
70
  This program is distributed in the hope that it will be useful,
71
  but WITHOUT ANY WARRANTY; without even the implied warranty of
72
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
73
  GNU Lesser General Public License for more details.
74
75
  You should have received a copy of the GNU Lesser General Public License
76
  along with this program; if not, write to the Free Software
77
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
78
  02110-1301  USA
79
80
 */
81
82
/*
83
84
  These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
85
86
 */
87
88
/*
89
#define VIPS_DEBUG
90
 */
91
92
#ifdef HAVE_CONFIG_H
93
#include <config.h>
94
#endif /*HAVE_CONFIG_H*/
95
#include <glib/gi18n-lib.h>
96
97
#include <stdio.h>
98
#include <string.h>
99
#include <stdlib.h>
100
#include <math.h>
101
102
#include <vips/vips.h>
103
#include <vips/internal.h>
104
#include <vips/debug.h>
105
106
#include "pconversion.h"
107
108
typedef struct _VipsCast {
109
  VipsConversion parent_instance;
110
111
  VipsImage *in;
112
  VipsBandFormat format;
113
  gboolean shift;
114
115
} VipsCast;
116
117
typedef VipsConversionClass VipsCastClass;
118
119
G_DEFINE_TYPE(VipsCast, vips_cast, VIPS_TYPE_CONVERSION);
120
121
/* Cast down from an int.
122
 */
123
4.68k
#define CAST_UCHAR(X) VIPS_CLIP(0, (X), UCHAR_MAX)
124
2.94k
#define CAST_CHAR(X) VIPS_CLIP(SCHAR_MIN, (X), SCHAR_MAX)
125
1.86k
#define CAST_USHORT(X) VIPS_CLIP(0, (X), USHRT_MAX)
126
1.69k
#define CAST_SHORT(X) VIPS_CLIP(SHRT_MIN, (X), SHRT_MAX)
127
128
/* These cast down from gint64 to uint32 or int32.
129
 */
130
2.00k
#define CAST_UINT(X) VIPS_CLIP(0, (X), UINT_MAX)
131
3.08k
#define CAST_INT(X) VIPS_CLIP(INT_MIN, (X), INT_MAX)
132
133
/* Rightshift an integer type, ie. sizeof(ITYPE) >= sizeof(OTYPE).
134
 *
135
 * If we're casting between two formats of the same size (eg. ushort to
136
 * short), sizes can be equal.
137
 */
138
#define SHIFT_RIGHT(ITYPE, OTYPE) \
139
0
  { \
140
0
    ITYPE *restrict p = (ITYPE *) in; \
141
0
    OTYPE *restrict q = (OTYPE *) out; \
142
0
    int n = ((int) sizeof(ITYPE) << 3) - ((int) sizeof(OTYPE) << 3); \
143
0
\
144
0
    g_assert(sizeof(ITYPE) >= sizeof(OTYPE)); \
145
0
\
146
0
    for (x = 0; x < sz; x++) \
147
0
      q[x] = p[x] >> n; \
148
0
  }
149
150
/* Leftshift an integer type, ie. sizeof(ITYPE) <= sizeof(OTYPE). We need to
151
 * copy the bottom bit up into the fresh new bits.
152
 */
153
#define SHIFT_LEFT(ITYPE, OTYPE) \
154
0
  { \
155
0
    ITYPE *restrict p = (ITYPE *) in; \
156
0
    OTYPE *restrict q = (OTYPE *) out; \
157
0
    int n = ((int) sizeof(OTYPE) << 3) - ((int) sizeof(ITYPE) << 3); \
158
0
\
159
0
    g_assert(sizeof(ITYPE) <= sizeof(OTYPE)); \
160
0
\
161
0
    for (x = 0; x < sz; x++) \
162
0
      q[x] = (p[x] << n) | (((p[x] & 1) << n) - (p[x] & 1)); \
163
0
  }
164
165
#define SHIFT_LEFT_SIGNED(ITYPE, OTYPE) \
166
0
  { \
167
0
    ITYPE *restrict p = (ITYPE *) in; \
168
0
    OTYPE *restrict q = (OTYPE *) out; \
169
0
    int n = ((int) sizeof(OTYPE) << 3) - ((int) sizeof(ITYPE) << 3); \
170
0
\
171
0
    g_assert(sizeof(ITYPE) <= sizeof(OTYPE)); \
172
0
\
173
0
    for (x = 0; x < sz; x++) \
174
0
      q[x] = VIPS_LSHIFT_INT(p[x], n) | \
175
0
        (((p[x] & 1) << n) - (p[x] & 1)); \
176
0
  }
177
178
/* Cast int types to an int type. We need to pass in the type of the
179
 * intermediate value, either int or int64, or we'll have problems with uint
180
 * sources turning -ve.
181
 */
182
#define CAST_INT_INT(ITYPE, OTYPE, TEMP, CAST) \
183
0
  { \
184
0
    ITYPE *restrict p = (ITYPE *) in; \
185
0
    OTYPE *restrict q = (OTYPE *) out; \
186
0
\
187
0
    for (x = 0; x < sz; x++) { \
188
0
      TEMP t = (TEMP) p[x]; \
189
0
\
190
0
      q[x] = CAST(t); \
191
0
    } \
192
0
  }
193
194
/* Int to int handling.
195
 */
196
#define INT_INT(ITYPE, OTYPE, TEMP, CAST) \
197
0
  { \
198
0
    if (cast->shift && \
199
0
      sizeof(ITYPE) > sizeof(OTYPE)) { \
200
0
      SHIFT_RIGHT(ITYPE, OTYPE); \
201
0
    } \
202
0
    else if (cast->shift) { \
203
0
      SHIFT_LEFT(ITYPE, OTYPE); \
204
0
    } \
205
0
    else { \
206
0
      CAST_INT_INT(ITYPE, OTYPE, TEMP, CAST); \
207
0
    } \
208
0
  }
209
210
/* Int to int handling for signed int types.
211
 */
212
#define INT_INT_SIGNED(ITYPE, OTYPE, TEMP, CAST) \
213
0
  { \
214
0
    if (cast->shift && \
215
0
      sizeof(ITYPE) > sizeof(OTYPE)) { \
216
0
      SHIFT_RIGHT(ITYPE, OTYPE); \
217
0
    } \
218
0
    else if (cast->shift) { \
219
0
      SHIFT_LEFT_SIGNED(ITYPE, OTYPE); \
220
0
    } \
221
0
    else { \
222
0
      CAST_INT_INT(ITYPE, OTYPE, TEMP, CAST); \
223
0
    } \
224
0
  }
225
226
/* Cast float types to an int type.
227
 *
228
 * We need to do the range clip as double or we'll get errors for int max,
229
 * since that can't be represented as a 32-bit float.
230
 */
231
#define CAST_FLOAT_INT(ITYPE, OTYPE, TEMP, CAST) \
232
16.2k
  { \
233
16.2k
    ITYPE *restrict p = (ITYPE *) in; \
234
16.2k
    OTYPE *restrict q = (OTYPE *) out; \
235
16.2k
\
236
1.98M
    for (x = 0; x < sz; x++) \
237
1.96M
      q[x] = CAST((double) p[x]); \
238
16.2k
  }
239
240
/* Cast complex types to an int type. Just take the real part.
241
 *
242
 * We need to do the range clip as double or we'll get errors for int max,
243
 * since that can't be represented as a 32-bit float.
244
 */
245
#define CAST_COMPLEX_INT(ITYPE, OTYPE, TEMP, CAST) \
246
0
  { \
247
0
    ITYPE *restrict p = (ITYPE *) in; \
248
0
    OTYPE *restrict q = (OTYPE *) out; \
249
0
\
250
0
    for (x = 0; x < sz; x++) { \
251
0
      q[x] = CAST((double) p[0]); \
252
0
      p += 2; \
253
0
    } \
254
0
  }
255
256
/* Cast non-complex types to a float type.
257
 */
258
#define CAST_REAL_FLOAT(ITYPE, OTYPE) \
259
0
  { \
260
0
    ITYPE *restrict p = (ITYPE *) in; \
261
0
    OTYPE *restrict q = (OTYPE *) out; \
262
0
\
263
0
    for (x = 0; x < sz; x++) \
264
0
      q[x] = p[x]; \
265
0
  }
266
267
/* Cast complex types to a float type ... just take real.
268
 */
269
#define CAST_COMPLEX_FLOAT(ITYPE, OTYPE) \
270
0
  { \
271
0
    ITYPE *restrict p = (ITYPE *) in; \
272
0
    OTYPE *restrict q = (OTYPE *) out; \
273
0
\
274
0
    for (x = 0; x < sz; x++) { \
275
0
      q[x] = p[0]; \
276
0
      p += 2; \
277
0
    } \
278
0
  }
279
280
/* Cast any non-complex to a complex type ... set imaginary to zero.
281
 */
282
#define CAST_REAL_COMPLEX(ITYPE, OTYPE) \
283
0
  { \
284
0
    ITYPE *restrict p = (ITYPE *) in; \
285
0
    OTYPE *restrict q = (OTYPE *) out; \
286
0
\
287
0
    for (x = 0; x < sz; x++) { \
288
0
      q[0] = p[x]; \
289
0
      q[1] = 0.0; \
290
0
      q += 2; \
291
0
    } \
292
0
  }
293
294
/* Cast any complex to a complex type.
295
 */
296
#define CAST_COMPLEX_COMPLEX(ITYPE, OTYPE) \
297
0
  { \
298
0
    ITYPE *restrict p = (ITYPE *) in; \
299
0
    OTYPE *restrict q = (OTYPE *) out; \
300
0
\
301
0
    for (x = 0; x < sz; x++) { \
302
0
      q[0] = p[0]; \
303
0
      q[1] = p[1]; \
304
0
      p += 2; \
305
0
      q += 2; \
306
0
    } \
307
0
  }
308
309
#define BAND_SWITCH_INNER(ITYPE, INT, FLOAT, COMPLEX) \
310
16.2k
  { \
311
16.2k
    switch (conversion->out->BandFmt) { \
312
4.68k
    case VIPS_FORMAT_UCHAR: \
313
4.68k
      INT(ITYPE, unsigned char, int, CAST_UCHAR); \
314
4.68k
      break; \
315
0
\
316
2.94k
    case VIPS_FORMAT_CHAR: \
317
2.94k
      INT(ITYPE, signed char, int, CAST_CHAR); \
318
2.94k
      break; \
319
0
\
320
1.86k
    case VIPS_FORMAT_USHORT: \
321
1.86k
      INT(ITYPE, unsigned short, int, CAST_USHORT); \
322
1.86k
      break; \
323
0
\
324
1.69k
    case VIPS_FORMAT_SHORT: \
325
1.69k
      INT(ITYPE, signed short, int, CAST_SHORT); \
326
1.69k
      break; \
327
0
\
328
2.00k
    case VIPS_FORMAT_UINT: \
329
2.00k
      INT(ITYPE, unsigned int, gint64, CAST_UINT); \
330
2.00k
      break; \
331
0
\
332
3.08k
    case VIPS_FORMAT_INT: \
333
3.08k
      INT(ITYPE, signed int, gint64, CAST_INT); \
334
3.08k
      break; \
335
0
\
336
0
    case VIPS_FORMAT_FLOAT: \
337
0
      FLOAT(ITYPE, float); \
338
0
      break; \
339
0
\
340
0
    case VIPS_FORMAT_DOUBLE: \
341
0
      FLOAT(ITYPE, double); \
342
0
      break; \
343
0
\
344
0
    case VIPS_FORMAT_COMPLEX: \
345
0
      COMPLEX(ITYPE, float); \
346
0
      break; \
347
0
\
348
0
    case VIPS_FORMAT_DPCOMPLEX: \
349
0
      COMPLEX(ITYPE, double); \
350
0
      break; \
351
0
\
352
0
    default: \
353
0
      g_assert_not_reached(); \
354
16.2k
    } \
355
16.2k
  }
356
357
static int
358
vips_cast_gen(VipsRegion *out_region,
359
  void *vseq, void *a, void *b, gboolean *stop)
360
1.28k
{
361
1.28k
  VipsRegion *ir = (VipsRegion *) vseq;
362
1.28k
  VipsCast *cast = (VipsCast *) b;
363
1.28k
  VipsConversion *conversion = (VipsConversion *) b;
364
1.28k
  VipsRect *r = &out_region->valid;
365
1.28k
  int sz = VIPS_REGION_N_ELEMENTS(out_region);
366
367
1.28k
  int x, y;
368
369
1.28k
  if (vips_region_prepare(ir, r))
370
32
    return -1;
371
372
1.28k
  VIPS_GATE_START("vips_cast_gen: work");
373
374
17.5k
  for (y = 0; y < r->height; y++) {
375
16.2k
    VipsPel *in = VIPS_REGION_ADDR(ir, r->left, r->top + y);
376
16.2k
    VipsPel *out = VIPS_REGION_ADDR(out_region, r->left, r->top + y);
377
378
16.2k
    switch (ir->im->BandFmt) {
379
0
    case VIPS_FORMAT_UCHAR:
380
0
      BAND_SWITCH_INNER(unsigned char,
381
0
        INT_INT,
382
0
        CAST_REAL_FLOAT,
383
0
        CAST_REAL_COMPLEX);
384
0
      break;
385
386
0
    case VIPS_FORMAT_CHAR:
387
0
      BAND_SWITCH_INNER(signed char,
388
0
        INT_INT_SIGNED,
389
0
        CAST_REAL_FLOAT,
390
0
        CAST_REAL_COMPLEX);
391
0
      break;
392
393
0
    case VIPS_FORMAT_USHORT:
394
0
      BAND_SWITCH_INNER(unsigned short,
395
0
        INT_INT,
396
0
        CAST_REAL_FLOAT,
397
0
        CAST_REAL_COMPLEX);
398
0
      break;
399
400
0
    case VIPS_FORMAT_SHORT:
401
0
      BAND_SWITCH_INNER(signed short,
402
0
        INT_INT_SIGNED,
403
0
        CAST_REAL_FLOAT,
404
0
        CAST_REAL_COMPLEX);
405
0
      break;
406
407
0
    case VIPS_FORMAT_UINT:
408
0
      BAND_SWITCH_INNER(unsigned int,
409
0
        INT_INT,
410
0
        CAST_REAL_FLOAT,
411
0
        CAST_REAL_COMPLEX);
412
0
      break;
413
414
0
    case VIPS_FORMAT_INT:
415
0
      BAND_SWITCH_INNER(signed int,
416
0
        INT_INT_SIGNED,
417
0
        CAST_REAL_FLOAT,
418
0
        CAST_REAL_COMPLEX);
419
0
      break;
420
421
16.2k
    case VIPS_FORMAT_FLOAT:
422
16.2k
      BAND_SWITCH_INNER(float,
423
16.2k
        CAST_FLOAT_INT,
424
16.2k
        CAST_REAL_FLOAT,
425
16.2k
        CAST_REAL_COMPLEX);
426
16.2k
      break;
427
428
0
    case VIPS_FORMAT_DOUBLE:
429
0
      BAND_SWITCH_INNER(double,
430
0
        CAST_FLOAT_INT,
431
0
        CAST_REAL_FLOAT,
432
0
        CAST_REAL_COMPLEX);
433
0
      break;
434
435
0
    case VIPS_FORMAT_COMPLEX:
436
0
      BAND_SWITCH_INNER(float,
437
0
        CAST_COMPLEX_INT,
438
0
        CAST_COMPLEX_FLOAT,
439
0
        CAST_COMPLEX_COMPLEX);
440
0
      break;
441
442
0
    case VIPS_FORMAT_DPCOMPLEX:
443
0
      BAND_SWITCH_INNER(double,
444
0
        CAST_COMPLEX_INT,
445
0
        CAST_COMPLEX_FLOAT,
446
0
        CAST_COMPLEX_COMPLEX);
447
0
      break;
448
449
0
    default:
450
0
      g_assert_not_reached();
451
16.2k
    }
452
16.2k
  }
453
454
1.24k
  VIPS_GATE_STOP("vips_cast_gen: work");
455
456
1.24k
  return 0;
457
1.24k
}
458
459
static int
460
vips_cast_build(VipsObject *object)
461
835
{
462
835
  VipsConversion *conversion = VIPS_CONVERSION(object);
463
835
  VipsCast *cast = (VipsCast *) object;
464
835
  VipsImage **t = (VipsImage **)
465
835
    vips_object_local_array(object, 2);
466
467
835
  VipsImage *in;
468
469
835
  if (VIPS_OBJECT_CLASS(vips_cast_parent_class)->build(object))
470
0
    return -1;
471
472
835
  in = cast->in;
473
474
  /* Trivial case: fall back to copy().
475
   */
476
835
  if (in->BandFmt == cast->format)
477
297
    return vips_image_write(in, conversion->out);
478
479
538
  if (vips_image_decode(in, &t[0]))
480
0
    return -1;
481
538
  in = t[0];
482
483
  /* If @shift is on but we're not in an int format and we're going to
484
   * an int format, we need to cast to int first. For example, what
485
   * about a float image tagged as rgb16 being cast to uint8? We need
486
   * to cast to ushort before we do the final cast to uint8.
487
   */
488
538
  if (cast->shift &&
489
538
    !vips_band_format_isint(in->BandFmt) &&
490
538
    vips_band_format_isint(cast->format)) {
491
0
    if (vips_cast(in, &t[1],
492
0
        vips_image_guess_format(in), NULL))
493
0
      return -1;
494
0
    in = t[1];
495
0
  }
496
497
538
  if (vips_image_pipelinev(conversion->out,
498
538
      VIPS_DEMAND_STYLE_THINSTRIP, in, NULL))
499
0
    return -1;
500
501
538
  conversion->out->BandFmt = cast->format;
502
503
538
  if (vips_image_generate(conversion->out,
504
538
      vips_start_one, vips_cast_gen, vips_stop_one,
505
538
      in, cast))
506
0
    return -1;
507
508
538
  return 0;
509
538
}
510
511
static void
512
vips_cast_class_init(VipsCastClass *class)
513
1
{
514
1
  GObjectClass *gobject_class = G_OBJECT_CLASS(class);
515
1
  VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS(class);
516
1
  VipsOperationClass *operation_class = VIPS_OPERATION_CLASS(class);
517
518
1
  VIPS_DEBUG_MSG("vips_cast_class_init\n");
519
520
1
  gobject_class->set_property = vips_object_set_property;
521
1
  gobject_class->get_property = vips_object_get_property;
522
523
1
  vobject_class->nickname = "cast";
524
1
  vobject_class->description = _("cast an image");
525
1
  vobject_class->build = vips_cast_build;
526
527
1
  operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
528
529
1
  VIPS_ARG_IMAGE(class, "in", 1,
530
1
    _("Input"),
531
1
    _("Input image"),
532
1
    VIPS_ARGUMENT_REQUIRED_INPUT,
533
1
    G_STRUCT_OFFSET(VipsCast, in));
534
535
1
  VIPS_ARG_ENUM(class, "format", 6,
536
1
    _("Format"),
537
1
    _("Format to cast to"),
538
1
    VIPS_ARGUMENT_REQUIRED_INPUT,
539
1
    G_STRUCT_OFFSET(VipsCast, format),
540
1
    VIPS_TYPE_BAND_FORMAT, VIPS_FORMAT_UCHAR);
541
542
1
  VIPS_ARG_BOOL(class, "shift", 7,
543
1
    _("Shift"),
544
1
    _("Shift integer values up and down"),
545
1
    VIPS_ARGUMENT_OPTIONAL_INPUT,
546
1
    G_STRUCT_OFFSET(VipsCast, shift),
547
1
    FALSE);
548
1
}
549
550
static void
551
vips_cast_init(VipsCast *cast)
552
835
{
553
835
}
554
555
static int
556
vips_castv(VipsImage *in, VipsImage **out, VipsBandFormat format, va_list ap)
557
835
{
558
835
  return vips_call_split("cast", ap, in, out, format);
559
835
}
560
561
/**
562
 * vips_cast: (method)
563
 * @in: input image
564
 * @out: (out): output image
565
 * @format: format to convert to
566
 * @...: %NULL-terminated list of optional named arguments
567
 *
568
 * Optional arguments:
569
 *
570
 * * @shift: %gboolean, integer values are shifted
571
 *
572
 * Convert @in to @format. You can convert between any pair of formats.
573
 * Floats are truncated (not rounded). Out of range values are clipped.
574
 *
575
 * Casting from complex to real returns the real part.
576
 *
577
 * If @shift is %TRUE, integer values are shifted up and down. For example,
578
 * casting from unsigned 8 bit to unsigned 16 bit would
579
 * shift every value left by 8 bits. The bottom bit is copied into the new
580
 * bits, so 255 would become 65535.
581
 *
582
 * See also: vips_scale(), vips_complexform(), vips_real(), vips_imag(),
583
 * vips_cast_uchar(), vips_msb().
584
 *
585
 * Returns: 0 on success, -1 on error
586
 */
587
int
588
vips_cast(VipsImage *in, VipsImage **out, VipsBandFormat format, ...)
589
835
{
590
835
  va_list ap;
591
835
  int result;
592
593
835
  va_start(ap, format);
594
835
  result = vips_castv(in, out, format, ap);
595
835
  va_end(ap);
596
597
835
  return result;
598
835
}
599
600
/**
601
 * vips_cast_uchar: (method)
602
 * @in: input image
603
 * @out: (out): output image
604
 * @...: %NULL-terminated list of optional named arguments
605
 *
606
 * Convert @in to #VIPS_FORMAT_UCHAR. See vips_cast().
607
 *
608
 * Returns: 0 on success, -1 on error
609
 */
610
int
611
vips_cast_uchar(VipsImage *in, VipsImage **out, ...)
612
0
{
613
0
  va_list ap;
614
0
  int result;
615
616
0
  va_start(ap, out);
617
0
  result = vips_castv(in, out, VIPS_FORMAT_UCHAR, ap);
618
0
  va_end(ap);
619
620
0
  return result;
621
0
}
622
623
/**
624
 * vips_cast_char: (method)
625
 * @in: input image
626
 * @out: (out): output image
627
 * @...: %NULL-terminated list of optional named arguments
628
 *
629
 * Convert @in to #VIPS_FORMAT_CHAR. See vips_cast().
630
 *
631
 * Returns: 0 on success, -1 on error
632
 */
633
int
634
vips_cast_char(VipsImage *in, VipsImage **out, ...)
635
0
{
636
0
  va_list ap;
637
0
  int result;
638
639
0
  va_start(ap, out);
640
0
  result = vips_castv(in, out, VIPS_FORMAT_CHAR, ap);
641
0
  va_end(ap);
642
643
0
  return result;
644
0
}
645
646
/**
647
 * vips_cast_ushort: (method)
648
 * @in: input image
649
 * @out: (out): output image
650
 * @...: %NULL-terminated list of optional named arguments
651
 *
652
 * Convert @in to #VIPS_FORMAT_USHORT. See vips_cast().
653
 *
654
 * Returns: 0 on success, -1 on error
655
 */
656
int
657
vips_cast_ushort(VipsImage *in, VipsImage **out, ...)
658
0
{
659
0
  va_list ap;
660
0
  int result;
661
662
0
  va_start(ap, out);
663
0
  result = vips_castv(in, out, VIPS_FORMAT_USHORT, ap);
664
0
  va_end(ap);
665
666
0
  return result;
667
0
}
668
669
/**
670
 * vips_cast_short: (method)
671
 * @in: input image
672
 * @out: (out): output image
673
 * @...: %NULL-terminated list of optional named arguments
674
 *
675
 * Convert @in to #VIPS_FORMAT_SHORT. See vips_cast().
676
 *
677
 * Returns: 0 on success, -1 on error
678
 */
679
int
680
vips_cast_short(VipsImage *in, VipsImage **out, ...)
681
0
{
682
0
  va_list ap;
683
0
  int result;
684
685
0
  va_start(ap, out);
686
0
  result = vips_castv(in, out, VIPS_FORMAT_SHORT, ap);
687
0
  va_end(ap);
688
689
0
  return result;
690
0
}
691
692
/**
693
 * vips_cast_uint: (method)
694
 * @in: input image
695
 * @out: (out): output image
696
 * @...: %NULL-terminated list of optional named arguments
697
 *
698
 * Convert @in to #VIPS_FORMAT_UINT. See vips_cast().
699
 *
700
 * Returns: 0 on success, -1 on error
701
 */
702
int
703
vips_cast_uint(VipsImage *in, VipsImage **out, ...)
704
0
{
705
0
  va_list ap;
706
0
  int result;
707
708
0
  va_start(ap, out);
709
0
  result = vips_castv(in, out, VIPS_FORMAT_UINT, ap);
710
0
  va_end(ap);
711
712
0
  return result;
713
0
}
714
715
/**
716
 * vips_cast_int: (method)
717
 * @in: input image
718
 * @out: (out): output image
719
 * @...: %NULL-terminated list of optional named arguments
720
 *
721
 * Convert @in to #VIPS_FORMAT_INT. See vips_cast().
722
 *
723
 * Returns: 0 on success, -1 on error
724
 */
725
int
726
vips_cast_int(VipsImage *in, VipsImage **out, ...)
727
0
{
728
0
  va_list ap;
729
0
  int result;
730
731
0
  va_start(ap, out);
732
0
  result = vips_castv(in, out, VIPS_FORMAT_INT, ap);
733
0
  va_end(ap);
734
735
0
  return result;
736
0
}
737
738
/**
739
 * vips_cast_float: (method)
740
 * @in: input image
741
 * @out: (out): output image
742
 * @...: %NULL-terminated list of optional named arguments
743
 *
744
 * Convert @in to #VIPS_FORMAT_FLOAT. See vips_cast().
745
 *
746
 * Returns: 0 on success, -1 on error
747
 */
748
int
749
vips_cast_float(VipsImage *in, VipsImage **out, ...)
750
0
{
751
0
  va_list ap;
752
0
  int result;
753
754
0
  va_start(ap, out);
755
0
  result = vips_castv(in, out, VIPS_FORMAT_FLOAT, ap);
756
0
  va_end(ap);
757
758
0
  return result;
759
0
}
760
761
/**
762
 * vips_cast_double: (method)
763
 * @in: input image
764
 * @out: (out): output image
765
 * @...: %NULL-terminated list of optional named arguments
766
 *
767
 * Convert @in to #VIPS_FORMAT_DOUBLE. See vips_cast().
768
 *
769
 * Returns: 0 on success, -1 on error
770
 */
771
int
772
vips_cast_double(VipsImage *in, VipsImage **out, ...)
773
0
{
774
0
  va_list ap;
775
0
  int result;
776
777
0
  va_start(ap, out);
778
0
  result = vips_castv(in, out, VIPS_FORMAT_DOUBLE, ap);
779
0
  va_end(ap);
780
781
0
  return result;
782
0
}
783
784
/**
785
 * vips_cast_complex: (method)
786
 * @in: input image
787
 * @out: (out): output image
788
 * @...: %NULL-terminated list of optional named arguments
789
 *
790
 * Convert @in to #VIPS_FORMAT_COMPLEX. See vips_cast().
791
 *
792
 * Returns: 0 on success, -1 on error
793
 */
794
int
795
vips_cast_complex(VipsImage *in, VipsImage **out, ...)
796
0
{
797
0
  va_list ap;
798
0
  int result;
799
800
0
  va_start(ap, out);
801
0
  result = vips_castv(in, out, VIPS_FORMAT_COMPLEX, ap);
802
0
  va_end(ap);
803
804
0
  return result;
805
0
}
806
807
/**
808
 * vips_cast_dpcomplex: (method)
809
 * @in: input image
810
 * @out: (out): output image
811
 * @...: %NULL-terminated list of optional named arguments
812
 *
813
 * Convert @in to #VIPS_FORMAT_DPCOMPLEX. See vips_cast().
814
 *
815
 * Returns: 0 on success, -1 on error
816
 */
817
int
818
vips_cast_dpcomplex(VipsImage *in, VipsImage **out, ...)
819
0
{
820
0
  va_list ap;
821
0
  int result;
822
823
0
  va_start(ap, out);
824
0
  result = vips_castv(in, out, VIPS_FORMAT_DPCOMPLEX, ap);
825
0
  va_end(ap);
826
827
0
  return result;
828
0
}