vips 8.6.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.travis.yml +47 -0
  4. data/.yardopts +2 -0
  5. data/Gemfile +4 -0
  6. data/README.md +64 -0
  7. data/Rakefile +28 -0
  8. data/example/annotate.rb +17 -0
  9. data/example/daltonize8.rb +75 -0
  10. data/example/example1.rb +12 -0
  11. data/example/example2.rb +34 -0
  12. data/example/example3.rb +19 -0
  13. data/example/example4.rb +18 -0
  14. data/example/example5.rb +31 -0
  15. data/example/inheritance_with_refcount.rb +286 -0
  16. data/example/thumb.rb +31 -0
  17. data/example/trim8.rb +41 -0
  18. data/example/watermark.rb +44 -0
  19. data/example/wobble.rb +36 -0
  20. data/ext/Rakefile +35 -0
  21. data/lib/vips.rb +597 -0
  22. data/lib/vips/access.rb +11 -0
  23. data/lib/vips/align.rb +11 -0
  24. data/lib/vips/angle.rb +12 -0
  25. data/lib/vips/angle45.rb +16 -0
  26. data/lib/vips/bandformat.rb +20 -0
  27. data/lib/vips/coding.rb +14 -0
  28. data/lib/vips/compass_direction.rb +17 -0
  29. data/lib/vips/direction.rb +11 -0
  30. data/lib/vips/extend.rb +17 -0
  31. data/lib/vips/gobject.rb +122 -0
  32. data/lib/vips/gvalue.rb +281 -0
  33. data/lib/vips/image.rb +1500 -0
  34. data/lib/vips/interesting.rb +14 -0
  35. data/lib/vips/interpolate.rb +62 -0
  36. data/lib/vips/interpretation.rb +28 -0
  37. data/lib/vips/kernel.rb +22 -0
  38. data/lib/vips/methods.rb +2145 -0
  39. data/lib/vips/object.rb +244 -0
  40. data/lib/vips/operation.rb +365 -0
  41. data/lib/vips/operationboolean.rb +14 -0
  42. data/lib/vips/operationcomplex.rb +12 -0
  43. data/lib/vips/operationcomplex2.rb +10 -0
  44. data/lib/vips/operationcomplexget.rb +11 -0
  45. data/lib/vips/operationmath.rb +18 -0
  46. data/lib/vips/operationmath2.rb +10 -0
  47. data/lib/vips/operationrelational.rb +15 -0
  48. data/lib/vips/operationround.rb +11 -0
  49. data/lib/vips/size.rb +13 -0
  50. data/lib/vips/version.rb +4 -0
  51. data/vips.gemspec +36 -0
  52. metadata +209 -0
@@ -0,0 +1,11 @@
1
+ module Vips
2
+ # The type of access an operation has to supply.
3
+ #
4
+ # * `:random` means requests can come in any order.
5
+ #
6
+ # * `:sequential` means requests will be top-to-bottom, but with some
7
+ # amount of buffering behind the read point for small non-local
8
+ # accesses.
9
+ class Access < Symbol
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Vips
2
+
3
+ # Various types of alignment. See {Image#join}, for example.
4
+ #
5
+ # * `:low` Align on the low coordinate edge
6
+ # * `:centre` Align on the centre
7
+ # * `:high` Align on the high coordinate edge
8
+
9
+ class Align < Symbol
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module Vips
2
+
3
+ # Various fixed 90 degree rotation angles. See {Image#rot}.
4
+ #
5
+ # * `:d0` no rotate
6
+ # * `:d90` 90 degrees clockwise
7
+ # * `:d180` 180 degrees
8
+ # * `:d270` 90 degrees anti-clockwise
9
+
10
+ class Angle < Symbol
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ module Vips
2
+
3
+ # Various fixed 45 degree rotation angles. See {Image#rot45}.
4
+ #
5
+ # * `:d0` no rotate
6
+ # * `:d45` 45 degrees clockwise
7
+ # * `:d90` 90 degrees clockwise
8
+ # * `:d135` 135 degrees clockwise
9
+ # * `:d180` 180 degrees
10
+ # * `:d225` 135 degrees anti-clockwise
11
+ # * `:d270` 90 degrees anti-clockwise
12
+ # * `:d315` 45 degrees anti-clockwise
13
+
14
+ class Angle45 < Symbol
15
+ end
16
+ end
@@ -0,0 +1,20 @@
1
+ module Vips
2
+
3
+ # The format used for each band element. Each corresponds to a native C type
4
+ # for the current machine.
5
+ #
6
+ # * `:notset` invalid setting
7
+ # * `:uchar` unsigned char format
8
+ # * `:char` char format
9
+ # * `:ushort` unsigned short format
10
+ # * `:short` short format
11
+ # * `:uint` unsigned int format
12
+ # * `:int` int format
13
+ # * `:float` float format
14
+ # * `:complex` complex (two floats) format
15
+ # * `:double` double float format
16
+ # * `:dpcomplex` double complex (two double) format
17
+ class BandFormat < Symbol
18
+ end
19
+
20
+ end
@@ -0,0 +1,14 @@
1
+ module Vips
2
+
3
+ # How pixels are coded.
4
+ #
5
+ # Normally, pixels are uncoded and can be manipulated as you would expect.
6
+ # However some file formats code pixels for compression, and sometimes it's
7
+ # useful to be able to manipulate images in the coded format.
8
+ #
9
+ # * `:none` pixels are not coded
10
+ # * `:labq` pixels encode 3 float CIELAB values as 4 uchar
11
+ # * `:rad` pixels encode 3 float RGB as 4 uchar (Radiance coding)
12
+ class Coding < Symbol
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ module Vips
2
+
3
+ # A direction on a compass used for placing images. See {Image#gravity}.
4
+ #
5
+ # * `:centre`
6
+ # * `:north`
7
+ # * `:east`
8
+ # * `:south`
9
+ # * `:west`
10
+ # * `:north-east`
11
+ # * `"south-east`
12
+ # * `:south-west`
13
+ # * `:north-west`
14
+
15
+ class CompassDirection < Symbol
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ module Vips
2
+
3
+ # Operations like {Image#flip} need to be told whether to flip
4
+ # left-right or top-bottom.
5
+ #
6
+ # * `:horizontal` left-right
7
+ # * `:vertical` top-bottom
8
+
9
+ class Direction < Symbol
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ module Vips
2
+
3
+ # When the edges of an image are extended, you can specify
4
+ # how you want the extension done.
5
+ # See {Image#embed}, {Image#conv}, {Image#affine} and
6
+ # so on.
7
+ #
8
+ # * `:black` new pixels are black, ie. all bits are zero.
9
+ # * `:copy` each new pixel takes the value of the nearest edge pixel
10
+ # * `:repeat` the image is tiled to fill the new area
11
+ # * `:mirror` the image is reflected and tiled to reduce hash edges
12
+ # * `:white` new pixels are white, ie. all bits are set
13
+ # * `:background` colour set from the @background property
14
+
15
+ class Extend < Symbol
16
+ end
17
+ end
@@ -0,0 +1,122 @@
1
+ # This module provides an interface to the top level bits of GObject
2
+ # via ruby-ffi.
3
+ #
4
+ # Author:: John Cupitt (mailto:jcupitt@gmail.com)
5
+ # License:: MIT
6
+
7
+ require 'ffi'
8
+ require 'forwardable'
9
+
10
+ module GObject
11
+
12
+ # we have a number of things we need to inherit in different ways:
13
+ #
14
+ # - we want to be able to subclass GObject in Ruby in a simple way
15
+ # - the layouts of the nested structs need to inherit
16
+ # - we need to be able to cast between structs which share a base struct
17
+ # without creating new wrappers or messing up refcounting
18
+ # - we need automatic gobject refcounting
19
+ #
20
+ # the solution is to split the class into four areas which we treat
21
+ # differently:
22
+ #
23
+ # - we have a "wrapper" Ruby class to allow easy subclassing ... this has a
24
+ # @struct member which holds the actual pointer
25
+ # - we use "forwardable" to forward the various ffi methods on to the
26
+ # @struct member ... we arrange things so that subclasses do not need to
27
+ # do the forwarding themselves
28
+ # - we have two versions of the struct: a plain one which we can use for
29
+ # casting that will not change the refcounts
30
+ # - and a managed one with an unref which we just use for .new
31
+ # - we separate the struct layout into a separate module to avoid repeating
32
+ # ourselves
33
+
34
+ class GObject
35
+ extend Forwardable
36
+ extend SingleForwardable
37
+
38
+ def_instance_delegators :@struct, :[], :to_ptr
39
+ def_single_delegators :ffi_struct, :ptr
40
+
41
+ # the layout of the GObject struct
42
+ module GObjectLayout
43
+ def self.included base
44
+ base.class_eval do
45
+ layout :g_type_instance, :pointer,
46
+ :ref_count, :uint,
47
+ :qdata, :pointer
48
+ end
49
+ end
50
+ end
51
+
52
+ # the struct with unref ... manage object lifetime with this
53
+ class ManagedStruct < FFI::ManagedStruct
54
+ include GObjectLayout
55
+
56
+ def self.release ptr
57
+ # GLib::logger.debug("GObject::GObject::ManagedStruct.release") {
58
+ # "unreffing #{ptr}"
59
+ # }
60
+ ::GObject::g_object_unref ptr
61
+ end
62
+ end
63
+
64
+ # the plain struct ... cast with this
65
+ class Struct < FFI::Struct
66
+ include GObjectLayout
67
+
68
+ end
69
+
70
+ # don't allow ptr == nil, we never want to allocate a GObject struct
71
+ # ourselves, we just want to wrap GLib-allocated GObjects
72
+ #
73
+ # here we use ManagedStruct, not Struct, since this is the ref that will
74
+ # need the unref
75
+ def initialize ptr
76
+ # GLib::logger.debug("GObject::GObject.initialize") {"ptr = #{ptr}"}
77
+ @struct = ffi_managed_struct.new ptr
78
+ end
79
+
80
+ # access to the casting struct for this class
81
+ def ffi_struct
82
+ self.class.ffi_struct
83
+ end
84
+
85
+ class << self
86
+ def ffi_struct
87
+ self.const_get :Struct
88
+ end
89
+ end
90
+
91
+ # access to the managed struct for this class
92
+ def ffi_managed_struct
93
+ self.class.ffi_managed_struct
94
+ end
95
+
96
+ class << self
97
+ def ffi_managed_struct
98
+ self.const_get :ManagedStruct
99
+ end
100
+ end
101
+
102
+ end
103
+
104
+ class GParamSpec < FFI::Struct
105
+ # the first few public fields
106
+ layout :g_type_instance, :pointer,
107
+ :name, :string,
108
+ :flags, :uint,
109
+ :value_type, :GType,
110
+ :owner_type, :GType
111
+ end
112
+
113
+ class GParamSpecPtr < FFI::Struct
114
+ layout :value, GParamSpec.ptr
115
+ end
116
+
117
+ attach_function :g_param_spec_get_blurb, [GParamSpec.ptr], :string
118
+
119
+ attach_function :g_object_ref, [:pointer], :void
120
+ attach_function :g_object_unref, [:pointer], :void
121
+
122
+ end
@@ -0,0 +1,281 @@
1
+ # This module provides an interface GValue via ruby-ffi.
2
+ #
3
+ # Author:: John Cupitt (mailto:jcupitt@gmail.com)
4
+ # License:: MIT
5
+
6
+ require 'ffi'
7
+
8
+ module GObject
9
+
10
+ # Represent a GValue. Example use:
11
+ #
12
+ # ```ruby
13
+ # gvalue = GValue::alloc
14
+ # gvalue.init GObject::GDOUBLE_TYPE
15
+ # gvalue.set 3.1415
16
+ # value = gvalue.get
17
+ # ```
18
+ #
19
+ # Lifetime is managed automatically. It doesn't know about all GType values,
20
+ # but it does know the ones that libvips uses.
21
+
22
+ class GValue < FFI::ManagedStruct
23
+ layout :gtype, :GType,
24
+ :data, [:ulong_long, 2]
25
+
26
+ # convert an enum value (str/symb/int) into an int ready for libvips
27
+ def self.from_nick(gtype, value)
28
+ value = value.to_s if value.is_a? Symbol
29
+
30
+ if value.is_a? String
31
+ value = Vips::vips_enum_from_nick "ruby-vips", gtype, value
32
+ if value == -1
33
+ raise Vips::Error
34
+ end
35
+ end
36
+
37
+ value
38
+ end
39
+
40
+ # convert an int enum back into a symbol
41
+ def self.to_nick(gtype, enum_value)
42
+ enum_name = Vips::vips_enum_nick gtype, enum_value
43
+ if enum_name == nil
44
+ raise Vips::Error
45
+ end
46
+
47
+ enum_name.to_sym
48
+ end
49
+
50
+ def self.release ptr
51
+ # GLib::logger.debug("GObject::GValue::release") {"ptr = #{ptr}"}
52
+ ::GObject::g_value_unset ptr
53
+ end
54
+
55
+ # Allocate memory for a GValue and return a class wrapper. Memory will
56
+ # be freed automatically when it goes out of scope. The GValue is inited
57
+ # to 0, use {GValue.init} to set a type.
58
+ #
59
+ # @return [GValue] a new gvalue set to 0
60
+ def self.alloc
61
+ # allocate memory
62
+ memory = FFI::MemoryPointer.new GValue
63
+
64
+ # make this alloc autorelease ... we mustn't release in
65
+ # GValue::release, since we are used to wrap GValue pointers
66
+ # made by other people
67
+ pointer = FFI::Pointer.new GValue, memory
68
+
69
+ # ... and wrap in a GValue
70
+ return GValue.new pointer
71
+ end
72
+
73
+ # Set the type of thing a gvalue can hold.
74
+ #
75
+ # @param gtype [GType] the type of thing this GValue can hold.
76
+ def init gtype
77
+ ::GObject::g_value_init self, gtype
78
+ end
79
+
80
+ # Set the value of a GValue. The value is converted to the type of the
81
+ # GValue, if possible.
82
+ #
83
+ # @param value [Any] The value to set
84
+ def set value
85
+ # GLib::logger.debug("GObject::GValue.set") {
86
+ # "value = #{value.inspect[0..50]}"
87
+ # }
88
+
89
+ gtype = self[:gtype]
90
+ fundamental = ::GObject::g_type_fundamental gtype
91
+
92
+ case gtype
93
+ when GBOOL_TYPE
94
+ ::GObject::g_value_set_boolean self, (value ? 1 : 0)
95
+
96
+ when GINT_TYPE
97
+ ::GObject::g_value_set_int self, value
98
+
99
+ when GUINT64_TYPE
100
+ ::GObject::g_value_set_uint64 self, value
101
+
102
+ when GDOUBLE_TYPE
103
+ ::GObject::g_value_set_double self, value
104
+
105
+ when GSTR_TYPE
106
+ ::GObject::g_value_set_string self, value
107
+
108
+ when Vips::REFSTR_TYPE
109
+ ::Vips::vips_value_set_ref_string self, value
110
+
111
+ when Vips::ARRAY_INT_TYPE
112
+ value = [value] unless value.is_a? Array
113
+
114
+ Vips::vips_value_set_array_int self, nil, value.length
115
+ ptr = Vips::vips_value_get_array_int self, nil
116
+ ptr.write_array_of_int32 value
117
+
118
+ when Vips::ARRAY_DOUBLE_TYPE
119
+ value = [value] unless value.is_a? Array
120
+
121
+ # this will allocate an array in the gvalue
122
+ Vips::vips_value_set_array_double self, nil, value.length
123
+
124
+ # pull the array out and fill it
125
+ ptr = Vips::vips_value_get_array_double self, nil
126
+
127
+ ptr.write_array_of_double value
128
+
129
+ when Vips::ARRAY_IMAGE_TYPE
130
+ value = [value] unless value.is_a? Array
131
+
132
+ Vips::vips_value_set_array_image self, value.length
133
+ ptr = Vips::vips_value_get_array_image self, nil
134
+ ptr.write_array_of_pointer value
135
+
136
+ # the gvalue needs a ref on each of the images
137
+ value.each {|image| ::GObject::g_object_ref image}
138
+
139
+ when Vips::BLOB_TYPE
140
+ len = value.bytesize
141
+ ptr = GLib::g_malloc len
142
+ Vips::vips_value_set_blob self, GLib::G_FREE, ptr, len
143
+ ptr.write_bytes value
144
+
145
+ else
146
+ case fundamental
147
+ when GFLAGS_TYPE
148
+ ::GObject::g_value_set_flags self, value
149
+
150
+ when GENUM_TYPE
151
+ enum_value = GValue.from_nick(self[:gtype], value)
152
+ ::GObject::g_value_set_enum self, enum_value
153
+
154
+ when GOBJECT_TYPE
155
+ ::GObject::g_value_set_object self, value
156
+
157
+ else
158
+ raise Vips::Error, "unimplemented gtype for set: " +
159
+ "#{::GObject::g_type_name gtype} (#{gtype})"
160
+
161
+ end
162
+ end
163
+ end
164
+
165
+ # Get the value of a GValue. The value is converted to a Ruby type in
166
+ # the obvious way.
167
+ #
168
+ # @return [Any] the value held by the GValue
169
+ def get
170
+ gtype = self[:gtype]
171
+ fundamental = ::GObject::g_type_fundamental gtype
172
+ result = nil
173
+
174
+ case gtype
175
+ when GBOOL_TYPE
176
+ result = ::GObject::g_value_get_boolean(self) != 0 ? true : false
177
+
178
+ when GINT_TYPE
179
+ result = ::GObject::g_value_get_int self
180
+
181
+ when GUINT64_TYPE
182
+ result = ::GObject::g_value_get_uint64 self
183
+
184
+ when GDOUBLE_TYPE
185
+ result = ::GObject::g_value_get_double self
186
+
187
+ when GSTR_TYPE
188
+ result = ::GObject::g_value_get_string self
189
+
190
+ when Vips::REFSTR_TYPE
191
+ len = Vips::SizeStruct.new
192
+ result = ::Vips::vips_value_get_ref_string self, len
193
+
194
+ when Vips::ARRAY_INT_TYPE
195
+ len = Vips::IntStruct.new
196
+ array = Vips::vips_value_get_array_int self, len
197
+ result = array.get_array_of_int32 0, len[:value]
198
+
199
+ when Vips::ARRAY_DOUBLE_TYPE
200
+ len = Vips::IntStruct.new
201
+ array = Vips::vips_value_get_array_double self, len
202
+ result = array.get_array_of_double 0, len[:value]
203
+
204
+ when Vips::ARRAY_IMAGE_TYPE
205
+ len = Vips::IntStruct.new
206
+ array = Vips::vips_value_get_array_image self, len
207
+ result = array.get_array_of_pointer 0, len[:value]
208
+ result.map! do |pointer|
209
+ ::GObject::g_object_ref pointer
210
+ Vips::Image.new pointer
211
+ end
212
+
213
+ when Vips::BLOB_TYPE
214
+ len = Vips::SizeStruct.new
215
+ array = Vips::vips_value_get_blob self, len
216
+ result = array.get_bytes 0, len[:value]
217
+
218
+ else
219
+ case fundamental
220
+ when GFLAGS_TYPE
221
+ result = ::GObject::g_value_get_flags self
222
+
223
+ when GENUM_TYPE
224
+ enum_value = ::GObject::g_value_get_enum(self)
225
+ result = GValue.to_nick self[:gtype], enum_value
226
+
227
+ when GOBJECT_TYPE
228
+ obj = ::GObject::g_value_get_object self
229
+ # g_value_get_object() does not add a ref ... we need to add
230
+ # one to match the unref in gobject release
231
+ ::GObject::g_object_ref obj
232
+ result = Vips::Image.new obj
233
+
234
+ else
235
+ raise Vips::Error, "unimplemented gtype for get: " +
236
+ "#{::GObject::g_type_name gtype} (#{gtype})"
237
+
238
+ end
239
+ end
240
+
241
+ # GLib::logger.debug("GObject::GValue.get") {
242
+ # "result = #{result.inspect[0..50]}"
243
+ # }
244
+
245
+ return result
246
+
247
+ end
248
+
249
+ end
250
+
251
+ attach_function :g_value_init, [GValue.ptr, :GType], :void
252
+
253
+ # we must use a plain :pointer here, since we call this from #release, which
254
+ # just gives us the unwrapped pointer, not the ruby class
255
+ attach_function :g_value_unset, [:pointer], :void
256
+
257
+ attach_function :g_value_set_boolean, [GValue.ptr, :int], :void
258
+ attach_function :g_value_set_int, [GValue.ptr, :int], :void
259
+ attach_function :g_value_set_uint64, [GValue.ptr, :uint64], :void
260
+ attach_function :g_value_set_double, [GValue.ptr, :double], :void
261
+ attach_function :g_value_set_enum, [GValue.ptr, :int], :void
262
+ attach_function :g_value_set_flags, [GValue.ptr, :uint], :void
263
+ attach_function :g_value_set_string, [GValue.ptr, :string], :void
264
+ attach_function :g_value_set_object, [GValue.ptr, :pointer], :void
265
+
266
+ attach_function :g_value_get_boolean, [GValue.ptr], :int
267
+ attach_function :g_value_get_int, [GValue.ptr], :int
268
+ attach_function :g_value_get_uint64, [GValue.ptr], :uint64
269
+ attach_function :g_value_get_double, [GValue.ptr], :double
270
+ attach_function :g_value_get_enum, [GValue.ptr], :int
271
+ attach_function :g_value_get_flags, [GValue.ptr], :int
272
+ attach_function :g_value_get_string, [GValue.ptr], :string
273
+ attach_function :g_value_get_object, [GValue.ptr], :pointer
274
+
275
+ # use :pointer rather than GObject.ptr to avoid casting later
276
+ attach_function :g_object_set_property,
277
+ [:pointer, :string, GValue.ptr], :void
278
+ attach_function :g_object_get_property,
279
+ [:pointer, :string, GValue.ptr], :void
280
+
281
+ end