Coverage Report

Created: 2025-12-31 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libvips/libvips/conversion/cast.c
Line
Count
Source
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
36
G_DEFINE_TYPE(VipsCast, vips_cast, VIPS_TYPE_CONVERSION);
120
36
121
36
/* Cast down from an int.
122
36
 */
123
4.92M
#define CAST_UCHAR(X) VIPS_CLIP(0, (X), UCHAR_MAX)
124
15.2k
#define CAST_CHAR(X) VIPS_CLIP(SCHAR_MIN, (X), SCHAR_MAX)
125
1.12M
#define CAST_USHORT(X) VIPS_CLIP(0, (X), USHRT_MAX)
126
85.6k
#define CAST_SHORT(X) VIPS_CLIP(SHRT_MIN, (X), SHRT_MAX)
127
128
/* These cast down from gint64 to uint32 or int32.
129
 */
130
50.7k
#define CAST_UINT(X) VIPS_CLIP(0, (X), UINT_MAX)
131
21.2k
#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
85.7k
  { \
140
85.7k
    ITYPE *restrict p = (ITYPE *) in; \
141
85.7k
    OTYPE *restrict q = (OTYPE *) out; \
142
85.7k
    int n = ((int) sizeof(ITYPE) << 3) - ((int) sizeof(OTYPE) << 3); \
143
85.7k
\
144
85.7k
    g_assert(sizeof(ITYPE) >= sizeof(OTYPE)); \
145
85.7k
\
146
10.6M
    for (x = 0; x < sz; x++) \
147
10.5M
      q[x] = p[x] >> n; \
148
85.7k
  }
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
5.59k
  { \
155
5.59k
    ITYPE *restrict p = (ITYPE *) in; \
156
5.59k
    OTYPE *restrict q = (OTYPE *) out; \
157
5.59k
    int n = ((int) sizeof(OTYPE) << 3) - ((int) sizeof(ITYPE) << 3); \
158
5.59k
\
159
5.59k
    g_assert(sizeof(ITYPE) <= sizeof(OTYPE)); \
160
5.59k
\
161
766k
    for (x = 0; x < sz; x++) \
162
760k
      q[x] = (p[x] << n) | (((p[x] & 1) << n) - (p[x] & 1)); \
163
5.59k
  }
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
66.7k
  { \
184
66.7k
    ITYPE *restrict p = (ITYPE *) in; \
185
66.7k
    OTYPE *restrict q = (OTYPE *) out; \
186
66.7k
\
187
5.61M
    for (x = 0; x < sz; x++) { \
188
5.54M
      TEMP t = (TEMP) p[x]; \
189
5.54M
\
190
5.54M
      q[x] = CAST(t); \
191
5.54M
    } \
192
66.7k
  }
193
194
/* Int to int handling.
195
 */
196
#define INT_INT(ITYPE, OTYPE, TEMP, CAST) \
197
120k
  { \
198
120k
    if (cast->shift && \
199
120k
      sizeof(ITYPE) > sizeof(OTYPE)) { \
200
79.0k
      SHIFT_RIGHT(ITYPE, OTYPE); \
201
79.0k
    } \
202
120k
    else if (cast->shift) { \
203
5.59k
      SHIFT_LEFT(ITYPE, OTYPE); \
204
5.59k
    } \
205
41.5k
    else { \
206
35.9k
      CAST_INT_INT(ITYPE, OTYPE, TEMP, CAST); \
207
35.9k
    } \
208
120k
  }
209
210
/* Int to int handling for signed int types.
211
 */
212
#define INT_INT_SIGNED(ITYPE, OTYPE, TEMP, CAST) \
213
37.4k
  { \
214
37.4k
    if (cast->shift && \
215
37.4k
      sizeof(ITYPE) > sizeof(OTYPE)) { \
216
6.71k
      SHIFT_RIGHT(ITYPE, OTYPE); \
217
6.71k
    } \
218
37.4k
    else if (cast->shift) { \
219
0
      SHIFT_LEFT_SIGNED(ITYPE, OTYPE); \
220
0
    } \
221
30.7k
    else { \
222
30.7k
      CAST_INT_INT(ITYPE, OTYPE, TEMP, CAST); \
223
30.7k
    } \
224
37.4k
  }
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
673k
  { \
233
673k
    ITYPE *restrict p = (ITYPE *) in; \
234
673k
    OTYPE *restrict q = (OTYPE *) out; \
235
673k
\
236
75.4M
    for (x = 0; x < sz; x++) \
237
74.7M
      q[x] = CAST((double) p[x]); \
238
673k
  }
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
1.38k
  { \
247
1.38k
    ITYPE *restrict p = (ITYPE *) in; \
248
1.38k
    OTYPE *restrict q = (OTYPE *) out; \
249
1.38k
\
250
8.54k
    for (x = 0; x < sz; x++) { \
251
7.16k
      q[x] = CAST((double) p[0]); \
252
7.16k
      p += 2; \
253
7.16k
    } \
254
1.38k
  }
255
256
/* Cast non-complex types to a float type.
257
 */
258
#define CAST_REAL_FLOAT(ITYPE, OTYPE) \
259
553k
  { \
260
553k
    ITYPE *restrict p = (ITYPE *) in; \
261
553k
    OTYPE *restrict q = (OTYPE *) out; \
262
553k
\
263
40.8M
    for (x = 0; x < sz; x++) \
264
40.2M
      q[x] = p[x]; \
265
553k
  }
266
267
/* Cast complex types to a float type ... just take real.
268
 */
269
#define CAST_COMPLEX_FLOAT(ITYPE, OTYPE) \
270
166
  { \
271
166
    ITYPE *restrict p = (ITYPE *) in; \
272
166
    OTYPE *restrict q = (OTYPE *) out; \
273
166
\
274
737
    for (x = 0; x < sz; x++) { \
275
571
      q[x] = p[0]; \
276
571
      p += 2; \
277
571
    } \
278
166
  }
279
280
/* Cast any non-complex to a complex type ... set imaginary to zero.
281
 */
282
#define CAST_REAL_COMPLEX(ITYPE, OTYPE) \
283
227
  { \
284
227
    ITYPE *restrict p = (ITYPE *) in; \
285
227
    OTYPE *restrict q = (OTYPE *) out; \
286
227
\
287
470
    for (x = 0; x < sz; x++) { \
288
243
      q[0] = p[x]; \
289
243
      q[1] = 0.0; \
290
243
      q += 2; \
291
243
    } \
292
227
  }
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
1.38M
  { \
311
1.38M
    switch (conversion->out->BandFmt) { \
312
630k
    case VIPS_FORMAT_UCHAR: \
313
4.92M
      INT(ITYPE, unsigned char, int, CAST_UCHAR); \
314
630k
      break; \
315
0
\
316
15.2k
    case VIPS_FORMAT_CHAR: \
317
15.2k
      INT(ITYPE, signed char, int, CAST_CHAR); \
318
15.2k
      break; \
319
0
\
320
58.2k
    case VIPS_FORMAT_USHORT: \
321
1.12M
      INT(ITYPE, unsigned short, int, CAST_USHORT); \
322
58.2k
      break; \
323
0
\
324
83.7k
    case VIPS_FORMAT_SHORT: \
325
85.6k
      INT(ITYPE, signed short, int, CAST_SHORT); \
326
83.7k
      break; \
327
0
\
328
24.4k
    case VIPS_FORMAT_UINT: \
329
50.7k
      INT(ITYPE, unsigned int, gint64, CAST_UINT); \
330
24.4k
      break; \
331
0
\
332
21.2k
    case VIPS_FORMAT_INT: \
333
21.2k
      INT(ITYPE, signed int, gint64, CAST_INT); \
334
21.2k
      break; \
335
0
\
336
307k
    case VIPS_FORMAT_FLOAT: \
337
307k
      FLOAT(ITYPE, float); \
338
307k
      break; \
339
0
\
340
245k
    case VIPS_FORMAT_DOUBLE: \
341
245k
      FLOAT(ITYPE, double); \
342
245k
      break; \
343
0
\
344
214
    case VIPS_FORMAT_COMPLEX: \
345
214
      COMPLEX(ITYPE, float); \
346
214
      break; \
347
0
\
348
13
    case VIPS_FORMAT_DPCOMPLEX: \
349
13
      COMPLEX(ITYPE, double); \
350
13
      break; \
351
0
\
352
0
    default: \
353
0
      g_assert_not_reached(); \
354
1.38M
    } \
355
1.38M
  }
356
357
static int
358
vips_cast_gen(VipsRegion *out_region,
359
  void *vseq, void *a, void *b, gboolean *stop)
360
139k
{
361
139k
  VipsRegion *ir = (VipsRegion *) vseq;
362
139k
  VipsCast *cast = (VipsCast *) b;
363
139k
  VipsConversion *conversion = (VipsConversion *) b;
364
139k
  VipsRect *r = &out_region->valid;
365
139k
  int sz = VIPS_REGION_N_ELEMENTS(out_region);
366
367
139k
  int x, y;
368
369
139k
  if (vips_region_prepare(ir, r))
370
36.6k
    return -1;
371
372
139k
  VIPS_GATE_START("vips_cast_gen: work");
373
374
1.48M
  for (y = 0; y < r->height; y++) {
375
1.38M
    VipsPel *in = VIPS_REGION_ADDR(ir, r->left, r->top + y);
376
1.38M
    VipsPel *out = VIPS_REGION_ADDR(out_region, r->left, r->top + y);
377
378
1.38M
    switch (ir->im->BandFmt) {
379
432k
    case VIPS_FORMAT_UCHAR:
380
432k
      BAND_SWITCH_INNER(unsigned char,
381
432k
        INT_INT,
382
432k
        CAST_REAL_FLOAT,
383
432k
        CAST_REAL_COMPLEX);
384
432k
      break;
385
386
12.8k
    case VIPS_FORMAT_CHAR:
387
12.8k
      BAND_SWITCH_INNER(signed char,
388
12.8k
        INT_INT_SIGNED,
389
12.8k
        CAST_REAL_FLOAT,
390
12.8k
        CAST_REAL_COMPLEX);
391
12.8k
      break;
392
393
100k
    case VIPS_FORMAT_USHORT:
394
100k
      BAND_SWITCH_INNER(unsigned short,
395
100k
        INT_INT,
396
100k
        CAST_REAL_FLOAT,
397
100k
        CAST_REAL_COMPLEX);
398
100k
      break;
399
400
88.4k
    case VIPS_FORMAT_SHORT:
401
88.4k
      BAND_SWITCH_INNER(signed short,
402
88.4k
        INT_INT_SIGNED,
403
88.4k
        CAST_REAL_FLOAT,
404
88.4k
        CAST_REAL_COMPLEX);
405
88.4k
      break;
406
407
53.8k
    case VIPS_FORMAT_UINT:
408
53.8k
      BAND_SWITCH_INNER(unsigned int,
409
53.8k
        INT_INT,
410
53.8k
        CAST_REAL_FLOAT,
411
53.8k
        CAST_REAL_COMPLEX);
412
53.8k
      break;
413
414
17.9k
    case VIPS_FORMAT_INT:
415
17.9k
      BAND_SWITCH_INNER(signed int,
416
17.9k
        INT_INT_SIGNED,
417
17.9k
        CAST_REAL_FLOAT,
418
17.9k
        CAST_REAL_COMPLEX);
419
17.9k
      break;
420
421
670k
    case VIPS_FORMAT_FLOAT:
422
670k
      BAND_SWITCH_INNER(float,
423
670k
        CAST_FLOAT_INT,
424
670k
        CAST_REAL_FLOAT,
425
670k
        CAST_REAL_COMPLEX);
426
670k
      break;
427
428
8.58k
    case VIPS_FORMAT_DOUBLE:
429
8.58k
      BAND_SWITCH_INNER(double,
430
8.58k
        CAST_FLOAT_INT,
431
8.58k
        CAST_REAL_FLOAT,
432
8.58k
        CAST_REAL_COMPLEX);
433
8.58k
      break;
434
435
854
    case VIPS_FORMAT_COMPLEX:
436
854
      BAND_SWITCH_INNER(float,
437
854
        CAST_COMPLEX_INT,
438
854
        CAST_COMPLEX_FLOAT,
439
854
        CAST_COMPLEX_COMPLEX);
440
854
      break;
441
442
694
    case VIPS_FORMAT_DPCOMPLEX:
443
694
      BAND_SWITCH_INNER(double,
444
694
        CAST_COMPLEX_INT,
445
694
        CAST_COMPLEX_FLOAT,
446
694
        CAST_COMPLEX_COMPLEX);
447
694
      break;
448
449
0
    default:
450
0
      g_assert_not_reached();
451
1.38M
    }
452
1.38M
  }
453
454
102k
  VIPS_GATE_STOP("vips_cast_gen: work");
455
456
102k
  return 0;
457
102k
}
458
459
static int
460
vips_cast_build(VipsObject *object)
461
720k
{
462
720k
  VipsConversion *conversion = VIPS_CONVERSION(object);
463
720k
  VipsCast *cast = (VipsCast *) object;
464
720k
  VipsImage **t = (VipsImage **)
465
720k
    vips_object_local_array(object, 2);
466
467
720k
  VipsImage *in;
468
469
720k
  if (VIPS_OBJECT_CLASS(vips_cast_parent_class)->build(object))
470
0
    return -1;
471
472
720k
  in = cast->in;
473
474
  /* Trivial case: fall back to copy().
475
   */
476
720k
  if (in->BandFmt == cast->format)
477
616k
    return vips_image_write(in, conversion->out);
478
479
104k
  if (vips_image_decode(in, &t[0]))
480
0
    return -1;
481
104k
  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
104k
  if (cast->shift &&
489
11.6k
    !vips_band_format_isint(in->BandFmt) &&
490
1.23k
    vips_band_format_isint(cast->format)) {
491
1.23k
    if (vips_cast(in, &t[1], vips_image_guess_format(in), NULL))
492
0
      return -1;
493
1.23k
    in = t[1];
494
1.23k
  }
495
496
104k
  if (vips_image_pipelinev(conversion->out,
497
104k
      VIPS_DEMAND_STYLE_THINSTRIP, in, NULL))
498
0
    return -1;
499
500
104k
  conversion->out->BandFmt = cast->format;
501
502
104k
  if (vips_image_generate(conversion->out,
503
104k
      vips_start_one, vips_cast_gen, vips_stop_one,
504
104k
      in, cast))
505
0
    return -1;
506
507
104k
  return 0;
508
104k
}
509
510
static void
511
vips_cast_class_init(VipsCastClass *class)
512
18
{
513
18
  GObjectClass *gobject_class = G_OBJECT_CLASS(class);
514
18
  VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS(class);
515
18
  VipsOperationClass *operation_class = VIPS_OPERATION_CLASS(class);
516
517
18
  VIPS_DEBUG_MSG("vips_cast_class_init\n");
518
519
18
  gobject_class->set_property = vips_object_set_property;
520
18
  gobject_class->get_property = vips_object_get_property;
521
522
18
  vobject_class->nickname = "cast";
523
18
  vobject_class->description = _("cast an image");
524
18
  vobject_class->build = vips_cast_build;
525
526
18
  operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
527
528
18
  VIPS_ARG_IMAGE(class, "in", 1,
529
18
    _("Input"),
530
18
    _("Input image"),
531
18
    VIPS_ARGUMENT_REQUIRED_INPUT,
532
18
    G_STRUCT_OFFSET(VipsCast, in));
533
534
18
  VIPS_ARG_ENUM(class, "format", 6,
535
18
    _("Format"),
536
18
    _("Format to cast to"),
537
18
    VIPS_ARGUMENT_REQUIRED_INPUT,
538
18
    G_STRUCT_OFFSET(VipsCast, format),
539
18
    VIPS_TYPE_BAND_FORMAT, VIPS_FORMAT_UCHAR);
540
541
18
  VIPS_ARG_BOOL(class, "shift", 7,
542
18
    _("Shift"),
543
18
    _("Shift integer values up and down"),
544
18
    VIPS_ARGUMENT_OPTIONAL_INPUT,
545
18
    G_STRUCT_OFFSET(VipsCast, shift),
546
18
    FALSE);
547
18
}
548
549
static void
550
vips_cast_init(VipsCast *cast)
551
798k
{
552
798k
}
553
554
static int
555
vips_castv(VipsImage *in, VipsImage **out, VipsBandFormat format, va_list ap)
556
798k
{
557
798k
  return vips_call_split("cast", ap, in, out, format);
558
798k
}
559
560
/**
561
 * vips_cast: (method)
562
 * @in: input image
563
 * @out: (out): output image
564
 * @format: format to convert to
565
 * @...: `NULL`-terminated list of optional named arguments
566
 *
567
 * Convert @in to @format. You can convert between any pair of formats.
568
 * Floats are truncated (not rounded). Out of range values are clipped.
569
 *
570
 * Casting from complex to real returns the real part.
571
 *
572
 * If @shift is `TRUE`, integer values are shifted up and down. For example,
573
 * casting from unsigned 8 bit to unsigned 16 bit would
574
 * shift every value left by 8 bits. The bottom bit is copied into the new
575
 * bits, so 255 would become 65535.
576
 *
577
 * ::: tip "Optional arguments"
578
 *     * @shift: `gboolean`, integer values are shifted
579
 *
580
 * ::: seealso
581
 *     [method@Image.scale], [method@Image.complexform], [method@Image.real],
582
 *     [method@Image.imag], [method@Image.cast_uchar], [method@Image.msb].
583
 *
584
 * Returns: 0 on success, -1 on error
585
 */
586
int
587
vips_cast(VipsImage *in, VipsImage **out, VipsBandFormat format, ...)
588
645k
{
589
645k
  va_list ap;
590
645k
  int result;
591
592
645k
  va_start(ap, format);
593
645k
  result = vips_castv(in, out, format, ap);
594
645k
  va_end(ap);
595
596
645k
  return result;
597
645k
}
598
599
/**
600
 * vips_cast_uchar: (method)
601
 * @in: input image
602
 * @out: (out): output image
603
 * @...: `NULL`-terminated list of optional named arguments
604
 *
605
 * Convert @in to [enum@Vips.BandFormat.UCHAR]. See [method@Image.cast].
606
 *
607
 * ::: tip "Optional arguments"
608
 *     * @shift: `gboolean`, integer values are shifted
609
 *
610
 * Returns: 0 on success, -1 on error
611
 */
612
int
613
vips_cast_uchar(VipsImage *in, VipsImage **out, ...)
614
116k
{
615
116k
  va_list ap;
616
116k
  int result;
617
618
116k
  va_start(ap, out);
619
116k
  result = vips_castv(in, out, VIPS_FORMAT_UCHAR, ap);
620
116k
  va_end(ap);
621
622
116k
  return result;
623
116k
}
624
625
/**
626
 * vips_cast_char: (method)
627
 * @in: input image
628
 * @out: (out): output image
629
 * @...: `NULL`-terminated list of optional named arguments
630
 *
631
 * Convert @in to [enum@Vips.BandFormat.CHAR]. See [method@Image.cast].
632
 *
633
 * ::: tip "Optional arguments"
634
 *     * @shift: `gboolean`, integer values are shifted
635
 *
636
 * Returns: 0 on success, -1 on error
637
 */
638
int
639
vips_cast_char(VipsImage *in, VipsImage **out, ...)
640
0
{
641
0
  va_list ap;
642
0
  int result;
643
644
0
  va_start(ap, out);
645
0
  result = vips_castv(in, out, VIPS_FORMAT_CHAR, ap);
646
0
  va_end(ap);
647
648
0
  return result;
649
0
}
650
651
/**
652
 * vips_cast_ushort: (method)
653
 * @in: input image
654
 * @out: (out): output image
655
 * @...: `NULL`-terminated list of optional named arguments
656
 *
657
 * Convert @in to [enum@Vips.BandFormat.USHORT]. See [method@Image.cast].
658
 *
659
 * ::: tip "Optional arguments"
660
 *     * @shift: `gboolean`, integer values are shifted
661
 *
662
 * Returns: 0 on success, -1 on error
663
 */
664
int
665
vips_cast_ushort(VipsImage *in, VipsImage **out, ...)
666
15.2k
{
667
15.2k
  va_list ap;
668
15.2k
  int result;
669
670
15.2k
  va_start(ap, out);
671
15.2k
  result = vips_castv(in, out, VIPS_FORMAT_USHORT, ap);
672
15.2k
  va_end(ap);
673
674
15.2k
  return result;
675
15.2k
}
676
677
/**
678
 * vips_cast_short: (method)
679
 * @in: input image
680
 * @out: (out): output image
681
 * @...: `NULL`-terminated list of optional named arguments
682
 *
683
 * Convert @in to [enum@Vips.BandFormat.SHORT]. See [method@Image.cast].
684
 *
685
 * ::: tip "Optional arguments"
686
 *     * @shift: `gboolean`, integer values are shifted
687
 *
688
 * Returns: 0 on success, -1 on error
689
 */
690
int
691
vips_cast_short(VipsImage *in, VipsImage **out, ...)
692
19.3k
{
693
19.3k
  va_list ap;
694
19.3k
  int result;
695
696
19.3k
  va_start(ap, out);
697
19.3k
  result = vips_castv(in, out, VIPS_FORMAT_SHORT, ap);
698
19.3k
  va_end(ap);
699
700
19.3k
  return result;
701
19.3k
}
702
703
/**
704
 * vips_cast_uint: (method)
705
 * @in: input image
706
 * @out: (out): output image
707
 * @...: `NULL`-terminated list of optional named arguments
708
 *
709
 * Convert @in to [enum@Vips.BandFormat.UINT]. See [method@Image.cast].
710
 *
711
 * ::: tip "Optional arguments"
712
 *     * @shift: `gboolean`, integer values are shifted
713
 *
714
 * Returns: 0 on success, -1 on error
715
 */
716
int
717
vips_cast_uint(VipsImage *in, VipsImage **out, ...)
718
0
{
719
0
  va_list ap;
720
0
  int result;
721
722
0
  va_start(ap, out);
723
0
  result = vips_castv(in, out, VIPS_FORMAT_UINT, ap);
724
0
  va_end(ap);
725
726
0
  return result;
727
0
}
728
729
/**
730
 * vips_cast_int: (method)
731
 * @in: input image
732
 * @out: (out): output image
733
 * @...: `NULL`-terminated list of optional named arguments
734
 *
735
 * Convert @in to [enum@Vips.BandFormat.INT]. See [method@Image.cast].
736
 *
737
 * ::: tip "Optional arguments"
738
 *     * @shift: `gboolean`, integer values are shifted
739
 *
740
 * Returns: 0 on success, -1 on error
741
 */
742
int
743
vips_cast_int(VipsImage *in, VipsImage **out, ...)
744
0
{
745
0
  va_list ap;
746
0
  int result;
747
748
0
  va_start(ap, out);
749
0
  result = vips_castv(in, out, VIPS_FORMAT_INT, ap);
750
0
  va_end(ap);
751
752
0
  return result;
753
0
}
754
755
/**
756
 * vips_cast_float: (method)
757
 * @in: input image
758
 * @out: (out): output image
759
 * @...: `NULL`-terminated list of optional named arguments
760
 *
761
 * Convert @in to [enum@Vips.BandFormat.FLOAT]. See [method@Image.cast].
762
 *
763
 * Returns: 0 on success, -1 on error
764
 */
765
int
766
vips_cast_float(VipsImage *in, VipsImage **out, ...)
767
877
{
768
877
  va_list ap;
769
877
  int result;
770
771
877
  va_start(ap, out);
772
877
  result = vips_castv(in, out, VIPS_FORMAT_FLOAT, ap);
773
877
  va_end(ap);
774
775
877
  return result;
776
877
}
777
778
/**
779
 * vips_cast_double: (method)
780
 * @in: input image
781
 * @out: (out): output image
782
 * @...: `NULL`-terminated list of optional named arguments
783
 *
784
 * Convert @in to [enum@Vips.BandFormat.DOUBLE]. See [method@Image.cast].
785
 *
786
 * Returns: 0 on success, -1 on error
787
 */
788
int
789
vips_cast_double(VipsImage *in, VipsImage **out, ...)
790
0
{
791
0
  va_list ap;
792
0
  int result;
793
794
0
  va_start(ap, out);
795
0
  result = vips_castv(in, out, VIPS_FORMAT_DOUBLE, ap);
796
0
  va_end(ap);
797
798
0
  return result;
799
0
}
800
801
/**
802
 * vips_cast_complex: (method)
803
 * @in: input image
804
 * @out: (out): output image
805
 * @...: `NULL`-terminated list of optional named arguments
806
 *
807
 * Convert @in to [enum@Vips.BandFormat.COMPLEX]. See [method@Image.cast].
808
 *
809
 * Returns: 0 on success, -1 on error
810
 */
811
int
812
vips_cast_complex(VipsImage *in, VipsImage **out, ...)
813
0
{
814
0
  va_list ap;
815
0
  int result;
816
817
0
  va_start(ap, out);
818
0
  result = vips_castv(in, out, VIPS_FORMAT_COMPLEX, ap);
819
0
  va_end(ap);
820
821
0
  return result;
822
0
}
823
824
/**
825
 * vips_cast_dpcomplex: (method)
826
 * @in: input image
827
 * @out: (out): output image
828
 * @...: `NULL`-terminated list of optional named arguments
829
 *
830
 * Convert @in to [enum@Vips.BandFormat.DPCOMPLEX]. See [method@Image.cast].
831
 *
832
 * Returns: 0 on success, -1 on error
833
 */
834
int
835
vips_cast_dpcomplex(VipsImage *in, VipsImage **out, ...)
836
0
{
837
0
  va_list ap;
838
0
  int result;
839
840
0
  va_start(ap, out);
841
0
  result = vips_castv(in, out, VIPS_FORMAT_DPCOMPLEX, ap);
842
0
  va_end(ap);
843
844
0
  return result;
845
0
}