ruby-vips 0.1.1 → 0.2.0
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 +28 -1
- data/README.md +100 -48
- data/ext/extconf.rb +3 -2
- data/ext/image.c +158 -157
- data/ext/image_conversion.c +24 -0
- data/ext/image_conversion.h +2 -1
- data/ext/ruby_vips.c +9 -4
- data/lib/vips/reader.rb +37 -3
- data/lib/vips/version.rb +1 -1
- data/ruby-vips.gemspec +2 -2
- metadata +3 -3
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,31 @@
|
|
1
|
-
# master
|
1
|
+
# master
|
2
|
+
...
|
3
|
+
|
4
|
+
# Version 0.2.0
|
5
|
+
|
6
|
+
Release date: 2012-06-29
|
7
|
+
|
8
|
+
### Added
|
9
|
+
|
10
|
+
* Add tile_cache [John Cupitt]
|
11
|
+
* Add :sequential option to tiff, jpeg and png readers [John Cupitt]
|
12
|
+
* Add raise if suitable pkg_config for libvips is not found, thanks to Pierre
|
13
|
+
Chapuis [Stanislaw Pankevich]
|
14
|
+
* Add backward compatibility of 0.1.x ruby-vips with libvips versions less than 7.28 [John Cupitt]
|
15
|
+
* Add Travis. ruby-vips now is being tested on travis-ci.org. [Stanislaw Pankevich]
|
16
|
+
|
17
|
+
### Changed
|
18
|
+
|
19
|
+
* Disable the vips8 operation cache to save some memory [John Cupitt]
|
20
|
+
* Update example shrinker [John Cupitt]
|
21
|
+
|
22
|
+
### Fixed
|
23
|
+
|
24
|
+
* #8: Memory allocation-free issues [Grigoriy Chudnov]
|
25
|
+
|
26
|
+
# Version 0.1.1
|
27
|
+
|
28
|
+
Release date: 2012-06-22
|
2
29
|
|
3
30
|
### Changed
|
4
31
|
|
data/README.md
CHANGED
@@ -1,11 +1,35 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
# ruby-vips : A fast image processing extension for Ruby.
|
2
|
+
|
3
|
+
*Note*: ruby-vips git master is the development version and uses features
|
4
|
+
from git master of libvips (the unreleased 7.29) as well. You may prefer
|
5
|
+
the stable 0.2 branch of ruby-vips.
|
6
|
+
|
7
|
+
ruby-vips is a ruby extension for [vips](http://www.vips.ecs.soton.ac.uk).
|
8
|
+
It is extremely fast and it can process huge images without requiring the
|
9
|
+
entire image to be loaded into memory. For example, the benchmark at
|
10
|
+
[vips-benchmarks](https://github.com/stanislaw/vips-benchmarks) loads a large
|
11
|
+
image, crops, shrinks, sharpens and saves again:
|
12
|
+
|
13
|
+
[](http://travis-ci.org/jcupitt/ruby-vips)
|
14
|
+
|
15
|
+
<pre>
|
16
|
+
real time in seconds, fastest of three runs
|
17
|
+
benchmark tiff jpeg
|
18
|
+
ruby-vips.rb 0.45 0.56
|
19
|
+
rmagick.rb 1.69 1.90
|
20
|
+
netpbm.sh 1.74 1.63
|
21
|
+
image-magick 2.87 3.02
|
22
|
+
image_sci.rb 3.19 2.90
|
23
|
+
|
24
|
+
peak memory use in kilobytes
|
25
|
+
benchmark peak RSS
|
26
|
+
ruby-vips.rb 160400
|
27
|
+
image_sci.rb 546992
|
28
|
+
rmagick.rb 1370064
|
29
|
+
</pre>
|
30
|
+
|
31
|
+
See also [benchmarks at the official libvips
|
32
|
+
website](http://www.vips.ecs.soton.ac.uk/index.php?title=Speed_and_Memory_Use).
|
9
33
|
|
10
34
|
ruby-vips allows you to set up pipelines that don't get executed until you
|
11
35
|
output the image to disk or to a string. This means you can create,
|
@@ -16,27 +40,30 @@ or to disk.
|
|
16
40
|
## Requirements.
|
17
41
|
|
18
42
|
* OS X or Linux
|
19
|
-
* MRI 1.8.
|
20
|
-
* libvips 7.
|
43
|
+
* MRI 1.8.7, 1.9.2
|
44
|
+
* libvips 7.29 and later (it will work with earlier libvips, but some
|
45
|
+
features may not be functional -- you may prefer the stable 0.1 branch)
|
21
46
|
|
22
47
|
## Installation.
|
23
48
|
|
24
49
|
### Ubuntu Prerequisites.
|
25
50
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
Though ruby-vips will work with libvips 7.12.x, many features are disabled, and
|
30
|
-
there are a few caveats.
|
51
|
+
```bash
|
52
|
+
$ apt-get install libvips-dev
|
53
|
+
```
|
31
54
|
|
32
55
|
### OS X Prerequisites.
|
33
56
|
|
34
|
-
|
35
|
-
|
36
|
-
|
57
|
+
```bash
|
58
|
+
$ brew install vips -HEAD
|
59
|
+
```
|
37
60
|
|
38
61
|
TODO: Describe & test with macports.
|
39
62
|
|
63
|
+
### Other platforms
|
64
|
+
|
65
|
+
See [Installiation on various platforms](https://github.com/jcupitt/ruby-vips/wiki/installiation-on-various-platforms).
|
66
|
+
|
40
67
|
### Installing the gem.
|
41
68
|
|
42
69
|
```bash
|
@@ -51,46 +78,71 @@ gem 'ruby-vips'
|
|
51
78
|
|
52
79
|
## Documentation.
|
53
80
|
|
54
|
-
ruby-vips has [rdoc
|
81
|
+
ruby-vips has [rdoc
|
82
|
+
documentation](http://rubydoc.info/gems/ruby-vips/0.1.1/frames). Also
|
83
|
+
see [Wiki page](https://github.com/jcupitt/ruby-vips/wiki)
|
84
|
+
|
85
|
+
## Small example
|
55
86
|
|
56
|
-
|
87
|
+
See also the
|
88
|
+
[examples](https://github.com/jcupitt/ruby-vips/tree/master/examples)
|
89
|
+
directory.
|
57
90
|
|
58
|
-
|
59
|
-
|
60
|
-
|
91
|
+
```ruby
|
92
|
+
require 'rubygems'
|
93
|
+
require 'vips'
|
94
|
+
|
95
|
+
include VIPS
|
96
|
+
|
97
|
+
# Create an image object. It will not actually load the image until needed.
|
98
|
+
im = Image.jpeg('mypic.jpg')
|
61
99
|
|
62
|
-
|
63
|
-
|
100
|
+
# Shrink the jpeg by a factor of four when loading -- huge speed and CPU
|
101
|
+
# improvements on large images.
|
102
|
+
im = Image.jpeg('mypic.jpg', :shrink_factor => 4)
|
64
103
|
|
65
|
-
|
66
|
-
|
67
|
-
|
104
|
+
# Add a shrink by a factor of two to the pipeline. This will not actually be
|
105
|
+
# executed yet.
|
106
|
+
im_shrink_by_two = im.shrink(2)
|
68
107
|
|
69
|
-
|
70
|
-
|
71
|
-
|
108
|
+
# Write out the shrunk image to a PNG file. This is where the image is
|
109
|
+
# actually loaded and resized. With images that allow for random access from
|
110
|
+
# the hard drive (VIPS native format, tiled OpenEXR, ppm/pbm/pgm/pfm, tiled
|
111
|
+
# tiff, and RAW images), the entire image is never read into memory.
|
112
|
+
im_shrink_by_two.png('out.png', :interlace => true)
|
72
113
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
114
|
+
# All ruby-vips image commands can be chained, so the above sequence could
|
115
|
+
# be written as:
|
116
|
+
Image.jpeg('mypic.jpg', :shrink_factor => 4).shrink(2).png('out.png')
|
117
|
+
|
118
|
+
# The statement above will load the jpeg (pre-shrunk by a factor of four),
|
119
|
+
# shrink the image again by a factor of two, and then save as a png image.
|
120
|
+
|
121
|
+
# If you want to let vips determine file formats, you can use the generic
|
122
|
+
# reader and writer:
|
123
|
+
Image.new('mypic.jpg').shrink(2).write('out.png')
|
124
|
+
```
|
78
125
|
|
79
|
-
|
80
|
-
|
81
|
-
|
126
|
+
## Gotchas
|
127
|
+
|
128
|
+
### Contain memuse
|
129
|
+
|
130
|
+
ruby-vips only finalises vips images on GC. In other words:
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
a = Image.new(filename)
|
134
|
+
a = nil
|
135
|
+
```
|
82
136
|
|
83
|
-
|
84
|
-
|
137
|
+
will not release the resources associated with a, you have to
|
138
|
+
either request a GC explicitly or wait for Ruby to GC for you. This can
|
139
|
+
be a problem if you're processing many images.
|
85
140
|
|
86
|
-
|
87
|
-
# reader and writer:
|
88
|
-
Image.new('mypic.jpg').shrink(2).write('out.png')
|
141
|
+
We suggest you schedule a GC every 100 images processed.
|
89
142
|
|
90
143
|
## Why use ruby-vips?
|
91
144
|
|
92
145
|
- It supports over 250 low-level image and color manipulation operations.
|
93
|
-
- Operations are chainable, and do not get executed until the image is sent to
|
94
|
-
|
95
|
-
- Fastest ruby library for resizing large images. See [benchmarks at the
|
96
|
-
official libvips website](http://www.vips.ecs.soton.ac.uk/index.php?title=Speed_and_Memory_Use).
|
146
|
+
- Operations are chainable, and do not get executed until the image is sent to an output.
|
147
|
+
- Memory use is low, even for very, very large images.
|
148
|
+
- Fastest ruby library for resizing large images. See [benchmarks at the official libvips website](http://www.vips.ecs.soton.ac.uk/index.php?title=Speed_and_Memory_Use) and [vips-benchmarks](https://github.com/stanislaw/vips-benchmarks)
|
data/ext/extconf.rb
CHANGED
@@ -4,7 +4,8 @@ require "mkmf"
|
|
4
4
|
|
5
5
|
File::unlink("Makefile") if (File::exist?("Makefile"))
|
6
6
|
|
7
|
-
%w
|
7
|
+
VIPS_VERSIONS = %w[7.29 7.28 7.27 7.26 7.24 7.23 7.22 7.20]
|
8
|
+
|
9
|
+
raise("There is no pkg_config for any of following libvips versions: #{VIPS_VERSIONS.join(', ')}") unless VIPS_VERSIONS.detect {|x| pkg_config("vips-#{x}") }
|
8
10
|
|
9
|
-
have_header('vips/vips.h')
|
10
11
|
create_makefile('vips_ext')
|
data/ext/image.c
CHANGED
@@ -27,8 +27,8 @@ img_free(vipsImg *im)
|
|
27
27
|
if(im->in)
|
28
28
|
im_close(im->in);
|
29
29
|
|
30
|
-
|
31
|
-
|
30
|
+
if(im->deps)
|
31
|
+
free(im->deps);
|
32
32
|
|
33
33
|
xfree(im);
|
34
34
|
}
|
@@ -36,10 +36,10 @@ img_free(vipsImg *im)
|
|
36
36
|
static void
|
37
37
|
img_mark(vipsImg *im)
|
38
38
|
{
|
39
|
-
|
39
|
+
int i;
|
40
40
|
|
41
|
-
|
42
|
-
|
41
|
+
for (i = 0; i < im->deps_len; i++)
|
42
|
+
rb_gc_mark(im->deps[i]);
|
43
43
|
}
|
44
44
|
|
45
45
|
VALUE
|
@@ -49,7 +49,7 @@ img_alloc(VALUE klass)
|
|
49
49
|
VALUE new = Data_Make_Struct(klass, vipsImg, img_mark, img_free, im);
|
50
50
|
im->in = NULL;
|
51
51
|
im->deps = NULL;
|
52
|
-
|
52
|
+
im->deps_len = 0;
|
53
53
|
|
54
54
|
return new;
|
55
55
|
}
|
@@ -57,15 +57,15 @@ img_alloc(VALUE klass)
|
|
57
57
|
void
|
58
58
|
img_add_dep(vipsImg *im, VALUE dep)
|
59
59
|
{
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
60
|
+
int i;
|
61
|
+
|
62
|
+
for (i = 0; i < im->deps_len; i++)
|
63
|
+
if (im->deps[i] == dep)
|
64
|
+
return;
|
65
|
+
|
66
|
+
im->deps_len++;
|
67
|
+
im->deps = (VALUE*)realloc(im->deps, im->deps_len * sizeof(VALUE));
|
68
|
+
im->deps[im->deps_len - 1] = dep;
|
69
69
|
}
|
70
70
|
|
71
71
|
VALUE
|
@@ -112,7 +112,7 @@ img_spawn(VALUE parent)
|
|
112
112
|
VALUE
|
113
113
|
img_spawn2(VALUE parent1, VALUE parent2)
|
114
114
|
{
|
115
|
-
|
115
|
+
VALUE new = img_spawn(parent1);
|
116
116
|
vipsImg *im;
|
117
117
|
Data_Get_Struct(new, vipsImg, im);
|
118
118
|
|
@@ -123,7 +123,7 @@ img_spawn2(VALUE parent1, VALUE parent2)
|
|
123
123
|
VALUE
|
124
124
|
img_spawn3(VALUE parent1, VALUE parent2, VALUE parent3)
|
125
125
|
{
|
126
|
-
|
126
|
+
VALUE new = img_spawn2(parent1, parent2);
|
127
127
|
vipsImg *im;
|
128
128
|
Data_Get_Struct(new, vipsImg, im);
|
129
129
|
|
@@ -179,10 +179,10 @@ img_coding_to_id(VipsCoding coding)
|
|
179
179
|
static VALUE
|
180
180
|
img_vtype(VALUE obj)
|
181
181
|
{
|
182
|
-
|
182
|
+
GetImg(obj, data, im);
|
183
183
|
|
184
184
|
if (im)
|
185
|
-
|
185
|
+
return ID2SYM(img_vtype_to_id(im->Type));
|
186
186
|
|
187
187
|
return Qnil;
|
188
188
|
}
|
@@ -198,7 +198,7 @@ img_vtype(VALUE obj)
|
|
198
198
|
static VALUE
|
199
199
|
img_coding(VALUE obj)
|
200
200
|
{
|
201
|
-
|
201
|
+
GetImg(obj, data, im);
|
202
202
|
|
203
203
|
if (im)
|
204
204
|
return ID2SYM(img_coding_to_id(im->Coding));
|
@@ -216,7 +216,7 @@ img_coding(VALUE obj)
|
|
216
216
|
static VALUE
|
217
217
|
img_kill(VALUE obj)
|
218
218
|
{
|
219
|
-
|
219
|
+
GetImg(obj, data, im);
|
220
220
|
return INT2FIX(im->kill);
|
221
221
|
}
|
222
222
|
|
@@ -230,7 +230,7 @@ img_kill(VALUE obj)
|
|
230
230
|
static VALUE
|
231
231
|
img_filename(VALUE obj)
|
232
232
|
{
|
233
|
-
|
233
|
+
GetImg(obj, data, im);
|
234
234
|
|
235
235
|
if (im)
|
236
236
|
return rb_tainted_str_new2(im->filename);
|
@@ -240,50 +240,50 @@ img_filename(VALUE obj)
|
|
240
240
|
|
241
241
|
|
242
242
|
#define GETPIX( TYPE, CONVERSION ) { \
|
243
|
-
|
243
|
+
TYPE *p = (TYPE *) IM_IMAGE_ADDR(im, x, y); \
|
244
244
|
\
|
245
|
-
|
246
|
-
|
245
|
+
if (sz == 1) \
|
246
|
+
return CONVERSION(*p); \
|
247
247
|
\
|
248
|
-
|
249
|
-
|
250
|
-
|
248
|
+
ary = rb_ary_new2(sz); \
|
249
|
+
for (i = 0; i < sz; i++) \
|
250
|
+
rb_ary_push(ary, CONVERSION(p[i])); \
|
251
251
|
\
|
252
|
-
|
252
|
+
return ary; \
|
253
253
|
}
|
254
254
|
|
255
255
|
#define CGETPIX( TYPE, CONVERSION ) { \
|
256
|
-
|
256
|
+
TYPE *p = (TYPE *) IM_IMAGE_ADDR(im, x, y); \
|
257
257
|
\
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
258
|
+
ary = rb_ary_new2(sz); \
|
259
|
+
for (i = 0; i < sz; i++) { \
|
260
|
+
rb_ary_push(ary, rb_ary_new3(2, CONVERSION(p[0]), CONVERSION(p[1]))); \
|
261
|
+
p += 2; \
|
262
|
+
} \
|
263
263
|
\
|
264
|
-
|
264
|
+
return ary; \
|
265
265
|
}
|
266
266
|
|
267
267
|
static VALUE
|
268
268
|
img_pixel_to_rb(VipsImage *im, int x, int y)
|
269
269
|
{
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
270
|
+
const int sz = im->Bands;
|
271
|
+
int i;
|
272
|
+
VALUE ary;
|
273
|
+
|
274
|
+
switch( im->BandFmt ) {
|
275
|
+
case IM_BANDFMT_UCHAR: GETPIX( unsigned char, UINT2NUM ); break;
|
276
|
+
case IM_BANDFMT_CHAR: GETPIX( signed char, INT2NUM ); break;
|
277
|
+
case IM_BANDFMT_USHORT: GETPIX( unsigned short, UINT2NUM ); break;
|
278
|
+
case IM_BANDFMT_SHORT: GETPIX( signed short, INT2NUM ); break;
|
279
|
+
case IM_BANDFMT_UINT: GETPIX( unsigned int, UINT2NUM ); break;
|
280
|
+
case IM_BANDFMT_INT: GETPIX( signed int, INT2FIX ); break;
|
281
|
+
case IM_BANDFMT_FLOAT: GETPIX( float, rb_float_new ); break;
|
282
|
+
|
283
|
+
case IM_BANDFMT_DOUBLE: GETPIX( double, rb_float_new ); break;
|
284
|
+
case IM_BANDFMT_COMPLEX: CGETPIX( float, rb_float_new ); break;
|
285
|
+
case IM_BANDFMT_DPCOMPLEX: CGETPIX( double, rb_float_new ); break;
|
286
|
+
}
|
287
287
|
}
|
288
288
|
|
289
289
|
/*
|
@@ -301,17 +301,17 @@ img_pixel_to_rb(VipsImage *im, int x, int y)
|
|
301
301
|
static VALUE
|
302
302
|
img_aref(VALUE obj, VALUE v_x, VALUE v_y)
|
303
303
|
{
|
304
|
-
|
305
|
-
|
306
|
-
|
304
|
+
int x = NUM2INT(v_x);
|
305
|
+
int y = NUM2INT(v_y);
|
306
|
+
GetImg(obj, data, im);
|
307
307
|
|
308
|
-
|
309
|
-
|
308
|
+
if (im_incheck(im) || im_check_uncoded("img_aref", im))
|
309
|
+
vips_lib_error();
|
310
310
|
|
311
|
-
|
312
|
-
|
311
|
+
if (x >= im->Xsize || x < 0 || y >= im->Ysize || y < 0)
|
312
|
+
rb_raise(rb_eIndexError, "Index out of bounds");
|
313
313
|
|
314
|
-
|
314
|
+
return img_pixel_to_rb(im, x, y);
|
315
315
|
}
|
316
316
|
|
317
317
|
/*
|
@@ -324,21 +324,21 @@ img_aref(VALUE obj, VALUE v_x, VALUE v_y)
|
|
324
324
|
static VALUE
|
325
325
|
img_each_pixel(VALUE obj)
|
326
326
|
{
|
327
|
-
|
328
|
-
|
329
|
-
|
327
|
+
int x, y;
|
328
|
+
VALUE pixel;
|
329
|
+
GetImg(obj, data, im);
|
330
330
|
|
331
|
-
|
332
|
-
|
331
|
+
if (im_incheck(im) || im_check_uncoded("img_each_pixel", im))
|
332
|
+
return( Qnil );
|
333
333
|
|
334
334
|
for(y = 0; y < im->Ysize; y++) {
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
335
|
+
for(x = 0; x < im->Xsize; x++) {
|
336
|
+
pixel = img_pixel_to_rb(im, x, y);
|
337
|
+
rb_yield(rb_ary_new3(3, pixel, INT2FIX(x), INT2FIX(y)));
|
338
|
+
}
|
339
|
+
}
|
340
340
|
|
341
|
-
|
341
|
+
return obj;
|
342
342
|
}
|
343
343
|
|
344
344
|
/*
|
@@ -351,12 +351,12 @@ img_each_pixel(VALUE obj)
|
|
351
351
|
static VALUE
|
352
352
|
img_data(VALUE obj)
|
353
353
|
{
|
354
|
-
|
354
|
+
GetImg(obj, data, im);
|
355
355
|
|
356
|
-
|
357
|
-
|
356
|
+
if (im_incheck(im) || im_check_uncoded("img_aref", im))
|
357
|
+
return( Qnil );
|
358
358
|
|
359
|
-
|
359
|
+
return rb_tainted_str_new(im->data, IM_IMAGE_SIZEOF_LINE(im) * im->Ysize);
|
360
360
|
}
|
361
361
|
|
362
362
|
/*
|
@@ -398,8 +398,8 @@ init_Image(void)
|
|
398
398
|
rb_define_singleton_method(cVIPSImage, "fractsurf", img_s_fractsurf, 2); // in image_freq_filt.c
|
399
399
|
rb_define_singleton_method(cVIPSImage, "identity", img_s_identity, 1); // in image_histograms_lut.c
|
400
400
|
rb_define_singleton_method(cVIPSImage, "identity_ushort", img_s_identity_ushort, 2); // in image_histograms_lut.c
|
401
|
-
|
402
|
-
|
401
|
+
rb_define_singleton_method(cVIPSImage, "invertlut", img_s_invertlut, 2); // in image_histograms_lut.c
|
402
|
+
rb_define_singleton_method(cVIPSImage, "buildlut", img_s_buildlut, 1); // in image_histograms_lut.c
|
403
403
|
rb_define_singleton_method(cVIPSImage, "tone_build_range", img_s_tone_build_range, 10); // in image_histograms_lut.c
|
404
404
|
rb_define_singleton_method(cVIPSImage, "tone_build", img_s_tone_build, 8); // in image_histograms_lut.c
|
405
405
|
|
@@ -410,47 +410,47 @@ init_Image(void)
|
|
410
410
|
rb_define_method(cVIPSImage, "coding", img_coding, 0);
|
411
411
|
rb_define_method(cVIPSImage, "filename", img_filename, 0);
|
412
412
|
rb_define_method(cVIPSImage, "kill", img_kill, 0);
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
413
|
+
rb_define_method(cVIPSImage, "measure_area", img_measure_area, 7); // in image_arithmetic.c
|
414
|
+
rb_define_method(cVIPSImage, "stats", img_stats, 0); // in image_arithmetic.c
|
415
|
+
rb_define_method(cVIPSImage, "max", img_max, 0); // in image_arithmetic.c
|
416
|
+
rb_define_method(cVIPSImage, "min", img_min, 0); // in image_arithmetic.c
|
417
|
+
rb_define_method(cVIPSImage, "avg", img_avg, 0); // in image_arithmetic.c
|
418
|
+
rb_define_method(cVIPSImage, "deviate", img_deviate, 0); // in image_arithmetic.c
|
419
|
+
rb_define_method(cVIPSImage, "maxpos", img_maxpos, -1); // in image_arithmetic.c
|
420
|
+
rb_define_method(cVIPSImage, "minpos", img_minpos, -1); // in image_arithmetic.c
|
421
|
+
rb_define_method(cVIPSImage, "maxpos_avg", img_maxpos_avg, 0); // in image_arithmetic.c
|
422
|
+
rb_define_method(cVIPSImage, "bandmean", img_bandmean, 0); // in image_arithmetic.c
|
423
|
+
rb_define_method(cVIPSImage, "add", img_add, 1); // in image_arithmetic.c
|
424
|
+
rb_define_alias(cVIPSImage, "+", "add");
|
425
|
+
rb_define_method(cVIPSImage, "subtract", img_subtract, 1); // in image_arithmetic.c
|
426
|
+
rb_define_alias(cVIPSImage, "-", "subtract");
|
427
|
+
rb_define_method(cVIPSImage, "invert", img_invert, 0); // in image_arithmetic.c
|
428
|
+
rb_define_method(cVIPSImage, "lin", img_lin, 2); // in image_arithmetic.c
|
429
|
+
rb_define_method(cVIPSImage, "multiply", img_multiply, 1); // in image_arithmetic.c
|
430
|
+
rb_define_alias(cVIPSImage, "*", "multiply");
|
431
|
+
rb_define_method(cVIPSImage, "divide", img_divide, 1); // in image_arithmetic.c
|
432
|
+
rb_define_alias(cVIPSImage, "/", "divide");
|
433
|
+
rb_define_method(cVIPSImage, "remainder", img_remainder, -1); // in image_arithmetic.c
|
434
|
+
rb_define_method(cVIPSImage, "%", img_remainder_binop, 1);
|
435
|
+
rb_define_method(cVIPSImage, "recomb", img_recomb, 1); // in image_arithmetic.c
|
436
|
+
rb_define_method(cVIPSImage, "sign", img_sign, 0); // in image_arithmetic.c
|
437
|
+
rb_define_method(cVIPSImage, "abs", img_abs, 0); // in image_arithmetic.c
|
438
|
+
rb_define_method(cVIPSImage, "floor", img_floor, 0); // in image_arithmetic.c
|
439
|
+
rb_define_method(cVIPSImage, "rint", img_rint, 0); // in image_arithmetic.c
|
440
|
+
rb_define_method(cVIPSImage, "ceil", img_ceil, 0); // in image_arithmetic.c
|
441
|
+
rb_define_method(cVIPSImage, "point", img_point, 4); // in image_arithmetic.c
|
442
|
+
rb_define_method(cVIPSImage, "pow", img_pow, -1); // in image_arithmetic.c
|
443
|
+
rb_define_method(cVIPSImage, "**", img_pow_binop, 1); // in image_arithmetic.c
|
444
|
+
rb_define_method(cVIPSImage, "expn", img_expn, -1); // in image_arithmetic.c
|
445
|
+
rb_define_method(cVIPSImage, "log", img_log, 0); // in image_arithmetic.c
|
446
|
+
rb_define_method(cVIPSImage, "log10", img_log10, 0); // in image_arithmetic.c
|
447
|
+
rb_define_method(cVIPSImage, "sin", img_sin, 0); // in image_arithmetic.c
|
448
|
+
rb_define_method(cVIPSImage, "cos", img_cos, 0); // in image_arithmetic.c
|
449
|
+
rb_define_method(cVIPSImage, "tan", img_tan, 0); // in image_arithmetic.c
|
450
|
+
rb_define_method(cVIPSImage, "asin", img_asin, 0); // in image_arithmetic.c
|
451
|
+
rb_define_method(cVIPSImage, "acos", img_acos, 0); // in image_arithmetic.c
|
452
|
+
rb_define_method(cVIPSImage, "atan", img_atan, 0); // in image_arithmetic.c
|
453
|
+
rb_define_method(cVIPSImage, "cross_phase", img_cross_phase, 1); // in image_arithmetic.c
|
454
454
|
rb_define_method(cVIPSImage, "and", img_and, -1); // in image_boolean.c
|
455
455
|
rb_define_method(cVIPSImage, "&", img_and_binop, 1);
|
456
456
|
rb_define_method(cVIPSImage, "or", img_or, -1); // in image_boolean.c
|
@@ -488,12 +488,12 @@ init_Image(void)
|
|
488
488
|
rb_define_method(cVIPSImage, "de00_from_lab", img_de00_from_lab, 1); // in image_colour.c
|
489
489
|
rb_define_method(cVIPSImage, "de_from_xyz", img_de_from_xyz, 1); // in image_colour.c
|
490
490
|
rb_define_method(cVIPSImage, "de_from_lab", img_de_from_lab, 1); // in image_colour.c
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
491
|
+
rb_define_method(cVIPSImage, "im_lab_morph", img_lab_morph, 5); // in image_colour.c
|
492
|
+
rb_define_method(cVIPSImage, "icc_transform", img_icc_transform, 3); // in image_colour.c
|
493
|
+
rb_define_method(cVIPSImage, "icc_import", img_icc_import, 2); // in image_colour.c
|
494
|
+
rb_define_method(cVIPSImage, "icc_import_embedded", img_icc_import_embedded, 1); // in image_colour.c
|
495
|
+
rb_define_method(cVIPSImage, "icc_export_depth", img_icc_export_depth, 3); // in image_colour.c
|
496
|
+
rb_define_method(cVIPSImage, "icc_ac2rc", img_icc_ac2rc, 1); // in image_colour.c
|
497
497
|
rb_define_method(cVIPSImage, "to_mask", img_to_mask, 0); // in image_conversion.c
|
498
498
|
rb_define_method(cVIPSImage, "copy_file", img_copy_file, 0); // in image_conversion.c
|
499
499
|
rb_define_method(cVIPSImage, "dup", img_dup, 0); // in image_conversion.c
|
@@ -512,6 +512,7 @@ init_Image(void)
|
|
512
512
|
rb_define_method(cVIPSImage, "extract_band", img_extract_band, -1); // in image_conversion.c
|
513
513
|
rb_define_method(cVIPSImage, "extract_area", img_extract_area, -1); // in image_conversion.c
|
514
514
|
rb_define_method(cVIPSImage, "embed", img_embed, 5); // in image_conversion.c
|
515
|
+
rb_define_method(cVIPSImage, "tile_cache", img_tile_cache, 3); // in image_conversion.c
|
515
516
|
rb_define_method(cVIPSImage, "bandjoin", img_bandjoin, -1); // in image_conversion.c
|
516
517
|
rb_define_method(cVIPSImage, "insert", img_insert, -1); // in image_conversion.c
|
517
518
|
rb_define_method(cVIPSImage, "insert_noexpand", img_insert_noexpand, 3); // in image_conversion.c
|
@@ -542,7 +543,7 @@ init_Image(void)
|
|
542
543
|
rb_define_method(cVIPSImage, "addgnoise", img_addgnoise, 1); // in image_convolution.c
|
543
544
|
rb_define_method(cVIPSImage, "fwfft", img_fwfft, 0); // in image_freq_filt.c
|
544
545
|
rb_define_method(cVIPSImage, "invfft", img_invfft, 0); // in image_freq_filt.c
|
545
|
-
|
546
|
+
rb_define_method(cVIPSImage, "rotquad", img_rotquad, 0); // in image_freq_filt.c
|
546
547
|
rb_define_method(cVIPSImage, "invfftr", img_invfftr, 0); // in image_freq_filt.c
|
547
548
|
rb_define_method(cVIPSImage, "freqflt", img_freqflt, 1); // in image_freq_filt.c
|
548
549
|
rb_define_method(cVIPSImage, "disp_ps", img_disp_ps, 0); // in image_freq_filt.c
|
@@ -565,20 +566,20 @@ init_Image(void)
|
|
565
566
|
rb_define_method(cVIPSImage, "lhisteq", img_lhisteq, 2); // in image_histograms_lut.c
|
566
567
|
rb_define_method(cVIPSImage, "stdif", img_stdif, 6); // in image_histograms_lut.c
|
567
568
|
rb_define_method(cVIPSImage, "tone_analyze", img_tone_analyze, 6); // in image_histograms_lut.c
|
568
|
-
|
569
|
-
|
569
|
+
rb_define_method(cVIPSImage, "maplut", img_maplut, 1); // in image_histograms_lut.c
|
570
|
+
rb_define_method(cVIPSImage, "histplot", img_histplot, 0); // in image_histograms_lut.c
|
570
571
|
rb_define_method(cVIPSImage, "dilate", img_dilate, 1); // in image_morphology.c
|
571
572
|
rb_define_method(cVIPSImage, "erode", img_erode, 1); // in image_morphology.c
|
572
573
|
rb_define_method(cVIPSImage, "rank", img_rank, 3); // in image_morphology.c
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
574
|
+
rb_define_method(cVIPSImage, "rank_image", img_rank_image, -1); // in image_morphology.c
|
575
|
+
rb_define_method(cVIPSImage, "maxvalue", img_maxvalue, -1); // in image_morphology.c
|
576
|
+
rb_define_method(cVIPSImage, "cntlines_h", img_cntlines_h, 0); // in image_morphology.c
|
577
|
+
rb_define_method(cVIPSImage, "cntlines_v", img_cntlines_v, 0); // in image_morphology.c
|
578
|
+
rb_define_method(cVIPSImage, "zerox_pos", img_zerox_pos, 0); // in image_morphology.c
|
579
|
+
rb_define_method(cVIPSImage, "zerox_neg", img_zerox_neg, 0); // in image_morphology.c
|
580
|
+
rb_define_method(cVIPSImage, "profile_h", img_profile_h, 0); // in image_morphology.c
|
581
|
+
rb_define_method(cVIPSImage, "profile_v", img_profile_v, 0); // in image_morphology.c
|
582
|
+
rb_define_method(cVIPSImage, "label_regions", img_label_regions, 0); // in image_morphology.c
|
582
583
|
rb_define_method(cVIPSImage, "lrmerge", img_lrmerge, -1); // in image_mosaicing.c
|
583
584
|
rb_define_method(cVIPSImage, "tbmerge", img_tbmerge, -1); // in image_mosaicing.c
|
584
585
|
rb_define_method(cVIPSImage, "lrmerge1", img_lrmerge1, -1); // in image_mosaicing.c
|
@@ -590,8 +591,8 @@ init_Image(void)
|
|
590
591
|
rb_define_method(cVIPSImage, "global_balance", img_global_balance, 1); // in image_mosaicing.c
|
591
592
|
rb_define_method(cVIPSImage, "global_balancef", img_global_balancef, 1); // in image_mosaicing.c
|
592
593
|
rb_define_method(cVIPSImage, "correl", img_correl, 7); // in image_mosaicing.c
|
593
|
-
|
594
|
-
|
594
|
+
rb_define_method(cVIPSImage, "align_bands", img_align_bands, 0); // in image_mosaicing.c
|
595
|
+
rb_define_method(cVIPSImage, "maxpos_subpel", img_maxpos_subpel, 0); // in image_mosaicing.c
|
595
596
|
rb_define_method(cVIPSImage, "equal", img_equal, -1); // in image_relational.c
|
596
597
|
rb_define_method(cVIPSImage, "notequal", img_notequal, -1); // in image_relational.c
|
597
598
|
rb_define_method(cVIPSImage, "less", img_less, -1); // in image_relational.c
|
@@ -608,24 +609,24 @@ init_Image(void)
|
|
608
609
|
rb_define_method(cVIPSImage, "match_linear", img_match_linear, 9); // in image_resample.c
|
609
610
|
rb_define_method(cVIPSImage, "match_linear_search", img_match_linear_search, 11); // in image_resample.c
|
610
611
|
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
612
|
+
id_b_w = rb_intern("B_W");
|
613
|
+
id_histogram = rb_intern("HISTOGRAM");
|
614
|
+
id_fourier = rb_intern("FOURIER");
|
615
|
+
id_xyz = rb_intern("XYZ");
|
616
|
+
id_lab = rb_intern("LAB");
|
617
|
+
id_cmyk = rb_intern("CMYK");
|
618
|
+
id_labq = rb_intern("LABQ");
|
619
|
+
id_rgb = rb_intern("RGB");
|
620
|
+
id_ucs = rb_intern("UCS");
|
621
|
+
id_lch = rb_intern("LCH");
|
622
|
+
id_labs = rb_intern("LABS");
|
623
|
+
id_srgb = rb_intern("sRGB");
|
624
|
+
id_yxy = rb_intern("YXY");
|
625
|
+
id_rgb16 = rb_intern("RGB16");
|
626
|
+
id_grey16 = rb_intern("GREY16");
|
627
|
+
|
628
|
+
id_none = rb_intern("NONE");
|
629
|
+
id_rad = rb_intern("RAD");
|
629
630
|
|
630
631
|
init_Image_colour();
|
631
632
|
init_Image_conversion();
|
data/ext/image_conversion.c
CHANGED
@@ -473,6 +473,30 @@ img_embed(VALUE obj, VALUE type_v, VALUE x, VALUE y, VALUE width, VALUE height)
|
|
473
473
|
return new;
|
474
474
|
}
|
475
475
|
|
476
|
+
/*
|
477
|
+
* call-seq:
|
478
|
+
* im.tile_cache(tile_width, tile_height, max_tiles) -> image
|
479
|
+
*
|
480
|
+
* This operation behaves rather like copy between images,
|
481
|
+
* except that it keeps a cache of computed pixels.
|
482
|
+
* This cache is made of up to max_tiles tiles (a value of -1 for
|
483
|
+
* means any number of tiles), and each tile is of size tile_width
|
484
|
+
* by tile_height pixels.
|
485
|
+
*/
|
486
|
+
|
487
|
+
VALUE
|
488
|
+
img_tile_cache(VALUE obj, VALUE tile_width, VALUE tile_height, VALUE max_tiles)
|
489
|
+
{
|
490
|
+
GetImg(obj, data, im);
|
491
|
+
OutImg(obj, new, data_new, im_new);
|
492
|
+
|
493
|
+
if (im_tile_cache(im, im_new,
|
494
|
+
NUM2INT(tile_width), NUM2INT(tile_height), NUM2INT(max_tiles)))
|
495
|
+
vips_lib_error();
|
496
|
+
|
497
|
+
return new;
|
498
|
+
}
|
499
|
+
|
476
500
|
/*
|
477
501
|
* call-seq:
|
478
502
|
* im.bandjoin(other_image, ...) -> image
|
data/ext/image_conversion.h
CHANGED
@@ -19,6 +19,7 @@ VALUE img_s_text(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
|
|
19
19
|
VALUE img_extract_band(int, VALUE*, VALUE);
|
20
20
|
VALUE img_extract_area(int, VALUE*, VALUE);
|
21
21
|
VALUE img_embed(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
|
22
|
+
VALUE img_tile_cache(VALUE, VALUE, VALUE, VALUE);
|
22
23
|
VALUE img_bandjoin(int, VALUE *argv, VALUE);
|
23
24
|
VALUE img_insert_noexpand(VALUE, VALUE, VALUE, VALUE);
|
24
25
|
VALUE img_insert(int, VALUE *argv, VALUE);
|
@@ -34,4 +35,4 @@ VALUE img_rot180(VALUE);
|
|
34
35
|
VALUE img_rot270(VALUE);
|
35
36
|
VALUE img_subsample(int, VALUE*, VALUE);
|
36
37
|
VALUE img_zoom(int, VALUE*, VALUE);
|
37
|
-
void init_Image_conversion();
|
38
|
+
void init_Image_conversion();
|
data/ext/ruby_vips.c
CHANGED
@@ -72,8 +72,8 @@ init_vips_library()
|
|
72
72
|
argv_0 = rb_gv_get("0");
|
73
73
|
|
74
74
|
if (NIL_P(argv_0))
|
75
|
-
|
76
|
-
|
75
|
+
im_init_world("");
|
76
|
+
else
|
77
77
|
im_init_world(RSTRING_PTR(argv_0));
|
78
78
|
|
79
79
|
argv_v = rb_const_get(rb_mKernel, rb_intern("ARGV"));
|
@@ -88,8 +88,6 @@ init_vips_library()
|
|
88
88
|
for (i=0; i < argc - 1; i++)
|
89
89
|
argv[i+1] = RSTRING_PTR(RARRAY_PTR(argv_v)[i]);
|
90
90
|
|
91
|
-
im_init_world(argv[0]);
|
92
|
-
|
93
91
|
context = g_option_context_new("- ruby-vips");
|
94
92
|
g_option_context_set_ignore_unknown_options(context, TRUE);
|
95
93
|
|
@@ -100,6 +98,13 @@ init_vips_library()
|
|
100
98
|
|
101
99
|
xfree(argv);
|
102
100
|
}
|
101
|
+
|
102
|
+
/* We use the vips7 interface, so the vips8 cache will not help us.
|
103
|
+
* Disable it and save 100mb or so of memory in vips-7.28 and later.
|
104
|
+
*/
|
105
|
+
#if IM_MAJOR_VERSION >= 7 && IM_MINOR_VERSION >= 28
|
106
|
+
vips_cache_set_max_mem( 0 );
|
107
|
+
#endif
|
103
108
|
}
|
104
109
|
|
105
110
|
/*
|
data/lib/vips/reader.rb
CHANGED
@@ -69,6 +69,7 @@ module VIPS
|
|
69
69
|
class JPEGReader < Reader
|
70
70
|
attr_reader :shrink_factor
|
71
71
|
attr_accessor :fail_on_warn
|
72
|
+
attr_accessor :sequential
|
72
73
|
|
73
74
|
SHRINK_FACTOR = [1, 2, 4, 8]
|
74
75
|
|
@@ -76,9 +77,11 @@ module VIPS
|
|
76
77
|
def initialize(path, options={})
|
77
78
|
@shrink_factor = 1
|
78
79
|
@fail_on_warn = false
|
80
|
+
@sequential = false
|
79
81
|
|
80
82
|
self.shrink_factor = options[:shrink_factor] if options.has_key?(:shrink_factor)
|
81
83
|
self.fail_on_warn = options[:fail_on_warn] if options.has_key?(:fail_on_warn)
|
84
|
+
self.sequential = options[:sequential] if options.has_key?(:sequential)
|
82
85
|
|
83
86
|
super path, options
|
84
87
|
end
|
@@ -86,7 +89,10 @@ module VIPS
|
|
86
89
|
# Read the jpeg file from disk and return a VIPS Image object.
|
87
90
|
def read
|
88
91
|
str = "#{@path}:#{shrink_factor}"
|
89
|
-
str << ",
|
92
|
+
str << ","
|
93
|
+
str << "fail" if @fail_on_warn
|
94
|
+
str << ","
|
95
|
+
str << "sequential" if @sequential
|
90
96
|
|
91
97
|
read_internal str
|
92
98
|
end
|
@@ -105,17 +111,24 @@ module VIPS
|
|
105
111
|
|
106
112
|
class TIFFReader < Reader
|
107
113
|
attr_reader :page_number
|
114
|
+
attr_accessor :sequential
|
108
115
|
|
109
116
|
# Create a tiff image file reader.
|
110
117
|
def initialize(path, options={})
|
118
|
+
@page_number = nil
|
119
|
+
@sequential = false
|
120
|
+
|
111
121
|
self.page_number = options[:page_number] if options.has_key?(:page_number)
|
122
|
+
self.sequential = options[:sequential] if options.has_key?(:sequential)
|
112
123
|
super path, options
|
113
124
|
end
|
114
125
|
|
115
126
|
# Read the tiff file from disk and return a VIPS Image object.
|
116
127
|
def read
|
117
|
-
str = @path
|
118
|
-
str << "
|
128
|
+
str = "#{@path}:"
|
129
|
+
str << "#{@page_number}" if @page_number
|
130
|
+
str << ","
|
131
|
+
str << "sequential" if @sequential
|
119
132
|
|
120
133
|
read_internal str
|
121
134
|
end
|
@@ -131,6 +144,27 @@ module VIPS
|
|
131
144
|
end
|
132
145
|
end
|
133
146
|
|
147
|
+
class PNGReader < Reader
|
148
|
+
attr_accessor :sequential
|
149
|
+
|
150
|
+
# Create a png image file reader.
|
151
|
+
def initialize(path, options={})
|
152
|
+
@sequential = false
|
153
|
+
|
154
|
+
self.sequential = options[:sequential] if options.has_key?(:sequential)
|
155
|
+
super path, options
|
156
|
+
end
|
157
|
+
|
158
|
+
# Read the png file from disk and return a VIPS Image object.
|
159
|
+
def read
|
160
|
+
str = @path
|
161
|
+
str << ":"
|
162
|
+
str << "sequential" if @sequential
|
163
|
+
|
164
|
+
read_internal str
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
134
168
|
class Image
|
135
169
|
|
136
170
|
# Load a ppm file straight to a VIPS Image.
|
data/lib/vips/version.rb
CHANGED
data/ruby-vips.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "ruby-vips"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Timothy Elliott", "John Cupitt"]
|
12
|
-
s.date = "2012-06-
|
12
|
+
s.date = "2012-06-29"
|
13
13
|
s.description = "Ruby extension for the vips image processing library."
|
14
14
|
s.email = "jcupitt@gmail.com"
|
15
15
|
s.extensions = ["ext/extconf.rb"]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-vips
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-06-
|
13
|
+
date: 2012-06-29 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rdoc
|
@@ -146,7 +146,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
146
146
|
version: '0'
|
147
147
|
segments:
|
148
148
|
- 0
|
149
|
-
hash: -
|
149
|
+
hash: -423159501
|
150
150
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
151
151
|
none: false
|
152
152
|
requirements:
|