Coverage Report

Created: 2025-01-28 06:31

/src/libvips/libvips/arithmetic/maxpair.c
Line
Count
Source (jump to first uncovered line)
1
/* max of a pair of images
2
 *
3
 * 18/6/24
4
 *  - from add.c
5
 */
6
7
/*
8
9
  Copyright (C) 1991-2005 The National Gallery
10
11
  This library is free software; you can redistribute it and/or
12
  modify it under the terms of the GNU Lesser General Public
13
  License as published by the Free Software Foundation; either
14
  version 2.1 of the License, or (at your option) any later version.
15
16
  This library is distributed in the hope that it will be useful,
17
  but WITHOUT ANY WARRANTY; without even the implied warranty of
18
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19
  Lesser General Public License for more details.
20
21
  You should have received a copy of the GNU Lesser General Public
22
  License along with this library; if not, write to the Free Software
23
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24
  02110-1301  USA
25
26
 */
27
28
/*
29
30
  These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
31
32
 */
33
34
/*
35
#define DEBUG
36
 */
37
38
#ifdef HAVE_CONFIG_H
39
#include <config.h>
40
#endif /*HAVE_CONFIG_H*/
41
#include <glib/gi18n-lib.h>
42
43
#include <stdio.h>
44
#include <stdlib.h>
45
#include <math.h>
46
47
#include <vips/vips.h>
48
49
#include "binary.h"
50
51
typedef VipsBinary VipsMaxpair;
52
typedef VipsBinaryClass VipsMaxpairClass;
53
54
G_DEFINE_TYPE(VipsMaxpair, vips_maxpair, VIPS_TYPE_BINARY);
55
56
#define LOOP(TYPE) \
57
0
  { \
58
0
    TYPE *restrict left = (TYPE *) in[0]; \
59
0
    TYPE *restrict right = (TYPE *) in[1]; \
60
0
    TYPE *restrict q = (TYPE *) out; \
61
0
\
62
0
    for (int x = 0; x < sz; x++) \
63
0
      q[x] = VIPS_MAX(left[x], right[x]); \
64
0
  }
65
66
#define FLOOP(TYPE) \
67
0
  { \
68
0
    TYPE *restrict left = (TYPE *) in[0]; \
69
0
    TYPE *restrict right = (TYPE *) in[1]; \
70
0
    TYPE *restrict q = (TYPE *) out; \
71
0
\
72
0
    for (int x = 0; x < sz; x++) \
73
0
      q[x] = VIPS_FMAX(left[x], right[x]); \
74
0
  }
75
76
static void
77
maxpair_buffer(VipsArithmetic *arithmetic,
78
  VipsPel *out, VipsPel **in, int width)
79
0
{
80
0
  VipsImage *im = arithmetic->ready[0];
81
0
  int bands = vips_image_get_bands(im);
82
0
  VipsBandFormat format = vips_image_get_format(im);
83
0
  int sz = width * bands * (vips_band_format_iscomplex(format) ? 2 : 1);
84
85
  /* Maxpair all input types. Keep types here in sync with
86
   * vips_maxpair_format_table[] below.
87
   */
88
0
  switch (vips_image_get_format(im)) {
89
0
  case VIPS_FORMAT_UCHAR:
90
0
    LOOP(unsigned char);
91
0
    break;
92
93
0
  case VIPS_FORMAT_CHAR:
94
0
    LOOP(signed char);
95
0
    break;
96
97
0
  case VIPS_FORMAT_USHORT:
98
0
    LOOP(unsigned short);
99
0
    break;
100
101
0
  case VIPS_FORMAT_SHORT:
102
0
    LOOP(signed short);
103
0
    break;
104
105
0
  case VIPS_FORMAT_UINT:
106
0
    LOOP(unsigned int);
107
0
    break;
108
109
0
  case VIPS_FORMAT_INT:
110
0
    LOOP(signed int);
111
0
    break;
112
113
0
  case VIPS_FORMAT_FLOAT:
114
0
  case VIPS_FORMAT_COMPLEX:
115
0
    FLOOP(float);
116
0
    break;
117
118
0
  case VIPS_FORMAT_DOUBLE:
119
0
  case VIPS_FORMAT_DPCOMPLEX:
120
0
    FLOOP(double);
121
0
    break;
122
123
0
  default:
124
0
    g_assert_not_reached();
125
0
  }
126
0
}
127
128
#define UC VIPS_FORMAT_UCHAR
129
#define C VIPS_FORMAT_CHAR
130
#define US VIPS_FORMAT_USHORT
131
#define S VIPS_FORMAT_SHORT
132
#define UI VIPS_FORMAT_UINT
133
#define I VIPS_FORMAT_INT
134
#define F VIPS_FORMAT_FLOAT
135
#define X VIPS_FORMAT_COMPLEX
136
#define D VIPS_FORMAT_DOUBLE
137
#define DX VIPS_FORMAT_DPCOMPLEX
138
139
static const VipsBandFormat vips_maxpair_format_table[10] = {
140
  /* Band format:  UC  C  US  S  UI  I  F  X  D  DX */
141
  /* Promotion: */ UC, C, US, S, UI, I, F, X, D, DX
142
};
143
144
static void
145
vips_maxpair_class_init(VipsMaxpairClass *class)
146
1
{
147
1
  VipsObjectClass *object_class = (VipsObjectClass *) class;
148
1
  VipsArithmeticClass *aclass = VIPS_ARITHMETIC_CLASS(class);
149
150
1
  object_class->nickname = "maxpair";
151
1
  object_class->description = _("maximum of a pair of images");
152
153
1
  aclass->process_line = maxpair_buffer;
154
155
1
  vips_arithmetic_set_format_table(aclass, vips_maxpair_format_table);
156
1
}
157
158
static void
159
vips_maxpair_init(VipsMaxpair *maxpair)
160
0
{
161
0
}
162
163
/**
164
 * vips_maxpair:
165
 * @left: input image
166
 * @right: input image
167
 * @out: (out): output image
168
 * @...: %NULL-terminated list of optional named arguments
169
 *
170
 * For each pixel, pick the maximum of a pair of images.
171
 *
172
 * See also: vips_minpair().
173
 *
174
 * Returns: 0 on success, -1 on error
175
 */
176
int
177
vips_maxpair(VipsImage *left, VipsImage *right, VipsImage **out, ...)
178
0
{
179
0
  va_list ap;
180
0
  int result;
181
182
0
  va_start(ap, out);
183
0
  result = vips_call_split("maxpair", ap, left, right, out);
184
0
  va_end(ap);
185
186
0
  return result;
187
0
}