ruby-vips 1.0.6 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 614489c8022d27d06892f9980c0df0cca00d7598
4
- data.tar.gz: 9c0332039d753a99a4eb526f6b424d6a432c4b6b
3
+ metadata.gz: 294dcea3bbc7b03ef6652be00b29732722bde853
4
+ data.tar.gz: 407c694bb0080bd7bdca1469e3db50f58c5c0daf
5
5
  SHA512:
6
- metadata.gz: c9f73109c2116d56f607e9cee9a01b8bce41d380b223f0e734576a4066184cab9162e514759fcbf36750c6adc30df86467ed1755b9904b6469c66063efee1542
7
- data.tar.gz: 12f7e4f9e3af5ead044a1fd9e46a2e080f0e612b34216fe26966c734501dd2633a66417a25144644b96e00440970345939e591503ca660fa76837b6ff365f85d
6
+ metadata.gz: a36160fc23f5953312f4e3e4fb44db4c45bf4f024586e72f397b7c88457284d4a1e2e0705ca83d2c993b04500d5347ea226b3af3889b91d81396ea432e1e4664
7
+ data.tar.gz: 83e9faa1e666f2d503a9d93f8a249b49c03bf4cda7a5b83bbc60df98e4dde0f51fd73086108749266b752dc887047a02e0ddad49b2f4f0a94b02815a3b2bd884
@@ -5,27 +5,22 @@ env:
5
5
  - NOKOGIRI_USE_SYSTEM_LIBRARIES=true
6
6
  - VIPS_VERSION_MAJOR=8
7
7
  - VIPS_VERSION_MINOR=5
8
- - VIPS_VERSION_MICRO=3
8
+ - VIPS_VERSION_MICRO=7
9
9
  - PATH=$HOME/vips/bin:$PATH
10
10
  - LD_LIBRARY_PATH=$HOME/vips/lib:$LD_LIBRARY_PATH
11
11
  - PKG_CONFIG_PATH=$HOME/vips/lib/pkgconfig:$PKG_CONFIG_PATH
12
- - PYTHONPATH=$HOME/vips/lib/python2.7/site-packages:$PYTHONPATH
13
- - GI_TYPELIB_PATH=$HOME/vips/lib/girepository-1.0:$GI_TYPELIB_PATH
14
12
 
15
13
  dist: trusty
16
14
 
17
15
  addons:
18
16
  apt:
19
17
  packages:
20
- - libxml2-dev
18
+ - libexpat1-dev
21
19
  - gettext
22
- - python-dev
23
- - liblcms1-dev
20
+ - liblcms2-dev
24
21
  - libmagickwand-dev
25
22
  - libopenexr-dev
26
23
  - libcfitsio3-dev
27
- - gobject-introspection
28
- - libgirepository1.0-dev
29
24
  - libgif-dev
30
25
  - libgs-dev
31
26
  - libgsf-1-dev
@@ -34,18 +29,20 @@ addons:
34
29
  - liborc-0.4-dev
35
30
  - libpango1.0-dev
36
31
  - libpoppler-glib-dev
32
+ - librsvg2-dev
37
33
  - libwebp-dev
34
+ # missing on trusty, unfortunately
35
+ # - libwebpmux2
36
+ - libfftw3-dev
38
37
  - libglib2.0-dev
39
38
 
40
39
  cache:
41
40
  directories:
42
41
  - $HOME/vips
43
42
 
44
- # gobject-introspection 3.1 declares itself as 2.1 minimum, so we can't test
45
- # 2.0 ... in fact it seems to work if you force it, but I don't think we can do
46
- # that on travis
47
43
  language: ruby
48
44
  rvm:
45
+ - 2.0
49
46
  - 2.1
50
47
  - 2.2
51
48
  - 2.3
@@ -58,4 +55,4 @@ gemfile:
58
55
 
59
56
  before_install:
60
57
  - uname -a
61
- - bash install-vips.sh
58
+ - bash install-vips.sh --without-python
@@ -1,8 +1,12 @@
1
1
  # master
2
2
 
3
+ # Version 2.0.0
4
+
5
+ * rewrite on top of 'ffi' [John Cupitt, Kleis Auke Wolthuizen]
6
+
3
7
  # Version 1.0.6
4
8
 
5
- * remove lazy load, fixing a race with fork() [felixbuenemann]
9
+ * remove lazy load, fixing a race with multi-threading [felixbuenemann]
6
10
  * make `Image#to_a` much faster [John Cupitt]
7
11
  * remove the `at_exit` handler [John Cupitt]
8
12
 
data/README.md CHANGED
@@ -3,12 +3,7 @@
3
3
  [![Gem Version](https://badge.fury.io/rb/ruby-vips.svg)](https://badge.fury.io/rb/ruby-vips)
4
4
  [![Build Status](https://travis-ci.org/jcupitt/ruby-vips.svg?branch=master)](https://travis-ci.org/jcupitt/ruby-vips)
5
5
 
6
- *API break:* version 1.0 of this gem is an API break, see below for some notes
7
- on why there is a break and how to update your code.
8
- The older `ruby-vips` is still here and still maintained in branch
9
- `0.3-stable`.
10
-
11
- This gem provides a Ruby binding for the [vips image processing
6
+ This gem provides a Ruby binding for the [libvips image processing
12
7
  library](https://jcupitt.github.io/libvips).
13
8
 
14
9
  Programs that use `ruby-vips` don't
@@ -17,25 +12,22 @@ operations building on a source image. When the end of the pipe is connected
17
12
  to a destination, the whole pipeline executes at once, streaming the image
18
13
  in parallel from source to destination a section at a time.
19
14
 
20
- Because `ruby-vips` is very parallel, it's quick, and because it doesn't need
21
- to keep entire images in memory, it's light.
22
- For example, the benchmark at
23
- [vips-benchmarks](https://github.com/stanislaw/vips-benchmarks) loads a large
24
- image, crops, shrinks, sharpens and saves again, and repeats 10 times.
15
+ Because `ruby-vips` is parallel, it's quick, and because it doesn't need to
16
+ keep entire images in memory, it's light. For example, the benchmark at
17
+ [vips-benchmarks](https://github.com/jcupitt/vips-benchmarks) loads a
18
+ large image, crops, shrinks, sharpens and saves again, and repeats 10 times.
25
19
 
26
20
  ```text
27
21
  real time in seconds, fastest of three runs
28
- benchmark tiff jpeg
29
- ruby-vips.rb 2.97 3.29
30
- image-magick 8.18 9.71
31
- rmagick.rb 9.22 10.06
32
- image_sci.rb 9.39 7.20
22
+ benchmark tiff jpeg
23
+ ruby-vips.rb 0.66 0.44
24
+ image-magick 1.10 1.50
25
+ rmagick.rb 1.63 2.16
33
26
 
34
27
  peak memory use in bytes
35
28
  benchmark peak RSS
36
- ruby-vips.rb 117604
37
- image_sci.rb 146536
38
- rmagick.rb 3352020
29
+ ruby-vips.rb 58696
30
+ rmagick.rb 787564
39
31
  ```
40
32
 
41
33
  See also [benchmarks at the official libvips
@@ -46,50 +38,32 @@ which gives some more background.
46
38
 
47
39
  ## Requirements
48
40
 
49
- * OS X or Linux
50
- * libvips 8.2 and later
41
+ * macOS, Linux, and Windows tested
51
42
 
52
- ## Installation prerequisites
43
+ * libvips 8.2 or later, see the [libvips install instructions](https://jcupitt.github.io/libvips/install.html)
53
44
 
54
- ### OS X
45
+ * [ruby-ffi](https://github.com/ffi/ffi) 1.9 or later
55
46
 
56
- Install [homebrew](http://mxcl.github.com/homebrew) and enter:
47
+ * Ruby 2.0+, JRuby should work
57
48
 
58
- ```bash
59
- $ brew install homebrew/science/vips
60
- ```
49
+ ## Install
61
50
 
62
- To verify that your vips install is working, try:
51
+ It's just:
63
52
 
64
- ```bash
65
- $ vips --version
66
- vips-8.2.1
67
53
  ```
68
-
69
- ### Other platforms
70
-
71
- Check your package manager and see if the libvips on your system is new enough.
72
- `ruby-vips` needs libvips 8.2 or later.
73
-
74
- If it's too old, you'll need to build libvips from source.
75
- Download a tarball from the
76
- [libvips website](https://jcupitt.github.io/libvips), or build
77
- from [the git repository](https://github.com/jcupitt/libvips) and see the
78
- README.
79
-
80
- ## Installing the gem.
81
-
82
- ```bash
83
- $ gem install ruby-vips
54
+ $ gem install ruby-vips
84
55
  ```
85
56
 
86
- or include it in Gemfile:
57
+ or include it in `Gemfile`:
87
58
 
88
59
  ```ruby
89
60
  gem 'ruby-vips'
90
61
  ```
91
62
 
92
- And take a look in `examples/`. There is full yard documentation, take a look
63
+ On Windows, you'll need to set the `RUBY_DLL_PATH` environment variable to
64
+ point to the libvips bin directory.
65
+
66
+ Take a look in `examples/`. There is full yard documentation, take a look
93
67
  there too.
94
68
 
95
69
  # Example
@@ -103,7 +77,7 @@ im = Vips::Image.new_from_file filename
103
77
  # make the other pixels in the image by mirroring im up / down /
104
78
  # left / right, see
105
79
  # https://jcupitt.github.io/libvips/API/current/libvips-conversion.html#vips-embed
106
- im = im.embed 100, 100, 3000, 3000, :extend => :mirror
80
+ im = im.embed 100, 100, 3000, 3000, extend: :mirror
107
81
 
108
82
  # multiply the green (middle) band by 2, leave the other two alone
109
83
  im *= [1, 2, 1]
@@ -113,76 +87,19 @@ mask = Vips::Image.new_from_array [
113
87
  [-1, -1, -1],
114
88
  [-1, 16, -1],
115
89
  [-1, -1, -1]], 8
116
- im = im.conv mask
90
+ im = im.conv mask, precision: :integer
117
91
 
118
92
  # finally, write the result back to a file on disk
119
93
  im.write_to_file output_filename
120
94
  ```
121
95
 
122
- # Why the API break?
123
-
124
- There's been a `ruby-vips` for a few years now.
125
- It was written by a Ruby
126
- expert, it works well, it includes a test-suite, and has pretty full
127
- documentation. Why rewrite?
128
-
129
- `ruby-vips` 0.3 was based on the old vips7 API. There's now vips8,
130
- which adds several
131
- very useful new features:
132
-
133
- * [GObject](https://developer.gnome.org/gobject/stable/)-based API with full
134
- introspection. You can discover the vips8 API at runtime. This means that if
135
- libvips gets a new operator, any binding that goes via vips8 will
136
- get the new thing immediately. With vips7, whenever libvips was changed, all
137
- the bindings needed to be changed too.
138
-
139
- * No C required. Thanks to
140
- [gobject-introspection](https://wiki.gnome.org/Projects/GObjectIntrospection)
141
- you can write the binding in Ruby itself, there's no need for any C. This
142
- makes it a lot smaller and more portable.
143
-
144
- * vips7 probably won't get new features. vips7 doesn't really exist any more:
145
- the API is still there, but now just a thin compatibility layer over vips8.
146
- New features may well not get added to the vips7 API.
147
-
148
- There are some more minor pluses as well:
149
-
150
- * Named and optional arguments. vips8 lets you have optional and required
151
- arguments, both input and output, and optional arguments can have default
152
- values.
153
-
154
- * Operation cache. vips8 keeps track of the last 1,000 or so operations and
155
- will automatically reuse results when it can. This can give a huge speedup
156
- in some cases.
157
-
158
- * vips8 is much simpler and more regular. For example,
159
- ruby-vips had to work hard to offer a nice loader system, but that's all
160
- built into vips8. It can do things like load and save formatted images to
161
- and from memory buffers as well, which just wasn't possible before.
162
-
163
- This binding adds some extra useful features over the old `ruby-vips` binding.
164
-
165
- * Full set of arithmetic operator overloads.
166
-
167
- * Automatic constant expansion. You can write things like
168
- `image.bandjoin(255)` and the 255 will be automatically expanded to an image
169
- and attached as an extra band. You can mix int, float, scalar, vector and
170
- image constants freely.
171
-
172
- # How to update your code
173
-
174
- * `VIPS::` becomes `Vips::`
175
-
176
- * `VIPS::Image.new(filename)` becomes `Vips::Image.new_from_file(filename)`.
177
- `VIPS::Image.jpeg(filename)` also becomes
178
- `Vips::Image.new_from_file(filename)`, similarly for other formats.
96
+ # Older versions
179
97
 
180
- * `#write(filename)` becomes `#write_to_file(filename)`. `#png(filename)` also
181
- becomes `#write_to_file(filename)`, same for all other
182
- formats.
98
+ There are two older versions of this gem.
183
99
 
184
- * Most member functions are unchanged, but check the yard docs. You can also
185
- use the C docs directly, since `ruby-vips` is now a very thin layer over the
186
- C API. See the docs for the `Vips` class for guidance.
100
+ The `0.3-stable` branch is written in C and supports a different API. It still
101
+ works, but is only maintained for compatibility.
187
102
 
188
- * There are lots of nice new features, see the docs and examples.
103
+ The `1.0-stable` branch is based on `gobject-introspection` rather than
104
+ `ffi`. It supports the same API as the current version, but is harder to
105
+ install, less portable, slower, and less stable.
data/TODO CHANGED
@@ -1,11 +1,5 @@
1
1
  # Notes
2
2
 
3
- - mail about the getpoint unimplemented error
4
-
5
- http://sourceforge.net/p/ruby-gnome2/mailman/ruby-gnome2-devel-en/thread/CAGNS0RuZ5N6bha3M7B0%2BYf2M9-oni44idzZO17mtQiykS%2BmJKQ%40mail.gmail.com/#msg34790843
6
-
7
- - still missing a few enum docs
8
-
9
3
  - support complex constants, eg.
10
4
 
11
5
  Complex(1, 2)
@@ -28,3 +22,7 @@
28
22
  - push new gem to rubygems, tag repository with version
29
23
 
30
24
  bundle exec rake release
25
+
26
+ - regenerate docs
27
+
28
+ bundle exec rake yard
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.6
1
+ 2.0.0
@@ -0,0 +1,286 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'ffi'
4
+ require 'forwardable'
5
+
6
+ # this is really very crude logging
7
+
8
+ # @private
9
+ $vips_debug = true
10
+
11
+ # @private
12
+ def log str
13
+ if $vips_debug
14
+ puts str
15
+ end
16
+ end
17
+
18
+ def set_debug debug
19
+ $vips_debug = debug
20
+ end
21
+
22
+ module Libc
23
+ extend FFI::Library
24
+ ffi_lib FFI::Library::LIBC
25
+
26
+ attach_function :malloc, [:size_t], :pointer
27
+ attach_function :free, [:pointer], :void
28
+ end
29
+
30
+ module GLib
31
+ extend FFI::Library
32
+ ffi_lib 'gobject-2.0'
33
+
34
+ # nil being the default
35
+ glib_log_domain = nil
36
+
37
+ def self.set_log_domain(domain)
38
+ glib_log_domain = domain
39
+ end
40
+
41
+ # we have a set of things we need to inherit in different ways:
42
+ #
43
+ # - we want to be able to subclass GObject in a simple way
44
+ # - the layouts of the nested structs
45
+ # - casting between structs which share a base
46
+ # - gobject refcounting
47
+ #
48
+ # the solution is to split the class into four areas which we treat
49
+ # differently:
50
+ #
51
+ # - we have a "wrapper" Ruby class to allow easy subclassing ... this has a
52
+ # @struct member which holds the actual pointer
53
+ # - we use "forwardable" to forward the various ffi methods on to the
54
+ # @struct member ... we arrange things so that subclasses do not need to
55
+ # do the forwarding themselves
56
+ # - we have two versions of the struct: a plain one which we can use for
57
+ # casting that will not change the refcounts
58
+ # - and a managed one with an unref which we just use for .new
59
+ # - we separate the struct layout into a separate module to avoid repeating
60
+ # ourselves
61
+
62
+ class GObject
63
+ extend Forwardable
64
+ extend SingleForwardable
65
+
66
+ def_instance_delegators :@struct, :[], :to_ptr
67
+ def_single_delegators :ffi_struct, :ptr
68
+
69
+ # the layout of the GObject struct
70
+ module GObjectLayout
71
+ def self.included(base)
72
+ base.class_eval do
73
+ layout :g_type_instance, :pointer,
74
+ :ref_count, :uint,
75
+ :qdata, :pointer
76
+ end
77
+ end
78
+ end
79
+
80
+ # the struct with unref ... manage object lifetime with this
81
+ class ManagedStruct < FFI::ManagedStruct
82
+ include GObjectLayout
83
+
84
+ def initialize(ptr)
85
+ log "GLib::GObject::ManagedStruct.new: #{ptr}"
86
+ super
87
+ end
88
+
89
+ def self.release(ptr)
90
+ log "GLib::GObject::ManagedStruct.release: unreffing #{ptr}"
91
+ GLib::g_object_unref(ptr) unless ptr.null?
92
+ end
93
+
94
+ end
95
+
96
+ # the plain struct ... cast with this
97
+ class Struct < FFI::Struct
98
+ include GObjectLayout
99
+
100
+ def initialize(ptr)
101
+ log "GLib::GObject::Struct.new: #{ptr}"
102
+ super
103
+ end
104
+
105
+ end
106
+
107
+ # don't allow ptr == nil, we never want to allocate a GObject struct
108
+ # ourselves, we just want to wrap GLib-allocated GObjects
109
+ #
110
+ # here we use ManagedStruct, not Struct, since this is the ref that will
111
+ # need the unref
112
+ def initialize(ptr)
113
+ log "GLib::GObject.initialize: ptr = #{ptr}"
114
+ @struct = ffi_managed_struct.new(ptr)
115
+ end
116
+
117
+ # access to the cast struct for this class
118
+ def ffi_struct
119
+ self.class.ffi_struct
120
+ end
121
+
122
+ class << self
123
+ def ffi_struct
124
+ self.const_get(:Struct)
125
+ end
126
+ end
127
+
128
+ # access to the lifetime managed struct for this class
129
+ def ffi_managed_struct
130
+ self.class.ffi_managed_struct
131
+ end
132
+
133
+ class << self
134
+ def ffi_managed_struct
135
+ self.const_get(:ManagedStruct)
136
+ end
137
+ end
138
+
139
+ end
140
+
141
+ # :gtype will usually be 64-bit, but will be 32-bit on 32-bit Windows
142
+ typedef :ulong, :GType
143
+
144
+ end
145
+
146
+ module Vips
147
+ extend FFI::Library
148
+ ffi_lib 'vips'
149
+
150
+ LOG_DOMAIN = "VIPS"
151
+ GLib::set_log_domain(LOG_DOMAIN)
152
+
153
+ # need to repeat this
154
+ typedef :ulong, :GType
155
+
156
+ attach_function :vips_init, [:string], :int
157
+ attach_function :vips_shutdown, [], :void
158
+
159
+ attach_function :vips_error_buffer, [], :string
160
+ attach_function :vips_error_clear, [], :void
161
+
162
+ def self.get_error
163
+ errstr = Vips::vips_error_buffer
164
+ Vips::vips_error_clear
165
+ errstr
166
+ end
167
+
168
+ if Vips::vips_init($0) != 0
169
+ puts Vips::get_error
170
+ exit 1
171
+ end
172
+
173
+ at_exit {
174
+ Vips::vips_shutdown
175
+ }
176
+
177
+ attach_function :vips_object_print_all, [], :void
178
+ attach_function :vips_leak_set, [:int], :void
179
+
180
+ def self.showall
181
+ if $vips_debug
182
+ GC.start
183
+ vips_object_print_all
184
+ end
185
+ end
186
+
187
+ if $vips_debug
188
+ vips_leak_set 1
189
+ end
190
+
191
+ class VipsObject < GLib::GObject
192
+
193
+ # the layout of the VipsObject struct
194
+ module VipsObjectLayout
195
+ def self.included(base)
196
+ base.class_eval do
197
+ # don't actually need most of these, remove them later
198
+ layout :parent, GLib::GObject::Struct,
199
+ :constructed, :int,
200
+ :static_object, :int,
201
+ :argument_table, :pointer,
202
+ :nickname, :string,
203
+ :description, :string,
204
+ :preclose, :int,
205
+ :close, :int,
206
+ :postclose, :int,
207
+ :local_memory, :size_t
208
+ end
209
+ end
210
+ end
211
+
212
+ class Struct < GLib::GObject::Struct
213
+ include VipsObjectLayout
214
+
215
+ def initialize(ptr)
216
+ log "Vips::VipsObject::Struct.new: #{ptr}"
217
+ super
218
+ end
219
+
220
+ end
221
+
222
+ class ManagedStruct < GLib::GObject::ManagedStruct
223
+ include VipsObjectLayout
224
+
225
+ def initialize(ptr)
226
+ log "Vips::VipsObject::ManagedStruct.new: #{ptr}"
227
+ super
228
+ end
229
+
230
+ end
231
+
232
+ end
233
+
234
+ class VipsImage < VipsObject
235
+
236
+ # the layout of the VipsImage struct
237
+ module VipsImageLayout
238
+ def self.included(base)
239
+ base.class_eval do
240
+ layout :parent, VipsObject::Struct
241
+ # rest opaque
242
+ end
243
+ end
244
+ end
245
+
246
+ class Struct < VipsObject::Struct
247
+ include VipsImageLayout
248
+
249
+ def initialize(ptr)
250
+ log "Vips::VipsImage::Struct.new: #{ptr}"
251
+ super
252
+ end
253
+
254
+ end
255
+
256
+ class ManagedStruct < VipsObject::ManagedStruct
257
+ include VipsImageLayout
258
+
259
+ def initialize(ptr)
260
+ log "Vips::VipsImage::ManagedStruct.new: #{ptr}"
261
+ super
262
+ end
263
+
264
+ end
265
+
266
+ def self.new_partial
267
+ VipsImage.new(Vips::vips_image_new)
268
+ end
269
+
270
+ end
271
+
272
+ attach_function :vips_image_new, [], :pointer
273
+
274
+ end
275
+
276
+ puts "creating image"
277
+ begin
278
+ x = Vips::VipsImage.new_partial
279
+ puts "x = #{x}"
280
+ puts ""
281
+ puts "x[:parent] = #{x[:parent]}"
282
+ puts ""
283
+ puts "x[:parent][:description] = #{x[:parent][:description]}"
284
+ puts ""
285
+ end
286
+