ruby-vips 1.0.2 → 1.0.3

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: 5bfef1f0c49c2977f9561ace1a05cdd74c3e43bc
4
- data.tar.gz: 135f092e8c9294be05a841b17f1ddb32070192ba
3
+ metadata.gz: f9821647ddcaaa31442cb2f6ce3b488004bfecd1
4
+ data.tar.gz: 77f02bd4c937b0b08d78419878728a2d62e47293
5
5
  SHA512:
6
- metadata.gz: c105a43796733f2512eaa627e5d63aa71e1edffd616fed682782a388283033f7ed90be3747a970b872686f8a84a9718aedcaad75c3b23612571f9c1abd14fa4c
7
- data.tar.gz: 282d2ad30057efd9a78f4e183a1d3833c4abd56fba1f111819f536b029c961d6ae302c4a0fa6f0715521a3929b1be1a3fd32de5f445455e74815e1941914eea5
6
+ metadata.gz: a7e07153fe581bb27cb56533e3274abdb3dca1bcc95e33e964606c35ed8aa3ad1007131fee4d2d5543bc704dc52ec52ff90f160ee71da996d2f59fc74b90a3e0
7
+ data.tar.gz: 865c2cc4d66b7ea6359225f36f9ae6c17274e1c4e0c34f54efc0a6cdce457cbe72fdb7388692b6c5836ef4c24ee243d26b9d1b9383078d0d2d38b2e65a441384
@@ -1,6 +1,15 @@
1
1
  # master
2
2
 
3
- # Version 1.0.1
3
+ # Version 1.0.3
4
+
5
+ * doc improvements [John Cupitt]
6
+ * add #size to get [width, height] [John Cupitt]
7
+ * only ask for ruby 2.0 to help OS X [John Cupitt]
8
+ * break up Image.call to make it easier to understand [John Cupitt]
9
+ * detect operation build fail correctly [John Cupitt]
10
+ * lock gobject-introspection at 3.0.8 to avoid breakage [John Cupitt]
11
+
12
+ # Version 1.0.2
4
13
 
5
14
  * add .yardopts to fix ruby-gems docs [John Cupitt]
6
15
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.2
1
+ 1.0.3
@@ -1,225 +1,281 @@
1
1
  module Vips
2
2
 
3
- # call a vips operation ... this will crash if there's a GC during the call,
4
- # I've really no idea why :-(
3
+ # Call a vips operation.
5
4
  #
6
- # Workaround: don't call this directly, use call_base (see below) instead.
7
- # This will disable the GC, call this operation, then reenable it.
5
+ # This will crash if there's a GC during the call, only use
6
+ # this via {Vips.call}.
7
+ private
8
+ class Call
9
+ attr_writer :instance, :option_string
10
+
11
+ def initialize(name, supplied_values)
12
+ @name = name
13
+ @supplied_values = supplied_values
14
+ @instance = nil
15
+ @option_string = nil
16
+
17
+ if @supplied_values.last.is_a? Hash
18
+ @optional_values = @supplied_values.last
19
+ @supplied_values.delete_at -1
20
+ else
21
+ @optional_values = {}
22
+ end
8
23
 
9
- private
10
- def self.call_base_nogc(name, instance, option_string, supplied_values)
11
- log "in Vips::call_base"
12
- log "name = #{name}"
13
- log "instance = #{instance}"
14
- log "option_string = #{option_string}"
15
- log "supplied_values are:"
16
- supplied_values.each {|x| log " #{x}"}
17
-
18
- if supplied_values.last.is_a? Hash
19
- optional_values = supplied_values.last
20
- supplied_values.delete_at -1
21
- else
22
- optional_values = {}
23
- end
24
+ begin
25
+ @op = Vips::Operation.new @name
26
+ rescue
27
+ raise Vips::Error, "no operator '#{@name}'"
28
+ end
24
29
 
25
- begin
26
- op = Vips::Operation.new name
27
- rescue
28
- raise Vips::Error, "no operator '#{name}'"
30
+ log "Vips::Call.init"
31
+ log "name = #{@name}"
32
+ log "supplied_values are:"
33
+ @supplied_values.each {|x| log " #{x}"}
34
+ log "optional_values are:"
35
+ @optional_values.each {|x| log " #{x}"}
29
36
  end
30
37
 
31
- # set string options first
32
- log "setting string options ..."
33
- if option_string
34
- if op.set_from_string(option_string) != 0
35
- raise Error
38
+ # set any string options on the operation
39
+ def set_string_args
40
+ if @option_string
41
+ log "setting string options #{@option_string} ..."
42
+
43
+ if @op.set_from_string(@option_string) != 0
44
+ raise Error
45
+ end
36
46
  end
37
47
  end
38
48
 
39
- all_args = op.get_args
40
-
41
- # the instance, if supplied, must be a vips image ... we use it for
42
- # match_image, below
43
- if instance and not instance.is_a? Vips::Image
44
- raise Vips::Error, "@instance is not a Vips::Image."
45
- end
49
+ # set @match_image to be the image we build constants to match
50
+ def find_match_image
51
+ # the instance, if supplied, must be a vips image ... we use it for
52
+ # match_image, below
53
+ if @instance and not @instance.is_a? Vips::Image
54
+ raise Vips::Error, "@instance is not a Vips::Image."
55
+ end
46
56
 
47
- # if the op needs images but the user supplies constants, we expand
48
- # them to match the first input image argument ... find the first
49
- # image
50
- log "searching for first image argument ..."
51
- match_image = instance
52
- if match_image == nil
53
- match_image = supplied_values.find {|x| x.is_a? Vips::Image}
54
- end
55
- if match_image == nil
56
- match = optional_values.find do |name, value|
57
- value.is_a? Vips::Image
57
+ # if the op needs images but the user supplies constants, we expand
58
+ # them to match the first input image argument ... find the first
59
+ # image
60
+ log "searching for first image argument ..."
61
+ match_image = @instance
62
+ if match_image == nil
63
+ match_image = @supplied_values.find {|x| x.is_a? Vips::Image}
58
64
  end
59
- # if we found a match, it'll be [name, value]
60
- if match
61
- match_image = match[1]
65
+ if match_image == nil
66
+ match = @optional_values.find do |name, value|
67
+ value.is_a? Vips::Image
68
+ end
69
+ # if we found a match, it'll be [name, value]
70
+ if match
71
+ match_image = match[1]
72
+ end
62
73
  end
63
- end
64
74
 
65
- # find unassigned required input args
66
- log "finding unassigned required input arguments ..."
67
- required_input = all_args.select do |arg|
68
- not arg.isset and
69
- (arg.flags & :input) != 0 and
70
- (arg.flags & :required) != 0
75
+ return match_image
71
76
  end
72
77
 
73
- # do we have a non-nil instance? set the first image arg with this
74
- if instance != nil
75
- log "setting first image arg with instance ..."
76
- x = required_input.find do |arg|
77
- gtype = GLib::Type["VipsImage"]
78
- vtype = arg.prop.value_type
78
+ # look through the operation args and find required and optional
79
+ # input args
80
+ def find_input
81
+ all_args = @op.get_args
79
82
 
80
- vtype.type_is_a? gtype
83
+ # find unassigned required input args
84
+ log "finding unassigned required input arguments ..."
85
+ required_input = all_args.select do |arg|
86
+ not arg.isset and
87
+ (arg.flags & :input) != 0 and
88
+ (arg.flags & :required) != 0
81
89
  end
82
- if x == nil
83
- raise Vips::Error,
84
- "No #{instance.class} argument to #{name}."
90
+
91
+ # find optional unassigned input args
92
+ log "finding optional unassigned input arguments ..."
93
+ optional_input = all_args.select do |arg|
94
+ not arg.isset and
95
+ (arg.flags & :input) != 0 and
96
+ (arg.flags & :required) == 0
85
97
  end
86
- x.set_value match_image, instance
87
- required_input.delete x
88
- end
89
98
 
90
- if required_input.length != supplied_values.length
91
- raise Vips::Error,
92
- "Wrong number of arguments. '#{name}' requires " +
93
- "#{required_input.length} arguments, you supplied " +
94
- "#{supplied_values.length}."
95
- end
99
+ # make a hash from name to arg for the options
100
+ optional_input = Hash[
101
+ optional_input.map(&:name).zip(optional_input)]
96
102
 
97
- log "setting required input arguments ..."
98
- required_input.zip(supplied_values).each do |arg, value|
99
- arg.set_value match_image, value
103
+ return required_input, optional_input
100
104
  end
101
105
 
102
- # find optional unassigned input args
103
- log "finding optional unassigned input arguments ..."
104
- optional_input = all_args.select do |arg|
105
- not arg.isset and
106
- (arg.flags & :input) != 0 and
107
- (arg.flags & :required) == 0
108
- end
106
+ def find_optional_output
107
+ all_args = @op.get_args
108
+
109
+ log "finding optional output arguments ..."
110
+ optional_output = all_args.select do |arg|
111
+ (arg.flags & :output) != 0 and
112
+ (arg.flags & :required) == 0
113
+ end
114
+ optional_output = Hash[
115
+ optional_output.map(&:name).zip(optional_output)]
109
116
 
110
- # make a hash from name to arg
111
- optional_input = Hash[
112
- optional_input.map(&:name).zip(optional_input)]
117
+ return optional_output
113
118
 
114
- # find optional unassigned output args
115
- log "finding optional unassigned output arguments ..."
116
- optional_output = all_args.select do |arg|
117
- not arg.isset and
118
- (arg.flags & :output) != 0 and
119
- (arg.flags & :required) == 0
120
119
  end
121
- optional_output = Hash[
122
- optional_output.map(&:name).zip(optional_output)]
123
-
124
- # set all optional args
125
- log "setting optional values ..."
126
- optional_values.each do |name, value|
127
- # we are passed symbols as keys
128
- name = name.to_s
129
- if optional_input.has_key? name
130
- log "setting #{name} to #{value}"
131
- optional_input[name].set_value match_image, value
132
- elsif optional_output.has_key? name and value != true
120
+
121
+ def set_required_input(match_image, required_input)
122
+ # do we have a non-nil instance? set the first image arg with this
123
+ if @instance != nil
124
+ log "setting first image arg with instance ..."
125
+ x = required_input.find do |arg|
126
+ gtype = GLib::Type["VipsImage"]
127
+ vtype = arg.prop.value_type
128
+
129
+ vtype.type_is_a? gtype
130
+ end
131
+ if x == nil
132
+ raise Vips::Error,
133
+ "No #{@instance.class} argument to #{@name}."
134
+ end
135
+ x.set_value match_image, @instance
136
+ required_input.delete x
137
+ end
138
+
139
+ if required_input.length != @supplied_values.length
133
140
  raise Vips::Error,
134
- "Optional output argument #{name} must be true."
135
- elsif not optional_output.has_key? name
136
- raise Vips::Error, "No such option '#{name}',"
141
+ "Wrong number of arguments. '#{@name}' requires " +
142
+ "#{required_input.length} arguments, you supplied " +
143
+ "#{@supplied_values.length}."
144
+ end
145
+
146
+ log "setting required input arguments ..."
147
+ required_input.zip(@supplied_values).each do |arg, value|
148
+ arg.set_value match_image, value
149
+ end
150
+
151
+ end
152
+
153
+ def set_optional_input(match_image, optional_input, optional_output)
154
+ log "setting optional input args ..."
155
+ @optional_values.each do |name, value|
156
+ # we are passed symbols as keys
157
+ name = name.to_s
158
+ if optional_input.has_key? name
159
+ log "setting #{name} to #{value}"
160
+ optional_input[name].set_value match_image, value
161
+ elsif optional_output.has_key? name and value != true
162
+ raise Vips::Error,
163
+ "Optional output argument #{name} must be true."
164
+ elsif not optional_output.has_key? name
165
+ raise Vips::Error, "No such option '#{name}',"
166
+ end
137
167
  end
138
168
  end
139
169
 
140
- log "building ..."
170
+ def build
171
+ log "building ..."
141
172
 
142
- op2 = Vips::cache_operation_lookup op
143
- if op2
144
- log "cache hit"
145
- op = op2
173
+ op2 = Vips::cache_operation_lookup @op
174
+ if op2
175
+ log "cache hit"
146
176
 
147
- all_args = op.get_args
177
+ hit = true
178
+ @op = op2
179
+ else
180
+ log "cache miss ... building"
148
181
 
149
- # find optional output args
150
- optional_output = all_args.select do |arg|
151
- (arg.flags & :output) != 0 and
152
- (arg.flags & :required) == 0
153
- end
154
- optional_output = Hash[
155
- optional_output.map(&:name).zip(optional_output)]
156
- else
157
- log "cache miss ... building"
158
- if not op.build
159
- raise Vips::Error
182
+ hit = false
183
+ if @op.build() != 0
184
+ raise Vips::Error
185
+ end
186
+ # showall
187
+
188
+ log "adding to cache ... "
189
+ Vips::cache_operation_add @op
160
190
  end
161
- showall
162
191
 
163
- log "adding to cache ... "
164
- Vips::cache_operation_add op
192
+ return hit
165
193
  end
166
194
 
167
- log "fetching outputs ..."
168
-
169
- # gather output args
170
- out = []
195
+ def fetch_output(optional_output)
196
+ log "fetching outputs ..."
197
+
198
+ # gather output args
199
+ out = []
200
+
201
+ all_args = @op.get_args
202
+ all_args.each do |arg|
203
+ # required output
204
+ if (arg.flags & :output) != 0 and
205
+ (arg.flags & :required) != 0
206
+ log "fetching required output #{arg.name}"
207
+ out << arg.get_value
208
+ end
209
+
210
+ # modified input arg ... this will get the result of the
211
+ # copy() we did in Argument.set_value
212
+ if (arg.flags & :input) != 0 and
213
+ (arg.flags & :modify) != 0
214
+ log "fetching modified input arg ..."
215
+ out << arg.get_value
216
+ end
217
+ end
171
218
 
172
- all_args.each do |arg|
173
- # required output
174
- if (arg.flags & :output) != 0 and
175
- (arg.flags & :required) != 0
176
- log "fetching required output #{arg.name}"
177
- out << arg.get_value
219
+ opts = {}
220
+ @optional_values.each do |name, value|
221
+ # we are passed symbols as keys
222
+ name = name.to_s
223
+ if optional_output.has_key? name
224
+ log "fetching optional output arg ..."
225
+ opts[name] = optional_output[name].get_value
226
+ end
178
227
  end
228
+ out << opts if opts != {}
179
229
 
180
- # modified input arg ... this will get the result of the
181
- # copy() we did in Argument.set_value above
182
- if (arg.flags & :input) != 0 and
183
- (arg.flags & :modify) != 0
184
- log "fetching modified input arg ..."
185
- out << arg.get_value
230
+ if out.length == 1
231
+ out = out[0]
232
+ elsif out.length == 0
233
+ out = nil
186
234
  end
235
+
236
+ return out
237
+
187
238
  end
188
239
 
189
- opts = {}
190
- optional_values.each do |name, value|
191
- # we are passed symbols as keys
192
- name = name.to_s
193
- if optional_output.has_key? name
194
- log "fetching optional output arg ..."
195
- opts[name] = optional_output[name].get_value
240
+ def invoke
241
+ set_string_args()
242
+ match_image = find_match_image()
243
+ required_input, optional_input = find_input()
244
+ optional_output = find_optional_output()
245
+
246
+ set_required_input(match_image, required_input)
247
+ set_optional_input(match_image, optional_input, optional_output)
248
+
249
+ hit = build()
250
+
251
+ # if there was a cache hit, we need to refind this since all the arg
252
+ # pointers will have changed
253
+ if hit
254
+ optional_output = find_optional_output()
196
255
  end
197
- end
198
- out << opts if opts != {}
256
+ out = fetch_output(optional_output)
199
257
 
200
- if out.length == 1
201
- out = out[0]
202
- elsif out.length == 0
203
- out = nil
204
- end
258
+ log "unreffing outputs ..."
259
+ @op.unref_outputs()
260
+ @op = nil
261
+ # showall
205
262
 
206
- log "unreffing outputs ..."
207
- op.unref_outputs
208
- op = nil
209
- # showall
263
+ log "success! #{@name}.out = #{out}"
210
264
 
211
- log "success! #{name}.out = #{out}"
265
+ return out
266
+ end
212
267
 
213
- return out
214
268
  end
215
269
 
216
- # run call_base_nogc, with the GC disabled
270
+ # full-fat call, with the GC disabled
217
271
  private
218
272
  def self.call_base(name, instance, option_string, supplied_values)
219
273
  gc_was_enabled = GC.disable
220
274
  begin
221
- result = call_base_nogc name, instance,
222
- option_string, supplied_values
275
+ call = Call.new(name, supplied_values)
276
+ call.instance = instance
277
+ call.option_string = option_string
278
+ result = call.invoke
223
279
  ensure
224
280
  GC.enable if gc_was_enabled
225
281
  end
@@ -283,7 +339,7 @@ module Vips
283
339
  # y = x % [1]
284
340
  # ```
285
341
  #
286
- # Similarly, whereever an image is required, you can use a constant. The
342
+ # Similarly, wherever an image is required, you can use a constant. The
287
343
  # constant will be expanded to an image matching the first input image
288
344
  # argument. For example, you can write:
289
345
  #
@@ -296,7 +352,15 @@ module Vips
296
352
  # the constant value 255.
297
353
 
298
354
  def self.call(name, *args)
299
- Vips::call_base name, nil, "", args
355
+ gc_was_enabled = GC.disable
356
+ begin
357
+ call = Call.new(name, args)
358
+ result = call.invoke
359
+ ensure
360
+ GC.enable if gc_was_enabled
361
+ end
362
+
363
+ return result
300
364
  end
301
365
 
302
366
  end