ruby-vips 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://secure.travis-ci.org/jcupitt/ruby-vips.png)](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:
|