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,9 @@
1
+ VALUE img_affinei(int, VALUE*, VALUE);
2
+ VALUE img_affinei_resize(int, VALUE*, VALUE);
3
+ VALUE img_stretch3(int, VALUE*, VALUE);
4
+ VALUE img_shrink(int, VALUE*, VALUE);
5
+ VALUE img_rightshift_size(VALUE, VALUE, VALUE, VALUE);
6
+ VALUE img_match_linear(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE,
7
+ VALUE, VALUE);
8
+ VALUE img_match_linear_search(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE,
9
+ VALUE, VALUE, VALUE, VALUE, VALUE);
@@ -0,0 +1,106 @@
1
+ #include "ruby_vips.h"
2
+
3
+ static VALUE cVIPSInterpolator;
4
+ static ID id_INTERPOLATORS;
5
+
6
+ VipsInterpolate*
7
+ interp_lookup(VALUE itrp_sym)
8
+ {
9
+ VALUE rb_interp;
10
+ VipsInterpolate *itrp;
11
+ VALUE hVIPSInterpolators = rb_const_get(cVIPSInterpolator,
12
+ id_INTERPOLATORS);
13
+
14
+ rb_interp = rb_hash_aref(hVIPSInterpolators, itrp_sym);
15
+ Data_Get_Struct(rb_interp, VipsInterpolate, itrp);
16
+
17
+ return itrp;
18
+ }
19
+
20
+ static void*
21
+ interp_register(VipsInterpolateClass *itrp, void *hash)
22
+ {
23
+ VipsInterpolate *inst;
24
+ VipsObjectClass *klass = (VipsObjectClass*) itrp;;
25
+ VALUE obj, hVIPSInterpolators = (VALUE)hash;
26
+
27
+ inst = vips_interpolate_new(klass->nickname);
28
+ obj = Data_Wrap_Struct(cVIPSInterpolator, 0, 0, inst);
29
+
30
+ rb_hash_aset(hVIPSInterpolators, ID2SYM(rb_intern(klass->nickname)), obj);
31
+
32
+ return NULL;
33
+ }
34
+
35
+ static void
36
+ interp_register_builtin()
37
+ {
38
+ VALUE hVIPSInterpolators = rb_hash_new();
39
+
40
+ /* Hash of available interpolators. Keys are the symbols, and values are
41
+ * interpolator objects.
42
+ */
43
+ rb_define_const(cVIPSInterpolator, "INTERPOLATORS", hVIPSInterpolators);
44
+
45
+ vips_class_map_concrete_all(
46
+ g_type_from_name( "VipsInterpolate" ),
47
+ (void *) interp_register,
48
+ (void *) hVIPSInterpolators
49
+ );
50
+ }
51
+
52
+
53
+ /*
54
+ * call-seq:
55
+ * interp.nickname -> string
56
+ *
57
+ * Retrieve the internally used nickname of the interpolator.
58
+ */
59
+
60
+ static VALUE
61
+ interp_nickname(VALUE obj)
62
+ {
63
+ VipsObject *v_obj;
64
+ Data_Get_Struct(obj, VipsObject, v_obj);
65
+ return rb_str_new2(v_obj->nickname);
66
+ }
67
+
68
+ /*
69
+ * call-seq:
70
+ * interp.description -> string
71
+ *
72
+ * Retrieve the description of the interpolator.
73
+ */
74
+
75
+ static VALUE
76
+ interp_description(VALUE obj)
77
+ {
78
+ VipsObject *v_obj;
79
+ Data_Get_Struct(obj, VipsObject, v_obj);
80
+ return rb_str_new2(v_obj->description);
81
+ }
82
+
83
+ /*
84
+ * VIPS Interpolators determine how color values will be estimated when an
85
+ * image is modified.
86
+ *
87
+ * This class provides information on which interpolators are available to
88
+ * VIPS.
89
+ */
90
+
91
+ void
92
+ init_Interpolator()
93
+ {
94
+ cVIPSInterpolator = rb_define_class_under(mVIPS, "Interpolator", rb_cObject);
95
+
96
+ rb_define_method(cVIPSInterpolator, "nickname", interp_nickname, 0);
97
+ rb_define_method(cVIPSInterpolator, "description", interp_description, 0);
98
+
99
+ id_INTERPOLATORS = rb_intern("INTERPOLATORS");
100
+
101
+ interp_register_builtin();
102
+
103
+ #if 0
104
+ VALUE mVIPS = rb_define_module("VIPS");
105
+ #endif
106
+ }
@@ -0,0 +1,6 @@
1
+ #ifndef RUBY_VIPS_INTERPOLATOR_H
2
+ #define RUBY_VIPS_INTERPOLATOR_H
3
+
4
+ VipsInterpolate* interp_lookup(VALUE);
5
+
6
+ #endif
data/ext/mask.c ADDED
@@ -0,0 +1,349 @@
1
+ #include "ruby_vips.h"
2
+ #include "mask.h"
3
+ #include "image.h"
4
+
5
+ VALUE cVIPSMask;
6
+
7
+ static void
8
+ mask_free(vipsMask *msk)
9
+ {
10
+ if(msk->dmask)
11
+ im_free_dmask(msk->dmask);
12
+
13
+ if(msk->imask)
14
+ im_free_imask(msk->imask);
15
+
16
+ xfree(msk);
17
+ }
18
+
19
+ VALUE
20
+ mask_alloc(VALUE klass)
21
+ {
22
+ vipsMask *msk;
23
+ VALUE new = Data_Make_Struct(klass, vipsMask, 0, mask_free, msk);
24
+ msk->imask = NULL;
25
+ msk->dmask = NULL;
26
+
27
+ return new;
28
+ }
29
+
30
+ static int
31
+ ary_is_int_2d(VALUE ary)
32
+ {
33
+ Check_Type(ary, T_ARRAY);
34
+
35
+ VALUE *row, *rows = RARRAY_PTR(ary);
36
+ int i, j;
37
+ for(i = 0; i < RARRAY_LEN(ary); i++) {
38
+ Check_Type(rows[i], T_ARRAY);
39
+ for(j = 0; j < RARRAY_LEN(rows[i]); j++) {
40
+ row = RARRAY_PTR(rows[i]);
41
+ if(TYPE(row[j]) != T_FIXNUM)
42
+ return 0;
43
+ }
44
+ }
45
+
46
+ return 1;
47
+ }
48
+
49
+ /* initialize an INTMASK from a ruby array */
50
+
51
+ static INTMASK*
52
+ mask_ary2imask(VALUE coeffs)
53
+ {
54
+ INTMASK *msk;
55
+ VALUE row, *rows = RARRAY_PTR(coeffs);
56
+ int i, j, num_cols, num_rows = RARRAY_LEN(coeffs);
57
+
58
+ num_cols = RARRAY_LEN(rows[0]);
59
+ if( !(msk = im_create_imask("mask_initialize_imask", num_cols, num_rows)) )
60
+ vips_lib_error();
61
+
62
+ for(i = 0; i < num_rows; i++) {
63
+ row = rows[i];
64
+ for(j = 0; j < RARRAY_LEN(row) && j < num_cols; j++)
65
+ msk->coeff[i * num_cols + j] = NUM2INT(RARRAY_PTR(row)[j]);
66
+ }
67
+
68
+ return msk;
69
+ }
70
+
71
+ static DOUBLEMASK*
72
+ mask_ary2dmask(VALUE coeffs)
73
+ {
74
+ DOUBLEMASK *msk;
75
+ VALUE row, *rows = RARRAY_PTR(coeffs);
76
+ int i, j, num_cols, num_rows = RARRAY_LEN(coeffs);
77
+
78
+ num_cols = RARRAY_LEN(rows[0]);
79
+ if (!(msk = im_create_dmask("mask_ary2dmask", num_cols, num_rows)))
80
+ vips_lib_error();
81
+
82
+ for(i = 0; i < num_rows; i++) {
83
+ row = rows[i];
84
+ for(j = 0; j < RARRAY_LEN(row) && j < num_cols; j++)
85
+ msk->coeff[i * num_cols + j] = NUM2DBL(RARRAY_PTR(row)[j]);
86
+ }
87
+
88
+ return msk;
89
+ }
90
+
91
+ /*
92
+ * call-seq:
93
+ * Mask.new(coeffs, scale=1, offset=0) -> mask
94
+ *
95
+ * Create a new Mask object. <i>coeffs</i> is a two-dimensional array where
96
+ * every row must have the same length. Note that some methods require a mask
97
+ * where all values in <i>coeffs</i> are whole integers.
98
+ */
99
+ static VALUE
100
+ mask_initialize(int argc, VALUE *argv, VALUE obj)
101
+ {
102
+ VALUE coeffs, scale, offset;
103
+ vipsMask *msk;
104
+ Data_Get_Struct(obj, vipsMask, msk);
105
+
106
+ rb_scan_args(argc, argv, "12", &coeffs, &scale, &offset);
107
+
108
+ if (NIL_P(scale))
109
+ scale = INT2NUM(1);
110
+
111
+ if (NIL_P(offset))
112
+ offset = INT2NUM(0);
113
+
114
+ if(TYPE(scale) == T_FIXNUM && TYPE(offset) == T_FIXNUM &&
115
+ ary_is_int_2d(coeffs)) {
116
+ msk->imask = mask_ary2imask(coeffs);
117
+ msk->imask->scale = NUM2INT(scale);
118
+ msk->imask->offset = NUM2INT(offset);
119
+ }
120
+
121
+ msk->dmask = mask_ary2dmask(coeffs);
122
+ msk->dmask->scale = NUM2DBL(scale);
123
+ msk->dmask->offset = NUM2DBL(offset);
124
+
125
+ return obj;
126
+ }
127
+
128
+ /*
129
+ * call-seq:
130
+ * msk.xsize -> number
131
+ *
132
+ * Retrieve the number of columns in the mask.
133
+ */
134
+
135
+ static VALUE
136
+ mask_xsize(VALUE obj)
137
+ {
138
+ vipsMask *msk;
139
+ Data_Get_Struct(obj, vipsMask, msk);
140
+ return INT2FIX(msk->dmask->xsize);
141
+ }
142
+
143
+ /*
144
+ * call-seq:
145
+ * msk.ysize -> number
146
+ *
147
+ * Retrieve the number of rows in the mask.
148
+ */
149
+
150
+ static VALUE
151
+ mask_ysize(VALUE obj)
152
+ {
153
+ vipsMask *msk;
154
+ Data_Get_Struct(obj, vipsMask, msk);
155
+ return INT2FIX(msk->dmask->ysize);
156
+ }
157
+
158
+ /*
159
+ * call-seq:
160
+ * msk.scale -> number
161
+ *
162
+ * Retrieve the scale of the mask.
163
+ */
164
+
165
+ static VALUE
166
+ mask_scale(VALUE obj)
167
+ {
168
+ vipsMask *msk;
169
+ Data_Get_Struct(obj, vipsMask, msk);
170
+ return msk->imask ? INT2FIX(msk->imask->scale) : DBL2NUM(msk->dmask->scale);
171
+ }
172
+
173
+ /*
174
+ * call-seq:
175
+ * msk.offset -> number
176
+ *
177
+ * Retrieve the offset of the mask.
178
+ */
179
+
180
+ static VALUE
181
+ mask_offset(VALUE obj)
182
+ {
183
+ vipsMask *msk;
184
+ Data_Get_Struct(obj, vipsMask, msk);
185
+ return msk->imask ? INT2FIX(msk->imask->offset) : DBL2NUM(msk->dmask->offset);
186
+ }
187
+
188
+ VALUE
189
+ imask2rb(INTMASK *msk)
190
+ {
191
+ int i, j;
192
+ VALUE row, rows = rb_ary_new2(msk->ysize);
193
+
194
+ for(i = 0; i < msk->ysize; i++) {
195
+ row = rb_ary_new2(msk->xsize);
196
+ rb_ary_push(rows, row);
197
+ for(j = 0; j < msk->xsize; j++) {
198
+ rb_ary_push(row, INT2FIX(msk->coeff[i * msk->xsize + j]));
199
+ }
200
+ }
201
+
202
+ return rows;
203
+ }
204
+
205
+ VALUE
206
+ dmask2rb(DOUBLEMASK *msk)
207
+ {
208
+ int i, j;
209
+ VALUE row, rows = rb_ary_new2(msk->ysize);
210
+
211
+ for(i = 0; i < msk->ysize; i++) {
212
+ row = rb_ary_new2(msk->xsize);
213
+ rb_ary_push(rows, row);
214
+ for(j = 0; j < msk->xsize; j++) {
215
+ rb_ary_push(row, DBL2NUM(msk->coeff[i * msk->xsize + j]));
216
+ }
217
+ }
218
+
219
+ return rows;
220
+ }
221
+
222
+ /*
223
+ * call-seq:
224
+ * msk.coeff -> array
225
+ *
226
+ * Retrieve the two-dimensional array of coefficients for the mask.
227
+ */
228
+
229
+ static VALUE
230
+ mask_coeff(VALUE obj)
231
+ {
232
+ vipsMask *msk;
233
+ Data_Get_Struct(obj, vipsMask, msk);
234
+ if(msk->imask)
235
+ return imask2rb(msk->imask);
236
+ else
237
+ return dmask2rb(msk->dmask);
238
+ }
239
+
240
+ /*
241
+ * call-seq:
242
+ * msk.int? -> true or false
243
+ *
244
+ * Indicate whether all coefficients, the scale and the offset in the mask are
245
+ * integers. Some methods require an all-integer mask.
246
+ */
247
+
248
+ static VALUE
249
+ mask_int_p(VALUE obj)
250
+ {
251
+ vipsMask *msk;
252
+ Data_Get_Struct(obj, vipsMask, msk);
253
+ if(msk->imask)
254
+ return Qtrue;
255
+
256
+ return Qfalse;
257
+ }
258
+
259
+ void
260
+ mask_arg2mask(VALUE arg, INTMASK **imask, DOUBLEMASK **dmask)
261
+ {
262
+ INTMASK *imask_t = NULL;
263
+ DOUBLEMASK *dmask_t = NULL;
264
+ vipsMask *data;
265
+ const char *errstr;
266
+
267
+ if (TYPE(arg) == T_ARRAY) {
268
+ if (imask && ary_is_int_2d(arg))
269
+ imask_t = mask_ary2imask(arg);
270
+ else if (dmask)
271
+ dmask_t = mask_ary2dmask(arg);
272
+ } else if (CLASS_OF(arg) == cVIPSMask) {
273
+ Data_Get_Struct(arg, vipsMask, data);
274
+
275
+ if (imask)
276
+ imask_t = data->imask;
277
+ if (dmask)
278
+ dmask_t = data->dmask;
279
+ }
280
+
281
+ if (!imask_t && !dmask_t) {
282
+ if (imask && dmask)
283
+ errstr = "Expected an array or a Mask";
284
+ else
285
+ errstr = "Expected an int array or an int Mask";
286
+
287
+ rb_raise(rb_eArgError, errstr);
288
+ }
289
+
290
+ if (imask)
291
+ *imask = imask_t;
292
+
293
+ if (dmask)
294
+ *dmask = dmask_t;
295
+ }
296
+
297
+ /*
298
+ * call-seq:
299
+ * msk.int? -> true or false
300
+ *
301
+ * Create a one-band, band format :DOUBLE image based on mask *self*.
302
+ */
303
+
304
+ static VALUE
305
+ mask_to_image(VALUE obj)
306
+ {
307
+ vipsMask *msk;
308
+
309
+ OutImg(obj, new, data, im);
310
+ Data_Get_Struct(obj, vipsMask, msk);
311
+
312
+ if (im_mask2vips(msk->dmask, im))
313
+ vips_lib_error();
314
+
315
+ return new;
316
+ }
317
+
318
+ /*
319
+ * VIPS uses masks for various operations. A vips mask is a two-dimensional
320
+ * array with a scale and an offset.
321
+ *
322
+ * All operations that accept a Mask object also accept an array, in which case
323
+ * scale defaults to 1 and offset to zero.
324
+ *
325
+ * Some vips operations require that all values in the mask are integer values.
326
+ * These operations will raise an exception if given a mask that contains
327
+ * any float values.
328
+ */
329
+
330
+ void
331
+ init_Mask()
332
+ {
333
+ cVIPSMask = rb_define_class_under(mVIPS, "Mask", rb_cObject);
334
+
335
+ rb_define_alloc_func(cVIPSMask, mask_alloc);
336
+ rb_define_method(cVIPSMask, "initialize", mask_initialize, -1);
337
+ rb_define_method(cVIPSMask, "xsize", mask_xsize, 0);
338
+ rb_define_method(cVIPSMask, "ysize", mask_ysize, 0);
339
+ rb_define_method(cVIPSMask, "scale", mask_scale, 0);
340
+ rb_define_method(cVIPSMask, "offset", mask_offset, 0);
341
+ rb_define_method(cVIPSMask, "coeff", mask_coeff, 0);
342
+ rb_define_method(cVIPSMask, "int?", mask_int_p, 0);
343
+ rb_define_method(cVIPSMask, "to_image", mask_to_image, 0);
344
+
345
+ #if 0
346
+ VALUE mVIPS = rb_define_module("VIPS");
347
+ #endif
348
+ }
349
+