ruby-vips 1.0.6 → 2.0.0

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.
@@ -6,9 +6,6 @@ module Vips
6
6
  # * `:sequential` means requests will be top-to-bottom, but with some
7
7
  # amount of buffering behind the read point for small non-local
8
8
  # accesses.
9
- #
10
- # * `:sequential_unbuffered` means requests will be strictly
11
- # top-to-bottom with no read-behind. This can save some memory.
12
- class Access
9
+ class Access < Symbol
13
10
  end
14
11
  end
@@ -1,11 +1,11 @@
1
1
  module Vips
2
2
 
3
- # Various types of alignment. See {Vips::Image.join}, for example.
3
+ # Various types of alignment. See {Image#join}, for example.
4
4
  #
5
5
  # * `:low` Align on the low coordinate edge
6
6
  # * `:centre` Align on the centre
7
7
  # * `:high` Align on the high coordinate edge
8
8
 
9
- class Align
9
+ class Align < Symbol
10
10
  end
11
11
  end
@@ -1,12 +1,12 @@
1
1
  module Vips
2
2
 
3
- # Various fixed 90 degree rotation angles. See {Vips::Image.rot}.
3
+ # Various fixed 90 degree rotation angles. See {Image#rot}.
4
4
  #
5
5
  # * `:d0` no rotate
6
6
  # * `:d90` 90 degrees clockwise
7
7
  # * `:d180` 180 degrees
8
8
  # * `:d270` 90 degrees anti-clockwise
9
9
 
10
- class Angle
10
+ class Angle < Symbol
11
11
  end
12
12
  end
@@ -1,6 +1,6 @@
1
1
  module Vips
2
2
 
3
- # Various fixed 45 degree rotation angles. See {Vips::Image.rot45}.
3
+ # Various fixed 45 degree rotation angles. See {Image#rot45}.
4
4
  #
5
5
  # * `:d0` no rotate
6
6
  # * `:d45` 45 degrees clockwise
@@ -11,6 +11,6 @@ module Vips
11
11
  # * `:d270` 90 degrees anti-clockwise
12
12
  # * `:d315` 45 degrees anti-clockwise
13
13
 
14
- class Angle45
14
+ class Angle45 < Symbol
15
15
  end
16
16
  end
@@ -14,7 +14,7 @@ module Vips
14
14
  # * `:complex` complex (two floats) format
15
15
  # * `:double` double float format
16
16
  # * `:dpcomplex` double complex (two double) format
17
- class BandFormat
17
+ class BandFormat < Symbol
18
18
  end
19
19
 
20
20
  end
@@ -9,6 +9,6 @@ module Vips
9
9
  # * `:none` pixels are not coded
10
10
  # * `:labq` pixels encode 3 float CIELAB values as 4 uchar
11
11
  # * `:rad` pixels encode 3 float RGB as 4 uchar (Radiance coding)
12
- class Coding
12
+ class Coding < Symbol
13
13
  end
14
14
  end
@@ -1,11 +1,11 @@
1
1
  module Vips
2
2
 
3
- # Operations like {Vips::Image.flip} need to be told whether to flip
3
+ # Operations like {Image#flip} need to be told whether to flip
4
4
  # left-right or top-bottom.
5
5
  #
6
6
  # * `:horizontal` left-right
7
7
  # * `:vertical` top-bottom
8
8
 
9
- class Direction
9
+ class Direction < Symbol
10
10
  end
11
11
  end
@@ -2,21 +2,16 @@ module Vips
2
2
 
3
3
  # When the edges of an image are extended, you can specify
4
4
  # how you want the extension done.
5
- # See {Vips::Image.embed}, {Vips::Image.conv}, {Vips::Image.affine} and
5
+ # See {Image#embed}, {Image#conv}, {Image#affine} and
6
6
  # so on.
7
7
  #
8
- # * `:black` new pixels are black, ie. all bits are zero.
9
- #
10
- # * `:copy` each new pixel takes the value of the nearest edge pixel
11
- #
12
- # * `:repeat` the image is tiled to fill the new area
13
- #
14
- # * `:mirror` the image is reflected and tiled to reduce hash edges
15
- #
16
- # * `:white` new pixels are white, ie. all bits are set
17
- #
18
- # * `:background` colour set from the @background property
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
19
14
 
20
- class Extend
15
+ class Extend < Symbol
21
16
  end
22
17
  end
@@ -0,0 +1,121 @@
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
+ # Vips::log "GObject::GObject::ManagedStruct.release: " +
58
+ # "unreffing #{ptr}"
59
+ GObject::g_object_unref ptr
60
+ end
61
+ end
62
+
63
+ # the plain struct ... cast with this
64
+ class Struct < FFI::Struct
65
+ include GObjectLayout
66
+
67
+ end
68
+
69
+ # don't allow ptr == nil, we never want to allocate a GObject struct
70
+ # ourselves, we just want to wrap GLib-allocated GObjects
71
+ #
72
+ # here we use ManagedStruct, not Struct, since this is the ref that will
73
+ # need the unref
74
+ def initialize ptr
75
+ # Vips::log "GObject::GObject.initialize: ptr = #{ptr}"
76
+ @struct = ffi_managed_struct.new ptr
77
+ end
78
+
79
+ # access to the casting struct for this class
80
+ def ffi_struct
81
+ self.class.ffi_struct
82
+ end
83
+
84
+ class << self
85
+ def ffi_struct
86
+ self.const_get :Struct
87
+ end
88
+ end
89
+
90
+ # access to the managed struct for this class
91
+ def ffi_managed_struct
92
+ self.class.ffi_managed_struct
93
+ end
94
+
95
+ class << self
96
+ def ffi_managed_struct
97
+ self.const_get :ManagedStruct
98
+ end
99
+ end
100
+
101
+ end
102
+
103
+ class GParamSpec < FFI::Struct
104
+ # the first few public fields
105
+ layout :g_type_instance, :pointer,
106
+ :name, :string,
107
+ :flags, :uint,
108
+ :value_type, :GType,
109
+ :owner_type, :GType
110
+ end
111
+
112
+ attach_function :g_param_spec_get_blurb, [GParamSpec.ptr], :string
113
+
114
+ attach_function :g_object_ref, [:pointer], :void
115
+ attach_function :g_object_unref, [:pointer], :void
116
+
117
+ class GParamSpecPtr < FFI::Struct
118
+ layout :value, GParamSpec.ptr
119
+ end
120
+
121
+ end
@@ -0,0 +1,251 @@
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
+ def self.release ptr
27
+ # Vips::log "GObject::GValue::release ptr = #{ptr}"
28
+ ::GObject::g_value_unset ptr
29
+ end
30
+
31
+ # Allocate memory for a GValue and return a class wrapper. Memory will
32
+ # be freed automatically when it goes out of scope. The GValue is inited
33
+ # to 0, use {GValue.init} to set a type.
34
+ #
35
+ # @return [GValue] a new gvalue set to 0
36
+ def self.alloc
37
+ # allocate memory
38
+ memory = FFI::MemoryPointer.new GValue
39
+
40
+ # make this alloc autorelease ... we mustn't release in
41
+ # GValue::release, since we are used to wrap GValue pointers
42
+ # made by other people
43
+ pointer = FFI::Pointer.new GValue, memory
44
+
45
+ # ... and wrap in a GValue
46
+ return GValue.new pointer
47
+ end
48
+
49
+ # Set the type of thing a gvalue can hold.
50
+ #
51
+ # @param gtype [GType] the type of thing this GValue can hold.
52
+ def init gtype
53
+ ::GObject::g_value_init self, gtype
54
+ end
55
+
56
+ # Set the value of a GValue. The value is converted to the type of the
57
+ # GValue, if possible.
58
+ #
59
+ # @param value [Any] The value to set
60
+ def set value
61
+ # Vips::log "GObject::GValue.set: value = #{value.inspect[0..50]}"
62
+
63
+ gtype = self[:gtype]
64
+ fundamental = ::GObject::g_type_fundamental gtype
65
+
66
+ case gtype
67
+ when GBOOL_TYPE
68
+ ::GObject::g_value_set_boolean self, (value ? 1 : 0)
69
+
70
+ when GINT_TYPE
71
+ ::GObject::g_value_set_int self, value
72
+
73
+ when GDOUBLE_TYPE
74
+ ::GObject::g_value_set_double self, value
75
+
76
+ when GSTR_TYPE
77
+ # set_string takes a copy, no lifetime worries
78
+ ::GObject::g_value_set_string self, value
79
+
80
+ when Vips::ARRAY_INT_TYPE
81
+ value = [value] if not value.is_a? Array
82
+
83
+ Vips::vips_value_set_array_int self, nil, value.length
84
+ ptr = Vips::vips_value_get_array_int self, nil
85
+ ptr.write_array_of_int32 value
86
+
87
+ when Vips::ARRAY_DOUBLE_TYPE
88
+ value = [value] if not value.is_a? Array
89
+
90
+ # this will allocate an array in the gvalue
91
+ Vips::vips_value_set_array_double self, nil, value.length
92
+
93
+ # pull the array out and fill it
94
+ ptr = Vips::vips_value_get_array_double self, nil
95
+
96
+ ptr.write_array_of_double value
97
+
98
+ when Vips::ARRAY_IMAGE_TYPE
99
+ value = [value] if not value.is_a? Array
100
+
101
+ Vips::vips_value_set_array_image self, value.length
102
+ ptr = Vips::vips_value_get_array_image self, nil
103
+ ptr.write_array_of_pointer value
104
+
105
+ # the gvalue needs a ref on each of the images
106
+ value.each {|image| ::GObject::g_object_ref image}
107
+
108
+ when Vips::BLOB_TYPE
109
+ len = value.length
110
+ ptr = GLib::g_malloc len
111
+ Vips::vips_value_set_blob self, GLib::G_FREE, ptr, len
112
+ ptr.write_bytes value
113
+
114
+ else
115
+ case fundamental
116
+ when GFLAGS_TYPE
117
+ ::GObject::g_value_set_flags self, value
118
+
119
+ when GENUM_TYPE
120
+ value = value.to_s if value.is_a? Symbol
121
+
122
+ if value.is_a? String
123
+ value = Vips::vips_enum_from_nick "ruby-vips",
124
+ self[:gtype], value
125
+ if value == -1
126
+ raise Vips::Error
127
+ end
128
+ end
129
+
130
+ ::GObject::g_value_set_enum self, value
131
+
132
+ when GOBJECT_TYPE
133
+ ::GObject::g_value_set_object self, value
134
+
135
+ else
136
+ raise Vips::Error, "unimplemented gtype for set: #{gtype}"
137
+ end
138
+ end
139
+ end
140
+
141
+ # Get the value of a GValue. The value is converted to a Ruby type in
142
+ # the obvious way.
143
+ #
144
+ # @return [Any] the value held by the GValue
145
+ def get
146
+ gtype = self[:gtype]
147
+ fundamental = ::GObject::g_type_fundamental gtype
148
+ result = nil
149
+
150
+ case gtype
151
+ when GBOOL_TYPE
152
+ result = ::GObject::g_value_get_boolean(self) != 0 ? true : false
153
+
154
+ when GINT_TYPE
155
+ result = ::GObject::g_value_get_int self
156
+
157
+ when GDOUBLE_TYPE
158
+ result = ::GObject::g_value_get_double self
159
+
160
+ when GSTR_TYPE
161
+ # FIXME do we need to strdup here?
162
+ result = ::GObject::g_value_get_string self
163
+
164
+ when Vips::ARRAY_INT_TYPE
165
+ len = Vips::IntStruct.new
166
+ array = Vips::vips_value_get_array_int self, len
167
+ result = array.get_array_of_int32 0, len[:value]
168
+
169
+ when Vips::ARRAY_DOUBLE_TYPE
170
+ len = Vips::IntStruct.new
171
+ array = Vips::vips_value_get_array_double self, len
172
+ result = array.get_array_of_double 0, len[:value]
173
+
174
+ when Vips::ARRAY_IMAGE_TYPE
175
+ len = Vips::IntStruct.new
176
+ array = Vips::vips_value_get_array_image self, len
177
+ result = array.get_array_of_pointer 0, len[:value]
178
+ result.map! do |pointer|
179
+ ::GObject::g_object_ref pointer
180
+ Vips::Image.new pointer
181
+ end
182
+
183
+ when Vips::BLOB_TYPE
184
+ len = Vips::SizeStruct.new
185
+ array = Vips::vips_value_get_blob self, len
186
+ result = array.get_bytes 0, len[:value]
187
+
188
+ else
189
+ case fundamental
190
+ when GFLAGS_TYPE
191
+ result = ::GObject::g_value_get_flags self
192
+
193
+ when GENUM_TYPE
194
+ enum_value = ::GObject::g_value_get_enum self
195
+ # this returns a static string, no need to worry about
196
+ # lifetime
197
+ enum_name = Vips::vips_enum_nick self[:gtype], enum_value
198
+ if enum_name == nil
199
+ raise Vips::Error
200
+ end
201
+ result = enum_name.to_sym
202
+
203
+ when GOBJECT_TYPE
204
+ obj = ::GObject::g_value_get_object self
205
+ # g_value_get_object() does not add a ref ... we need to add
206
+ # one to match the unref in gobject release
207
+ ::GObject::g_object_ref obj
208
+ result = Vips::Image.new obj
209
+
210
+ else
211
+ raise Vips::Error, "unimplemented gtype for get: #{gtype}"
212
+
213
+ end
214
+ end
215
+
216
+ # Vips::log "GObject::GValue.get: result = #{result.inspect[0..50]}"
217
+
218
+ return result
219
+ end
220
+
221
+ end
222
+
223
+ attach_function :g_value_init, [GValue.ptr, :GType], :void
224
+
225
+ # we must use a plain :pointer here, since we call this from #release, which
226
+ # just gives us the unwrapped pointer, not the ruby class
227
+ attach_function :g_value_unset, [:pointer], :void
228
+
229
+ attach_function :g_value_set_boolean, [GValue.ptr, :int], :void
230
+ attach_function :g_value_set_int, [GValue.ptr, :int], :void
231
+ attach_function :g_value_set_double, [GValue.ptr, :double], :void
232
+ attach_function :g_value_set_enum, [GValue.ptr, :int], :void
233
+ attach_function :g_value_set_flags, [GValue.ptr, :uint], :void
234
+ attach_function :g_value_set_string, [GValue.ptr, :string], :void
235
+ attach_function :g_value_set_object, [GValue.ptr, :pointer], :void
236
+
237
+ attach_function :g_value_get_boolean, [GValue.ptr], :int
238
+ attach_function :g_value_get_int, [GValue.ptr], :int
239
+ attach_function :g_value_get_double, [GValue.ptr], :double
240
+ attach_function :g_value_get_enum, [GValue.ptr], :int
241
+ attach_function :g_value_get_flags, [GValue.ptr], :int
242
+ attach_function :g_value_get_string, [GValue.ptr], :string
243
+ attach_function :g_value_get_object, [GValue.ptr], :pointer
244
+
245
+ # use :pointer rather than GObject.ptr to avoid casting later
246
+ attach_function :g_object_set_property,
247
+ [:pointer, :string, GValue.ptr], :void
248
+ attach_function :g_object_get_property,
249
+ [:pointer, :string, GValue.ptr], :void
250
+
251
+ end