/src/libvips/libvips/histogram/hist_ismonotonic.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* test for monotonicity |
2 | | * |
3 | | * Author: John Cupitt |
4 | | * Written on: 18/7/1995 |
5 | | * 17/9/96 JC |
6 | | * - restrictions on Ps, Pm, Ph relaxed |
7 | | * - restrictions on S, M, H relaxed |
8 | | * 25/7/01 JC |
9 | | * - patched for im_extract_band() change |
10 | | * 11/7/04 |
11 | | * - generalised to im_tone_build_range() ... so you can use it for any |
12 | | * image, not just LabS |
13 | | * 26/3/10 |
14 | | * - cleanups |
15 | | * - gtkdoc |
16 | | * 20/9/13 |
17 | | * - redone as a class |
18 | | */ |
19 | | |
20 | | /* |
21 | | |
22 | | This file is part of VIPS. |
23 | | |
24 | | VIPS is free software; you can redistribute it and/or modify |
25 | | it under the terms of the GNU Lesser General Public License as published by |
26 | | the Free Software Foundation; either version 2 of the License, or |
27 | | (at your option) any later version. |
28 | | |
29 | | This program is distributed in the hope that it will be useful, |
30 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
31 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
32 | | GNU Lesser General Public License for more details. |
33 | | |
34 | | You should have received a copy of the GNU Lesser General Public License |
35 | | along with this program; if not, write to the Free Software |
36 | | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
37 | | 02110-1301 USA |
38 | | |
39 | | */ |
40 | | |
41 | | /* |
42 | | |
43 | | These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk |
44 | | |
45 | | */ |
46 | | |
47 | | #ifdef HAVE_CONFIG_H |
48 | | #include <config.h> |
49 | | #endif /*HAVE_CONFIG_H*/ |
50 | | #include <glib/gi18n-lib.h> |
51 | | |
52 | | #include <stdio.h> |
53 | | |
54 | | #include <vips/vips.h> |
55 | | |
56 | | typedef struct _VipsHistIsmonotonic { |
57 | | VipsOperation parent_instance; |
58 | | |
59 | | VipsImage *in; |
60 | | |
61 | | gboolean monotonic; |
62 | | } VipsHistIsmonotonic; |
63 | | |
64 | | typedef VipsOperationClass VipsHistIsmonotonicClass; |
65 | | |
66 | | G_DEFINE_TYPE(VipsHistIsmonotonic, vips_hist_ismonotonic, |
67 | | VIPS_TYPE_OPERATION); |
68 | | |
69 | | static int |
70 | | vips_hist_ismonotonic_build(VipsObject *object) |
71 | 0 | { |
72 | 0 | VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(object); |
73 | 0 | VipsHistIsmonotonic *ismonotonic = (VipsHistIsmonotonic *) object; |
74 | 0 | VipsImage **t = (VipsImage **) vips_object_local_array(object, 4); |
75 | |
|
76 | 0 | double m; |
77 | |
|
78 | 0 | if (VIPS_OBJECT_CLASS(vips_hist_ismonotonic_parent_class)->build(object)) |
79 | 0 | return -1; |
80 | | |
81 | 0 | if (vips_check_hist(class->nickname, ismonotonic->in)) |
82 | 0 | return -1; |
83 | | |
84 | 0 | if (ismonotonic->in->Xsize == 1) |
85 | 0 | t[0] = vips_image_new_matrixv(1, 2, -1.0, 1.0); |
86 | 0 | else |
87 | 0 | t[0] = vips_image_new_matrixv(2, 1, -1.0, 1.0); |
88 | 0 | vips_image_set_double(t[0], "offset", 128); |
89 | | |
90 | | /* We want >=128 everywhere, ie. no -ve transitions. |
91 | | */ |
92 | 0 | if (vips_conv(ismonotonic->in, &t[1], t[0], |
93 | 0 | "precision", VIPS_PRECISION_INTEGER, |
94 | 0 | NULL) || |
95 | 0 | vips_moreeq_const1(t[1], &t[2], 128, NULL) || |
96 | 0 | vips_min(t[2], &m, NULL)) |
97 | 0 | return -1; |
98 | | |
99 | 0 | g_object_set(ismonotonic, "monotonic", (int) m == 255, NULL); |
100 | |
|
101 | 0 | return 0; |
102 | 0 | } |
103 | | |
104 | | static void |
105 | | vips_hist_ismonotonic_class_init(VipsHistIsmonotonicClass *class) |
106 | 1 | { |
107 | 1 | GObjectClass *gobject_class = G_OBJECT_CLASS(class); |
108 | 1 | VipsObjectClass *object_class = (VipsObjectClass *) class; |
109 | | |
110 | 1 | gobject_class->set_property = vips_object_set_property; |
111 | 1 | gobject_class->get_property = vips_object_get_property; |
112 | | |
113 | 1 | object_class->nickname = "hist_ismonotonic"; |
114 | 1 | object_class->description = _("test for monotonicity"); |
115 | 1 | object_class->build = vips_hist_ismonotonic_build; |
116 | | |
117 | 1 | VIPS_ARG_IMAGE(class, "in", 1, |
118 | 1 | _("Input"), |
119 | 1 | _("Input histogram image"), |
120 | 1 | VIPS_ARGUMENT_REQUIRED_INPUT, |
121 | 1 | G_STRUCT_OFFSET(VipsHistIsmonotonic, in)); |
122 | | |
123 | 1 | VIPS_ARG_BOOL(class, "monotonic", 2, |
124 | 1 | _("Monotonic"), |
125 | 1 | _("true if in is monotonic"), |
126 | 1 | VIPS_ARGUMENT_REQUIRED_OUTPUT, |
127 | 1 | G_STRUCT_OFFSET(VipsHistIsmonotonic, monotonic), |
128 | 1 | FALSE); |
129 | 1 | } |
130 | | |
131 | | static void |
132 | | vips_hist_ismonotonic_init(VipsHistIsmonotonic *ismonotonic) |
133 | 0 | { |
134 | 0 | } |
135 | | |
136 | | /** |
137 | | * vips_hist_ismonotonic: (method) |
138 | | * @in: lookup-table to test |
139 | | * @out: (out): set non-zero if @in is monotonic |
140 | | * @...: %NULL-terminated list of optional named arguments |
141 | | * |
142 | | * Test @in for monotonicity. @out is set non-zero if @in is monotonic. |
143 | | * |
144 | | * Returns: 0 on success, -1 on error |
145 | | */ |
146 | | int |
147 | | vips_hist_ismonotonic(VipsImage *in, gboolean *out, ...) |
148 | 0 | { |
149 | 0 | va_list ap; |
150 | 0 | int result; |
151 | |
|
152 | 0 | va_start(ap, out); |
153 | 0 | result = vips_call_split("hist_ismonotonic", ap, in, out); |
154 | 0 | va_end(ap); |
155 | |
|
156 | 0 | return result; |
157 | 0 | } |