vips 8.7.0.1 → 8.8.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +25 -22
  3. data/CHANGELOG.md +266 -0
  4. data/example/annotate.rb +2 -2
  5. data/example/daltonize8.rb +14 -14
  6. data/example/example2.rb +6 -6
  7. data/example/example3.rb +5 -5
  8. data/example/example4.rb +4 -4
  9. data/example/example5.rb +2 -2
  10. data/example/inheritance_with_refcount.rb +207 -207
  11. data/example/thumb.rb +10 -10
  12. data/example/trim8.rb +2 -2
  13. data/example/watermark.rb +14 -35
  14. data/example/wobble.rb +24 -24
  15. data/lib/vips.rb +335 -306
  16. data/lib/vips/access.rb +9 -9
  17. data/lib/vips/align.rb +7 -7
  18. data/lib/vips/angle.rb +8 -8
  19. data/lib/vips/angle45.rb +12 -12
  20. data/lib/vips/bandformat.rb +16 -16
  21. data/lib/vips/blend_mode.rb +34 -0
  22. data/lib/vips/coding.rb +11 -11
  23. data/lib/vips/compass_direction.rb +13 -13
  24. data/lib/vips/direction.rb +7 -7
  25. data/lib/vips/extend.rb +13 -13
  26. data/lib/vips/gobject.rb +94 -94
  27. data/lib/vips/gvalue.rb +232 -232
  28. data/lib/vips/image.rb +1329 -1327
  29. data/lib/vips/interesting.rb +10 -10
  30. data/lib/vips/interpolate.rb +51 -51
  31. data/lib/vips/interpretation.rb +25 -25
  32. data/lib/vips/kernel.rb +18 -18
  33. data/lib/vips/methods.rb +2226 -2139
  34. data/lib/vips/object.rb +208 -208
  35. data/lib/vips/operation.rb +323 -321
  36. data/lib/vips/operationboolean.rb +10 -10
  37. data/lib/vips/operationcomplex.rb +8 -8
  38. data/lib/vips/operationcomplex2.rb +6 -6
  39. data/lib/vips/operationcomplexget.rb +7 -7
  40. data/lib/vips/operationmath.rb +14 -14
  41. data/lib/vips/operationmath2.rb +6 -6
  42. data/lib/vips/operationrelational.rb +11 -11
  43. data/lib/vips/operationround.rb +7 -7
  44. data/lib/vips/size.rb +9 -9
  45. data/lib/vips/version.rb +1 -1
  46. data/vips.gemspec +1 -1
  47. metadata +9 -8
data/lib/vips/object.rb CHANGED
@@ -7,237 +7,237 @@
7
7
  require 'ffi'
8
8
 
9
9
  module Vips
10
- private
11
-
12
- # debugging support
13
- attach_function :vips_object_print_all, [], :void
14
-
15
- # we must init these by hand, since they are usually made on first image
16
- # create
17
- attach_function :vips_band_format_get_type, [], :GType
18
- attach_function :vips_interpretation_get_type, [], :GType
19
- attach_function :vips_coding_get_type, [], :GType
20
-
21
- public
22
-
23
- # some handy gtypes
24
- IMAGE_TYPE = GObject::g_type_from_name "VipsImage"
25
- ARRAY_INT_TYPE = GObject::g_type_from_name "VipsArrayInt"
26
- ARRAY_DOUBLE_TYPE = GObject::g_type_from_name "VipsArrayDouble"
27
- ARRAY_IMAGE_TYPE = GObject::g_type_from_name "VipsArrayImage"
28
- REFSTR_TYPE = GObject::g_type_from_name "VipsRefString"
29
- BLOB_TYPE = GObject::g_type_from_name "VipsBlob"
30
-
31
- BAND_FORMAT_TYPE = Vips::vips_band_format_get_type
32
- INTERPRETATION_TYPE = Vips::vips_interpretation_get_type
33
- CODING_TYPE = Vips::vips_coding_get_type
34
-
35
- if Vips::at_least_libvips?(8, 6)
36
- attach_function :vips_blend_mode_get_type, [], :GType
37
- BLEND_MODE_TYPE = Vips::vips_blend_mode_get_type
38
- else
39
- BLEND_MODE_TYPE = nil
10
+ private
11
+
12
+ # debugging support
13
+ attach_function :vips_object_print_all, [], :void
14
+
15
+ # we must init these by hand, since they are usually made on first image
16
+ # create
17
+ attach_function :vips_band_format_get_type, [], :GType
18
+ attach_function :vips_interpretation_get_type, [], :GType
19
+ attach_function :vips_coding_get_type, [], :GType
20
+
21
+ public
22
+
23
+ # some handy gtypes
24
+ IMAGE_TYPE = GObject::g_type_from_name "VipsImage"
25
+ ARRAY_INT_TYPE = GObject::g_type_from_name "VipsArrayInt"
26
+ ARRAY_DOUBLE_TYPE = GObject::g_type_from_name "VipsArrayDouble"
27
+ ARRAY_IMAGE_TYPE = GObject::g_type_from_name "VipsArrayImage"
28
+ REFSTR_TYPE = GObject::g_type_from_name "VipsRefString"
29
+ BLOB_TYPE = GObject::g_type_from_name "VipsBlob"
30
+
31
+ BAND_FORMAT_TYPE = Vips::vips_band_format_get_type
32
+ INTERPRETATION_TYPE = Vips::vips_interpretation_get_type
33
+ CODING_TYPE = Vips::vips_coding_get_type
34
+
35
+ if Vips::at_least_libvips?(8, 6)
36
+ attach_function :vips_blend_mode_get_type, [], :GType
37
+ BLEND_MODE_TYPE = Vips::vips_blend_mode_get_type
38
+ else
39
+ BLEND_MODE_TYPE = nil
40
+ end
41
+
42
+ private
43
+
44
+ attach_function :vips_enum_from_nick, [:string, :GType, :string], :int
45
+ attach_function :vips_enum_nick, [:GType, :int], :string
46
+
47
+ attach_function :vips_value_set_ref_string,
48
+ [GObject::GValue.ptr, :string], :void
49
+ attach_function :vips_value_set_array_double,
50
+ [GObject::GValue.ptr, :pointer, :int], :void
51
+ attach_function :vips_value_set_array_int,
52
+ [GObject::GValue.ptr, :pointer, :int], :void
53
+ attach_function :vips_value_set_array_image,
54
+ [GObject::GValue.ptr, :int], :void
55
+ callback :free_fn, [:pointer], :void
56
+ attach_function :vips_value_set_blob,
57
+ [GObject::GValue.ptr, :free_fn, :pointer, :size_t], :void
58
+
59
+ class SizeStruct < FFI::Struct
60
+ layout :value, :size_t
61
+ end
62
+
63
+ class IntStruct < FFI::Struct
64
+ layout :value, :int
65
+ end
66
+
67
+ attach_function :vips_value_get_ref_string,
68
+ [GObject::GValue.ptr, SizeStruct.ptr], :string
69
+ attach_function :vips_value_get_array_double,
70
+ [GObject::GValue.ptr, IntStruct.ptr], :pointer
71
+ attach_function :vips_value_get_array_int,
72
+ [GObject::GValue.ptr, IntStruct.ptr], :pointer
73
+ attach_function :vips_value_get_array_image,
74
+ [GObject::GValue.ptr, IntStruct.ptr], :pointer
75
+ attach_function :vips_value_get_blob,
76
+ [GObject::GValue.ptr, SizeStruct.ptr], :pointer
77
+
78
+ attach_function :type_find, :vips_type_find, [:string, :string], :GType
79
+
80
+ class Object < GObject::GObject
81
+
82
+ # print all active VipsObjects, with their reference counts. Handy for
83
+ # debugging ruby-vips.
84
+ def self.print_all
85
+ GC.start
86
+ Vips::vips_object_print_all
40
87
  end
41
88
 
42
- private
43
-
44
- attach_function :vips_enum_from_nick, [:string, :GType, :string], :int
45
- attach_function :vips_enum_nick, [:GType, :int], :string
46
-
47
- attach_function :vips_value_set_ref_string,
48
- [GObject::GValue.ptr, :string], :void
49
- attach_function :vips_value_set_array_double,
50
- [GObject::GValue.ptr, :pointer, :int], :void
51
- attach_function :vips_value_set_array_int,
52
- [GObject::GValue.ptr, :pointer, :int], :void
53
- attach_function :vips_value_set_array_image,
54
- [GObject::GValue.ptr, :int], :void
55
- callback :free_fn, [:pointer], :void
56
- attach_function :vips_value_set_blob,
57
- [GObject::GValue.ptr, :free_fn, :pointer, :size_t], :void
58
-
59
- class SizeStruct < FFI::Struct
60
- layout :value, :size_t
61
- end
62
-
63
- class IntStruct < FFI::Struct
64
- layout :value, :int
65
- end
66
-
67
- attach_function :vips_value_get_ref_string,
68
- [GObject::GValue.ptr, SizeStruct.ptr], :string
69
- attach_function :vips_value_get_array_double,
70
- [GObject::GValue.ptr, IntStruct.ptr], :pointer
71
- attach_function :vips_value_get_array_int,
72
- [GObject::GValue.ptr, IntStruct.ptr], :pointer
73
- attach_function :vips_value_get_array_image,
74
- [GObject::GValue.ptr, IntStruct.ptr], :pointer
75
- attach_function :vips_value_get_blob,
76
- [GObject::GValue.ptr, SizeStruct.ptr], :pointer
77
-
78
- attach_function :type_find, :vips_type_find, [:string, :string], :GType
79
-
80
- class Object < GObject::GObject
81
-
82
- # print all active VipsObjects, with their reference counts. Handy for
83
- # debugging ruby-vips.
84
- def self.print_all
85
- GC.start
86
- Vips::vips_object_print_all
87
- end
88
-
89
- # the layout of the VipsObject struct
90
- module ObjectLayout
91
- def self.included base
92
- base.class_eval do
93
- # don't actually need most of these
94
- layout :parent, GObject::GObject::Struct,
95
- :constructed, :int,
96
- :static_object, :int,
97
- :argument_table, :pointer,
98
- :nickname, :string,
99
- :description, :string,
100
- :preclose, :int,
101
- :close, :int,
102
- :postclose, :int,
103
- :local_memory, :size_t
104
- end
105
- end
106
- end
107
-
108
- class Struct < GObject::GObject::Struct
109
- include ObjectLayout
110
-
111
- end
112
-
113
- class ManagedStruct < GObject::GObject::ManagedStruct
114
- include ObjectLayout
115
-
116
- end
117
-
118
- # return a pspec, or nil ... nil wil leave a message in the error log
119
- # which you must clear
120
- def get_pspec name
121
- pspec = GObject::GParamSpecPtr.new
122
- argument_class = Vips::ArgumentClassPtr.new
123
- argument_instance = Vips::ArgumentInstancePtr.new
124
-
125
- result = Vips::vips_object_get_argument self, name,
126
- pspec, argument_class, argument_instance
127
- return nil if result != 0
128
-
129
- pspec
130
- end
131
-
132
- # return a gtype, raise an error on not found
133
- def get_typeof_error name
134
- pspec = get_pspec name
135
- raise Vips::Error unless pspec
136
-
137
- pspec[:value][:value_type]
138
- end
139
-
140
- # return a gtype, 0 on not found
141
- def get_typeof name
142
- pspec = get_pspec name
143
- unless pspec
144
- Vips::vips_error_clear
145
- return 0
146
- end
147
-
148
- pspec[:value][:value_type]
89
+ # the layout of the VipsObject struct
90
+ module ObjectLayout
91
+ def self.included base
92
+ base.class_eval do
93
+ # don't actually need most of these
94
+ layout :parent, GObject::GObject::Struct,
95
+ :constructed, :int,
96
+ :static_object, :int,
97
+ :argument_table, :pointer,
98
+ :nickname, :string,
99
+ :description, :string,
100
+ :preclose, :int,
101
+ :close, :int,
102
+ :postclose, :int,
103
+ :local_memory, :size_t
149
104
  end
105
+ end
106
+ end
150
107
 
151
- def get name
152
- gtype = get_typeof_error name
153
- gvalue = GObject::GValue.alloc
154
- gvalue.init gtype
155
- GObject::g_object_get_property self, name, gvalue
156
- result = gvalue.get
108
+ class Struct < GObject::GObject::Struct
109
+ include ObjectLayout
157
110
 
158
- GLib::logger.debug("Vips::Object.get") {"#{name} == #{result}"}
111
+ end
159
112
 
160
- return result
161
- end
113
+ class ManagedStruct < GObject::GObject::ManagedStruct
114
+ include ObjectLayout
162
115
 
163
- def set name, value
164
- GLib::logger.debug("Vips::Object.set") {"#{name} = #{value}"}
116
+ end
165
117
 
166
- gtype = get_typeof_error name
167
- gvalue = GObject::GValue.alloc
168
- gvalue.init gtype
169
- gvalue.set value
170
- GObject::g_object_set_property self, name, gvalue
171
- end
118
+ # return a pspec, or nil ... nil wil leave a message in the error log
119
+ # which you must clear
120
+ def get_pspec name
121
+ pspec = GObject::GParamSpecPtr.new
122
+ argument_class = Vips::ArgumentClassPtr.new
123
+ argument_instance = Vips::ArgumentInstancePtr.new
172
124
 
173
- end
125
+ result = Vips::vips_object_get_argument self, name,
126
+ pspec, argument_class, argument_instance
127
+ return nil if result != 0
174
128
 
175
- class ObjectClass < FFI::Struct
176
- # opaque
129
+ pspec
177
130
  end
178
131
 
179
- class Argument < FFI::Struct
180
- layout :pspec, GObject::GParamSpec.ptr
181
- end
132
+ # return a gtype, raise an error on not found
133
+ def get_typeof_error name
134
+ pspec = get_pspec name
135
+ raise Vips::Error unless pspec
182
136
 
183
- class ArgumentInstance < Argument
184
- layout :parent, Argument
185
- # rest opaque
137
+ pspec[:value][:value_type]
186
138
  end
187
139
 
188
- # enum VipsArgumentFlags
189
- ARGUMENT_REQUIRED = 1
190
- ARGUMENT_CONSTRUCT = 2
191
- ARGUMENT_SET_ONCE = 4
192
- ARGUMENT_SET_ALWAYS = 8
193
- ARGUMENT_INPUT = 16
194
- ARGUMENT_OUTPUT = 32
195
- ARGUMENT_DEPRECATED = 64
196
- ARGUMENT_MODIFY = 128
197
-
198
- ARGUMENT_FLAGS = {
199
- :required => ARGUMENT_REQUIRED,
200
- :construct => ARGUMENT_CONSTRUCT,
201
- :set_once => ARGUMENT_SET_ONCE,
202
- :set_always => ARGUMENT_SET_ALWAYS,
203
- :input => ARGUMENT_INPUT,
204
- :output => ARGUMENT_OUTPUT,
205
- :deprecated => ARGUMENT_DEPRECATED,
206
- :modify => ARGUMENT_MODIFY
207
- }
208
-
209
- class ArgumentClass < Argument
210
- layout :parent, Argument,
211
- :object_class, ObjectClass.ptr,
212
- :flags, :uint,
213
- :priority, :int,
214
- :offset, :ulong_long
215
- end
140
+ # return a gtype, 0 on not found
141
+ def get_typeof name
142
+ pspec = get_pspec name
143
+ unless pspec
144
+ Vips::vips_error_clear
145
+ return 0
146
+ end
216
147
 
217
- class ArgumentClassPtr < FFI::Struct
218
- layout :value, ArgumentClass.ptr
148
+ pspec[:value][:value_type]
219
149
  end
220
150
 
221
- class ArgumentInstancePtr < FFI::Struct
222
- layout :value, ArgumentInstance.ptr
223
- end
151
+ def get name
152
+ gtype = get_typeof_error name
153
+ gvalue = GObject::GValue.alloc
154
+ gvalue.init gtype
155
+ GObject::g_object_get_property self, name, gvalue
156
+ result = gvalue.get
224
157
 
225
- # just use :pointer, not VipsObject.ptr, to avoid casting gobject
226
- # subclasses
227
- attach_function :vips_object_get_argument,
228
- [:pointer, :string,
229
- GObject::GParamSpecPtr.ptr,
230
- ArgumentClassPtr.ptr, ArgumentInstancePtr.ptr],
231
- :int
158
+ GLib::logger.debug("Vips::Object.get") {"#{name} == #{result}"}
232
159
 
233
- attach_function :vips_object_print_all, [], :void
160
+ return result
161
+ end
234
162
 
235
- attach_function :vips_object_set_from_string, [:pointer, :string], :int
163
+ def set name, value
164
+ GLib::logger.debug("Vips::Object.set") {"#{name} = #{value}"}
236
165
 
237
- callback :type_map_fn, [:GType, :pointer], :pointer
238
- attach_function :vips_type_map, [:GType, :type_map_fn, :pointer], :pointer
166
+ gtype = get_typeof_error name
167
+ gvalue = GObject::GValue.alloc
168
+ gvalue.init gtype
169
+ gvalue.set value
170
+ GObject::g_object_set_property self, name, gvalue
171
+ end
239
172
 
240
- attach_function :vips_object_get_description, [:pointer], :string
173
+ end
174
+
175
+ class ObjectClass < FFI::Struct
176
+ # opaque
177
+ end
178
+
179
+ class Argument < FFI::Struct
180
+ layout :pspec, GObject::GParamSpec.ptr
181
+ end
182
+
183
+ class ArgumentInstance < Argument
184
+ layout :parent, Argument
185
+ # rest opaque
186
+ end
187
+
188
+ # enum VipsArgumentFlags
189
+ ARGUMENT_REQUIRED = 1
190
+ ARGUMENT_CONSTRUCT = 2
191
+ ARGUMENT_SET_ONCE = 4
192
+ ARGUMENT_SET_ALWAYS = 8
193
+ ARGUMENT_INPUT = 16
194
+ ARGUMENT_OUTPUT = 32
195
+ ARGUMENT_DEPRECATED = 64
196
+ ARGUMENT_MODIFY = 128
197
+
198
+ ARGUMENT_FLAGS = {
199
+ :required => ARGUMENT_REQUIRED,
200
+ :construct => ARGUMENT_CONSTRUCT,
201
+ :set_once => ARGUMENT_SET_ONCE,
202
+ :set_always => ARGUMENT_SET_ALWAYS,
203
+ :input => ARGUMENT_INPUT,
204
+ :output => ARGUMENT_OUTPUT,
205
+ :deprecated => ARGUMENT_DEPRECATED,
206
+ :modify => ARGUMENT_MODIFY
207
+ }
208
+
209
+ class ArgumentClass < Argument
210
+ layout :parent, Argument,
211
+ :object_class, ObjectClass.ptr,
212
+ :flags, :uint,
213
+ :priority, :int,
214
+ :offset, :ulong_long
215
+ end
216
+
217
+ class ArgumentClassPtr < FFI::Struct
218
+ layout :value, ArgumentClass.ptr
219
+ end
220
+
221
+ class ArgumentInstancePtr < FFI::Struct
222
+ layout :value, ArgumentInstance.ptr
223
+ end
224
+
225
+ # just use :pointer, not VipsObject.ptr, to avoid casting gobject
226
+ # subclasses
227
+ attach_function :vips_object_get_argument,
228
+ [:pointer, :string,
229
+ GObject::GParamSpecPtr.ptr,
230
+ ArgumentClassPtr.ptr, ArgumentInstancePtr.ptr],
231
+ :int
232
+
233
+ attach_function :vips_object_print_all, [], :void
234
+
235
+ attach_function :vips_object_set_from_string, [:pointer, :string], :int
236
+
237
+ callback :type_map_fn, [:GType, :pointer], :pointer
238
+ attach_function :vips_type_map, [:GType, :type_map_fn, :pointer], :pointer
239
+
240
+ attach_function :vips_object_get_description, [:pointer], :string
241
241
 
242
242
  end
243
243
 
@@ -7,359 +7,361 @@
7
7
  require 'ffi'
8
8
 
9
9
  module Vips
10
- private
11
-
12
- attach_function :vips_operation_new, [:string], :pointer
13
-
14
- attach_function :vips_cache_operation_build, [:pointer], :pointer
15
- attach_function :vips_object_unref_outputs, [:pointer], :void
16
-
17
- callback :argument_map_fn, [:pointer,
18
- GObject::GParamSpec.ptr,
19
- ArgumentClass.ptr,
20
- ArgumentInstance.ptr,
21
- :pointer, :pointer], :pointer
22
- attach_function :vips_argument_map, [:pointer,
23
- :argument_map_fn,
24
- :pointer, :pointer], :pointer
25
-
26
- OPERATION_SEQUENTIAL = 1
27
- OPERATION_NOCACHE = 4
28
- OPERATION_DEPRECATED = 8
29
-
30
- OPERATION_FLAGS = {
31
- :sequential => OPERATION_SEQUENTIAL,
32
- :nocache => OPERATION_NOCACHE,
33
- :deprecated => OPERATION_DEPRECATED
34
- }
35
-
36
- attach_function :vips_operation_get_flags, [:pointer], :int
37
-
38
- class Operation < Object
39
-
40
- # the layout of the VipsOperation struct
41
- module OperationLayout
42
- def self.included base
43
- base.class_eval do
44
- layout :parent, Object::Struct
45
- # rest opaque
46
- end
47
- end
10
+ private
11
+
12
+ attach_function :vips_operation_new, [:string], :pointer
13
+
14
+ attach_function :vips_cache_operation_build, [:pointer], :pointer
15
+ attach_function :vips_object_unref_outputs, [:pointer], :void
16
+
17
+ callback :argument_map_fn, [:pointer,
18
+ GObject::GParamSpec.ptr,
19
+ ArgumentClass.ptr,
20
+ ArgumentInstance.ptr,
21
+ :pointer, :pointer], :pointer
22
+ attach_function :vips_argument_map, [:pointer,
23
+ :argument_map_fn,
24
+ :pointer, :pointer], :pointer
25
+
26
+ OPERATION_SEQUENTIAL = 1
27
+ OPERATION_NOCACHE = 4
28
+ OPERATION_DEPRECATED = 8
29
+
30
+ OPERATION_FLAGS = {
31
+ :sequential => OPERATION_SEQUENTIAL,
32
+ :nocache => OPERATION_NOCACHE,
33
+ :deprecated => OPERATION_DEPRECATED
34
+ }
35
+
36
+ attach_function :vips_operation_get_flags, [:pointer], :int
37
+
38
+ class Operation < Object
39
+
40
+ # the layout of the VipsOperation struct
41
+ module OperationLayout
42
+ def self.included base
43
+ base.class_eval do
44
+ layout :parent, Object::Struct
45
+ # rest opaque
48
46
  end
47
+ end
48
+ end
49
49
 
50
- class Struct < Object::Struct
51
- include OperationLayout
50
+ class Struct < Object::Struct
51
+ include OperationLayout
52
52
 
53
- end
53
+ end
54
54
 
55
- class ManagedStruct < Object::ManagedStruct
56
- include OperationLayout
55
+ class ManagedStruct < Object::ManagedStruct
56
+ include OperationLayout
57
57
 
58
- end
58
+ end
59
59
 
60
- def initialize value
61
- # allow init with a pointer so we can wrap the return values from
62
- # things like _build
63
- if value.is_a? String
64
- value = Vips::vips_operation_new value
65
- raise Vips::Error if value == nil
66
- end
60
+ def initialize value
61
+ # allow init with a pointer so we can wrap the return values from
62
+ # things like _build
63
+ if value.is_a? String
64
+ value = Vips::vips_operation_new value
65
+ raise Vips::Error if value == nil
66
+ end
67
67
 
68
- super value
69
- end
68
+ super value
69
+ end
70
70
 
71
- def build
72
- op = Vips::vips_cache_operation_build self
73
- if op == nil
74
- raise Vips::Error
75
- end
71
+ def build
72
+ op = Vips::vips_cache_operation_build self
73
+ if op == nil
74
+ raise Vips::Error
75
+ end
76
76
 
77
- return Operation.new op
78
- end
77
+ return Operation.new op
78
+ end
79
79
 
80
- def argument_map &block
81
- fn = Proc.new do |op, pspec, argument_class, argument_instance, a, b|
82
- block.call pspec, argument_class, argument_instance
83
- end
80
+ def argument_map &block
81
+ fn = Proc.new do |op, pspec, argument_class, argument_instance, a, b|
82
+ block.call pspec, argument_class, argument_instance
83
+ end
84
84
 
85
- Vips::vips_argument_map self, fn, nil, nil
86
- end
85
+ Vips::vips_argument_map self, fn, nil, nil
86
+ end
87
+
88
+ def get_flags
89
+ Vips::vips_operation_get_flags self
90
+ end
91
+
92
+ # not quick! try to call this infrequently
93
+ def get_construct_args
94
+ args = []
87
95
 
88
- def get_flags
89
- Vips::vips_operation_get_flags self
96
+ argument_map do |pspec, argument_class, argument_instance|
97
+ flags = argument_class[:flags]
98
+ if (flags & ARGUMENT_CONSTRUCT) != 0
99
+ # names can include - as punctuation, but we always use _ in
100
+ # Ruby
101
+ name = pspec[:name].tr("-", "_")
102
+
103
+ args << [name, flags]
90
104
  end
105
+ end
106
+
107
+ return args
108
+ end
109
+
110
+ # search array for the first element to match a predicate ...
111
+ # search inside subarrays and sub-hashes
112
+ def self.find_inside object, &block
113
+ return object if block.call object
91
114
 
92
- # not quick! try to call this infrequently
93
- def get_construct_args
94
- args = []
115
+ if object.is_a? Enumerable
116
+ object.find {|value| block.call value, block}
117
+ end
95
118
 
96
- argument_map do |pspec, argument_class, argument_instance|
97
- flags = argument_class[:flags]
98
- if (flags & ARGUMENT_CONSTRUCT) != 0
99
- # names can include - as punctuation, but we always use _ in
100
- # Ruby
101
- name = pspec[:name].tr("-", "_")
119
+ return nil
120
+ end
121
+
122
+ # expand a constant into an image
123
+ def self.imageize match_image, value
124
+ return value if value.is_a? Image
125
+
126
+ # 2D array values become tiny 2D images
127
+ # if there's nothing to match to, we also make a 2D image
128
+ if (value.is_a?(Array) && value[0].is_a?(Array)) ||
129
+ match_image == nil
130
+ return Image.new_from_array value
131
+ else
132
+ # we have a 1D array ... use that as a pixel constant and
133
+ # expand to match match_image
134
+ return match_image.new_from_image value
135
+ end
136
+ end
102
137
 
103
- args << [name, flags]
104
- end
105
- end
138
+ # set an operation argument, expanding constants and copying images as
139
+ # required
140
+ def set name, value, match_image = nil, flags = 0
141
+ gtype = get_typeof name
106
142
 
107
- return args
143
+ if gtype == IMAGE_TYPE
144
+ value = Operation::imageize match_image, value
145
+
146
+ if (flags & ARGUMENT_MODIFY) != 0
147
+ # make sure we have a unique copy
148
+ value = value.copy.copy_memory
108
149
  end
150
+ elsif gtype == ARRAY_IMAGE_TYPE
151
+ value = value.map {|x| Operation::imageize match_image, x}
152
+ end
109
153
 
110
- # search array for the first element to match a predicate ...
111
- # search inside subarrays and sub-hashes
112
- def self.find_inside object, &block
113
- return object if block.call object
154
+ super name, value
155
+ end
114
156
 
115
- if object.is_a? Enumerable
116
- object.find {|value| block.call value, block}
117
- end
157
+ public
158
+
159
+ # This is the public entry point for the vips binding. {call} will run
160
+ # any vips operation, for example:
161
+ #
162
+ # ```ruby
163
+ # out = Vips::Operation.call "black", [100, 100], {:bands => 12}
164
+ # ```
165
+ #
166
+ # will call the C function
167
+ #
168
+ # ```C
169
+ # vips_black( &out, 100, 100, "bands", 12, NULL );
170
+ # ```
171
+ #
172
+ # There are {Image#method_missing} hooks which will run {call} for you
173
+ # on {Image} for undefined instance or class methods. So you can also
174
+ # write:
175
+ #
176
+ # ```ruby
177
+ # out = Vips::Image.black 100, 100, bands: 12
178
+ # ```
179
+ #
180
+ # Or perhaps:
181
+ #
182
+ # ```ruby
183
+ # x = Vips::Image.black 100, 100
184
+ # y = x.invert
185
+ # ```
186
+ #
187
+ # to run the `vips_invert()` operator.
188
+ #
189
+ # There are also a set of operator overloads and some convenience
190
+ # functions, see {Image}.
191
+ #
192
+ # If the operator needs a vector constant, {call} will turn a scalar
193
+ # into a
194
+ # vector for you. So for `x.linear a, b`, which calculates
195
+ # `x * a + b` where `a` and `b` are vector constants, you can write:
196
+ #
197
+ # ```ruby
198
+ # x = Vips::Image.black 100, 100, bands: 3
199
+ # y = x.linear 1, 2
200
+ # y = x.linear [1], 4
201
+ # y = x.linear [1, 2, 3], 4
202
+ # ```
203
+ #
204
+ # or any other combination. The operator overloads use this facility to
205
+ # support all the variations on:
206
+ #
207
+ # ```ruby
208
+ # x = Vips::Image.black 100, 100, bands: 3
209
+ # y = x * 2
210
+ # y = x + [1,2,3]
211
+ # y = x % [1]
212
+ # ```
213
+ #
214
+ # Similarly, wherever an image is required, you can use a constant. The
215
+ # constant will be expanded to an image matching the first input image
216
+ # argument. For example, you can write:
217
+ #
218
+ # ```
219
+ # x = Vips::Image.black 100, 100, bands: 3
220
+ # y = x.bandjoin 255
221
+ # ```
222
+ #
223
+ # to add an extra band to the image where each pixel in the new band has
224
+ # the constant value 255.
225
+
226
+ def self.call name, supplied, optional = {}, option_string = ""
227
+ GLib::logger.debug("Vips::VipsOperation.call") {
228
+ "name = #{name}, supplied = #{supplied}, " +
229
+ "optional = #{optional}, option_string = #{option_string}"
230
+ }
231
+
232
+ op = Operation.new name
233
+
234
+ # find and classify all the arguments the operator can take
235
+ args = op.get_construct_args
236
+ required_input = []
237
+ optional_input = {}
238
+ required_output = []
239
+ optional_output = {}
240
+ args.each do |name, flags|
241
+ next if (flags & ARGUMENT_DEPRECATED) != 0
242
+
243
+ if (flags & ARGUMENT_INPUT) != 0
244
+ if (flags & ARGUMENT_REQUIRED) != 0
245
+ required_input << [name, flags]
246
+ else
247
+ optional_input[name] = flags
248
+ end
249
+ end
118
250
 
119
- return nil
251
+ # MODIFY INPUT args count as OUTPUT as well
252
+ if (flags & ARGUMENT_OUTPUT) != 0 ||
253
+ ((flags & ARGUMENT_INPUT) != 0 &&
254
+ (flags & ARGUMENT_MODIFY) != 0)
255
+ if (flags & ARGUMENT_REQUIRED) != 0
256
+ required_output << [name, flags]
257
+ else
258
+ optional_output[name] = flags
259
+ end
120
260
  end
121
261
 
122
- # expand a constant into an image
123
- def self.imageize match_image, value
124
- return value if value.is_a? Image
125
-
126
- # 2D array values become tiny 2D images
127
- # if there's nothing to match to, we also make a 2D image
128
- if (value.is_a?(Array) && value[0].is_a?(Array)) ||
129
- match_image == nil
130
- return Image.new_from_array value
131
- else
132
- # we have a 1D array ... use that as a pixel constant and
133
- # expand to match match_image
134
- return match_image.new_from_image value
135
- end
262
+ end
263
+
264
+ # so we should have been supplied with n_required_input values, or
265
+ # n_required_input + 1 if there's a hash of options at the end
266
+ unless supplied.is_a? Array
267
+ raise Vips::Error, "unable to call #{name}: " +
268
+ "argument array is not an array"
269
+ end
270
+ unless optional.is_a? Hash
271
+ raise Vips::Error, "unable to call #{name}: " +
272
+ "optional arguments are not a hash"
273
+ end
274
+ if supplied.length != required_input.length
275
+ raise Vips::Error, "unable to call #{name}: " +
276
+ "you supplied #{supplied.length} arguments, " +
277
+ "but operation needs #{required_input.length}."
278
+ end
279
+
280
+ # very that all supplied_optional keys are in optional_input or
281
+ # optional_output
282
+ optional.each do |key, value|
283
+ arg_name = key.to_s
284
+
285
+ unless optional_input.has_key?(arg_name) ||
286
+ optional_output.has_key?(arg_name)
287
+ raise Vips::Error, "unable to call #{name}: " +
288
+ "unknown option #{arg_name}"
289
+ end
290
+ end
291
+
292
+ # the first image arg is the thing we expand constants to match ...
293
+ # we need to find it
294
+ #
295
+ # look inside array and hash arguments, since we may be passing an
296
+ # array of images
297
+ match_image = find_inside(supplied) do |value|
298
+ value.is_a? Image
299
+ end
300
+
301
+ # set any string args first so they can't be overridden
302
+ if option_string != nil
303
+ if Vips::vips_object_set_from_string(op, option_string) != 0
304
+ raise Vips::Error
136
305
  end
306
+ end
307
+
308
+ # set all required inputs
309
+ required_input.each_index do |i|
310
+ arg_name = required_input[i][0]
311
+ flags = required_input[i][1]
312
+ value = supplied[i]
313
+
314
+ op.set arg_name, value, match_image, flags
315
+ end
137
316
 
138
- # set an operation argument, expanding constants and copying images as
139
- # required
140
- def set name, value, match_image = nil, flags = 0
141
- gtype = get_typeof name
317
+ # set all optional inputs
318
+ optional.each do |key, value|
319
+ next if value.nil?
142
320
 
143
- if gtype == IMAGE_TYPE
144
- value = Operation::imageize match_image, value
321
+ arg_name = key.to_s
145
322
 
146
- if (flags & ARGUMENT_MODIFY) != 0
147
- # make sure we have a unique copy
148
- value = value.copy.copy_memory
149
- end
150
- elsif gtype == ARRAY_IMAGE_TYPE
151
- value = value.map {|x| Operation::imageize match_image, x}
152
- end
323
+ if optional_input.has_key? arg_name
324
+ flags = optional_input[arg_name]
153
325
 
154
- super name, value
326
+ op.set arg_name, value, match_image, flags
155
327
  end
328
+ end
156
329
 
157
- public
158
-
159
- # This is the public entry point for the vips binding. {call} will run
160
- # any vips operation, for example:
161
- #
162
- # ```ruby
163
- # out = Vips::Operation.call "black", [100, 100], {:bands => 12}
164
- # ```
165
- #
166
- # will call the C function
167
- #
168
- # ```C
169
- # vips_black( &out, 100, 100, "bands", 12, NULL );
170
- # ```
171
- #
172
- # There are {Image#method_missing} hooks which will run {call} for you
173
- # on {Image} for undefined instance or class methods. So you can also
174
- # write:
175
- #
176
- # ```ruby
177
- # out = Vips::Image.black 100, 100, bands: 12
178
- # ```
179
- #
180
- # Or perhaps:
181
- #
182
- # ```ruby
183
- # x = Vips::Image.black 100, 100
184
- # y = x.invert
185
- # ```
186
- #
187
- # to run the `vips_invert()` operator.
188
- #
189
- # There are also a set of operator overloads and some convenience
190
- # functions, see {Image}.
191
- #
192
- # If the operator needs a vector constant, {call} will turn a scalar
193
- # into a
194
- # vector for you. So for `x.linear a, b`, which calculates
195
- # `x * a + b` where `a` and `b` are vector constants, you can write:
196
- #
197
- # ```ruby
198
- # x = Vips::Image.black 100, 100, bands: 3
199
- # y = x.linear 1, 2
200
- # y = x.linear [1], 4
201
- # y = x.linear [1, 2, 3], 4
202
- # ```
203
- #
204
- # or any other combination. The operator overloads use this facility to
205
- # support all the variations on:
206
- #
207
- # ```ruby
208
- # x = Vips::Image.black 100, 100, bands: 3
209
- # y = x * 2
210
- # y = x + [1,2,3]
211
- # y = x % [1]
212
- # ```
213
- #
214
- # Similarly, wherever an image is required, you can use a constant. The
215
- # constant will be expanded to an image matching the first input image
216
- # argument. For example, you can write:
217
- #
218
- # ```
219
- # x = Vips::Image.black 100, 100, bands: 3
220
- # y = x.bandjoin 255
221
- # ```
222
- #
223
- # to add an extra band to the image where each pixel in the new band has
224
- # the constant value 255.
225
-
226
- def self.call name, supplied, optional = {}, option_string = ""
227
- GLib::logger.debug("Vips::VipsOperation.call") {
228
- "name = #{name}, supplied = #{supplied}, " +
229
- "optional = #{optional}, option_string = #{option_string}"
230
- }
231
-
232
- op = Operation.new name
233
-
234
- # find and classify all the arguments the operator can take
235
- args = op.get_construct_args
236
- required_input = []
237
- optional_input = {}
238
- required_output = []
239
- optional_output = {}
240
- args.each do |name, flags|
241
- next if (flags & ARGUMENT_DEPRECATED) != 0
242
-
243
- if (flags & ARGUMENT_INPUT) != 0
244
- if (flags & ARGUMENT_REQUIRED) != 0
245
- required_input << [name, flags]
246
- else
247
- optional_input[name] = flags
248
- end
249
- end
250
-
251
- # MODIFY INPUT args count as OUTPUT as well
252
- if (flags & ARGUMENT_OUTPUT) != 0 ||
253
- ((flags & ARGUMENT_INPUT) != 0 &&
254
- (flags & ARGUMENT_MODIFY) != 0)
255
- if (flags & ARGUMENT_REQUIRED) != 0
256
- required_output << [name, flags]
257
- else
258
- optional_output[name] = flags
259
- end
260
- end
261
-
262
- end
263
-
264
- # so we should have been supplied with n_required_input values, or
265
- # n_required_input + 1 if there's a hash of options at the end
266
- unless supplied.is_a? Array
267
- raise Vips::Error, "unable to call #{name}: " +
268
- "argument array is not an array"
269
- end
270
- unless optional.is_a? Hash
271
- raise Vips::Error, "unable to call #{name}: " +
272
- "optional arguments are not a hash"
273
- end
274
- if supplied.length != required_input.length
275
- raise Vips::Error, "unable to call #{name}: " +
276
- "you supplied #{supplied.length} arguments, " +
277
- "but operation needs #{required_input.length}."
278
- end
279
-
280
- # very that all supplied_optional keys are in optional_input or
281
- # optional_output
282
- optional.each do |key, value|
283
- arg_name = key.to_s
284
-
285
- unless optional_input.has_key?(arg_name) ||
286
- optional_output.has_key?(arg_name)
287
- raise Vips::Error, "unable to call #{name}: " +
288
- "unknown option #{arg_name}"
289
- end
290
- end
291
-
292
- # the first image arg is the thing we expand constants to match ...
293
- # we need to find it
294
- #
295
- # look inside array and hash arguments, since we may be passing an
296
- # array of images
297
- match_image = find_inside(supplied) do |value|
298
- value.is_a? Image
299
- end
300
-
301
- # set any string args first so they can't be overridden
302
- if option_string != nil
303
- if Vips::vips_object_set_from_string(op, option_string) != 0
304
- raise Vips::Error
305
- end
306
- end
307
-
308
- # set all required inputs
309
- required_input.each_index do |i|
310
- arg_name = required_input[i][0]
311
- flags = required_input[i][1]
312
- value = supplied[i]
313
-
314
- op.set arg_name, value, match_image, flags
315
- end
316
-
317
- # set all optional inputs
318
- optional.each do |key, value|
319
- arg_name = key.to_s
320
-
321
- if optional_input.has_key? arg_name
322
- flags = optional_input[arg_name]
323
-
324
- op.set arg_name, value, match_image, flags
325
- end
326
- end
327
-
328
- op = op.build
329
-
330
- # get all required results
331
- result = []
332
- required_output.each do |arg_name, flags|
333
- result << op.get(arg_name)
334
- end
335
-
336
- # fetch all optional ones
337
- optional_results = {}
338
- optional.each do |key, value|
339
- arg_name = key.to_s
340
-
341
- if optional_output.has_key? arg_name
342
- flags = optional_output[arg_name]
343
-
344
- optional_results[arg_name] = op.get arg_name
345
- end
346
- end
347
-
348
- result << optional_results if optional_results != {}
349
-
350
- if result.length == 1
351
- result = result.first
352
- elsif result.length == 0
353
- result = nil
354
- end
355
-
356
- GLib::logger.debug("Vips::Operation.call") {"result = #{result}"}
357
-
358
- Vips::vips_object_unref_outputs op
359
-
360
- return result
330
+ op = op.build
331
+
332
+ # get all required results
333
+ result = []
334
+ required_output.each do |arg_name, flags|
335
+ result << op.get(arg_name)
336
+ end
337
+
338
+ # fetch all optional ones
339
+ optional_results = {}
340
+ optional.each do |key, value|
341
+ arg_name = key.to_s
342
+
343
+ if optional_output.has_key? arg_name
344
+ flags = optional_output[arg_name]
345
+
346
+ optional_results[arg_name] = op.get arg_name
361
347
  end
348
+ end
349
+
350
+ result << optional_results if optional_results != {}
362
351
 
352
+ if result.length == 1
353
+ result = result.first
354
+ elsif result.length == 0
355
+ result = nil
356
+ end
357
+
358
+ GLib::logger.debug("Vips::Operation.call") {"result = #{result}"}
359
+
360
+ Vips::vips_object_unref_outputs op
361
+
362
+ return result
363
363
  end
364
364
 
365
+ end
366
+
365
367
  end