ruby-vips 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +15 -0
- data/Gemfile.lock +31 -0
- data/LICENSE +20 -0
- data/README.md +96 -0
- data/TODO +18 -0
- data/ext/extconf.rb +10 -0
- data/ext/header.c +440 -0
- data/ext/header.h +8 -0
- data/ext/image.c +639 -0
- data/ext/image.h +71 -0
- data/ext/image_arithmetic.c +940 -0
- data/ext/image_arithmetic.h +38 -0
- data/ext/image_boolean.c +302 -0
- data/ext/image_boolean.h +8 -0
- data/ext/image_colour.c +593 -0
- data/ext/image_colour.h +36 -0
- data/ext/image_conversion.c +863 -0
- data/ext/image_conversion.h +37 -0
- data/ext/image_convolution.c +371 -0
- data/ext/image_convolution.h +13 -0
- data/ext/image_freq_filt.c +742 -0
- data/ext/image_freq_filt.h +27 -0
- data/ext/image_histograms_lut.c +646 -0
- data/ext/image_histograms_lut.h +28 -0
- data/ext/image_morphology.c +330 -0
- data/ext/image_morphology.h +13 -0
- data/ext/image_mosaicing.c +556 -0
- data/ext/image_mosaicing.h +14 -0
- data/ext/image_relational.c +386 -0
- data/ext/image_relational.h +8 -0
- data/ext/image_resample.c +253 -0
- data/ext/image_resample.h +9 -0
- data/ext/interpolator.c +106 -0
- data/ext/interpolator.h +6 -0
- data/ext/mask.c +349 -0
- data/ext/mask.h +17 -0
- data/ext/reader.c +315 -0
- data/ext/ruby_vips.c +131 -0
- data/ext/ruby_vips.h +26 -0
- data/ext/writer.c +346 -0
- data/lib/vips.rb +7 -0
- data/lib/vips/reader.rb +183 -0
- data/lib/vips/version.rb +3 -0
- data/lib/vips/writer.rb +275 -0
- data/ruby-vips.gemspec +93 -0
- metadata +163 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
VALUE img_measure_area(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
|
2
|
+
VALUE img_stats(VALUE);
|
3
|
+
VALUE img_max(VALUE);
|
4
|
+
VALUE img_min(VALUE);
|
5
|
+
VALUE img_avg(VALUE);
|
6
|
+
VALUE img_deviate(VALUE);
|
7
|
+
VALUE img_maxpos_avg(VALUE);
|
8
|
+
VALUE img_maxpos(int, VALUE*, VALUE);
|
9
|
+
VALUE img_minpos(int, VALUE*, VALUE);
|
10
|
+
VALUE img_bandmean(VALUE);
|
11
|
+
VALUE img_add(VALUE, VALUE);
|
12
|
+
VALUE img_subtract(VALUE, VALUE);
|
13
|
+
VALUE img_invert(VALUE);
|
14
|
+
VALUE img_lin(VALUE, VALUE, VALUE);
|
15
|
+
VALUE img_multiply(VALUE, VALUE);
|
16
|
+
VALUE img_remainder(int, VALUE*, VALUE);
|
17
|
+
VALUE img_remainder_binop(VALUE, VALUE);
|
18
|
+
VALUE img_divide(VALUE, VALUE);
|
19
|
+
VALUE img_recomb(VALUE, VALUE);
|
20
|
+
VALUE img_sign(VALUE);
|
21
|
+
VALUE img_abs(VALUE);
|
22
|
+
VALUE img_floor(VALUE);
|
23
|
+
VALUE img_rint(VALUE);
|
24
|
+
VALUE img_ceil(VALUE);
|
25
|
+
VALUE img_s_linreg(int, VALUE*, VALUE);
|
26
|
+
VALUE img_point(VALUE, VALUE, VALUE, VALUE, VALUE);
|
27
|
+
VALUE img_pow(int, VALUE*, VALUE);
|
28
|
+
VALUE img_pow_binop(int, VALUE*, VALUE);
|
29
|
+
VALUE img_expn(int, VALUE*, VALUE);
|
30
|
+
VALUE img_log(VALUE);
|
31
|
+
VALUE img_log10(VALUE);
|
32
|
+
VALUE img_sin(VALUE);
|
33
|
+
VALUE img_asin(VALUE);
|
34
|
+
VALUE img_cos(VALUE);
|
35
|
+
VALUE img_acos(VALUE);
|
36
|
+
VALUE img_tan(VALUE);
|
37
|
+
VALUE img_atan(VALUE);
|
38
|
+
VALUE img_cross_phase(VALUE, VALUE);
|
data/ext/image_boolean.c
ADDED
@@ -0,0 +1,302 @@
|
|
1
|
+
#include "ruby_vips.h"
|
2
|
+
#include "image.h"
|
3
|
+
|
4
|
+
static VALUE
|
5
|
+
img_and_img(VALUE obj, VALUE obj2)
|
6
|
+
{
|
7
|
+
RUBY_VIPS_BINARY(im_andimage);
|
8
|
+
}
|
9
|
+
|
10
|
+
static VALUE
|
11
|
+
img_and_const(int argc, VALUE *argv, VALUE obj)
|
12
|
+
{
|
13
|
+
int i;
|
14
|
+
double *c;
|
15
|
+
|
16
|
+
GetImg(obj, data, im);
|
17
|
+
OutImg(obj, new, data_new, im_new);
|
18
|
+
|
19
|
+
c = IM_ARRAY(im_new, argc, double);
|
20
|
+
for (i = 0; i < argc; i++)
|
21
|
+
c[i] = NUM2DBL(argv[i]);
|
22
|
+
|
23
|
+
if (im_andimage_vec(im, im_new, argc, c))
|
24
|
+
vips_lib_error();
|
25
|
+
|
26
|
+
return new;
|
27
|
+
}
|
28
|
+
|
29
|
+
/*
|
30
|
+
* call-seq:
|
31
|
+
* im & other_image -> image
|
32
|
+
* im & c -> image
|
33
|
+
* im & [ c1, ... ] -> image
|
34
|
+
*
|
35
|
+
* In the first form, this operation calculates the bitwise and between each
|
36
|
+
* pixel in this image and <i>other_image</i>. The images must be the same
|
37
|
+
* size. They may have any format.
|
38
|
+
*
|
39
|
+
* If the number of bands differs, one of the images must have one band. In
|
40
|
+
* this case, an n-band image is formed from the one-band image by joining n
|
41
|
+
* copies of the one-band image together and then the two n-band images are
|
42
|
+
* operated upon.
|
43
|
+
*
|
44
|
+
* In the second form, it calculates the bitwise and of image pixels with a
|
45
|
+
* constant. If the image has multiple bands, then the constant is applied to
|
46
|
+
* all bands.
|
47
|
+
*
|
48
|
+
* In the third form, it calculates the bitwise and of image pixels with an
|
49
|
+
* array of constants. If the image has one band, then the output will have as
|
50
|
+
* many bands as constants. Otherwise, the number of constants must match the
|
51
|
+
* number of bands in the image.
|
52
|
+
*/
|
53
|
+
|
54
|
+
VALUE
|
55
|
+
img_and(int argc, VALUE *argv, VALUE obj)
|
56
|
+
{
|
57
|
+
if (argc < 1)
|
58
|
+
rb_raise(rb_eArgError, "Expected at least one argument");
|
59
|
+
else if (argc == 1 && CLASS_OF(argv[0]) == cVIPSImage)
|
60
|
+
return img_and_img(obj, argv[0]);
|
61
|
+
else
|
62
|
+
return img_and_const(argc, argv, obj);
|
63
|
+
}
|
64
|
+
|
65
|
+
VALUE
|
66
|
+
img_and_binop(VALUE obj, VALUE arg)
|
67
|
+
{
|
68
|
+
int argc = 1;
|
69
|
+
VALUE *argv = &arg;
|
70
|
+
|
71
|
+
if (TYPE(arg) == T_ARRAY) {
|
72
|
+
argc = RARRAY_LEN(arg);
|
73
|
+
argv = RARRAY_PTR(arg);
|
74
|
+
}
|
75
|
+
|
76
|
+
return img_and(argc, argv, obj);
|
77
|
+
}
|
78
|
+
|
79
|
+
static VALUE
|
80
|
+
img_or_img(VALUE obj, VALUE obj2)
|
81
|
+
{
|
82
|
+
RUBY_VIPS_BINARY(im_orimage);
|
83
|
+
}
|
84
|
+
|
85
|
+
static VALUE
|
86
|
+
img_or_const(int argc, VALUE *argv, VALUE obj)
|
87
|
+
{
|
88
|
+
int i;
|
89
|
+
double *c;
|
90
|
+
|
91
|
+
GetImg(obj, data, im);
|
92
|
+
OutImg(obj, new, data_new, im_new);
|
93
|
+
|
94
|
+
c = IM_ARRAY(im_new, argc, double);
|
95
|
+
for (i = 0; i < argc; i++)
|
96
|
+
c[i] = NUM2DBL(argv[i]);
|
97
|
+
|
98
|
+
if (im_orimage_vec(im, im_new, argc, c))
|
99
|
+
vips_lib_error();
|
100
|
+
|
101
|
+
return new;
|
102
|
+
}
|
103
|
+
|
104
|
+
/*
|
105
|
+
* call-seq:
|
106
|
+
* im | other_image -> image
|
107
|
+
* im | c -> image
|
108
|
+
* im | [ c1, ... ] -> image
|
109
|
+
*
|
110
|
+
* In the first form, this operation calculates the bitwise or between each
|
111
|
+
* pixel in this image and <i>other_image</i>. The images must be the same
|
112
|
+
* size. They may have any format.
|
113
|
+
*
|
114
|
+
* If the number of bands differs, one of the images must have one band. In
|
115
|
+
* this case, an n-band image is formed from the one-band image by joining n
|
116
|
+
* copies of the one-band image together and then the two n-band images are
|
117
|
+
* operated upon.
|
118
|
+
*
|
119
|
+
* In the second form, it calculates the bitwise or of image pixels with a
|
120
|
+
* constant. If the image has multiple bands, then the constant is applied to
|
121
|
+
* all bands.
|
122
|
+
*
|
123
|
+
* In the third form, it calculates the bitwise or of image pixels with an
|
124
|
+
* array of constants. If the image has one band, then the output will have as
|
125
|
+
* many bands as constants. Otherwise, the number of constants must match the
|
126
|
+
* number of bands in the image.
|
127
|
+
*/
|
128
|
+
|
129
|
+
VALUE
|
130
|
+
img_or(int argc, VALUE *argv, VALUE obj)
|
131
|
+
{
|
132
|
+
if (argc < 1)
|
133
|
+
rb_raise(rb_eArgError, "Expected at least one argument");
|
134
|
+
else if (argc == 1 && CLASS_OF(argv[0]) == cVIPSImage)
|
135
|
+
return img_or_img(obj, argv[0]);
|
136
|
+
else
|
137
|
+
return img_or_const(argc, argv, obj);
|
138
|
+
}
|
139
|
+
|
140
|
+
VALUE
|
141
|
+
img_or_binop(VALUE obj, VALUE arg)
|
142
|
+
{
|
143
|
+
int argc = 1;
|
144
|
+
VALUE *argv = &arg;
|
145
|
+
|
146
|
+
if (TYPE(arg) == T_ARRAY) {
|
147
|
+
argc = RARRAY_LEN(arg);
|
148
|
+
argv = RARRAY_PTR(arg);
|
149
|
+
}
|
150
|
+
|
151
|
+
return img_or(argc, argv, obj);
|
152
|
+
}
|
153
|
+
|
154
|
+
static VALUE
|
155
|
+
img_xor_img(VALUE obj, VALUE obj2)
|
156
|
+
{
|
157
|
+
RUBY_VIPS_BINARY(im_eorimage);
|
158
|
+
}
|
159
|
+
|
160
|
+
static VALUE
|
161
|
+
img_xor_const(int argc, VALUE *argv, VALUE obj)
|
162
|
+
{
|
163
|
+
int i;
|
164
|
+
double *c;
|
165
|
+
|
166
|
+
GetImg(obj, data, im);
|
167
|
+
OutImg(obj, new, data_new, im_new);
|
168
|
+
|
169
|
+
c = IM_ARRAY(im_new, argc, double);
|
170
|
+
for (i = 0; i < argc; i++)
|
171
|
+
c[i] = NUM2DBL(argv[i]);
|
172
|
+
|
173
|
+
if (im_eorimage_vec(im, im_new, argc, c))
|
174
|
+
vips_lib_error();
|
175
|
+
|
176
|
+
return new;
|
177
|
+
}
|
178
|
+
|
179
|
+
/*
|
180
|
+
* call-seq:
|
181
|
+
* im ^ other_image -> image
|
182
|
+
* im ^ c -> image
|
183
|
+
* im ^ [ c1, ... ] -> image
|
184
|
+
*
|
185
|
+
* In the first form, this operation calculates the bitwise xor between each
|
186
|
+
* pixel in this image and <i>other_image</i>. The images must be the same
|
187
|
+
* size. They may have any format.
|
188
|
+
*
|
189
|
+
* If the number of bands differs, one of the images must have one band. In
|
190
|
+
* this case, an n-band image is formed from the one-band image by joining n
|
191
|
+
* copies of the one-band image together and then the two n-band images are
|
192
|
+
* operated upon.
|
193
|
+
*
|
194
|
+
* In the second form, it calculates the bitwise xor of image pixels with a
|
195
|
+
* constant. If the image has multiple bands, then the constant is applied to
|
196
|
+
* all bands.
|
197
|
+
*
|
198
|
+
* In the third form, it calculates the bitwise xor of image pixels with an
|
199
|
+
* array of constants. If the image has one band, then the output will have as
|
200
|
+
* many bands as constants. Otherwise, the number of constants must match the
|
201
|
+
* number of bands in the image.
|
202
|
+
*/
|
203
|
+
|
204
|
+
|
205
|
+
VALUE
|
206
|
+
img_xor(int argc, VALUE *argv, VALUE obj)
|
207
|
+
{
|
208
|
+
if (argc < 1)
|
209
|
+
rb_raise(rb_eArgError, "Expected at least one argument");
|
210
|
+
else if (argc == 1 && CLASS_OF(argv[0]) == cVIPSImage)
|
211
|
+
return img_xor_img(obj, argv[0]);
|
212
|
+
else
|
213
|
+
return img_xor_const(argc, argv, obj);
|
214
|
+
}
|
215
|
+
|
216
|
+
VALUE
|
217
|
+
img_xor_binop(VALUE obj, VALUE arg)
|
218
|
+
{
|
219
|
+
int argc = 1;
|
220
|
+
VALUE *argv = &arg;
|
221
|
+
|
222
|
+
if (TYPE(arg) == T_ARRAY) {
|
223
|
+
argc = RARRAY_LEN(arg);
|
224
|
+
argv = RARRAY_PTR(arg);
|
225
|
+
}
|
226
|
+
|
227
|
+
return img_xor(argc, argv, obj);
|
228
|
+
}
|
229
|
+
|
230
|
+
/*
|
231
|
+
* call-seq:
|
232
|
+
* im << c -> image
|
233
|
+
* im << [ c1, ... ] -> image
|
234
|
+
*
|
235
|
+
* Calculates the bitwise left-shift by <i>c</i> bits.
|
236
|
+
*
|
237
|
+
* If only one constant is given, it calculates the left-shift for all bands
|
238
|
+
* in the image. If an array of constants is given, it applies each constant
|
239
|
+
* to an image band.
|
240
|
+
*/
|
241
|
+
|
242
|
+
VALUE
|
243
|
+
img_shiftleft(VALUE obj, VALUE arg)
|
244
|
+
{
|
245
|
+
double *c;
|
246
|
+
int i, len = 1;
|
247
|
+
VALUE *argv = &arg;
|
248
|
+
|
249
|
+
GetImg(obj, data, im);
|
250
|
+
OutImg(obj, new, data_new, im_new);
|
251
|
+
|
252
|
+
if (TYPE(arg) == T_ARRAY) {
|
253
|
+
len = RARRAY_LEN(arg);
|
254
|
+
argv = RARRAY_PTR(arg);
|
255
|
+
}
|
256
|
+
|
257
|
+
c = IM_ARRAY(im_new, len, double);
|
258
|
+
for (i = 0; i < len; i++)
|
259
|
+
c[i] = NUM2DBL(argv[i]);
|
260
|
+
|
261
|
+
if (im_shiftleft_vec(im, im_new, len, c))
|
262
|
+
vips_lib_error();
|
263
|
+
|
264
|
+
return new;
|
265
|
+
}
|
266
|
+
|
267
|
+
/*
|
268
|
+
* call-seq:
|
269
|
+
* im >> c -> image
|
270
|
+
* im >> [ c1, ... ] -> image
|
271
|
+
*
|
272
|
+
* Calculates the bitwise right-shift by <i>c</i> bits.
|
273
|
+
*
|
274
|
+
* If only one constant is given, it calculates the right-shift for all bands
|
275
|
+
* in the image. If an array of constants is given, it applies each constant
|
276
|
+
* to an image band.
|
277
|
+
*/
|
278
|
+
|
279
|
+
VALUE
|
280
|
+
img_shiftright(VALUE obj, VALUE arg)
|
281
|
+
{
|
282
|
+
double *c;
|
283
|
+
int i, len = 1;
|
284
|
+
VALUE *argv = &arg;
|
285
|
+
|
286
|
+
GetImg(obj, data, im);
|
287
|
+
OutImg(obj, new, data_new, im_new);
|
288
|
+
|
289
|
+
if (TYPE(arg) == T_ARRAY) {
|
290
|
+
len = RARRAY_LEN(arg);
|
291
|
+
argv = RARRAY_PTR(arg);
|
292
|
+
}
|
293
|
+
|
294
|
+
c = IM_ARRAY(im_new, len, double);
|
295
|
+
for (i = 0; i < len; i++)
|
296
|
+
c[i] = NUM2DBL(argv[i]);
|
297
|
+
|
298
|
+
if (im_shiftright_vec(im, im_new, len, c))
|
299
|
+
vips_lib_error();
|
300
|
+
|
301
|
+
return new;
|
302
|
+
}
|
data/ext/image_boolean.h
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
VALUE img_and(int, VALUE*, VALUE);
|
2
|
+
VALUE img_and_binop(VALUE, VALUE);
|
3
|
+
VALUE img_or(int, VALUE*, VALUE);
|
4
|
+
VALUE img_or_binop(VALUE, VALUE arg);
|
5
|
+
VALUE img_xor(int, VALUE*, VALUE);
|
6
|
+
VALUE img_xor_binop(VALUE, VALUE arg);
|
7
|
+
VALUE img_shiftleft(int, VALUE*, VALUE);
|
8
|
+
VALUE img_shiftright(int, VALUE*, VALUE);
|
data/ext/image_colour.c
ADDED
@@ -0,0 +1,593 @@
|
|
1
|
+
#include "ruby_vips.h"
|
2
|
+
#include "image.h"
|
3
|
+
#include "mask.h"
|
4
|
+
#include "image_colour.h"
|
5
|
+
|
6
|
+
static ID id_perceptual, id_relative_colorimetric, id_saturation,
|
7
|
+
id_absolute_colorimetric;
|
8
|
+
|
9
|
+
/*
|
10
|
+
* call-seq:
|
11
|
+
* im.lab_to_lch -> image
|
12
|
+
*
|
13
|
+
* Turn Lab to LCh.
|
14
|
+
*/
|
15
|
+
|
16
|
+
VALUE
|
17
|
+
img_lab_to_lch(VALUE obj)
|
18
|
+
{
|
19
|
+
RUBY_VIPS_UNARY(im_Lab2LCh);
|
20
|
+
}
|
21
|
+
|
22
|
+
/*
|
23
|
+
* call-seq:
|
24
|
+
* im.lch_to_lab -> image
|
25
|
+
*
|
26
|
+
* Turn LCh to Lab.
|
27
|
+
*/
|
28
|
+
|
29
|
+
VALUE
|
30
|
+
img_lch_to_lab(VALUE obj)
|
31
|
+
{
|
32
|
+
RUBY_VIPS_UNARY(im_LCh2Lab);
|
33
|
+
}
|
34
|
+
|
35
|
+
/*
|
36
|
+
* call-seq:
|
37
|
+
* im.labq_to_xyz -> image
|
38
|
+
*
|
39
|
+
* Turn LabQ to XYZ.
|
40
|
+
*/
|
41
|
+
|
42
|
+
VALUE
|
43
|
+
img_labq_to_xyz(VALUE obj)
|
44
|
+
{
|
45
|
+
RUBY_VIPS_UNARY(im_LabQ2XYZ);
|
46
|
+
}
|
47
|
+
|
48
|
+
/*
|
49
|
+
* call-seq:
|
50
|
+
* im.rad_to_float -> image
|
51
|
+
*
|
52
|
+
* Unpack a RAD image to a three-band float image.
|
53
|
+
*/
|
54
|
+
|
55
|
+
VALUE
|
56
|
+
img_rad_to_float(VALUE obj)
|
57
|
+
{
|
58
|
+
RUBY_VIPS_UNARY(im_rad2float);
|
59
|
+
}
|
60
|
+
|
61
|
+
/*
|
62
|
+
* call-seq:
|
63
|
+
* im.float_to_rad -> image
|
64
|
+
*
|
65
|
+
* Convert a three-band float image to Radiance 32-bit packed format.
|
66
|
+
*/
|
67
|
+
|
68
|
+
VALUE
|
69
|
+
img_float_to_rad(VALUE obj)
|
70
|
+
{
|
71
|
+
RUBY_VIPS_UNARY(im_float2rad);
|
72
|
+
}
|
73
|
+
|
74
|
+
/*
|
75
|
+
* call-seq:
|
76
|
+
* im.lch_to_ucs -> image
|
77
|
+
*
|
78
|
+
* Turn LCh to UCS.
|
79
|
+
*/
|
80
|
+
|
81
|
+
VALUE
|
82
|
+
img_lch_to_ucs(VALUE obj)
|
83
|
+
{
|
84
|
+
RUBY_VIPS_UNARY(im_LCh2UCS);
|
85
|
+
}
|
86
|
+
|
87
|
+
/*
|
88
|
+
* call-seq:
|
89
|
+
* im.lab_to_labq -> image
|
90
|
+
*
|
91
|
+
* Turn Lab to LabQ.
|
92
|
+
*/
|
93
|
+
|
94
|
+
VALUE
|
95
|
+
img_lab_to_labq(VALUE obj)
|
96
|
+
{
|
97
|
+
RUBY_VIPS_UNARY(im_Lab2LabQ);
|
98
|
+
}
|
99
|
+
|
100
|
+
/*
|
101
|
+
* call-seq:
|
102
|
+
* im.lab_to_labs -> image
|
103
|
+
*
|
104
|
+
* Turn Lab to LabS.
|
105
|
+
*/
|
106
|
+
|
107
|
+
VALUE
|
108
|
+
img_lab_to_labs(VALUE obj)
|
109
|
+
{
|
110
|
+
RUBY_VIPS_UNARY(im_Lab2LabS);
|
111
|
+
}
|
112
|
+
|
113
|
+
/*
|
114
|
+
* call-seq:
|
115
|
+
* im.lab_to_xyz -> image
|
116
|
+
*
|
117
|
+
* Turn Lab to XYZ.
|
118
|
+
*/
|
119
|
+
|
120
|
+
VALUE
|
121
|
+
img_lab_to_xyz(VALUE obj)
|
122
|
+
{
|
123
|
+
RUBY_VIPS_UNARY(im_Lab2XYZ);
|
124
|
+
}
|
125
|
+
|
126
|
+
/*
|
127
|
+
* call-seq:
|
128
|
+
* im.lab_to_xyz_temp(x0, y0, z0) -> image
|
129
|
+
*
|
130
|
+
* Turn Lab to XYZ. <i>x0</i>, <i>y0</i>, <i>z0</i> give the Lab colour
|
131
|
+
* temperature.
|
132
|
+
*/
|
133
|
+
|
134
|
+
VALUE
|
135
|
+
img_lab_to_xyz_temp(VALUE obj, VALUE x0, VALUE y0, VALUE z0)
|
136
|
+
{
|
137
|
+
GetImg(obj, data, im);
|
138
|
+
OutImg(obj, new, data_new, im_new);
|
139
|
+
|
140
|
+
if (im_Lab2XYZ_temp(im, im_new, NUM2DBL(x0), NUM2DBL(y0), NUM2DBL(z0)))
|
141
|
+
vips_lib_error();
|
142
|
+
|
143
|
+
return new;
|
144
|
+
}
|
145
|
+
|
146
|
+
/*
|
147
|
+
* call-seq:
|
148
|
+
* im.lab_to_ucs -> image
|
149
|
+
*
|
150
|
+
* Turn Lab to UCS.
|
151
|
+
*/
|
152
|
+
|
153
|
+
VALUE
|
154
|
+
img_lab_to_ucs(VALUE obj)
|
155
|
+
{
|
156
|
+
RUBY_VIPS_UNARY(im_Lab2UCS);
|
157
|
+
}
|
158
|
+
|
159
|
+
/*
|
160
|
+
* call-seq:
|
161
|
+
* im.labq_to_lab -> image
|
162
|
+
*
|
163
|
+
* Turn LabQ to Lab.
|
164
|
+
*/
|
165
|
+
|
166
|
+
VALUE
|
167
|
+
img_labq_to_lab(VALUE obj)
|
168
|
+
{
|
169
|
+
RUBY_VIPS_UNARY(im_LabQ2Lab);
|
170
|
+
}
|
171
|
+
|
172
|
+
/*
|
173
|
+
* call-seq:
|
174
|
+
* im.labq_to_labs -> image
|
175
|
+
*
|
176
|
+
* Turn LabQ to LabS.
|
177
|
+
*/
|
178
|
+
|
179
|
+
VALUE
|
180
|
+
img_labq_to_labs(VALUE obj)
|
181
|
+
{
|
182
|
+
RUBY_VIPS_UNARY(im_LabQ2LabS);
|
183
|
+
}
|
184
|
+
|
185
|
+
/*
|
186
|
+
* call-seq:
|
187
|
+
* im.labs_to_labq -> image
|
188
|
+
*
|
189
|
+
* Turn LabS to LabQ.
|
190
|
+
*/
|
191
|
+
|
192
|
+
VALUE
|
193
|
+
img_labs_to_labq(VALUE obj)
|
194
|
+
{
|
195
|
+
RUBY_VIPS_UNARY(im_LabS2LabQ);
|
196
|
+
}
|
197
|
+
|
198
|
+
/*
|
199
|
+
* call-seq:
|
200
|
+
* im.labs_to_lab -> image
|
201
|
+
*
|
202
|
+
* Turn LabS to Lab.
|
203
|
+
*/
|
204
|
+
|
205
|
+
VALUE
|
206
|
+
img_labs_to_lab(VALUE obj)
|
207
|
+
{
|
208
|
+
RUBY_VIPS_UNARY(im_LabS2Lab);
|
209
|
+
}
|
210
|
+
|
211
|
+
/*
|
212
|
+
* call-seq:
|
213
|
+
* im.ucs_to_xyz -> image
|
214
|
+
*
|
215
|
+
* Turn UCS to XYZ.
|
216
|
+
*/
|
217
|
+
|
218
|
+
VALUE
|
219
|
+
img_ucs_to_xyz(VALUE obj)
|
220
|
+
{
|
221
|
+
RUBY_VIPS_UNARY(im_UCS2XYZ);
|
222
|
+
}
|
223
|
+
|
224
|
+
/*
|
225
|
+
* call-seq:
|
226
|
+
* im.ucs_to_lch -> image
|
227
|
+
*
|
228
|
+
* Turn UCS to LCh.
|
229
|
+
*/
|
230
|
+
|
231
|
+
VALUE
|
232
|
+
img_ucs_to_lch(VALUE obj)
|
233
|
+
{
|
234
|
+
RUBY_VIPS_UNARY(im_UCS2LCh);
|
235
|
+
}
|
236
|
+
|
237
|
+
/*
|
238
|
+
* call-seq:
|
239
|
+
* im.ucs_to_lab -> image
|
240
|
+
*
|
241
|
+
* Turn UCS to Lab.
|
242
|
+
*/
|
243
|
+
|
244
|
+
VALUE
|
245
|
+
img_ucs_to_lab(VALUE obj)
|
246
|
+
{
|
247
|
+
RUBY_VIPS_UNARY(im_UCS2Lab);
|
248
|
+
}
|
249
|
+
|
250
|
+
/*
|
251
|
+
* call-seq:
|
252
|
+
* im.xyz_to_lab -> image
|
253
|
+
*
|
254
|
+
* Turn XYZ to Lab.
|
255
|
+
*/
|
256
|
+
|
257
|
+
VALUE
|
258
|
+
img_xyz_to_lab(VALUE obj)
|
259
|
+
{
|
260
|
+
RUBY_VIPS_UNARY(im_XYZ2Lab);
|
261
|
+
}
|
262
|
+
|
263
|
+
/*
|
264
|
+
* call-seq:
|
265
|
+
* im.xyz_to_lab_temp(x0, y0, z0) -> image
|
266
|
+
*
|
267
|
+
* Turn XYZ to LAB. <i>x0</i>, <i>y0</i>, <i>z0</i> give the Lab colour
|
268
|
+
* temperature.
|
269
|
+
*/
|
270
|
+
|
271
|
+
VALUE
|
272
|
+
img_xyz_to_lab_temp(VALUE obj, VALUE x0, VALUE y0, VALUE z0)
|
273
|
+
{
|
274
|
+
GetImg(obj, data, im);
|
275
|
+
OutImg(obj, new, data_new, im_new);
|
276
|
+
|
277
|
+
if (im_XYZ2Lab_temp(im, im_new, NUM2DBL(x0), NUM2DBL(y0), NUM2DBL(z0)))
|
278
|
+
vips_lib_error();
|
279
|
+
|
280
|
+
return new;
|
281
|
+
}
|
282
|
+
|
283
|
+
/*
|
284
|
+
* call-seq:
|
285
|
+
* im.xyz_to_ucs -> image
|
286
|
+
*
|
287
|
+
* Turn XYZ to UCS.
|
288
|
+
*/
|
289
|
+
|
290
|
+
VALUE
|
291
|
+
img_xyz_to_ucs(VALUE obj)
|
292
|
+
{
|
293
|
+
RUBY_VIPS_UNARY(im_XYZ2UCS);
|
294
|
+
}
|
295
|
+
|
296
|
+
/*
|
297
|
+
* call-seq:
|
298
|
+
* im.srgb_to_xyz -> image
|
299
|
+
*
|
300
|
+
* Turn sRGB to XYZ.
|
301
|
+
*/
|
302
|
+
|
303
|
+
VALUE
|
304
|
+
img_srgb_to_xyz(VALUE obj)
|
305
|
+
{
|
306
|
+
RUBY_VIPS_UNARY(im_sRGB2XYZ);
|
307
|
+
}
|
308
|
+
|
309
|
+
/*
|
310
|
+
* call-seq:
|
311
|
+
* im.xyz_to_srgb -> image
|
312
|
+
*
|
313
|
+
* Turn XYZ to sRGB.
|
314
|
+
*/
|
315
|
+
|
316
|
+
VALUE
|
317
|
+
img_xyz_to_srgb(VALUE obj)
|
318
|
+
{
|
319
|
+
RUBY_VIPS_UNARY(im_XYZ2sRGB);
|
320
|
+
}
|
321
|
+
|
322
|
+
/*
|
323
|
+
* call-seq:
|
324
|
+
* im.yxy_to_xyz -> image
|
325
|
+
*
|
326
|
+
* Turn Yxy to XYZ.
|
327
|
+
*/
|
328
|
+
|
329
|
+
VALUE
|
330
|
+
img_yxy_to_xyz(VALUE obj)
|
331
|
+
{
|
332
|
+
RUBY_VIPS_UNARY(im_Yxy2XYZ);
|
333
|
+
}
|
334
|
+
|
335
|
+
/*
|
336
|
+
* call-seq:
|
337
|
+
* im.xyz_to_yxy -> image
|
338
|
+
*
|
339
|
+
* Turn XYZ to Yxy.
|
340
|
+
*/
|
341
|
+
|
342
|
+
VALUE
|
343
|
+
img_xyz_to_yxy(VALUE obj)
|
344
|
+
{
|
345
|
+
RUBY_VIPS_UNARY(im_XYZ2Yxy);
|
346
|
+
}
|
347
|
+
|
348
|
+
/*
|
349
|
+
* call-seq:
|
350
|
+
* im.decmc_from_lab(other_image) -> image
|
351
|
+
*
|
352
|
+
* Calculate dE CMC from two Lab images.
|
353
|
+
*/
|
354
|
+
|
355
|
+
VALUE
|
356
|
+
img_decmc_from_lab(VALUE obj, VALUE obj2)
|
357
|
+
{
|
358
|
+
RUBY_VIPS_BINARY(im_dECMC_fromLab);
|
359
|
+
}
|
360
|
+
|
361
|
+
/*
|
362
|
+
* call-seq:
|
363
|
+
* im.de00_from_lab(other_image) -> image
|
364
|
+
*
|
365
|
+
* Calculate CIE dE00 from two Lab images.
|
366
|
+
*/
|
367
|
+
|
368
|
+
VALUE
|
369
|
+
img_de00_from_lab(VALUE obj, VALUE obj2)
|
370
|
+
{
|
371
|
+
RUBY_VIPS_BINARY(im_dE00_fromLab);
|
372
|
+
}
|
373
|
+
|
374
|
+
/*
|
375
|
+
* call-seq:
|
376
|
+
* im.de_from_xyz(other_image) -> image
|
377
|
+
*
|
378
|
+
* Calculate CIELAB dE 1976 from a pair of XYZ images.
|
379
|
+
*/
|
380
|
+
|
381
|
+
VALUE
|
382
|
+
img_de_from_xyz(VALUE obj, VALUE obj2)
|
383
|
+
{
|
384
|
+
RUBY_VIPS_BINARY(im_dE_fromXYZ);
|
385
|
+
}
|
386
|
+
|
387
|
+
/*
|
388
|
+
* call-seq:
|
389
|
+
* im.de_from_lab(other_image) -> image
|
390
|
+
*
|
391
|
+
* Calculate CIE dE 1976 from two Lab images.
|
392
|
+
*/
|
393
|
+
|
394
|
+
VALUE
|
395
|
+
img_de_from_lab(VALUE obj, VALUE obj2)
|
396
|
+
{
|
397
|
+
RUBY_VIPS_BINARY(im_dE_fromLab);
|
398
|
+
}
|
399
|
+
|
400
|
+
/*
|
401
|
+
* call-seq:
|
402
|
+
* im.lab_morph(mask, l_offset, l_scale, a_scale, b_scale) -> image
|
403
|
+
*
|
404
|
+
* Morph an image in CIELAB colour space. Useful for certain types of gamut
|
405
|
+
* mapping, or correction of greyscales on some printers.
|
406
|
+
*
|
407
|
+
* We perform three adjustments.
|
408
|
+
*
|
409
|
+
* * cast
|
410
|
+
*
|
411
|
+
* Pass in <i>mask</i> containing CIELAB readings for a neutral greyscale.
|
412
|
+
* For example:
|
413
|
+
*
|
414
|
+
* mask = [
|
415
|
+
* [14.23, 4.8 , -3.95],
|
416
|
+
* [18.74, 2.76, -2.62],
|
417
|
+
* [23.46, 1.4 , -1.95],
|
418
|
+
* [27.46, 1.76, -2.01]
|
419
|
+
* ]
|
420
|
+
*
|
421
|
+
* Interpolation from this makes cast corrector. The top and tail are
|
422
|
+
* interpolated towards [0, 0, 0] and [100, 0, 0], intermediate values are
|
423
|
+
* interpolated along straight lines fitted between the specified points.
|
424
|
+
* Rows may be in any order (ie. they need not be sorted on L*).
|
425
|
+
*
|
426
|
+
* Each pixel is displaced in a/b by the amount specified for that L in the
|
427
|
+
* table.
|
428
|
+
*
|
429
|
+
* * L*
|
430
|
+
*
|
431
|
+
* Pass in <i>l_scale</i> and <i>l_offset</i> for L. L' = (L + offset) *
|
432
|
+
* scale.
|
433
|
+
*
|
434
|
+
* * saturation
|
435
|
+
*
|
436
|
+
* scale a and b by these amounts, eg. 1.5 increases saturation.
|
437
|
+
*
|
438
|
+
* Find the top two by generating and printing a greyscale. Find the bottom
|
439
|
+
* by printing a Macbeth and looking at a/b spread
|
440
|
+
*/
|
441
|
+
|
442
|
+
VALUE
|
443
|
+
img_lab_morph(VALUE obj, VALUE mask, VALUE l_offset, VALUE l_scale,
|
444
|
+
VALUE a_scale, VALUE b_scale)
|
445
|
+
{
|
446
|
+
DOUBLEMASK *dmask;
|
447
|
+
|
448
|
+
GetImg(obj, data, im);
|
449
|
+
OutImg(obj, new, data_new, im_new);
|
450
|
+
|
451
|
+
mask_arg2mask(mask, NULL, &dmask);
|
452
|
+
|
453
|
+
if( im_lab_morph(im, im_new, dmask, NUM2DBL(l_offset),
|
454
|
+
NUM2DBL(l_scale), NUM2DBL(a_scale), NUM2DBL(b_scale)) )
|
455
|
+
vips_lib_error();
|
456
|
+
|
457
|
+
return new;
|
458
|
+
}
|
459
|
+
|
460
|
+
VipsIntent
|
461
|
+
img_id_to_intent(ID rb)
|
462
|
+
{
|
463
|
+
if (rb == id_perceptual) return IM_INTENT_PERCEPTUAL;
|
464
|
+
else if (rb == id_relative_colorimetric) return IM_INTENT_RELATIVE_COLORIMETRIC;
|
465
|
+
else if (rb == id_saturation) return IM_INTENT_SATURATION;
|
466
|
+
else if (rb == id_absolute_colorimetric) return IM_INTENT_ABSOLUTE_COLORIMETRIC;
|
467
|
+
|
468
|
+
return (VipsIntent)NULL;
|
469
|
+
}
|
470
|
+
|
471
|
+
/*
|
472
|
+
* call-seq:
|
473
|
+
* im.icc_transform(input_filename, output_filename, intent) -> image
|
474
|
+
*
|
475
|
+
* Transform an image with the ICC library. The input image is moved to
|
476
|
+
* profile-connection space with the input profile and then to the output
|
477
|
+
* space with the output profile.
|
478
|
+
*
|
479
|
+
* Use Image#icc_import and Image#icc_export_depth to do either the first or
|
480
|
+
* second half of this operation in isolation.
|
481
|
+
*/
|
482
|
+
|
483
|
+
VALUE
|
484
|
+
img_icc_transform(VALUE obj, VALUE input_profile_filename,
|
485
|
+
VALUE output_profile_filename, VALUE intent)
|
486
|
+
{
|
487
|
+
ID id_intent = SYM2ID(intent);
|
488
|
+
GetImg(obj, data, im);
|
489
|
+
OutImg(obj, new, data_new, im_new);
|
490
|
+
|
491
|
+
if (im_icc_transform(im, im_new, StringValuePtr(input_profile_filename),
|
492
|
+
StringValuePtr(output_profile_filename), img_id_to_intent(id_intent)))
|
493
|
+
vips_lib_error();
|
494
|
+
|
495
|
+
return new;
|
496
|
+
}
|
497
|
+
|
498
|
+
/*
|
499
|
+
* call-seq:
|
500
|
+
* im.icc_import(input_filename, intent) -> image
|
501
|
+
*
|
502
|
+
* Import an image with the ICC library. The input image in device space
|
503
|
+
* is moved to D65 LAB with the input profile.
|
504
|
+
*/
|
505
|
+
|
506
|
+
VALUE
|
507
|
+
img_icc_import(VALUE obj, VALUE input_profile_filename, VALUE intent)
|
508
|
+
{
|
509
|
+
ID id_intent = SYM2ID(intent);
|
510
|
+
GetImg(obj, data, im);
|
511
|
+
OutImg(obj, new, data_new, im_new);
|
512
|
+
|
513
|
+
if (im_icc_import(im, im_new, StringValuePtr(input_profile_filename),
|
514
|
+
img_id_to_intent(id_intent)))
|
515
|
+
vips_lib_error();
|
516
|
+
|
517
|
+
return new;
|
518
|
+
}
|
519
|
+
|
520
|
+
/*
|
521
|
+
* call-seq:
|
522
|
+
* im.icc_import_embedded(intent) -> image
|
523
|
+
*
|
524
|
+
* Import an image with the ICC library. The input image in device space
|
525
|
+
* is moved to D65 LAB with the input profile from the input image header
|
526
|
+
* attached.
|
527
|
+
*/
|
528
|
+
|
529
|
+
VALUE
|
530
|
+
img_icc_import_embedded(VALUE obj, VALUE intent)
|
531
|
+
{
|
532
|
+
ID id_intent = SYM2ID(intent);
|
533
|
+
GetImg(obj, data, im);
|
534
|
+
OutImg(obj, new, data_new, im_new);
|
535
|
+
|
536
|
+
if (im_icc_import_embedded(im, im_new, img_id_to_intent(id_intent)))
|
537
|
+
vips_lib_error();
|
538
|
+
|
539
|
+
return new;
|
540
|
+
}
|
541
|
+
|
542
|
+
/*
|
543
|
+
* call-seq:
|
544
|
+
* im.icc_export_depth(depth, output_filename, intent) -> image
|
545
|
+
*
|
546
|
+
* Export an image with the ICC library. The input image in
|
547
|
+
* D65 LAB is transformed to device space using the supplied profile.
|
548
|
+
* <i>depth</i> can be 8 or 16, for 8 or 16-bit image export.
|
549
|
+
*/
|
550
|
+
|
551
|
+
VALUE
|
552
|
+
img_icc_export_depth(VALUE obj, VALUE depth, VALUE output_profile_filename,
|
553
|
+
VALUE intent)
|
554
|
+
{
|
555
|
+
ID id_intent = SYM2ID(intent);
|
556
|
+
GetImg(obj, data, im);
|
557
|
+
OutImg(obj, new, data_new, im_new);
|
558
|
+
|
559
|
+
if (im_icc_export_depth(im, im_new, NUM2INT(depth),
|
560
|
+
StringValuePtr(output_profile_filename), img_id_to_intent(id_intent)))
|
561
|
+
vips_lib_error();
|
562
|
+
|
563
|
+
return new;
|
564
|
+
}
|
565
|
+
|
566
|
+
/*
|
567
|
+
* call-seq:
|
568
|
+
* im.icc_ac2rc(depth, profile_filename) -> image
|
569
|
+
*
|
570
|
+
* Transform an image from absolute to relative colorimetry using the
|
571
|
+
* MediaWhitePoint stored in the ICC profile.
|
572
|
+
*/
|
573
|
+
|
574
|
+
VALUE
|
575
|
+
img_icc_ac2rc(VALUE obj, VALUE depth, VALUE profile_filename)
|
576
|
+
{
|
577
|
+
GetImg(obj, data, im);
|
578
|
+
OutImg(obj, new, data_new, im_new);
|
579
|
+
|
580
|
+
if (im_icc_ac2rc(im, im_new, StringValuePtr(profile_filename)))
|
581
|
+
vips_lib_error();
|
582
|
+
|
583
|
+
return new;
|
584
|
+
}
|
585
|
+
|
586
|
+
void
|
587
|
+
init_Image_colour()
|
588
|
+
{
|
589
|
+
id_perceptual = rb_intern("PERCEPTUAL");
|
590
|
+
id_relative_colorimetric = rb_intern("COLORIMETRIC");
|
591
|
+
id_saturation = rb_intern("SATURATION");
|
592
|
+
id_absolute_colorimetric = rb_intern("ABSOLUTE_COLORIMETRIC");
|
593
|
+
}
|