vips 8.8.4 → 8.12.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
- require 'ffi'
4
- require 'forwardable'
3
+ require "ffi"
4
+ require "forwardable"
5
5
 
6
6
  # this is really very crude logging
7
7
 
@@ -29,7 +29,7 @@ end
29
29
 
30
30
  module GLib
31
31
  extend FFI::Library
32
- ffi_lib 'gobject-2.0'
32
+ ffi_lib "gobject-2.0"
33
33
 
34
34
  def self.set_log_domain(_domain)
35
35
  # FIXME: this needs hooking up
@@ -68,8 +68,8 @@ module GLib
68
68
  def self.included(base)
69
69
  base.class_eval do
70
70
  layout :g_type_instance, :pointer,
71
- :ref_count, :uint,
72
- :qdata, :pointer
71
+ :ref_count, :uint,
72
+ :qdata, :pointer
73
73
  end
74
74
  end
75
75
  end
@@ -85,7 +85,7 @@ module GLib
85
85
 
86
86
  def self.release(ptr)
87
87
  log "GLib::GObject::ManagedStruct.release: unreffing #{ptr}"
88
- GLib::g_object_unref(ptr) unless ptr.null?
88
+ GLib.g_object_unref(ptr) unless ptr.null?
89
89
  end
90
90
  end
91
91
 
@@ -116,7 +116,7 @@ module GLib
116
116
 
117
117
  class << self
118
118
  def ffi_struct
119
- self.const_get(:Struct)
119
+ const_get(:Struct)
120
120
  end
121
121
  end
122
122
 
@@ -127,24 +127,32 @@ module GLib
127
127
 
128
128
  class << self
129
129
  def ffi_managed_struct
130
- self.const_get(:ManagedStruct)
130
+ const_get(:ManagedStruct)
131
131
  end
132
132
  end
133
133
  end
134
134
 
135
- # :gtype will usually be 64-bit, but will be 32-bit on 32-bit Windows
136
- typedef :ulong, :GType
135
+ # we can't just use ulong, windows has different int sizing rules
136
+ if FFI::Platform::ADDRESS_SIZE == 64
137
+ typedef :uint64, :GType
138
+ else
139
+ typedef :uint32, :GType
140
+ end
137
141
  end
138
142
 
139
143
  module Vips
140
144
  extend FFI::Library
141
- ffi_lib 'vips'
145
+ ffi_lib "vips"
142
146
 
143
147
  LOG_DOMAIN = "VIPS"
144
- GLib::set_log_domain(LOG_DOMAIN)
148
+ GLib.set_log_domain(LOG_DOMAIN)
145
149
 
146
150
  # need to repeat this
147
- typedef :ulong, :GType
151
+ if FFI::Platform::ADDRESS_SIZE == 64
152
+ typedef :uint64, :GType
153
+ else
154
+ typedef :uint32, :GType
155
+ end
148
156
 
149
157
  attach_function :vips_init, [:string], :int
150
158
  attach_function :vips_shutdown, [], :void
@@ -153,19 +161,19 @@ module Vips
153
161
  attach_function :vips_error_clear, [], :void
154
162
 
155
163
  def self.get_error
156
- errstr = Vips::vips_error_buffer
157
- Vips::vips_error_clear
164
+ errstr = Vips.vips_error_buffer
165
+ Vips.vips_error_clear
158
166
  errstr
159
167
  end
160
168
 
161
- if Vips::vips_init($0) != 0
162
- puts Vips::get_error
169
+ if Vips.vips_init($0) != 0
170
+ puts Vips.get_error
163
171
  exit 1
164
172
  end
165
173
 
166
- at_exit {
167
- Vips::vips_shutdown
168
- }
174
+ at_exit do
175
+ Vips.vips_shutdown
176
+ end
169
177
 
170
178
  attach_function :vips_object_print_all, [], :void
171
179
  attach_function :vips_leak_set, [:int], :void
@@ -188,15 +196,15 @@ module Vips
188
196
  base.class_eval do
189
197
  # don't actually need most of these, remove them later
190
198
  layout :parent, GLib::GObject::Struct,
191
- :constructed, :int,
192
- :static_object, :int,
193
- :argument_table, :pointer,
194
- :nickname, :string,
195
- :description, :string,
196
- :preclose, :int,
197
- :close, :int,
198
- :postclose, :int,
199
- :local_memory, :size_t
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
200
208
  end
201
209
  end
202
210
  end
@@ -250,7 +258,7 @@ module Vips
250
258
  end
251
259
 
252
260
  def self.new_partial
253
- VipsImage.new(Vips::vips_image_new)
261
+ VipsImage.new(Vips.vips_image_new)
254
262
  end
255
263
  end
256
264
 
@@ -258,12 +266,11 @@ module Vips
258
266
  end
259
267
 
260
268
  puts "creating image"
261
- begin
262
- x = Vips::VipsImage.new_partial
263
- puts "x = #{x}"
264
- puts ""
265
- puts "x[:parent] = #{x[:parent]}"
266
- puts ""
267
- puts "x[:parent][:description] = #{x[:parent][:description]}"
268
- puts ""
269
- end
269
+
270
+ x = Vips::VipsImage.new_partial
271
+ puts "x = #{x}"
272
+ puts ""
273
+ puts "x[:parent] = #{x[:parent]}"
274
+ puts ""
275
+ puts "x[:parent][:description] = #{x[:parent][:description]}"
276
+ puts ""
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require "vips"
4
+
5
+ image = Vips::Image.black 1, 100000
6
+ image.set_progress true
7
+
8
+ def progress_to_s(name, progress)
9
+ puts "#{name}:"
10
+ puts " progress.run = #{progress[:run]}"
11
+ puts " progress.eta = #{progress[:eta]}"
12
+ puts " progress.tpels = #{progress[:tpels]}"
13
+ puts " progress.npels = #{progress[:npels]}"
14
+ puts " progress.percent = #{progress[:percent]}"
15
+ end
16
+
17
+ image.signal_connect :preeval do |progress|
18
+ progress_to_s("preeval", progress)
19
+ end
20
+
21
+ image.signal_connect :eval do |progress|
22
+ progress_to_s("eval", progress)
23
+ image.set_kill(true) if progress[:percent] > 50
24
+ end
25
+
26
+ image.signal_connect :posteval do |progress|
27
+ progress_to_s("posteval", progress)
28
+ end
29
+
30
+ image.avg
data/example/thumb.rb CHANGED
@@ -1,25 +1,25 @@
1
- #!/usr/bin/env ruby
1
+ #!/usr/bin/ruby
2
2
 
3
3
  # batch-process a lot of files
4
4
  #
5
5
  # this should run in constant memory -- if it doesn't, something has broken
6
6
 
7
- require 'vips'
7
+ require "vips"
8
8
 
9
9
  # benchmark thumbnail via a memory buffer
10
10
  def via_memory(filename, thumbnail_width)
11
11
  data = IO.binread(filename)
12
12
 
13
- thumb = Vips::Image.thumbnail_buffer data, thumbnail_width, crop: 'centre'
13
+ thumb = Vips::Image.thumbnail_buffer data, thumbnail_width, crop: "centre"
14
14
 
15
- thumb.write_to_buffer '.jpg'
15
+ thumb.write_to_buffer ".jpg"
16
16
  end
17
17
 
18
18
  # benchmark thumbnail via files
19
19
  def via_files(filename, thumbnail_width)
20
- thumb = Vips::Image.thumbnail filename, thumbnail_width, crop: 'centre'
20
+ thumb = Vips::Image.thumbnail filename, thumbnail_width, crop: "centre"
21
21
 
22
- thumb.write_to_buffer '.jpg'
22
+ thumb.write_to_buffer ".jpg"
23
23
  end
24
24
 
25
25
  ARGV.each do |filename|
data/example/trim8.rb CHANGED
@@ -7,7 +7,7 @@
7
7
  # non-zero row or column is the object edge. We make the mask image with an
8
8
  # amount-different-from-background image plus a threshold.
9
9
 
10
- require 'vips'
10
+ require "vips"
11
11
 
12
12
  im = Vips::Image.new_from_file ARGV[0]
13
13
 
data/example/watermark.rb CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
- require 'vips'
3
+ require "vips"
4
4
 
5
5
  im = Vips::Image.new_from_file ARGV[0], access: :sequential
6
6
 
7
7
  # make the text mask
8
- text = Vips::Image.text ARGV[2], width: 200, dpi: 200, font: 'sans bold'
8
+ text = Vips::Image.text ARGV[2], width: 200, dpi: 200, font: "sans bold"
9
9
  text = text.rotate(-45)
10
10
  # make the text transparent
11
11
  text = (text * 0.3).cast(:uchar)
data/example/wobble.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
- require 'vips'
3
+ require "vips"
4
4
 
5
5
  image = Vips::Image.new_from_file ARGV[0]
6
6
 
@@ -1,31 +1,35 @@
1
1
  module Vips
2
2
  # Blend mode to use when compositing images. See {Image#composite}.
3
3
  #
4
- # `:clear` - where the second object is drawn, the first is removed
5
- # `:source` - the second object is drawn as if nothing were below
6
- # `:over` - the image shows what you would expect if you held two semi-transparent slides on top of each other
7
- # `:in` - the first object is removed completely, the second is only drawn where the first was
8
- # `:out` - the second is drawn only where the first isn't
9
- # `:atop` - this leaves the first object mostly intact, but mixes both objects in the overlapping area
10
- # `:dest` - leaves the first object untouched, the second is discarded completely
11
- # `:dest_over` - like `:over`, but swaps the arguments
12
- # `:dest_in` - like `:in`, but swaps the arguments
13
- # `:dest_out` - like `:out`, but swaps the arguments
14
- # `:dest_atop` - like `:atop`, but swaps the arguments
15
- # `:xor` - something like a difference operator
16
- # `:add` - a bit like adding the two images
17
- # `:saturate` - a bit like the darker of the two
18
- # `:multiply` - at least as dark as the darker of the two inputs
19
- # `:screen` - at least as light as the lighter of the inputs
20
- # `:overlay` - multiplies or screens colors, depending on the lightness
21
- # `:darken` - the darker of each component
22
- # `:lighten` - the lighter of each component
23
- # `:colour_dodge` - brighten first by a factor second
24
- # `:colour_burn` - darken first by a factor of second
25
- # `:hard_light` - multiply or screen, depending on lightness
26
- # `:soft_light` - darken or lighten, depending on lightness
27
- # `:difference` - difference of the two
28
- # `:exclusion` - somewhat like `:difference`, but lower-contrast
4
+ # * `:clear` where the second object is drawn, the first is removed
5
+ # * `:source` the second object is drawn as if nothing were below
6
+ # * `:over` the image shows what you would expect if you held two
7
+ # semi-transparent slides on top of each other
8
+ # * `:in` the first object is removed completely, the second is only
9
+ # drawn where the first was
10
+ # * `:out` the second is drawn only where the first isn't
11
+ # * `:atop` this leaves the first object mostly intact, but mixes both
12
+ # objects in the overlapping area
13
+ # * `:dest` leaves the first object untouched, the second is discarded
14
+ # completely
15
+ # * `:dest_over` like `:over`, but swaps the arguments
16
+ # * `:dest_in` like `:in`, but swaps the arguments
17
+ # * `:dest_out` like `:out`, but swaps the arguments
18
+ # * `:dest_atop` like `:atop`, but swaps the arguments
19
+ # * `:xor` something like a difference operator
20
+ # * `:add` a bit like adding the two images
21
+ # * `:saturate` a bit like the darker of the two
22
+ # * `:multiply` at least as dark as the darker of the two inputs
23
+ # * `:screen` at least as light as the lighter of the inputs
24
+ # * `:overlay` multiplies or screens colors, depending on the lightness
25
+ # * `:darken` the darker of each component
26
+ # * `:lighten` the lighter of each component
27
+ # * `:colour_dodge` brighten first by a factor second
28
+ # * `:colour_burn` darken first by a factor of second
29
+ # * `:hard_light` multiply or screen, depending on lightness
30
+ # * `:soft_light` darken or lighten, depending on lightness
31
+ # * `:difference` difference of the two
32
+ # * `:exclusion` somewhat like `:difference`, but lower-contrast
29
33
 
30
34
  class BlendMode < Symbol
31
35
  end
@@ -0,0 +1,46 @@
1
+ # This module provides an interface to the top level bits of libvips
2
+ # via ruby-ffi.
3
+ #
4
+ # Author:: John Cupitt (mailto:jcupitt@gmail.com)
5
+ # License:: MIT
6
+
7
+ require "ffi"
8
+
9
+ module Vips
10
+ if Vips.at_least_libvips?(8, 9)
11
+ attach_function :vips_connection_filename, [:pointer], :string
12
+ attach_function :vips_connection_nick, [:pointer], :string
13
+ end
14
+
15
+ # Abstract base class for connections.
16
+ class Connection < Vips::Object
17
+ # The layout of the VipsRegion struct.
18
+ module ConnectionLayout
19
+ def self.included(base)
20
+ base.class_eval do
21
+ layout :parent, Vips::Object::Struct
22
+ # rest opaque
23
+ end
24
+ end
25
+ end
26
+
27
+ class Struct < Vips::Object::Struct
28
+ include ConnectionLayout
29
+ end
30
+
31
+ class ManagedStruct < Vips::Object::ManagedStruct
32
+ include ConnectionLayout
33
+ end
34
+
35
+ # Get any filename associated with a connection, or nil.
36
+ def filename
37
+ Vips.vips_connection_filename self
38
+ end
39
+
40
+ # Get a nickname (short description) of a connection that could be shown to
41
+ # the user.
42
+ def nick
43
+ Vips.vips_connection_nick self
44
+ end
45
+ end
46
+ end
data/lib/vips/gobject.rb CHANGED
@@ -4,8 +4,8 @@
4
4
  # Author:: John Cupitt (mailto:jcupitt@gmail.com)
5
5
  # License:: MIT
6
6
 
7
- require 'ffi'
8
- require 'forwardable'
7
+ require "ffi"
8
+ require "forwardable"
9
9
 
10
10
  module GObject
11
11
  # we have a number of things we need to inherit in different ways:
@@ -37,13 +37,15 @@ module GObject
37
37
  def_instance_delegators :@struct, :[], :to_ptr
38
38
  def_single_delegators :ffi_struct, :ptr
39
39
 
40
+ attr_reader :references
41
+
40
42
  # the layout of the GObject struct
41
43
  module GObjectLayout
42
44
  def self.included base
43
45
  base.class_eval do
44
46
  layout :g_type_instance, :pointer,
45
- :ref_count, :uint,
46
- :qdata, :pointer
47
+ :ref_count, :uint,
48
+ :qdata, :pointer
47
49
  end
48
50
  end
49
51
  end
@@ -56,7 +58,7 @@ module GObject
56
58
  # GLib::logger.debug("GObject::GObject::ManagedStruct.release") {
57
59
  # "unreffing #{ptr}"
58
60
  # }
59
- ::GObject::g_object_unref ptr
61
+ ::GObject.g_object_unref ptr
60
62
  end
61
63
  end
62
64
 
@@ -72,7 +74,11 @@ module GObject
72
74
  # need the unref
73
75
  def initialize ptr
74
76
  # GLib::logger.debug("GObject::GObject.initialize") {"ptr = #{ptr}"}
77
+ @ptr = ptr
75
78
  @struct = ffi_managed_struct.new ptr
79
+
80
+ # sometimes we need to keep refs across C calls ... hide them here
81
+ @references = []
76
82
  end
77
83
 
78
84
  # access to the casting struct for this class
@@ -80,9 +86,13 @@ module GObject
80
86
  self.class.ffi_struct
81
87
  end
82
88
 
89
+ # get the pointer we were built from ... #to_ptr gets the pointer after we
90
+ # have wrapped it up with an auto unref
91
+ attr_reader :ptr
92
+
83
93
  class << self
84
94
  def ffi_struct
85
- self.const_get :Struct
95
+ const_get :Struct
86
96
  end
87
97
  end
88
98
 
@@ -93,7 +103,7 @@ module GObject
93
103
 
94
104
  class << self
95
105
  def ffi_managed_struct
96
- self.const_get :ManagedStruct
106
+ const_get :ManagedStruct
97
107
  end
98
108
  end
99
109
  end
@@ -101,18 +111,23 @@ module GObject
101
111
  class GParamSpec < FFI::Struct
102
112
  # the first few public fields
103
113
  layout :g_type_instance, :pointer,
104
- :name, :string,
105
- :flags, :uint,
106
- :value_type, :GType,
107
- :owner_type, :GType
114
+ :name, :string,
115
+ :flags, :uint,
116
+ :value_type, :GType,
117
+ :owner_type, :GType
108
118
  end
109
119
 
110
120
  class GParamSpecPtr < FFI::Struct
111
121
  layout :value, GParamSpec.ptr
112
122
  end
113
123
 
114
- attach_function :g_param_spec_get_blurb, [GParamSpec.ptr], :string
124
+ attach_function :g_param_spec_get_blurb, [:pointer], :string
115
125
 
116
126
  attach_function :g_object_ref, [:pointer], :void
117
127
  attach_function :g_object_unref, [:pointer], :void
128
+
129
+ # we just use one gcallback type for every signal, hopefully this is OK
130
+ callback :gcallback, [:pointer], :void
131
+ attach_function :g_signal_connect_data,
132
+ [:pointer, :string, :gcallback, :pointer, :pointer, :int], :long
118
133
  end