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/lib/vips/access.rb CHANGED
@@ -1,11 +1,11 @@
1
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
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
11
  end
data/lib/vips/align.rb CHANGED
@@ -1,11 +1,10 @@
1
1
  module Vips
2
+ # Various types of alignment. See {Image#join}, for example.
3
+ #
4
+ # * `:low` Align on the low coordinate edge
5
+ # * `:centre` Align on the centre
6
+ # * `:high` Align on the high coordinate edge
2
7
 
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
8
+ class Align < Symbol
9
+ end
11
10
  end
data/lib/vips/angle.rb CHANGED
@@ -1,12 +1,11 @@
1
1
  module Vips
2
+ # Various fixed 90 degree rotation angles. See {Image#rot}.
3
+ #
4
+ # * `:d0` no rotate
5
+ # * `:d90` 90 degrees clockwise
6
+ # * `:d180` 180 degrees
7
+ # * `:d270` 90 degrees anti-clockwise
2
8
 
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
9
+ class Angle < Symbol
10
+ end
12
11
  end
data/lib/vips/angle45.rb CHANGED
@@ -1,16 +1,15 @@
1
1
  module Vips
2
+ # Various fixed 45 degree rotation angles. See {Image#rot45}.
3
+ #
4
+ # * `:d0` no rotate
5
+ # * `:d45` 45 degrees clockwise
6
+ # * `:d90` 90 degrees clockwise
7
+ # * `:d135` 135 degrees clockwise
8
+ # * `:d180` 180 degrees
9
+ # * `:d225` 135 degrees anti-clockwise
10
+ # * `:d270` 90 degrees anti-clockwise
11
+ # * `:d315` 45 degrees anti-clockwise
2
12
 
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
13
+ class Angle45 < Symbol
14
+ end
16
15
  end
@@ -1,20 +1,18 @@
1
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
-
2
+ # The format used for each band element. Each corresponds to a native C type
3
+ # for the current machine.
4
+ #
5
+ # * `:notset` invalid setting
6
+ # * `:uchar` unsigned char format
7
+ # * `:char` char format
8
+ # * `:ushort` unsigned short format
9
+ # * `:short` short format
10
+ # * `:uint` unsigned int format
11
+ # * `:int` int format
12
+ # * `:float` float format
13
+ # * `:complex` complex (two floats) format
14
+ # * `:double` double float format
15
+ # * `:dpcomplex` double complex (two double) format
16
+ class BandFormat < Symbol
17
+ end
20
18
  end
@@ -0,0 +1,36 @@
1
+ module Vips
2
+ # Blend mode to use when compositing images. See {Image#composite}.
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
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
33
+
34
+ class BlendMode < Symbol
35
+ end
36
+ end
data/lib/vips/coding.rb CHANGED
@@ -1,14 +1,13 @@
1
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
2
+ # How pixels are coded.
3
+ #
4
+ # Normally, pixels are uncoded and can be manipulated as you would expect.
5
+ # However some file formats code pixels for compression, and sometimes it's
6
+ # useful to be able to manipulate images in the coded format.
7
+ #
8
+ # * `:none` pixels are not coded
9
+ # * `:labq` pixels encode 3 float CIELAB values as 4 uchar
10
+ # * `:rad` pixels encode 3 float RGB as 4 uchar (Radiance coding)
11
+ class Coding < Symbol
12
+ end
14
13
  end
@@ -1,17 +1,16 @@
1
1
  module Vips
2
+ # A direction on a compass used for placing images. See {Image#gravity}.
3
+ #
4
+ # * `:centre`
5
+ # * `:north`
6
+ # * `:east`
7
+ # * `:south`
8
+ # * `:west`
9
+ # * `:"north-east"`
10
+ # * `:"south-east"`
11
+ # * `:"south-west"`
12
+ # * `:"north-west"`
2
13
 
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
14
+ class CompassDirection < Symbol
15
+ end
17
16
  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
@@ -1,11 +1,10 @@
1
1
  module Vips
2
+ # Operations like {Image#flip} need to be told whether to flip
3
+ # left-right or top-bottom.
4
+ #
5
+ # * `:horizontal` left-right
6
+ # * `:vertical` top-bottom
2
7
 
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
8
+ class Direction < Symbol
9
+ end
11
10
  end
data/lib/vips/extend.rb CHANGED
@@ -1,17 +1,16 @@
1
1
  module Vips
2
+ # When the edges of an image are extended, you can specify
3
+ # how you want the extension done.
4
+ # See {Image#embed}, {Image#conv}, {Image#affine} and
5
+ # so on.
6
+ #
7
+ # * `:black` new pixels are black, ie. all bits are zero.
8
+ # * `:copy` each new pixel takes the value of the nearest edge pixel
9
+ # * `:repeat` the image is tiled to fill the new area
10
+ # * `:mirror` the image is reflected and tiled to reduce hash edges
11
+ # * `:white` new pixels are white, ie. all bits are set
12
+ # * `:background` colour set from the @background property
2
13
 
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
14
+ class Extend < Symbol
15
+ end
17
16
  end
data/lib/vips/gobject.rb CHANGED
@@ -4,119 +4,130 @@
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
-
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
11
+ # we have a number of things we need to inherit in different ways:
12
+ #
13
+ # - we want to be able to subclass GObject in Ruby in a simple way
14
+ # - the layouts of the nested structs need to inherit
15
+ # - we need to be able to cast between structs which share a base struct
16
+ # without creating new wrappers or messing up refcounting
17
+ # - we need automatic gobject refcounting
18
+ #
19
+ # the solution is to split the class into four areas which we treat
20
+ # differently:
21
+ #
22
+ # - we have a "wrapper" Ruby class to allow easy subclassing ... this has a
23
+ # @struct member which holds the actual pointer
24
+ # - we use "forwardable" to forward the various ffi methods on to the
25
+ # @struct member ... we arrange things so that subclasses do not need to
26
+ # do the forwarding themselves
27
+ # - we have two versions of the struct: a plain one which we can use for
28
+ # casting that will not change the refcounts
29
+ # - and a managed one with an unref which we just use for .new
30
+ # - we separate the struct layout into a separate module to avoid repeating
31
+ # ourselves
32
+
33
+ class GObject
34
+ extend Forwardable
35
+ extend SingleForwardable
36
+
37
+ def_instance_delegators :@struct, :[], :to_ptr
38
+ def_single_delegators :ffi_struct, :ptr
39
+
40
+ attr_reader :references
41
+
42
+ # the layout of the GObject struct
43
+ module GObjectLayout
44
+ def self.included base
45
+ base.class_eval do
46
+ layout :g_type_instance, :pointer,
47
+ :ref_count, :uint,
48
+ :qdata, :pointer
62
49
  end
50
+ end
51
+ end
63
52
 
64
- # the plain struct ... cast with this
65
- class Struct < FFI::Struct
66
- include GObjectLayout
67
-
68
- end
53
+ # the struct with unref ... manage object lifetime with this
54
+ class ManagedStruct < FFI::ManagedStruct
55
+ include GObjectLayout
69
56
 
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
57
+ def self.release ptr
58
+ # GLib::logger.debug("GObject::GObject::ManagedStruct.release") {
59
+ # "unreffing #{ptr}"
60
+ # }
61
+ ::GObject.g_object_unref ptr
62
+ end
63
+ end
79
64
 
80
- # access to the casting struct for this class
81
- def ffi_struct
82
- self.class.ffi_struct
83
- end
65
+ # the plain struct ... cast with this
66
+ class Struct < FFI::Struct
67
+ include GObjectLayout
68
+ end
84
69
 
85
- class << self
86
- def ffi_struct
87
- self.const_get :Struct
88
- end
89
- end
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
+ @ptr = ptr
78
+ @struct = ffi_managed_struct.new ptr
79
+
80
+ # sometimes we need to keep refs across C calls ... hide them here
81
+ @references = []
82
+ end
90
83
 
91
- # access to the managed struct for this class
92
- def ffi_managed_struct
93
- self.class.ffi_managed_struct
94
- end
84
+ # access to the casting struct for this class
85
+ def ffi_struct
86
+ self.class.ffi_struct
87
+ end
95
88
 
96
- class << self
97
- def ffi_managed_struct
98
- self.const_get :ManagedStruct
99
- end
100
- end
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
101
92
 
93
+ class << self
94
+ def ffi_struct
95
+ const_get :Struct
96
+ end
102
97
  end
103
98
 
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
99
+ # access to the managed struct for this class
100
+ def ffi_managed_struct
101
+ self.class.ffi_managed_struct
111
102
  end
112
103
 
113
- class GParamSpecPtr < FFI::Struct
114
- layout :value, GParamSpec.ptr
104
+ class << self
105
+ def ffi_managed_struct
106
+ const_get :ManagedStruct
107
+ end
115
108
  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
-
109
+ end
110
+
111
+ class GParamSpec < FFI::Struct
112
+ # the first few public fields
113
+ layout :g_type_instance, :pointer,
114
+ :name, :string,
115
+ :flags, :uint,
116
+ :value_type, :GType,
117
+ :owner_type, :GType
118
+ end
119
+
120
+ class GParamSpecPtr < FFI::Struct
121
+ layout :value, GParamSpec.ptr
122
+ end
123
+
124
+ attach_function :g_param_spec_get_blurb, [:pointer], :string
125
+
126
+ attach_function :g_object_ref, [:pointer], :void
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
122
133
  end