1 /* base class for correlation
2 *
3 * 7/11/13
4 * - from convolution.c
5 */
6
7 /*
8
9 This file is part of VIPS.
10
11 VIPS is free software; you can redistribute it and/or modify
12 it under the terms of the GNU Lesser General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program 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
19 GNU Lesser General Public License for more details.
20
21 You should have received a copy of the GNU Lesser General Public License
22 along with this program; 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 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif /*HAVE_CONFIG_H*/
37 #include <vips/intl.h>
38
39 #include <stdio.h>
40 #include <math.h>
41
42 #include <vips/vips.h>
43 #include <vips/internal.h>
44
45 #include "pconvolution.h"
46 #include "correlation.h"
47
48 G_DEFINE_ABSTRACT_TYPE( VipsCorrelation, vips_correlation,
49 VIPS_TYPE_OPERATION );
50
51 static int
vips_correlation_gen(VipsRegion * or,void * seq,void * a,void * b,gboolean * stop)52 vips_correlation_gen( VipsRegion *or,
53 void *seq, void *a, void *b, gboolean *stop )
54 {
55 VipsRegion *ir = (VipsRegion *) seq;
56 VipsCorrelation *correlation = (VipsCorrelation *) b;
57 VipsCorrelationClass *cclass =
58 VIPS_CORRELATION_GET_CLASS( correlation );
59 VipsRect *r = &or->valid;
60
61 VipsRect irect;
62
63 /* What part of ir do we need?
64 */
65 irect.left = r->left;
66 irect.top = r->top;
67 irect.width = r->width + correlation->ref_ready->Xsize - 1;
68 irect.height = r->height + correlation->ref_ready->Ysize - 1;
69
70 if( vips_region_prepare( ir, &irect ) )
71 return( -1 );
72
73 cclass->correlation( correlation, ir, or );
74
75 return( 0 );
76 }
77
78 static int
vips_correlation_build(VipsObject * object)79 vips_correlation_build( VipsObject *object )
80 {
81 VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
82 VipsCorrelationClass *cclass = VIPS_CORRELATION_CLASS( class );
83 VipsCorrelation *correlation = (VipsCorrelation *) object;
84 VipsImage **t = (VipsImage **) vips_object_local_array( object, 6 );
85
86 if( VIPS_OBJECT_CLASS( vips_correlation_parent_class )->
87 build( object ) )
88 return( -1 );
89
90 /* Stretch input out.
91 */
92 if( vips_embed( correlation->in, &t[0],
93 correlation->ref->Xsize / 2, correlation->ref->Ysize / 2,
94 correlation->in->Xsize + correlation->ref->Xsize - 1,
95 correlation->in->Ysize + correlation->ref->Ysize - 1,
96 "extend", VIPS_EXTEND_COPY,
97 NULL ) )
98 return( -1 );
99 if( vips__formatalike( t[0], correlation->ref, &t[1], &t[2] ) ||
100 vips__bandalike( class->nickname, t[1], t[2], &t[3], &t[4] ) ||
101 !(t[5] = vips_image_copy_memory( t[4] )) )
102 return( -1 );
103
104 correlation->in_ready = t[3];
105 correlation->ref_ready = t[5];
106
107 g_object_set( object, "out", vips_image_new(), NULL );
108
109 /* FATSTRIP is good for us as THINSTRIP will cause
110 * too many recalculations on overlaps.
111 */
112 if( vips_image_pipelinev( correlation->out,
113 VIPS_DEMAND_STYLE_FATSTRIP,
114 correlation->in_ready, correlation->ref_ready, NULL ) )
115 return( -1 );
116 correlation->out->Xsize = correlation->in->Xsize;
117 correlation->out->Ysize = correlation->in->Ysize;
118 correlation->out->BandFmt =
119 cclass->format_table[correlation->in_ready->BandFmt];
120 if( cclass->pre_generate &&
121 cclass->pre_generate( correlation ) )
122 return( -1 );
123 if( vips_image_generate( correlation->out,
124 vips_start_one, vips_correlation_gen, vips_stop_one,
125 correlation->in_ready, correlation ) )
126 return( -1 );
127
128 vips_reorder_margin_hint( correlation->out,
129 correlation->ref->Xsize * correlation->ref->Ysize );
130
131 return( 0 );
132 }
133
134 static void
vips_correlation_class_init(VipsCorrelationClass * class)135 vips_correlation_class_init( VipsCorrelationClass *class )
136 {
137 GObjectClass *gobject_class = G_OBJECT_CLASS( class );
138 VipsObjectClass *object_class = (VipsObjectClass *) class;
139 VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
140
141 gobject_class->set_property = vips_object_set_property;
142 gobject_class->get_property = vips_object_get_property;
143
144 object_class->nickname = "correlation";
145 object_class->description = _( "correlation operation" );
146 object_class->build = vips_correlation_build;
147
148 operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
149
150 VIPS_ARG_IMAGE( class, "in", 0,
151 _( "Input" ),
152 _( "Input image argument" ),
153 VIPS_ARGUMENT_REQUIRED_INPUT,
154 G_STRUCT_OFFSET( VipsCorrelation, in ) );
155
156 VIPS_ARG_IMAGE( class, "ref", 10,
157 _( "Mask" ),
158 _( "Input reference image" ),
159 VIPS_ARGUMENT_REQUIRED_INPUT,
160 G_STRUCT_OFFSET( VipsCorrelation, ref ) );
161
162 VIPS_ARG_IMAGE( class, "out", 20,
163 _( "Output" ),
164 _( "Output image" ),
165 VIPS_ARGUMENT_REQUIRED_OUTPUT,
166 G_STRUCT_OFFSET( VipsCorrelation, out ) );
167
168 }
169
170 static void
vips_correlation_init(VipsCorrelation * correlation)171 vips_correlation_init( VipsCorrelation *correlation )
172 {
173 }
174