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 ADDED
@@ -0,0 +1,15 @@
1
+ # master
2
+
3
+ ### Changed
4
+
5
+ * Upgrade spec/* code to latest RSpec [Stanislaw Pankevich]
6
+
7
+ ### Added
8
+
9
+ * Added CHANGELOG.md file (thanks to jnicklas/capybara - using the layout of their History.txt) [Stanislaw Pankevich]
10
+ * Added Gemfile with the only 'rspec' dependency. [Stanislaw Pankevich]
11
+ * Added Jeweler Rakefile contents to release ruby-vips as a gem. [Stanislaw Pankevich]
12
+
13
+ # Before (initial unreleased version 0.1.0)
14
+
15
+ Long-long history here undocumented...
data/Gemfile.lock ADDED
@@ -0,0 +1,31 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.3)
5
+ git (1.2.5)
6
+ jeweler (1.8.3)
7
+ bundler (~> 1.0)
8
+ git (>= 1.2.5)
9
+ rake
10
+ rdoc
11
+ json (1.7.3)
12
+ rake (0.9.2.2)
13
+ rdoc (3.12)
14
+ json (~> 1.4)
15
+ rspec (2.10.0)
16
+ rspec-core (~> 2.10.0)
17
+ rspec-expectations (~> 2.10.0)
18
+ rspec-mocks (~> 2.10.0)
19
+ rspec-core (2.10.1)
20
+ rspec-expectations (2.10.0)
21
+ diff-lcs (~> 1.1.3)
22
+ rspec-mocks (2.10.1)
23
+
24
+ PLATFORMS
25
+ ruby
26
+
27
+ DEPENDENCIES
28
+ bundler
29
+ jeweler (~> 1.8.3)
30
+ rdoc (~> 3.12)
31
+ rspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Timothy Elliott
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,96 @@
1
+ ## ruby-vips : A fast image processing extension for Ruby.
2
+
3
+ note: this fork aims to track the latest stable vips. There are no plans to
4
+ add more features, just to keep it working.
5
+
6
+ ruby-vips is a ruby extension for [vips](http://www.vips.ecs.soton.ac.uk). It is
7
+ extremely fast and it can process huge images without requiring the entire image
8
+ to be loaded into memory.
9
+
10
+ ruby-vips allows you to set up pipelines that don't get executed until you
11
+ output the image to disk or to a string. This means you can create,
12
+ manipulate, and pass around Image objects without incurring any memory or CPU
13
+ costs. The image is not actually processed until you write the image to memory
14
+ or to disk.
15
+
16
+ ## Requirements.
17
+
18
+ * OS X or Linux
19
+ * MRI 1.8.6, 1.8.7, 1.9.2 or Rubinius 1.0.1
20
+ * libvips 7.12.x, 7.20.x, 7.22.x, or 7.23.x
21
+
22
+ ## Installation.
23
+
24
+ ### Ubuntu Prerequisites.
25
+
26
+ $ apt-get install libvips-dev
27
+
28
+ The above installs libvips 7.20.x in Ubuntu 10.04 and 7.12.x in Ubuntu 8.04.
29
+ Though ruby-vips will work with libvips 7.12.x, many features are disabled, and
30
+ there are a few caveats.
31
+
32
+ ### OS X Prerequisites.
33
+
34
+ $ brew install vips -HEAD
35
+
36
+ The above installs libvips 7.22.x
37
+
38
+ TODO: Describe & test with macports.
39
+
40
+ ### Installing the gem.
41
+
42
+ ```bash
43
+ $ gem install ruby-vips
44
+ ```
45
+
46
+ or include it in Gemfile:
47
+
48
+ ```ruby
49
+ gem 'ruby-vips'
50
+ ```
51
+
52
+ ## Documentation.
53
+
54
+ ruby-vips has [rdoc documentation](http://rubyvips.holymonkey.com).
55
+
56
+ ## Example.
57
+
58
+ require 'rubygems'
59
+ require 'vips'
60
+ include VIPS
61
+
62
+ # Create an image object. It will not actually load the image until needed.
63
+ im = Image.jpeg('mypic.jpg')
64
+
65
+ # Shrink the jpeg by a factor of four when loading -- huge speed and CPU
66
+ # improvements on large images.
67
+ im = Image.jpeg('mypic.jpg', :shrink_factor => 4)
68
+
69
+ # Add a shrink by a factor of two to the pipeline. This will not actually be
70
+ # executed yet.
71
+ im_shrink_by_two = im.shrink(2)
72
+
73
+ # Write out the shrunk image to a PNG file. This is where the image is
74
+ # actually loaded and resized. With images that allow for random access from
75
+ # the hard drive (VIPS native format, tiled OpenEXR, ppm/pbm/pgm/pfm, tiled
76
+ # tiff, and RAW images), the entire image is never read into memory.
77
+ im_shrink_by_two.png('out.png', :interlace => true)
78
+
79
+ # All ruby-vips image commands can be chained, so the above sequence could
80
+ # be written as:
81
+ Image.jpeg('mypic.jpg', :shrink_factor => 4).shrink(2).png('out.png')
82
+
83
+ # The statement above will load the jpeg (pre-shrunk by a factor of four),
84
+ # shrink the image again by a factor of two, and then save as a png image.
85
+
86
+ # If you want to let vips determine file formats, you can use the generic
87
+ # reader and writer:
88
+ Image.new('mypic.jpg').shrink(2).write('out.png')
89
+
90
+ ## Why use ruby-vips?
91
+
92
+ - 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
+ an output.
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).
data/TODO ADDED
@@ -0,0 +1,18 @@
1
+ TODO
2
+ * Verify that all memory gets released when vips ops return errors. Namely,
3
+ make sure that the allocated IMAGEs get released via ruby's free callbacks.
4
+ * Allow for injecting ruby code into an image transformation pipeline (may be
5
+ slow to call out to ruby with every read, but may be worthwhile for fun custom
6
+ image processors).
7
+ * Tap into VIPS callback system to allow progress updates, etc.
8
+ * Allow for creating a ruby endpoint to the pipeline could be useful for
9
+ streaming.
10
+ * Image#to_a
11
+ * look into other.h, audit all libvips methods and make sure they are all
12
+ implemented
13
+ * JRuby support
14
+ * Optional extensions to core Ruby classes, allowing operations such as
15
+ [1, 2, 3] & im . This could be optionally enabled by requiring e.g.
16
+ vips/core_ext
17
+ * Put groups of image operations into modules, breaking docs into themes and
18
+ possibly allowing for selective loading of image ops.
data/ext/extconf.rb ADDED
@@ -0,0 +1,10 @@
1
+ ENV['RC_ARCHS'] = '' if RUBY_PLATFORM =~ /darwin/
2
+
3
+ require "mkmf"
4
+
5
+ File::unlink("Makefile") if (File::exist?("Makefile"))
6
+
7
+ %w{7.28 7.27 7.26 7.24 7.23 7.22 7.20}.each{|x| break if pkg_config("vips-#{x}")}
8
+
9
+ have_header('vips/vips.h')
10
+ create_makefile('vips_ext')
data/ext/header.c ADDED
@@ -0,0 +1,440 @@
1
+ #include "ruby_vips.h"
2
+ #include "image.h"
3
+ #include "header.h"
4
+
5
+ VALUE mVIPSHeader;
6
+
7
+ static ID id_notset, id_uchar, id_char, id_ushort, id_short, id_uint, id_int,
8
+ id_float, id_complex, id_double, id_dbcomplex;
9
+
10
+ ID
11
+ header_band_fmt_to_id(VipsBandFmt band_fmt)
12
+ {
13
+ switch(band_fmt) {
14
+ case IM_BANDFMT_NOTSET: return id_notset;
15
+ case IM_BANDFMT_UCHAR: return id_uchar;
16
+ case IM_BANDFMT_CHAR: return id_char;
17
+ case IM_BANDFMT_USHORT: return id_ushort;
18
+ case IM_BANDFMT_SHORT: return id_short;
19
+ case IM_BANDFMT_UINT: return id_uint;
20
+ case IM_BANDFMT_INT: return id_int;
21
+ case IM_BANDFMT_FLOAT: return id_float;
22
+ case IM_BANDFMT_COMPLEX: return id_complex; // two floats
23
+ case IM_BANDFMT_DOUBLE: return id_double;
24
+ case IM_BANDFMT_DPCOMPLEX: return id_dbcomplex; // two doubles
25
+ }
26
+ return id_notset;
27
+ }
28
+
29
+ VipsBandFmt
30
+ header_id_to_band_fmt(ID rb)
31
+ {
32
+ if(rb == id_notset) return IM_BANDFMT_NOTSET;
33
+ else if(rb == id_uchar) return IM_BANDFMT_UCHAR;
34
+ else if(rb == id_char) return IM_BANDFMT_CHAR;
35
+ else if(rb == id_ushort) return IM_BANDFMT_USHORT;
36
+ else if(rb == id_short) return IM_BANDFMT_SHORT;
37
+ else if(rb == id_uint) return IM_BANDFMT_UINT;
38
+ else if(rb == id_int) return IM_BANDFMT_INT;
39
+ else if(rb == id_float) return IM_BANDFMT_FLOAT;
40
+ else if(rb == id_complex) return IM_BANDFMT_COMPLEX;
41
+ else if(rb == id_double) return IM_BANDFMT_DOUBLE;
42
+ else if(rb == id_dbcomplex) return IM_BANDFMT_DPCOMPLEX;
43
+
44
+ return (VipsBandFmt)NULL;
45
+ }
46
+
47
+ /*
48
+ * call-seq:
49
+ * im.x_size -> number
50
+ *
51
+ * Get the width in pixels of the image.
52
+ */
53
+
54
+ static VALUE
55
+ header_x_size(VALUE obj)
56
+ {
57
+ GetImg(obj, data, im);
58
+
59
+ if (im)
60
+ return INT2FIX(im->Xsize);
61
+
62
+ return Qnil;
63
+ }
64
+
65
+ /*
66
+ * call-seq:
67
+ * im.y_size -> number
68
+ *
69
+ * Get the height in pixels of the image.
70
+ */
71
+
72
+ static VALUE
73
+ header_y_size(VALUE obj)
74
+ {
75
+ GetImg(obj, data, im);
76
+
77
+ if (im)
78
+ return INT2FIX(im->Ysize);
79
+
80
+ return Qnil;
81
+ }
82
+
83
+ /*
84
+ * call-seq:
85
+ * im.bands -> number
86
+ *
87
+ * Get the number of bands in the image.
88
+ */
89
+
90
+ static VALUE
91
+ header_bands(VALUE obj)
92
+ {
93
+ GetImg(obj, data, im);
94
+
95
+ if (im)
96
+ return INT2FIX(im->Bands);
97
+
98
+ return Qnil;
99
+ }
100
+
101
+ /*
102
+ * call-seq:
103
+ * im.band_fmt -> band_format_sym
104
+ *
105
+ * Get the band format of the image.
106
+ */
107
+
108
+ static VALUE
109
+ header_band_fmt(VALUE obj)
110
+ {
111
+ GetImg(obj, data, im);
112
+
113
+ if (im)
114
+ return ID2SYM(header_band_fmt_to_id(im->BandFmt));
115
+
116
+ return Qnil;
117
+ }
118
+
119
+ /*
120
+ * call-seq:
121
+ * im.x_res -> number
122
+ *
123
+ * Get the x-resolution of the image.
124
+ */
125
+
126
+ static VALUE
127
+ header_x_res(VALUE obj)
128
+ {
129
+ GetImg(obj, data, im);
130
+
131
+ if (im)
132
+ return rb_float_new(im->Xres);
133
+
134
+ return Qnil;
135
+ }
136
+
137
+ /*
138
+ * call-seq:
139
+ * im.y_res -> number
140
+ *
141
+ * Get the y-resolution of the image.
142
+ */
143
+
144
+ static VALUE
145
+ header_y_res(VALUE obj)
146
+ {
147
+ GetImg(obj, data, im);
148
+
149
+ if (im)
150
+ return rb_float_new(im->Yres);
151
+
152
+ return Qnil;
153
+ }
154
+
155
+ /*
156
+ * call-seq:
157
+ * im.x_offset -> number
158
+ *
159
+ * Get the x-offset of the image.
160
+ */
161
+
162
+ static VALUE
163
+ header_x_offset(VALUE obj)
164
+ {
165
+ GetImg(obj, data, im);
166
+
167
+ if (im)
168
+ return INT2FIX(im->Xoffset);
169
+
170
+ return Qnil;
171
+ }
172
+
173
+ /*
174
+ * call-seq:
175
+ * im.y_offset -> number
176
+ *
177
+ * Get the y-offset of the image.
178
+ */
179
+
180
+ static VALUE
181
+ header_y_offset(VALUE obj)
182
+ {
183
+ GetImg(obj, data, im);
184
+
185
+ if (im)
186
+ return INT2FIX(im->Yoffset);
187
+
188
+ return Qnil;
189
+ }
190
+
191
+ /* VipsImage macros with useful information */
192
+
193
+ /*
194
+ * call-seq:
195
+ * im.sizeof_element -> number
196
+ *
197
+ * Returns the size of a single image band item, in bytes.
198
+ */
199
+
200
+ static VALUE
201
+ header_sizeof_element(VALUE obj)
202
+ {
203
+ GetImg(obj, data, im);
204
+
205
+ if (im)
206
+ return INT2FIX(IM_IMAGE_SIZEOF_ELEMENT(im));
207
+
208
+ return Qnil;
209
+ }
210
+
211
+ /*
212
+ * call-seq:
213
+ * im.sizeof_pel -> number
214
+ *
215
+ * Returns the size of a pixel in the image, in bytes.
216
+ */
217
+
218
+ static VALUE
219
+ header_sizeof_pel(VALUE obj)
220
+ {
221
+ GetImg(obj, data, im);
222
+
223
+ if (im)
224
+ return INT2FIX(IM_IMAGE_SIZEOF_PEL(im));
225
+
226
+ return Qnil;
227
+ }
228
+
229
+ /*
230
+ * call-seq:
231
+ * im.sizeof_line -> number
232
+ *
233
+ * Returns the size of all pixels in the row of the image, uncompressed, in
234
+ * bytes.
235
+ */
236
+
237
+ static VALUE
238
+ header_sizeof_line(VALUE obj)
239
+ {
240
+ GetImg(obj, data, im);
241
+
242
+ if (im)
243
+ return INT2FIX(IM_IMAGE_SIZEOF_LINE(im));
244
+
245
+ return Qnil;
246
+ }
247
+
248
+ /*
249
+ * call-seq:
250
+ * im.n_elements -> number
251
+ *
252
+ * Returns the number of elements in an image row, i.e. bands * x_size.
253
+ */
254
+
255
+ static VALUE
256
+ header_n_elements(VALUE obj)
257
+ {
258
+ GetImg(obj, data, im);
259
+
260
+ if (im)
261
+ return INT2FIX(IM_IMAGE_N_ELEMENTS(im));
262
+
263
+ return Qnil;
264
+ }
265
+
266
+ static VALUE
267
+ header_meta_get(VALUE obj, const char* name)
268
+ {
269
+ GetImg(obj, data, im);
270
+
271
+ void *buf;
272
+ size_t len;
273
+
274
+ if (im_meta_get_blob(im, name, &buf, &len))
275
+ return Qnil;
276
+
277
+ return rb_tainted_str_new((char *)buf, len);
278
+ }
279
+
280
+ static VALUE
281
+ header_meta_get_string(VALUE obj, const char* name)
282
+ {
283
+ GetImg(obj, data, im);
284
+
285
+ char *str;
286
+ VALUE result;
287
+
288
+ if (vips_image_get_as_string(im, name, &str))
289
+ vips_lib_error();
290
+ result = rb_tainted_str_new(str, strlen(str));
291
+ g_free(str);
292
+
293
+ return result;
294
+ }
295
+
296
+ static void
297
+ header_meta_set_string(VALUE obj, const char* name, const char* value)
298
+ {
299
+ GetImg(obj, data, im);
300
+
301
+ vips_image_set_string(im, name, value);
302
+ }
303
+
304
+ static VALUE
305
+ header_meta_p(VALUE obj, const char* name)
306
+ {
307
+ GetImg(obj, data, im);
308
+
309
+ if (im_header_get_typeof(im, name))
310
+ return Qtrue;
311
+
312
+ return Qfalse;
313
+ }
314
+
315
+ /*
316
+ * call-seq:
317
+ * im.exif -> string
318
+ *
319
+ * Returns a binary string containing the raw exif header data.
320
+ */
321
+
322
+ static VALUE
323
+ header_exif(VALUE obj)
324
+ {
325
+ return header_meta_get(obj, IM_META_EXIF_NAME);
326
+ }
327
+
328
+ /*
329
+ * call-seq:
330
+ * im.exif? -> true or false
331
+ *
332
+ * Indicates whether the image has an exif header attached to it.
333
+ */
334
+
335
+ static VALUE
336
+ header_exif_p(VALUE obj)
337
+ {
338
+ return header_meta_p(obj, IM_META_EXIF_NAME);
339
+ }
340
+
341
+ /*
342
+ * call-seq:
343
+ * im.icc -> string
344
+ *
345
+ * Returns a binary string containing the raw icc header data.
346
+ */
347
+
348
+ static VALUE
349
+ header_icc(VALUE obj)
350
+ {
351
+ return header_meta_get(obj, IM_META_ICC_NAME);
352
+ }
353
+
354
+ /*
355
+ * call-seq:
356
+ * im.icc? -> true or false
357
+ *
358
+ * Indicates whether the image has an icc header attached to it.
359
+ */
360
+
361
+ static VALUE
362
+ header_icc_p(VALUE obj)
363
+ {
364
+ return header_meta_p(obj, IM_META_ICC_NAME);
365
+ }
366
+
367
+ /*
368
+ * call-seq:
369
+ * im.get(name) -> string
370
+ *
371
+ * Return metadata item 'name' as a string.
372
+ */
373
+
374
+ static VALUE
375
+ header_get(VALUE obj, VALUE name)
376
+ {
377
+ return header_meta_get_string(obj, StringValuePtr(name));
378
+ }
379
+
380
+ /*
381
+ * call-seq:
382
+ * im.set(name, value)
383
+ *
384
+ * Set metadata item 'name' to value.
385
+ */
386
+
387
+ static VALUE
388
+ header_set(VALUE obj, VALUE name, VALUE value)
389
+ {
390
+ header_meta_set_string(obj,
391
+ StringValuePtr(name), StringValuePtr(value));
392
+
393
+ return Qnil;
394
+ }
395
+
396
+ /*
397
+ * The header module holds image header operations that are common to readers,
398
+ * writers and image objects.
399
+ */
400
+
401
+ void
402
+ init_Header()
403
+ {
404
+ mVIPSHeader = rb_define_module_under(mVIPS, "Header");
405
+
406
+ rb_define_method(mVIPSHeader, "x_size", header_x_size, 0);
407
+ rb_define_method(mVIPSHeader, "y_size", header_y_size, 0);
408
+ rb_define_method(mVIPSHeader, "bands", header_bands, 0);
409
+ rb_define_method(mVIPSHeader, "band_fmt", header_band_fmt, 0);
410
+ rb_define_method(mVIPSHeader, "x_res", header_x_res, 0);
411
+ rb_define_method(mVIPSHeader, "y_res", header_y_res, 0);
412
+ rb_define_method(mVIPSHeader, "x_offset", header_x_offset, 0);
413
+ rb_define_method(mVIPSHeader, "y_offset", header_y_offset, 0);
414
+ rb_define_method(mVIPSHeader, "sizeof_element", header_sizeof_element, 0);
415
+ rb_define_method(mVIPSHeader, "sizeof_pel", header_sizeof_pel, 0);
416
+ rb_define_method(mVIPSHeader, "sizeof_line", header_sizeof_line, 0);
417
+ rb_define_method(mVIPSHeader, "n_elements", header_n_elements, 0);
418
+ rb_define_method(mVIPSHeader, "exif", header_exif, 0);
419
+ rb_define_method(mVIPSHeader, "exif?", header_exif_p, 0);
420
+ rb_define_method(mVIPSHeader, "icc", header_icc, 0);
421
+ rb_define_method(mVIPSHeader, "icc?", header_icc_p, 0);
422
+ rb_define_method(mVIPSHeader, "get", header_get, 1);
423
+ rb_define_method(mVIPSHeader, "set", header_set, 2);
424
+
425
+ id_notset = rb_intern("NOTSET");
426
+ id_uchar = rb_intern("UCHAR");
427
+ id_char = rb_intern("CHAR");
428
+ id_ushort = rb_intern("USHORT");
429
+ id_short = rb_intern("SHORT");
430
+ id_uint = rb_intern("UINT");
431
+ id_int = rb_intern("INT");
432
+ id_float = rb_intern("FLOAT");
433
+ id_complex = rb_intern("COMPLEX");
434
+ id_double = rb_intern("DOUBLE");
435
+ id_dbcomplex = rb_intern("DBCOMPLEX");
436
+
437
+ #if 0
438
+ VALUE mVIPS = rb_define_module("VIPS");
439
+ #endif
440
+ }