ruby-vips 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,14 @@
1
+ VALUE img_lrmerge(int, VALUE*, VALUE);
2
+ VALUE img_tbmerge(int, VALUE*, VALUE);
3
+ VALUE img_lrmerge1(int, VALUE*, VALUE);
4
+ VALUE img_tbmerge1(int, VALUE*, VALUE);
5
+ VALUE img_lrmosaic(int, VALUE*, VALUE);
6
+ VALUE img_tbmosaic(int, VALUE*, VALUE);
7
+ VALUE img_lrmosaic1(int, VALUE*, VALUE);
8
+ VALUE img_tbmosaic1(int, VALUE*, VALUE);
9
+ VALUE img_global_balance(VALUE, VALUE);
10
+ VALUE img_global_balancef(VALUE, VALUE);
11
+ VALUE img_correl(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
12
+ VALUE img_remosaic(VALUE, VALUE, VALUE);
13
+ VALUE img_align_bands(VALUE);
14
+ VALUE img_maxpos_subpel(VALUE);
@@ -0,0 +1,386 @@
1
+ #include "ruby_vips.h"
2
+ #include "image.h"
3
+ #include "image_relational.h"
4
+
5
+ static VALUE
6
+ img_equal_const(int argc, VALUE *argv, VALUE obj)
7
+ {
8
+ double *c;
9
+ int i;
10
+ GetImg(obj, data, im);
11
+ OutImg(obj, new, data_new, im_new);
12
+
13
+ c = IM_ARRAY(im_new, argc, double);
14
+
15
+ for(i = 0; i < argc; i++)
16
+ c[i] = NUM2DBL(argv[i]);
17
+
18
+ if (im_equal_vec(im, im_new, argc, c))
19
+ vips_lib_error();
20
+
21
+ return new;
22
+ }
23
+
24
+ static VALUE
25
+ img_equal_img(VALUE obj, VALUE obj2)
26
+ {
27
+ RUBY_VIPS_BINARY(im_equal);
28
+ }
29
+
30
+ /*
31
+ * call-seq:
32
+ * im.equal(other_image) -> image
33
+ * im.equal(constant, ...) -> image
34
+ *
35
+ * In the first form, this operation calculates *self* == <i>other_image</i>
36
+ * (image element equals image element) and writes the result to the output
37
+ * image.
38
+ *
39
+ * In the second form, this operation calculates *self* == <i>constant</i>
40
+ * (image element equals constant array) and writes the result to the output
41
+ * image.
42
+ */
43
+
44
+ VALUE
45
+ img_equal(int argc, VALUE *argv, VALUE obj)
46
+ {
47
+ if (argc < 1)
48
+ rb_raise(rb_eArgError, "Need at least one argument.");
49
+
50
+ if (TYPE(argv[0]) == T_FLOAT || TYPE(argv[0]) == T_FIXNUM)
51
+ return img_equal_const(argc, argv, obj);
52
+ else if (argc != 1)
53
+ rb_raise(rb_eArgError, "Need constants or one image.");
54
+
55
+ return img_equal_img(obj, argv[0]);
56
+ }
57
+
58
+ static VALUE
59
+ img_notequal_const(int argc, VALUE *argv, VALUE obj)
60
+ {
61
+ double *c;
62
+ int i;
63
+ GetImg(obj, data, im);
64
+ OutImg(obj, new, data_new, im_new);
65
+
66
+ c = IM_ARRAY(im_new, argc, double);
67
+
68
+ for(i = 0; i < argc; i++)
69
+ c[i] = NUM2DBL(argv[i]);
70
+
71
+ if (im_notequal_vec(im, im_new, argc, c))
72
+ vips_lib_error();
73
+
74
+ return new;
75
+ }
76
+
77
+ static VALUE
78
+ img_notequal_img(VALUE obj, VALUE obj2)
79
+ {
80
+ RUBY_VIPS_BINARY(im_notequal);
81
+ }
82
+
83
+ /*
84
+ * call-seq:
85
+ * im.notequal(other_image) -> image
86
+ * im.notequal(constant, ...) -> image
87
+ *
88
+ * In the first form, this operation calculates *self* != <i>other_image</i>
89
+ * (image element equals image element) and writes the result to the output
90
+ * image.
91
+ *
92
+ * In the second form, this operation calculates *self* != <i>constant</i>
93
+ * (image element equals constant array) and writes the result to the output
94
+ * image.
95
+ */
96
+
97
+ VALUE
98
+ img_notequal(int argc, VALUE *argv, VALUE obj)
99
+ {
100
+ if (argc < 1)
101
+ rb_raise(rb_eArgError, "Need at least one argument.");
102
+
103
+ if (TYPE(argv[0]) == T_FLOAT || TYPE(argv[0]) == T_FIXNUM)
104
+ return img_notequal_const(argc, argv, obj);
105
+ else if (argc != 1)
106
+ rb_raise(rb_eArgError, "Need constants or one image.");
107
+
108
+ return img_notequal_img(obj, argv[0]);
109
+ }
110
+
111
+ static VALUE
112
+ img_less_const(int argc, VALUE *argv, VALUE obj)
113
+ {
114
+ double *c;
115
+ int i;
116
+ GetImg(obj, data, im);
117
+ OutImg(obj, new, data_new, im_new);
118
+
119
+ c = IM_ARRAY(im_new, argc, double);
120
+
121
+ for(i = 0; i < argc; i++)
122
+ c[i] = NUM2DBL(argv[i]);
123
+
124
+ if (im_less_vec(im, im_new, argc, c))
125
+ vips_lib_error();
126
+
127
+ return new;
128
+ }
129
+
130
+ static VALUE
131
+ img_less_img(VALUE obj, VALUE obj2)
132
+ {
133
+ RUBY_VIPS_BINARY(im_less);
134
+ }
135
+
136
+ /*
137
+ * call-seq:
138
+ * im.less(other_image) -> image
139
+ * im.less(constant, ...) -> image
140
+ *
141
+ * In the first form, this operation calculates *self* < <i>other_image</i>
142
+ * (image element equals image element) and writes the result to the output
143
+ * image.
144
+ *
145
+ * In the second form, this operation calculates *self* < <i>constant</i>
146
+ * (image element equals constant array) and writes the result to the output
147
+ * image.
148
+ */
149
+
150
+ VALUE
151
+ img_less(int argc, VALUE *argv, VALUE obj)
152
+ {
153
+ if (argc < 1)
154
+ rb_raise(rb_eArgError, "Need at least one argument.");
155
+
156
+ if (TYPE(argv[0]) == T_FLOAT || TYPE(argv[0]) == T_FIXNUM)
157
+ return img_less_const(argc, argv, obj);
158
+ else if (argc != 1)
159
+ rb_raise(rb_eArgError, "Need constants or one image.");
160
+
161
+ return img_less_img(obj, argv[0]);
162
+ }
163
+
164
+ static VALUE
165
+ img_lesseq_const(int argc, VALUE *argv, VALUE obj)
166
+ {
167
+ double *c;
168
+ int i;
169
+ GetImg(obj, data, im);
170
+ OutImg(obj, new, data_new, im_new);
171
+
172
+ c = IM_ARRAY(im_new, argc, double);
173
+
174
+ for(i = 0; i < argc; i++)
175
+ c[i] = NUM2DBL(argv[i]);
176
+
177
+ if (im_lesseq_vec(im, im_new, argc, c))
178
+ vips_lib_error();
179
+
180
+ return new;
181
+ }
182
+
183
+ static VALUE
184
+ img_lesseq_img(VALUE obj, VALUE obj2)
185
+ {
186
+ RUBY_VIPS_BINARY(im_lesseq);
187
+ }
188
+
189
+ /*
190
+ * call-seq:
191
+ * im.lesseq(other_image) -> image
192
+ * im.lesseq(constant, ...) -> image
193
+ *
194
+ * In the first form, this operation calculates *self* <= <i>other_image</i>
195
+ * (image element equals image element) and writes the result to the output
196
+ * image.
197
+ *
198
+ * In the second form, this operation calculates *self* <= <i>constant</i>
199
+ * (image element equals constant array) and writes the result to the output
200
+ * image.
201
+ */
202
+
203
+ VALUE
204
+ img_lesseq(int argc, VALUE *argv, VALUE obj)
205
+ {
206
+ if (argc < 1)
207
+ rb_raise(rb_eArgError, "Need at least one argument.");
208
+
209
+ if (TYPE(argv[0]) == T_FLOAT || TYPE(argv[0]) == T_FIXNUM)
210
+ return img_lesseq_const(argc, argv, obj);
211
+ else if (argc != 1)
212
+ rb_raise(rb_eArgError, "Need constants or one image.");
213
+
214
+ return img_lesseq_img(obj, argv[0]);
215
+ }
216
+
217
+ static VALUE
218
+ img_more_const(int argc, VALUE *argv, VALUE obj)
219
+ {
220
+ double *c;
221
+ int i;
222
+ GetImg(obj, data, im);
223
+ OutImg(obj, new, data_new, im_new);
224
+
225
+ c = IM_ARRAY(im_new, argc, double);
226
+
227
+ for(i = 0; i < argc; i++)
228
+ c[i] = NUM2DBL(argv[i]);
229
+
230
+ if (im_more_vec(im, im_new, argc, c))
231
+ vips_lib_error();
232
+
233
+ return new;
234
+ }
235
+
236
+ static VALUE
237
+ img_more_img(VALUE obj, VALUE obj2)
238
+ {
239
+ RUBY_VIPS_BINARY(im_more);
240
+ }
241
+
242
+ /*
243
+ * call-seq:
244
+ * im.more(other_image) -> image
245
+ * im.more(constant, ...) -> image
246
+ *
247
+ * In the first form, this operation calculates *self* > <i>other_image</i>
248
+ * (image element equals image element) and writes the result to the output
249
+ * image.
250
+ *
251
+ * In the second form, this operation calculates *self* > <i>constant</i>
252
+ * (image element equals constant array) and writes the result to the output
253
+ * image.
254
+ */
255
+
256
+ VALUE
257
+ img_more(int argc, VALUE *argv, VALUE obj)
258
+ {
259
+ if (argc < 1)
260
+ rb_raise(rb_eArgError, "Need at least one argument.");
261
+
262
+ if (TYPE(argv[0]) == T_FLOAT || TYPE(argv[0]) == T_FIXNUM)
263
+ return img_more_const(argc, argv, obj);
264
+ else if (argc != 1)
265
+ rb_raise(rb_eArgError, "Need constants or one image.");
266
+
267
+ return img_more_img(obj, argv[0]);
268
+ }
269
+
270
+ static VALUE
271
+ img_moreeq_const(int argc, VALUE *argv, VALUE obj)
272
+ {
273
+ double *c;
274
+ int i;
275
+ GetImg(obj, data, im);
276
+ OutImg(obj, new, data_new, im_new);
277
+
278
+ c = IM_ARRAY(im_new, argc, double);
279
+
280
+ for(i = 0; i < argc; i++)
281
+ c[i] = NUM2DBL(argv[i]);
282
+
283
+ if (im_moreeq_vec(im, im_new, argc, c))
284
+ vips_lib_error();
285
+
286
+ return new;
287
+ }
288
+
289
+ static VALUE
290
+ img_moreeq_img(VALUE obj, VALUE obj2)
291
+ {
292
+ RUBY_VIPS_BINARY(im_moreeq);
293
+ }
294
+
295
+ /*
296
+ * call-seq:
297
+ * im.moreeq(other_image) -> image
298
+ * im.moreeq(constant, ...) -> image
299
+ *
300
+ * In the first form, this operation calculates *self* >= <i>other_image</i>
301
+ * (image element equals image element) and writes the result to the output
302
+ * image.
303
+ *
304
+ * In the second form, this operation calculates *self* >= <i>constant</i>
305
+ * (image element equals constant array) and writes the result to the output
306
+ * image.
307
+ */
308
+
309
+ VALUE
310
+ img_moreeq(int argc, VALUE *argv, VALUE obj)
311
+ {
312
+ if (argc < 1)
313
+ rb_raise(rb_eArgError, "Need at least one argument.");
314
+
315
+ if (TYPE(argv[0]) == T_FLOAT || TYPE(argv[0]) == T_FIXNUM)
316
+ return img_moreeq_const(argc, argv, obj);
317
+ else if (argc != 1)
318
+ rb_raise(rb_eArgError, "Need constants or one image.");
319
+
320
+ return img_moreeq_img(obj, argv[0]);
321
+ }
322
+
323
+ /*
324
+ * call-seq:
325
+ * im.ifthenelse(a_image, b_image) -> image
326
+ *
327
+ * This operation scans the condition image *self* and uses it to select pixels
328
+ * from either the then image <i>a_image</i> or the else image <i>b_image</i>.
329
+ * Non-zero means <i>a_image</i>, 0 means <i>b_image</i>.
330
+ *
331
+ * Any image can have either 1 band or n bands, where n is the same for all
332
+ * the non-1-band images. Single band images are then effectively copied to
333
+ * make n-band images.
334
+ *
335
+ * Images <i>a_image</i> and <i>b_image</i> are cast up to the smallest common
336
+ * format.
337
+ *
338
+ * Images <i>a_image</i> and <i>b_image</i> must match exactly in size.
339
+ */
340
+
341
+ VALUE
342
+ img_ifthenelse(VALUE obj, VALUE obj2, VALUE obj3)
343
+ {
344
+ GetImg(obj, data, im);
345
+ GetImg(obj2, data2, im2);
346
+ GetImg(obj3, data3, im3);
347
+ OutImg3(obj, obj2, obj3, new, data_new, im_new);
348
+
349
+ if (im_ifthenelse(im, im2, im3, im_new))
350
+ vips_lib_error();
351
+
352
+ return new;
353
+ }
354
+
355
+ /*
356
+ * call-seq:
357
+ * im.blend(a_image, b_image) -> image
358
+ *
359
+ * This operation scans the condition image *self* (which must be unsigned
360
+ * char) and uses it to blend pixels from either the then image <i>a_image</i>
361
+ * or the else image <i>b_image</i>. 255 means <i>a_image</i> only, 0 means
362
+ * <i>b_image</i> only, and intermediate values are a mixture.
363
+ *
364
+ * Any image can have either 1 band or n bands, where n is the same for all
365
+ * the non-1-band images. Single band images are then effectively copied to
366
+ * make n-band images.
367
+ *
368
+ * Images <i>a_image</i> and <i>b_image</i> are cast up to the smallest common
369
+ * format.
370
+ *
371
+ * Images <i>a_image</i> and <i>b_image</i> must match exactly in size.
372
+ */
373
+
374
+ VALUE
375
+ img_blend(VALUE obj, VALUE obj2, VALUE obj3)
376
+ {
377
+ GetImg(obj, data, im);
378
+ GetImg(obj2, data2, im2);
379
+ GetImg(obj3, data3, im3);
380
+ OutImg3(obj, obj2, obj3, new, data_new, im_new);
381
+
382
+ if (im_blend(im, im2, im3, im_new))
383
+ vips_lib_error();
384
+
385
+ return new;
386
+ }
@@ -0,0 +1,8 @@
1
+ VALUE img_equal(int , VALUE*, VALUE);
2
+ VALUE img_notequal(int , VALUE*, VALUE);
3
+ VALUE img_less(int , VALUE*, VALUE);
4
+ VALUE img_lesseq(int , VALUE*, VALUE);
5
+ VALUE img_more(int , VALUE*, VALUE);
6
+ VALUE img_moreeq(int , VALUE*, VALUE);
7
+ VALUE img_ifthenelse(VALUE , VALUE , VALUE);
8
+ VALUE img_blend(VALUE , VALUE , VALUE);
@@ -0,0 +1,253 @@
1
+ #include "ruby_vips.h"
2
+ #include "image.h"
3
+ #include "interpolator.h"
4
+ #include "header.h"
5
+ #include "image_resample.h"
6
+
7
+ /*
8
+ * call-seq:
9
+ * im.affinei(interpolator, a, b, c, d, dx, dy) -> image
10
+ * im.affinei(interpolator, a, b, c, d, dx, dy, ox, oy, ow, oh) -> image
11
+ *
12
+ * Applies an affine transformation on *self*. *self* many have any number of
13
+ * bands, be any size, and have any non-complex type.
14
+ *
15
+ * The transformation is described by <i>a</i>, <i>b</i>, <i>c</i>, <i>d</i>,
16
+ * <i>dx</i>, <i>dy</i>. The point (x,y) in
17
+ * the input is mapped onto point (X,Y) in the output by
18
+ *
19
+ * X = a * x + b * y + dx
20
+ * Y = c * x + d * y + dy
21
+ *
22
+ * In the first form, the entire image is transformed. In the second form, the
23
+ * area of the output image given by <i>ow</i>, <i>oh</i>, <i>ox</i>, <i>oy</i>
24
+ * is generated. (0,0) is the position of the transformed top-left-hand corner
25
+ * of the input image.
26
+ *
27
+ * Points are generated using the supplied interpolator.
28
+ */
29
+
30
+ VALUE
31
+ img_affinei(int argc, VALUE *argv, VALUE obj)
32
+ {
33
+ VALUE interpolator, a, b, c, d, dx, dy, ox, oy, ow, oh;
34
+ VipsInterpolate *itrp_vips;
35
+
36
+ rb_scan_args(argc, argv, "74", &interpolator, &a, &b, &c, &d, &dx, &dy, &ox,
37
+ &oy, &ow, &oh);
38
+
39
+ itrp_vips = interp_lookup(interpolator);
40
+ GetImg(obj, data, im);
41
+ OutImg(obj, new, data_new, im_new);
42
+
43
+ if (NIL_P(ox)) {
44
+ if (im_affinei_all(im, im_new, itrp_vips,
45
+ NUM2DBL(a), NUM2DBL(b), NUM2DBL(c), NUM2DBL(d),
46
+ NUM2DBL(dx), NUM2DBL(dy)))
47
+ vips_lib_error();
48
+ } else {
49
+ if (NIL_P(oh))
50
+ rb_raise(rb_eArgError, "If you supply any output parameters, you have to supply them all");
51
+
52
+ if (im_affinei(im, im_new, itrp_vips,
53
+ NUM2DBL(a), NUM2DBL(b), NUM2DBL(c), NUM2DBL(d),
54
+ NUM2DBL(dx), NUM2DBL(dy),
55
+ NUM2INT(ox), NUM2INT(oy), NUM2INT(ow), NUM2INT(oh)))
56
+ vips_lib_error();
57
+ }
58
+
59
+ return new;
60
+ }
61
+
62
+ /*
63
+ * call-seq:
64
+ * im.affinei_resize(interpolator, x [,y]) -> image
65
+ *
66
+ * Applies an affine resize using the supplied interpolator. If <i>y</i> is
67
+ * ommitted then the aspect ratio of *self* will be maintained.
68
+ */
69
+
70
+ VALUE
71
+ img_affinei_resize(int argc, VALUE *argv, VALUE obj)
72
+ {
73
+ VALUE interpolator, x_scale, y_scale;
74
+ VipsInterpolate *itrp_vips;
75
+
76
+ rb_scan_args(argc, argv, "21", &interpolator, &x_scale, &y_scale);
77
+
78
+ GetImg(obj, data, im);
79
+ OutImg(obj, new, data_new, im_new);
80
+
81
+ itrp_vips = interp_lookup(interpolator);
82
+
83
+ if (NIL_P(y_scale))
84
+ y_scale = x_scale;
85
+
86
+ if (im_affinei_all(im, im_new, itrp_vips, NUM2DBL(x_scale), 0, 0,
87
+ NUM2DBL(y_scale), 0, 0))
88
+ vips_lib_error();
89
+
90
+ return new;
91
+ }
92
+
93
+ /*
94
+ * call-seq:
95
+ * im.stretch3(dx [,dy]) -> image
96
+ *
97
+ * Stretches the input image by 3% horizontally, and displaces it by
98
+ * <i>dx</i>/<i>dy</i>. It uses bi-cubic interpolation, but runs quickly. It
99
+ * works only for unsigned short images.
100
+ *
101
+ * This function is part of the MARC acquisition software, but is generally
102
+ * useful for squaring up the pixels in images from the Kontron ProgRes camera
103
+ * range.
104
+ */
105
+
106
+ VALUE
107
+ img_stretch3(int argc, VALUE *argv, VALUE obj)
108
+ {
109
+ VALUE dx, dy;
110
+
111
+ rb_scan_args(argc, argv, "11", &dx, &dy);
112
+ if (NIL_P(dy))
113
+ dy = dx;
114
+
115
+ GetImg(obj, data, im);
116
+ OutImg(obj, new, data_new, im_new);
117
+
118
+ if (im_stretch3(im, im_new, NUM2DBL(dx), NUM2DBL(dy)))
119
+ vips_lib_error();
120
+
121
+ return new;
122
+ }
123
+
124
+ /*
125
+ * call-seq:
126
+ * im.shrink(width_ratio [,height_ratio]) -> image
127
+ *
128
+ * Shrink *self* by <i>width_ratio</i> along the horizontal and
129
+ * <i>height_ratio</i> along the vertical direction. If <i>height_ratio</i> is
130
+ * not given, it uses <i>width_ratio</i>. The function does not perform
131
+ * subpixel interpolation and therefore the resultant image can present
132
+ * aliasing especially for small x and y factors. Any size image, any
133
+ * non-complex type, any number of bands.
134
+ */
135
+
136
+ VALUE
137
+ img_shrink(int argc, VALUE *argv, VALUE obj)
138
+ {
139
+ VALUE width_ratio, height_ratio;
140
+
141
+ rb_scan_args(argc, argv, "11", &width_ratio, &height_ratio);
142
+ if (NIL_P(height_ratio))
143
+ height_ratio = width_ratio;
144
+
145
+ GetImg(obj, data, im);
146
+ OutImg(obj, new, data_new, im_new);
147
+
148
+ if (im_shrink(im, im_new, NUM2DBL(width_ratio), NUM2DBL(height_ratio)))
149
+ vips_lib_error();
150
+
151
+ return new;
152
+ }
153
+
154
+ /*
155
+ * call-seq:
156
+ * im.rightshift_size(xshift, yshift, fmt) -> image
157
+ *
158
+ * Decreases the size of an integer type image by a power-of-two factor, very
159
+ * quickly, by summing the values of adjacent pixels. The sum is shifted to
160
+ * produce output of the specified band format.
161
+ *
162
+ * <i>xshift</i> and <i>yshift</i> are positive and give the base-two
163
+ * logarithms of the scale factors.
164
+ *
165
+ * If the input image is a signed type, then the band format must be one of
166
+ * :CHAR, :SHORT or :INT. If it is an unsigned type, then the band format must
167
+ * be one of :UCHAR, :USHORT or :UINT.
168
+ */
169
+
170
+ VALUE
171
+ img_rightshift_size(VALUE obj, VALUE xshift, VALUE yshift, VALUE fmt)
172
+ {
173
+ GetImg(obj, data, im);
174
+ OutImg(obj, new, data_new, im_new);
175
+
176
+ if(im_rightshift_size(im, im_new, NUM2DBL(xshift), NUM2DBL(yshift),
177
+ header_id_to_band_fmt(SYM2ID(fmt))))
178
+ vips_lib_error();
179
+
180
+ return new;
181
+ }
182
+
183
+
184
+ /*
185
+ * call-seq:
186
+ * im.match_linear(other_image, xr1, yr1, xs1, ys1, xr2, yr2, xs2,
187
+ * ys2) -> image
188
+ *
189
+ * Works exactly as Image#match_linear_search, but does not attempt to
190
+ * correlate to correct your tie points. It can thus be used for any angle and
191
+ * any scale, but you must be far more careful in your selection.
192
+ */
193
+
194
+ VALUE
195
+ img_match_linear(VALUE obj, VALUE obj2,
196
+ VALUE xr1, VALUE yr1, VALUE xs1, VALUE ys1,
197
+ VALUE xr2, VALUE yr2, VALUE xs2, VALUE ys2)
198
+ {
199
+ GetImg(obj, data, im);
200
+ GetImg(obj2, data2, im2);
201
+ OutImg(obj, new, data_new, im_new);
202
+
203
+ if (im_match_linear(im, im2, im_new,
204
+ NUM2INT(xr1), NUM2INT(yr1), NUM2INT(xs1), NUM2INT(ys1),
205
+ NUM2INT(xr2), NUM2INT(yr2), NUM2INT(xs2), NUM2INT(ys2)))
206
+ vips_lib_error();
207
+
208
+ return new;
209
+ }
210
+
211
+ /*
212
+ * call-seq:
213
+ * im.match_linear_search(other_image, xr1, yr1, xs1, ys1, xr2, yr2, xs2,
214
+ * ys2, hwindowsize, hsearchsize) -> image
215
+ *
216
+ * Attempts to transform sec to make it match ref. The transformation is
217
+ * linear, that is, it only involves scale, rotate and translate.
218
+ *
219
+ * Requires a pair of tie points to fix the parameters of its transformation.
220
+ * You should pick points as far apart as possible to increase accuracy. It
221
+ * will search the area in the image around each tie point for a good fit, so
222
+ * your selection of points need not be exact. WARNING! This searching process
223
+ * will fail for rotations of more than about 10 degrees or for scales of more
224
+ * than about 10 percent.
225
+ *
226
+ * The best you can hope for is < 1 pixel error, since the command does not
227
+ * attempt sub-pixel correlation.
228
+ *
229
+ * <i>hwindowsize</i> and <i>hsearchsize</i> set the size of the area to be
230
+ * searched: we recommend values of 5 and 14.
231
+ *
232
+ * The output image is positioned and clipped so that you can immediately
233
+ * subtract it from orig to obtain pixel difference images.
234
+ */
235
+
236
+ VALUE
237
+ img_match_linear_search(VALUE obj, VALUE obj2,
238
+ VALUE xr1, VALUE yr1, VALUE xs1, VALUE ys1,
239
+ VALUE xr2, VALUE yr2, VALUE xs2, VALUE ys2,
240
+ VALUE hwindowsize, VALUE hsearchsize)
241
+ {
242
+ GetImg(obj, data, im);
243
+ GetImg(obj2, data2, im2);
244
+ OutImg(obj, new, data_new, im_new);
245
+
246
+ if (im_match_linear_search(im, im2, im_new,
247
+ NUM2INT(xr1), NUM2INT(yr1), NUM2INT(xs1), NUM2INT(ys1),
248
+ NUM2INT(xr2), NUM2INT(yr2), NUM2INT(xs2), NUM2INT(ys2),
249
+ NUM2INT(hwindowsize), NUM2INT(hsearchsize)))
250
+ vips_lib_error();
251
+
252
+ return new;
253
+ }