1 /* base class for all histogram operations
2 */
3
4 /*
5
6 Copyright (C) 1991-2005 The National Gallery
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301 USA
22
23 */
24
25 /*
26
27 These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
28
29 */
30
31 /*
32 #define DEBUG
33 */
34
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif /*HAVE_CONFIG_H*/
38 #include <vips/intl.h>
39
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <math.h>
43
44 #include <vips/vips.h>
45 #include <vips/internal.h>
46
47 #include "phistogram.h"
48
49 /**
50 * SECTION: histogram
51 * @short_description: find, manipulate and apply histograms and lookup tables
52 * @stability: Stable
53 * @see_also: <link linkend="VipsImage">image</link>
54 * <link linkend="libvips-arithmetic">arithmetic</link>
55 * <link linkend="libvips-create">create</link>
56 * @include: vips/vips.h
57 *
58 * Histograms and look-up tables are 1xn or nx1 images, where n is less than
59 * 256 or less than 65536, corresponding to 8- and 16-bit unsigned int images.
60 * They are tagged with a #VipsInterpretation of
61 * #VIPS_INTERPRETATION_HISTOGRAM and usually displayed by user-interfaces
62 * such as nip2 as plots rather than images.
63 *
64 * These functions can be broadly grouped as things to find or build
65 * histograms (vips_hist_find(), vips_hist_find_indexed(),
66 * vips_hist_find_ndim(), vips_buildlut(), vips_identity()),
67 * operations that
68 * manipulate histograms in some way (vips_hist_cum(), vips_hist_norm()),
69 * operations to apply histograms (vips_maplut()), and a variety of utility
70 * operations.
71 *
72 * A final group of operations build tone curves. These are useful in
73 * pre-press work for adjusting the appearance of images. They are designed
74 * for CIELAB images, but might be useful elsewhere.
75 */
76
77 G_DEFINE_ABSTRACT_TYPE( VipsHistogram, vips_histogram, VIPS_TYPE_OPERATION );
78
79 /* sizealike by expanding in just one dimension and copying the final element.
80 */
81 static int
vips__hist_sizealike_vec(VipsImage ** in,VipsImage ** out,int n)82 vips__hist_sizealike_vec( VipsImage **in, VipsImage **out, int n )
83 {
84 int i;
85 int max_size;
86
87 g_assert( n >= 1 );
88
89 max_size = VIPS_MAX( in[0]->Xsize, in[0]->Ysize );
90 for( i = 1; i < n; i++ )
91 max_size = VIPS_MAX( max_size,
92 VIPS_MAX( in[0]->Xsize, in[0]->Ysize ) );
93
94 for( i = 0; i < n; i++ )
95 if( in[i]->Ysize == 1 ) {
96 if( vips_embed( in[i], &out[i], 0, 0, max_size, 1,
97 "extend", VIPS_EXTEND_COPY,
98 NULL ) )
99 return( -1 );
100 }
101 else {
102 if( vips_embed( in[i], &out[i], 0, 0, 1, max_size,
103 "extend", VIPS_EXTEND_COPY,
104 NULL ) )
105 return( -1 );
106 }
107
108 return( 0 );
109 }
110
111 static int
vips_histogram_build(VipsObject * object)112 vips_histogram_build( VipsObject *object )
113 {
114 VipsHistogram *histogram = VIPS_HISTOGRAM( object );
115 VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
116 VipsHistogramClass *hclass = VIPS_HISTOGRAM_GET_CLASS( histogram );
117
118 VipsImage **decode;
119 VipsImage **format;
120 VipsImage **band;
121 VipsImage **size;
122 VipsImage **memory;
123
124 VipsPel *outbuf;
125 VipsPel **inbuf;
126 int i;
127
128 #ifdef DEBUG
129 printf( "vips_histogram_build: " );
130 vips_object_print_name( object );
131 printf( "\n" );
132 #endif /*DEBUG*/
133
134 if( VIPS_OBJECT_CLASS( vips_histogram_parent_class )->build( object ) )
135 return( -1 );
136
137 g_assert( histogram->n > 0 );
138
139 /* Must be NULL-terminated.
140 */
141 g_assert( !histogram->in[histogram->n] );
142
143 decode = (VipsImage **) vips_object_local_array( object, histogram->n );
144 format = (VipsImage **) vips_object_local_array( object, histogram->n );
145 band = (VipsImage **) vips_object_local_array( object, histogram->n );
146 size = (VipsImage **) vips_object_local_array( object, histogram->n );
147 memory = (VipsImage **) vips_object_local_array( object, histogram->n );
148
149 g_object_set( histogram, "out", vips_image_new(), NULL );
150
151 for( i = 0; i < histogram->n; i++ )
152 if( vips_image_decode( histogram->in[i], &decode[i] ) ||
153 vips_check_hist( class->nickname, decode[i] ) )
154 return( -1 );
155
156 /* Cast our input images up to a common format, bands and size. If
157 * input_format is set, cast to a fixed input type.
158 */
159 if( hclass->input_format != VIPS_FORMAT_NOTSET ) {
160 for( i = 0; i < histogram->n; i++ )
161 if( vips_cast( decode[i], &format[i],
162 hclass->input_format, NULL ) )
163 return( -1 );
164 }
165 else {
166 if( vips__formatalike_vec( decode, format, histogram->n ) )
167 return( -1 );
168 }
169
170 if( vips__bandalike_vec( class->nickname,
171 format, band, histogram->n, 1 ) ||
172 vips__hist_sizealike_vec( band, size, histogram->n ) )
173 return( -1 );
174
175 if( vips_image_pipeline_array( histogram->out,
176 VIPS_DEMAND_STYLE_THINSTRIP, size ) )
177 return( -1 );
178
179 /* Need a copy of the inputs in memory.
180 */
181 if( !(inbuf = VIPS_ARRAY( object, histogram->n + 1, VipsPel * )) )
182 return( -1 );
183 for( i = 0; i < histogram->n; i++ ) {
184 if( !(memory[i] = vips_image_copy_memory( size[i] )) )
185 return( -1 );
186 inbuf[i] = VIPS_IMAGE_ADDR( memory[i], 0, 0 );
187 }
188 inbuf[i] = NULL;
189
190 /* Keep a copy of the memory images here for subclasses.
191 */
192 histogram->ready = memory;
193
194 histogram->out->Xsize = VIPS_IMAGE_N_PELS( histogram->ready[0] );
195 histogram->out->Ysize = 1;
196 if( hclass->format_table )
197 histogram->out->BandFmt =
198 hclass->format_table[histogram->ready[0]->BandFmt];
199 histogram->out->Type = VIPS_INTERPRETATION_HISTOGRAM;
200
201 if( !(outbuf = vips_malloc( object,
202 VIPS_IMAGE_SIZEOF_LINE( histogram->out ))) )
203 return( -1 );
204
205 hclass->process( histogram, outbuf, inbuf, histogram->ready[0]->Xsize );
206
207 if( vips_image_write_line( histogram->out, 0, outbuf ) )
208 return( -1 );
209
210 return( 0 );
211 }
212
213 static void
vips_histogram_class_init(VipsHistogramClass * class)214 vips_histogram_class_init( VipsHistogramClass *class )
215 {
216 GObjectClass *gobject_class = G_OBJECT_CLASS( class );
217 VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class );
218
219 gobject_class->set_property = vips_object_set_property;
220 gobject_class->get_property = vips_object_get_property;
221
222 vobject_class->nickname = "histogram";
223 vobject_class->description = _( "histogram operations" );
224 vobject_class->build = vips_histogram_build;
225
226 class->input_format = VIPS_FORMAT_NOTSET;
227
228 /* Inputs set by subclassess.
229 */
230
231 VIPS_ARG_IMAGE( class, "out", 10,
232 _( "Output" ),
233 _( "Output image" ),
234 VIPS_ARGUMENT_REQUIRED_OUTPUT,
235 G_STRUCT_OFFSET( VipsHistogram, out ) );
236
237 }
238
239 static void
vips_histogram_init(VipsHistogram * histogram)240 vips_histogram_init( VipsHistogram *histogram )
241 {
242 /* Sanity check this above.
243 */
244 histogram->n = -1;
245 }
246
247 /* Called from iofuncs to init all operations in this dir. Use a plugin system
248 * instead?
249 */
250 void
vips_histogram_operation_init(void)251 vips_histogram_operation_init( void )
252 {
253 extern GType vips_maplut_get_type( void );
254 extern GType vips_case_get_type( void );
255 extern GType vips_percent_get_type( void );
256 extern GType vips_hist_cum_get_type( void );
257 extern GType vips_hist_norm_get_type( void );
258 extern GType vips_hist_equal_get_type( void );
259 extern GType vips_hist_plot_get_type( void );
260 extern GType vips_hist_match_get_type( void );
261 extern GType vips_hist_local_get_type( void );
262 extern GType vips_hist_ismonotonic_get_type( void );
263 extern GType vips_hist_entropy_get_type( void );
264 extern GType vips_stdif_get_type( void );
265
266 vips_maplut_get_type();
267 vips_case_get_type();
268 vips_percent_get_type();
269 vips_stdif_get_type();
270 vips_hist_cum_get_type();
271 vips_hist_norm_get_type();
272 vips_hist_equal_get_type();
273 vips_hist_plot_get_type();
274 vips_hist_match_get_type();
275 vips_hist_local_get_type();
276 vips_hist_ismonotonic_get_type();
277 vips_hist_entropy_get_type();
278 }
279