ruby-vips 2.0.13 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +42 -0
  3. data/.github/workflows/test.yml +80 -0
  4. data/.standard.yml +17 -0
  5. data/.yardopts +0 -1
  6. data/CHANGELOG.md +44 -0
  7. data/Gemfile +3 -1
  8. data/README.md +45 -47
  9. data/Rakefile +13 -15
  10. data/TODO +19 -10
  11. data/VERSION +1 -1
  12. data/example/annotate.rb +7 -7
  13. data/example/connection.rb +26 -0
  14. data/example/daltonize8.rb +27 -29
  15. data/example/draw_lines.rb +30 -0
  16. data/example/example1.rb +5 -6
  17. data/example/example2.rb +11 -11
  18. data/example/example3.rb +9 -9
  19. data/example/example4.rb +8 -8
  20. data/example/example5.rb +8 -9
  21. data/example/inheritance_with_refcount.rb +203 -221
  22. data/example/progress.rb +30 -0
  23. data/example/thumb.rb +12 -14
  24. data/example/trim8.rb +7 -7
  25. data/example/watermark.rb +15 -36
  26. data/example/wobble.rb +25 -25
  27. data/lib/ruby-vips.rb +1 -1
  28. data/lib/vips.rb +473 -338
  29. data/lib/vips/access.rb +9 -9
  30. data/lib/vips/align.rb +7 -8
  31. data/lib/vips/angle.rb +8 -9
  32. data/lib/vips/angle45.rb +12 -13
  33. data/lib/vips/bandformat.rb +16 -18
  34. data/lib/vips/blend_mode.rb +36 -0
  35. data/lib/vips/coding.rb +11 -12
  36. data/lib/vips/compass_direction.rb +13 -14
  37. data/lib/vips/connection.rb +46 -0
  38. data/lib/vips/direction.rb +7 -8
  39. data/lib/vips/extend.rb +13 -14
  40. data/lib/vips/gobject.rb +111 -100
  41. data/lib/vips/gvalue.rb +243 -237
  42. data/lib/vips/image.rb +1501 -1338
  43. data/lib/vips/interesting.rb +10 -11
  44. data/lib/vips/interpolate.rb +50 -54
  45. data/lib/vips/interpretation.rb +25 -26
  46. data/lib/vips/kernel.rb +18 -19
  47. data/lib/vips/methods.rb +929 -309
  48. data/lib/vips/mutableimage.rb +154 -0
  49. data/lib/vips/object.rb +318 -208
  50. data/lib/vips/operation.rb +467 -320
  51. data/lib/vips/operationboolean.rb +10 -11
  52. data/lib/vips/operationcomplex.rb +8 -9
  53. data/lib/vips/operationcomplex2.rb +6 -7
  54. data/lib/vips/operationcomplexget.rb +7 -8
  55. data/lib/vips/operationmath.rb +14 -15
  56. data/lib/vips/operationmath2.rb +6 -7
  57. data/lib/vips/operationrelational.rb +11 -12
  58. data/lib/vips/operationround.rb +7 -8
  59. data/lib/vips/region.rb +73 -0
  60. data/lib/vips/size.rb +9 -10
  61. data/lib/vips/source.rb +88 -0
  62. data/lib/vips/sourcecustom.rb +89 -0
  63. data/lib/vips/target.rb +86 -0
  64. data/lib/vips/targetcustom.rb +77 -0
  65. data/lib/vips/version.rb +1 -2
  66. data/ruby-vips.gemspec +29 -20
  67. metadata +51 -40
  68. data/.travis.yml +0 -55
  69. data/install-vips.sh +0 -26
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.13
1
+ 2.1.0
data/example/annotate.rb CHANGED
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
- require 'vips'
3
+ require "vips"
4
4
 
5
- im = Vips::Image.new_from_file ARGV[0], :access => :sequential
5
+ im = Vips::Image.new_from_file ARGV[0], access: :sequential
6
6
 
7
- left_text = Vips::Image.text "left corner", :dpi => 300
8
- left = left_text.embed 50, 50, im.width, 150
7
+ left_text = Vips::Image.text "left corner", dpi: 300
8
+ left = left_text.embed 50, 50, im.width, 150
9
9
 
10
- right_text = Vips::Image.text "right corner", :dpi => 300
10
+ right_text = Vips::Image.text "right corner", dpi: 300
11
11
  right = right_text.embed im.width - right_text.width - 50, 50, im.width, 150
12
12
 
13
- footer = (left | right).ifthenelse(0, [255, 0, 0], :blend => true)
13
+ footer = (left | right).ifthenelse(0, [255, 0, 0], blend: true)
14
14
 
15
- im = im.insert footer, 0, im.height, :expand => true
15
+ im = im.insert footer, 0, im.height, expand: true
16
16
 
17
17
  im.write_to_file ARGV[1]
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require "vips"
4
+ require "down/http"
5
+
6
+ # byte_source = File.open ARGV[0], "rb"
7
+ # eg. https://images.unsplash.com/photo-1491933382434-500287f9b54b
8
+ byte_source = Down::Http.open(ARGV[0])
9
+
10
+ source = Vips::SourceCustom.new
11
+ source.on_read do |length|
12
+ puts "reading #{length} bytes ..."
13
+ byte_source.read length
14
+ end
15
+ source.on_seek do |offset, whence|
16
+ puts "seeking to #{offset}, #{whence}"
17
+ byte_source.seek(offset, whence)
18
+ end
19
+
20
+ byte_target = File.open ARGV[1], "wb"
21
+ target = Vips::TargetCustom.new
22
+ target.on_write { |chunk| byte_target.write(chunk) }
23
+ target.on_finish { byte_target.close }
24
+
25
+ image = Vips::Image.new_from_source source, "", access: :sequential
26
+ image.write_to_target target, ".jpg"
@@ -7,20 +7,20 @@
7
7
  # http://libvips.blogspot.co.uk/2013/05/daltonize-in-ruby-vips-carrierwave-and.html
8
8
  # for a discussion of this code
9
9
 
10
- require 'vips'
10
+ require "vips"
11
11
 
12
- #Vips.set_debug true
12
+ # Vips.set_debug true
13
13
 
14
14
  # matrices to convert D65 XYZ to and from bradford cone space
15
15
  xyz_to_brad = [
16
- [0.8951, 0.2664, -0.1614],
17
- [-0.7502, 1.7135, 0.0367],
18
- [0.0389, -0.0685, 1.0296]
16
+ [0.8951, 0.2664, -0.1614],
17
+ [-0.7502, 1.7135, 0.0367],
18
+ [0.0389, -0.0685, 1.0296]
19
19
  ]
20
20
  brad_to_xyz = [
21
- [0.987, -0.147, 0.16],
22
- [0.432, 0.5184, 0.0493],
23
- [-0.0085, 0.04, 0.968]
21
+ [0.987, -0.147, 0.16],
22
+ [0.432, 0.5184, 0.0493],
23
+ [-0.0085, 0.04, 0.968]
24
24
  ]
25
25
 
26
26
  im = Vips::Image.new_from_file ARGV[0]
@@ -28,48 +28,46 @@ im = Vips::Image.new_from_file ARGV[0]
28
28
  # remove any alpha channel before processing
29
29
  alpha = nil
30
30
  if im.bands == 4
31
- alpha = im[3]
32
- im = im.extract_band 0, :n => 3
31
+ alpha = im[3]
32
+ im = im.extract_band 0, n: 3
33
33
  end
34
34
 
35
35
  begin
36
- # import to XYZ with lcms
37
- # if there's no profile there, we'll fall back to the thing below
38
- xyz = im.icc_import :embedded => true, :pcs => :xyz
36
+ # import to XYZ with lcms
37
+ # if there's no profile there, we'll fall back to the thing below
38
+ xyz = im.icc_import embedded: true, pcs: :xyz
39
39
  rescue Vips::Error
40
- # nope .. use the built-in converter instead
41
- xyz = im.colourspace :xyz
40
+ # nope .. use the built-in converter instead
41
+ xyz = im.colourspace :xyz
42
42
  end
43
43
 
44
- brad = xyz.recomb xyz_to_brad
44
+ brad = xyz.recomb xyz_to_brad
45
45
 
46
46
  # through the Deuteranope matrix
47
47
  # we need rows to sum to 1 in Bradford space --- the matrix in the original
48
48
  # Python code sums to 1.742
49
49
  deut = brad.recomb [
50
- [1, 0, 0],
51
- [0.7, 0, 0.3],
52
- [0, 0, 1]
50
+ [1, 0, 0],
51
+ [0.7, 0, 0.3],
52
+ [0, 0, 1]
53
53
  ]
54
54
 
55
- xyz = deut.recomb brad_to_xyz
55
+ xyz = deut.recomb brad_to_xyz
56
56
 
57
- # .. and back to sRGB
57
+ # .. and back to sRGB
58
58
  rgb = xyz.colourspace :srgb
59
59
 
60
- # so this is the colour error
60
+ # so this is the colour error
61
61
  err = im - rgb
62
62
 
63
63
  # add the error back to other channels to make a compensated image
64
- im = im + err.recomb([
65
- [0, 0, 0],
66
- [0.7, 1, 0],
67
- [0.7, 0, 1]
68
- ])
64
+ im += err.recomb([[0, 0, 0],
65
+ [0.7, 1, 0],
66
+ [0.7, 0, 1]])
69
67
 
70
68
  # reattach any alpha we saved above
71
69
  if alpha
72
- im = im.bandjoin(alpha)
70
+ im = im.bandjoin(alpha)
73
71
  end
74
72
 
75
- im.write_to_file ARGV[1]
73
+ im.write_to_file ARGV[1]
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require "vips"
4
+
5
+ # load and stream into memory
6
+ image = Vips::Image.new_from_file(ARGV[0], access: :sequential).copy_memory
7
+
8
+ starting = Process.clock_gettime(Process::CLOCK_MONOTONIC)
9
+
10
+ lines = image
11
+ (0..1).step 0.01 do |i|
12
+ lines = lines.draw_line 255, lines.width * i, 0, 0, lines.height * (1 - i)
13
+ end
14
+
15
+ ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
16
+ puts "non-destructive took #{ending - starting}s"
17
+
18
+ starting = Process.clock_gettime(Process::CLOCK_MONOTONIC)
19
+
20
+ lines = image
21
+ lines = lines.mutate do |x|
22
+ (0..1).step 0.01 do |i|
23
+ x.draw_line! 255, x.width * i, 0, 0, x.height * (1 - i)
24
+ end
25
+ end
26
+
27
+ ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
28
+ puts "mutate took #{ending - starting}s"
29
+
30
+ lines.write_to_file ARGV[1]
data/example/example1.rb CHANGED
@@ -1,12 +1,11 @@
1
- #!/usr/bin/env ruby
1
+ #!/usr/bin/ruby
2
2
 
3
- require 'logger'
4
- require 'vips'
3
+ require "logger"
4
+ require "vips"
5
5
 
6
- GLib::logger.level = Logger::DEBUG
6
+ GLib.logger.level = Logger::DEBUG
7
7
 
8
- op = Vips::Operation.new "black"
8
+ Vips::Operation.new "black"
9
9
 
10
- op = nil
11
10
  GC.start
12
11
  Vips::Operation.print_all
data/example/example2.rb CHANGED
@@ -1,34 +1,34 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
- require 'logger'
4
- require 'vips'
3
+ require "logger"
4
+ require "vips"
5
5
 
6
6
  puts ""
7
7
  puts "starting up:"
8
8
 
9
9
  # this makes vips keep a list of all active objects which we can print out
10
- Vips::leak_set true
10
+ Vips.leak_set true
11
11
 
12
12
  # disable the operation cache
13
- Vips::cache_set_max 0
13
+ Vips.cache_set_max 0
14
14
 
15
15
  # GLib::logger.level = Logger::DEBUG
16
16
 
17
17
  n = 10000
18
18
 
19
19
  n.times do |i|
20
- puts ""
21
- puts "call #{i} ..."
22
- out = Vips::Operation.call "black", [200, 300]
23
- if out.width != 200 or out.height != 300
24
- puts "bad image result from black"
25
- end
20
+ puts ""
21
+ puts "call #{i} ..."
22
+ out = Vips::Operation.call "black", [200, 300]
23
+ if out.width != 200 || out.height != 300
24
+ puts "bad image result from black"
25
+ end
26
26
  end
27
27
 
28
28
  puts ""
29
29
  puts "after #{n} calls:"
30
30
  GC.start
31
- Vips::Object::print_all
31
+ Vips::Object.print_all
32
32
 
33
33
  puts ""
34
34
  puts "shutting down:"
data/example/example3.rb CHANGED
@@ -1,19 +1,19 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
- require 'vips'
3
+ require "vips"
4
4
 
5
- # this makes vips keep a list of all active objects
6
- Vips::leak_set true
5
+ # this makes vips keep a list of all active objects
6
+ Vips.leak_set true
7
7
 
8
8
  # disable the operation cache
9
9
  # Vips::cache_set_max 0
10
10
 
11
11
  # turn on debug logging
12
- GLib::logger.level = Logger::DEBUG
12
+ GLib.logger.level = Logger::DEBUG
13
13
 
14
- 1.times do |i|
15
- puts "loop #{i} ..."
16
- im = Vips::Image.new_from_file ARGV[0]
17
- im = im.embed 100, 100, 3000, 3000, :extend => :mirror
18
- im.write_to_file "x.v"
14
+ 10.times do |i|
15
+ puts "loop #{i} ..."
16
+ im = Vips::Image.new_from_file ARGV[0]
17
+ im = im.embed 100, 100, 3000, 3000, extend: :mirror
18
+ im.write_to_file "x.v"
19
19
  end
data/example/example4.rb CHANGED
@@ -1,18 +1,18 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
- require 'vips'
3
+ require "vips"
4
4
 
5
- # this makes vips keep a list of all active objects
6
- Vips::leak_set true
5
+ # this makes vips keep a list of all active objects
6
+ Vips.leak_set true
7
7
 
8
8
  # disable the operation cache
9
- #Vips::cache_set_max 0
9
+ # Vips::cache_set_max 0
10
10
 
11
11
  # turn on debug logging
12
- #Vips.set_debug true
12
+ # Vips.set_debug true
13
13
 
14
14
  ARGV.each do |filename|
15
- im = Vips::Image.new_from_file filename
16
- profile = im.get_value "icc-profile-data"
17
- puts "profile has #{profile.length} bytes"
15
+ im = Vips::Image.new_from_file filename
16
+ profile = im.get_value "icc-profile-data"
17
+ puts "profile has #{profile.length} bytes"
18
18
  end
data/example/example5.rb CHANGED
@@ -1,31 +1,30 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
- require 'vips'
3
+ require "vips"
4
4
 
5
- # this makes vips keep a list of all active objects
5
+ # this makes vips keep a list of all active objects
6
6
  # Vips::leak_set true
7
7
 
8
8
  # disable the operation cache
9
9
  # Vips::cache_set_max 0
10
10
 
11
11
  # turn on debug logging
12
- #Vips.set_debug true
12
+ # Vips.set_debug true
13
13
 
14
14
  if ARGV.length < 2
15
- raise "usage: #{$PROGRAM_NAME}: input-file output-file"
15
+ raise "usage: #{$PROGRAM_NAME}: input-file output-file"
16
16
  end
17
17
 
18
- im = Vips::Image.new_from_file ARGV[0], :access => :sequential
18
+ im = Vips::Image.new_from_file ARGV[0], access: :sequential
19
19
 
20
20
  im *= [1, 2, 1]
21
21
 
22
22
  # we want to be able to specify a scale for the convolution mask, so we have to
23
23
  # make it ourselves
24
24
  # if you are OK with scale=1, you can just pass the array directly to .conv()
25
- mask = Vips::Image.new_from_array [
26
- [-1, -1, -1],
27
- [-1, 16, -1],
28
- [-1, -1, -1]], 8
25
+ mask = Vips::Image.new_from_array [[-1, -1, -1],
26
+ [-1, 16, -1],
27
+ [-1, -1, -1]], 8
29
28
  im = im.conv mask
30
29
 
31
30
  im.write_to_file ARGV[1]
@@ -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
 
@@ -10,277 +10,259 @@ $vips_debug = true
10
10
 
11
11
  # @private
12
12
  def log str
13
- if $vips_debug
14
- puts str
15
- end
13
+ if $vips_debug
14
+ puts str
15
+ end
16
16
  end
17
17
 
18
18
  def set_debug debug
19
- $vips_debug = debug
19
+ $vips_debug = debug
20
20
  end
21
21
 
22
22
  module Libc
23
- extend FFI::Library
24
- ffi_lib FFI::Library::LIBC
23
+ extend FFI::Library
24
+ ffi_lib FFI::Library::LIBC
25
25
 
26
- attach_function :malloc, [:size_t], :pointer
27
- attach_function :free, [:pointer], :void
26
+ attach_function :malloc, [:size_t], :pointer
27
+ attach_function :free, [:pointer], :void
28
28
  end
29
29
 
30
30
  module GLib
31
- extend FFI::Library
32
- ffi_lib 'gobject-2.0'
33
-
34
- # nil being the default
35
- glib_log_domain = nil
36
-
37
- def self.set_log_domain(domain)
38
- glib_log_domain = domain
39
- end
40
-
41
- # we have a set of things we need to inherit in different ways:
42
- #
43
- # - we want to be able to subclass GObject in a simple way
44
- # - the layouts of the nested structs
45
- # - casting between structs which share a base
46
- # - gobject refcounting
47
- #
48
- # the solution is to split the class into four areas which we treat
49
- # differently:
50
- #
51
- # - we have a "wrapper" Ruby class to allow easy subclassing ... this has a
52
- # @struct member which holds the actual pointer
53
- # - we use "forwardable" to forward the various ffi methods on to the
54
- # @struct member ... we arrange things so that subclasses do not need to
55
- # do the forwarding themselves
56
- # - we have two versions of the struct: a plain one which we can use for
57
- # casting that will not change the refcounts
58
- # - and a managed one with an unref which we just use for .new
59
- # - we separate the struct layout into a separate module to avoid repeating
60
- # ourselves
61
-
62
- class GObject
63
- extend Forwardable
64
- extend SingleForwardable
65
-
66
- def_instance_delegators :@struct, :[], :to_ptr
67
- def_single_delegators :ffi_struct, :ptr
68
-
69
- # the layout of the GObject struct
70
- module GObjectLayout
71
- def self.included(base)
72
- base.class_eval do
73
- layout :g_type_instance, :pointer,
74
- :ref_count, :uint,
75
- :qdata, :pointer
76
- end
77
- end
78
- end
79
-
80
- # the struct with unref ... manage object lifetime with this
81
- class ManagedStruct < FFI::ManagedStruct
82
- include GObjectLayout
83
-
84
- def initialize(ptr)
85
- log "GLib::GObject::ManagedStruct.new: #{ptr}"
86
- super
87
- end
88
-
89
- def self.release(ptr)
90
- log "GLib::GObject::ManagedStruct.release: unreffing #{ptr}"
91
- GLib::g_object_unref(ptr) unless ptr.null?
92
- end
93
-
31
+ extend FFI::Library
32
+ ffi_lib "gobject-2.0"
33
+
34
+ def self.set_log_domain(_domain)
35
+ # FIXME: this needs hooking up
36
+ end
37
+
38
+ # we have a set of things we need to inherit in different ways:
39
+ #
40
+ # - we want to be able to subclass GObject in a simple way
41
+ # - the layouts of the nested structs
42
+ # - casting between structs which share a base
43
+ # - gobject refcounting
44
+ #
45
+ # the solution is to split the class into four areas which we treat
46
+ # differently:
47
+ #
48
+ # - we have a "wrapper" Ruby class to allow easy subclassing ... this has a
49
+ # @struct member which holds the actual pointer
50
+ # - we use "forwardable" to forward the various ffi methods on to the
51
+ # @struct member ... we arrange things so that subclasses do not need to
52
+ # do the forwarding themselves
53
+ # - we have two versions of the struct: a plain one which we can use for
54
+ # casting that will not change the refcounts
55
+ # - and a managed one with an unref which we just use for .new
56
+ # - we separate the struct layout into a separate module to avoid repeating
57
+ # ourselves
58
+
59
+ class GObject
60
+ extend Forwardable
61
+ extend SingleForwardable
62
+
63
+ def_instance_delegators :@struct, :[], :to_ptr
64
+ def_single_delegators :ffi_struct, :ptr
65
+
66
+ # the layout of the GObject struct
67
+ module GObjectLayout
68
+ def self.included(base)
69
+ base.class_eval do
70
+ layout :g_type_instance, :pointer,
71
+ :ref_count, :uint,
72
+ :qdata, :pointer
94
73
  end
74
+ end
75
+ end
95
76
 
96
- # the plain struct ... cast with this
97
- class Struct < FFI::Struct
98
- include GObjectLayout
77
+ # the struct with unref ... manage object lifetime with this
78
+ class ManagedStruct < FFI::ManagedStruct
79
+ include GObjectLayout
99
80
 
100
- def initialize(ptr)
101
- log "GLib::GObject::Struct.new: #{ptr}"
102
- super
103
- end
81
+ def initialize(ptr)
82
+ log "GLib::GObject::ManagedStruct.new: #{ptr}"
83
+ super
84
+ end
104
85
 
105
- end
86
+ def self.release(ptr)
87
+ log "GLib::GObject::ManagedStruct.release: unreffing #{ptr}"
88
+ GLib.g_object_unref(ptr) unless ptr.null?
89
+ end
90
+ end
106
91
 
107
- # don't allow ptr == nil, we never want to allocate a GObject struct
108
- # ourselves, we just want to wrap GLib-allocated GObjects
109
- #
110
- # here we use ManagedStruct, not Struct, since this is the ref that will
111
- # need the unref
112
- def initialize(ptr)
113
- log "GLib::GObject.initialize: ptr = #{ptr}"
114
- @struct = ffi_managed_struct.new(ptr)
115
- end
92
+ # the plain struct ... cast with this
93
+ class Struct < FFI::Struct
94
+ include GObjectLayout
116
95
 
117
- # access to the cast struct for this class
118
- def ffi_struct
119
- self.class.ffi_struct
120
- end
96
+ def initialize(ptr)
97
+ log "GLib::GObject::Struct.new: #{ptr}"
98
+ super
99
+ end
100
+ end
121
101
 
122
- class << self
123
- def ffi_struct
124
- self.const_get(:Struct)
125
- end
126
- end
102
+ # don't allow ptr == nil, we never want to allocate a GObject struct
103
+ # ourselves, we just want to wrap GLib-allocated GObjects
104
+ #
105
+ # here we use ManagedStruct, not Struct, since this is the ref that will
106
+ # need the unref
107
+ def initialize(ptr)
108
+ log "GLib::GObject.initialize: ptr = #{ptr}"
109
+ @struct = ffi_managed_struct.new(ptr)
110
+ end
127
111
 
128
- # access to the lifetime managed struct for this class
129
- def ffi_managed_struct
130
- self.class.ffi_managed_struct
131
- end
112
+ # access to the cast struct for this class
113
+ def ffi_struct
114
+ self.class.ffi_struct
115
+ end
132
116
 
133
- class << self
134
- def ffi_managed_struct
135
- self.const_get(:ManagedStruct)
136
- end
137
- end
117
+ class << self
118
+ def ffi_struct
119
+ const_get(:Struct)
120
+ end
121
+ end
138
122
 
123
+ # access to the lifetime managed struct for this class
124
+ def ffi_managed_struct
125
+ self.class.ffi_managed_struct
139
126
  end
140
127
 
141
- # :gtype will usually be 64-bit, but will be 32-bit on 32-bit Windows
142
- typedef :ulong, :GType
128
+ class << self
129
+ def ffi_managed_struct
130
+ const_get(:ManagedStruct)
131
+ end
132
+ end
133
+ end
143
134
 
135
+ # :gtype will usually be 64-bit, but will be 32-bit on 32-bit Windows
136
+ typedef :ulong, :GType
144
137
  end
145
138
 
146
139
  module Vips
147
- extend FFI::Library
148
- ffi_lib 'vips'
140
+ extend FFI::Library
141
+ ffi_lib "vips"
149
142
 
150
- LOG_DOMAIN = "VIPS"
151
- GLib::set_log_domain(LOG_DOMAIN)
143
+ LOG_DOMAIN = "VIPS"
144
+ GLib.set_log_domain(LOG_DOMAIN)
152
145
 
153
- # need to repeat this
154
- typedef :ulong, :GType
146
+ # need to repeat this
147
+ typedef :ulong, :GType
155
148
 
156
- attach_function :vips_init, [:string], :int
157
- attach_function :vips_shutdown, [], :void
149
+ attach_function :vips_init, [:string], :int
150
+ attach_function :vips_shutdown, [], :void
158
151
 
159
- attach_function :vips_error_buffer, [], :string
160
- attach_function :vips_error_clear, [], :void
152
+ attach_function :vips_error_buffer, [], :string
153
+ attach_function :vips_error_clear, [], :void
161
154
 
162
- def self.get_error
163
- errstr = Vips::vips_error_buffer
164
- Vips::vips_error_clear
165
- errstr
166
- end
155
+ def self.get_error
156
+ errstr = Vips.vips_error_buffer
157
+ Vips.vips_error_clear
158
+ errstr
159
+ end
167
160
 
168
- if Vips::vips_init($0) != 0
169
- puts Vips::get_error
170
- exit 1
171
- end
161
+ if Vips.vips_init($0) != 0
162
+ puts Vips.get_error
163
+ exit 1
164
+ end
172
165
 
173
- at_exit {
174
- Vips::vips_shutdown
175
- }
166
+ at_exit do
167
+ Vips.vips_shutdown
168
+ end
176
169
 
177
- attach_function :vips_object_print_all, [], :void
178
- attach_function :vips_leak_set, [:int], :void
179
-
180
- def self.showall
181
- if $vips_debug
182
- GC.start
183
- vips_object_print_all
184
- end
185
- end
170
+ attach_function :vips_object_print_all, [], :void
171
+ attach_function :vips_leak_set, [:int], :void
186
172
 
173
+ def self.showall
187
174
  if $vips_debug
188
- vips_leak_set 1
175
+ GC.start
176
+ vips_object_print_all
189
177
  end
190
-
191
- class VipsObject < GLib::GObject
192
-
193
- # the layout of the VipsObject struct
194
- module VipsObjectLayout
195
- def self.included(base)
196
- base.class_eval do
197
- # don't actually need most of these, remove them later
198
- layout :parent, GLib::GObject::Struct,
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
208
- end
209
- end
178
+ end
179
+
180
+ if $vips_debug
181
+ vips_leak_set 1
182
+ end
183
+
184
+ class VipsObject < GLib::GObject
185
+ # the layout of the VipsObject struct
186
+ module VipsObjectLayout
187
+ def self.included(base)
188
+ base.class_eval do
189
+ # don't actually need most of these, remove them later
190
+ 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
210
200
  end
211
-
212
- class Struct < GLib::GObject::Struct
213
- include VipsObjectLayout
214
-
215
- def initialize(ptr)
216
- log "Vips::VipsObject::Struct.new: #{ptr}"
217
- super
218
- end
219
-
220
- end
221
-
222
- class ManagedStruct < GLib::GObject::ManagedStruct
223
- include VipsObjectLayout
224
-
225
- def initialize(ptr)
226
- log "Vips::VipsObject::ManagedStruct.new: #{ptr}"
227
- super
228
- end
229
-
230
- end
231
-
201
+ end
232
202
  end
233
203
 
234
- class VipsImage < VipsObject
235
-
236
- # the layout of the VipsImage struct
237
- module VipsImageLayout
238
- def self.included(base)
239
- base.class_eval do
240
- layout :parent, VipsObject::Struct
241
- # rest opaque
242
- end
243
- end
244
- end
204
+ class Struct < GLib::GObject::Struct
205
+ include VipsObjectLayout
245
206
 
246
- class Struct < VipsObject::Struct
247
- include VipsImageLayout
207
+ def initialize(ptr)
208
+ log "Vips::VipsObject::Struct.new: #{ptr}"
209
+ super
210
+ end
211
+ end
248
212
 
249
- def initialize(ptr)
250
- log "Vips::VipsImage::Struct.new: #{ptr}"
251
- super
252
- end
213
+ class ManagedStruct < GLib::GObject::ManagedStruct
214
+ include VipsObjectLayout
253
215
 
216
+ def initialize(ptr)
217
+ log "Vips::VipsObject::ManagedStruct.new: #{ptr}"
218
+ super
219
+ end
220
+ end
221
+ end
222
+
223
+ class VipsImage < VipsObject
224
+ # the layout of the VipsImage struct
225
+ module VipsImageLayout
226
+ def self.included(base)
227
+ base.class_eval do
228
+ layout :parent, VipsObject::Struct
229
+ # rest opaque
254
230
  end
231
+ end
232
+ end
255
233
 
256
- class ManagedStruct < VipsObject::ManagedStruct
257
- include VipsImageLayout
258
-
259
- def initialize(ptr)
260
- log "Vips::VipsImage::ManagedStruct.new: #{ptr}"
261
- super
262
- end
234
+ class Struct < VipsObject::Struct
235
+ include VipsImageLayout
263
236
 
264
- end
237
+ def initialize(ptr)
238
+ log "Vips::VipsImage::Struct.new: #{ptr}"
239
+ super
240
+ end
241
+ end
265
242
 
266
- def self.new_partial
267
- VipsImage.new(Vips::vips_image_new)
268
- end
243
+ class ManagedStruct < VipsObject::ManagedStruct
244
+ include VipsImageLayout
269
245
 
246
+ def initialize(ptr)
247
+ log "Vips::VipsImage::ManagedStruct.new: #{ptr}"
248
+ super
249
+ end
270
250
  end
271
251
 
272
- attach_function :vips_image_new, [], :pointer
252
+ def self.new_partial
253
+ VipsImage.new(Vips.vips_image_new)
254
+ end
255
+ end
273
256
 
257
+ attach_function :vips_image_new, [], :pointer
274
258
  end
275
259
 
276
260
  puts "creating image"
277
- begin
278
- x = Vips::VipsImage.new_partial
279
- puts "x = #{x}"
280
- puts ""
281
- puts "x[:parent] = #{x[:parent]}"
282
- puts ""
283
- puts "x[:parent][:description] = #{x[:parent][:description]}"
284
- puts ""
285
- end
286
261
 
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 ""