vips 8.8.4 → 8.12.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/vips.rb CHANGED
@@ -4,28 +4,45 @@
4
4
  # Author:: John Cupitt (mailto:jcupitt@gmail.com)
5
5
  # License:: MIT
6
6
 
7
- require 'ffi'
8
- require 'logger'
7
+ require "ffi"
8
+ require "logger"
9
9
 
10
10
  # This module uses FFI to make a simple layer over the glib and gobject
11
11
  # libraries.
12
12
 
13
+ # Generate a library name for ffi.
14
+ #
15
+ # Platform notes:
16
+ # linux:
17
+ # Some distros allow "libvips.so", but only if the -dev headers have been
18
+ # installed. To work everywhere, you must include the ABI number.
19
+ # Confusingly, the file extension is not at the end. ffi adds the "lib"
20
+ # prefix.
21
+ # mac:
22
+ # As linux, but the extension is at the end and is added by ffi.
23
+ # windows:
24
+ # The ABI number must be included, but with a hyphen. ffi does not add a
25
+ # "lib" prefix or a ".dll" suffix.
26
+ def library_name(name, abi_number)
27
+ if FFI::Platform.windows?
28
+ "lib#{name}-#{abi_number}.dll"
29
+ elsif FFI::Platform.mac?
30
+ "#{name}.#{abi_number}"
31
+ else
32
+ "#{name}.so.#{abi_number}"
33
+ end
34
+ end
35
+
13
36
  module GLib
14
37
  class << self
15
38
  attr_accessor :logger
16
39
  end
17
- @logger = Logger.new(STDOUT)
40
+ @logger = Logger.new($stdout)
18
41
  @logger.level = Logger::WARN
19
42
 
20
43
  extend FFI::Library
21
44
 
22
- if FFI::Platform.windows?
23
- glib_libname = 'libglib-2.0-0.dll'
24
- else
25
- glib_libname = 'glib-2.0'
26
- end
27
-
28
- ffi_lib glib_libname
45
+ ffi_lib library_name("glib-2.0", 0)
29
46
 
30
47
  attach_function :g_malloc, [:size_t], :pointer
31
48
 
@@ -35,20 +52,20 @@ module GLib
35
52
 
36
53
  callback :g_log_func, [:string, :int, :string, :pointer], :void
37
54
  attach_function :g_log_set_handler,
38
- [:string, :int, :g_log_func, :pointer], :int
55
+ [:string, :int, :g_log_func, :pointer], :int
39
56
  attach_function :g_log_remove_handler, [:string, :int], :void
40
57
 
41
58
  # log flags
42
- LOG_FLAG_RECURSION = 1 << 0
43
- LOG_FLAG_FATAL = 1 << 1
59
+ LOG_FLAG_RECURSION = 1 << 0
60
+ LOG_FLAG_FATAL = 1 << 1
44
61
 
45
62
  # GLib log levels
46
- LOG_LEVEL_ERROR = 1 << 2 # always fatal
47
- LOG_LEVEL_CRITICAL = 1 << 3
48
- LOG_LEVEL_WARNING = 1 << 4
49
- LOG_LEVEL_MESSAGE = 1 << 5
50
- LOG_LEVEL_INFO = 1 << 6
51
- LOG_LEVEL_DEBUG = 1 << 7
63
+ LOG_LEVEL_ERROR = 1 << 2 # always fatal
64
+ LOG_LEVEL_CRITICAL = 1 << 3
65
+ LOG_LEVEL_WARNING = 1 << 4
66
+ LOG_LEVEL_MESSAGE = 1 << 5
67
+ LOG_LEVEL_INFO = 1 << 6
68
+ LOG_LEVEL_DEBUG = 1 << 7
52
69
 
53
70
  # map glib levels to Logger::Severity
54
71
  GLIB_TO_SEVERITY = {
@@ -66,9 +83,9 @@ module GLib
66
83
  @glib_log_handler_id = 0
67
84
 
68
85
  # module-level, so it's not GCd away
69
- LOG_HANDLER = Proc.new do |domain, level, message, _user_data|
86
+ LOG_HANDLER = proc { |domain, level, message, _user_data|
70
87
  @logger.log(GLIB_TO_SEVERITY[level], message, domain)
71
- end
88
+ }
72
89
 
73
90
  def self.remove_log_handler
74
91
  if @glib_log_handler_id != 0 && @glib_log_domain
@@ -78,7 +95,7 @@ module GLib
78
95
  end
79
96
 
80
97
  def self.set_log_domain domain
81
- GLib::remove_log_handler
98
+ GLib.remove_log_handler
82
99
 
83
100
  @glib_log_domain = domain
84
101
 
@@ -108,7 +125,7 @@ module GLib
108
125
  # on shutdown and we don't want LOG_HANDLER to be invoked
109
126
  # after Ruby has gone
110
127
  at_exit {
111
- GLib::remove_log_handler
128
+ GLib.remove_log_handler
112
129
  }
113
130
  end
114
131
  end
@@ -117,13 +134,7 @@ end
117
134
  module GObject
118
135
  extend FFI::Library
119
136
 
120
- if FFI::Platform.windows?
121
- gobject_libname = 'libgobject-2.0-0.dll'
122
- else
123
- gobject_libname = 'gobject-2.0'
124
- end
125
-
126
- ffi_lib gobject_libname
137
+ ffi_lib library_name("gobject-2.0", 0)
127
138
 
128
139
  # we can't just use ulong, windows has different int sizing rules
129
140
  if FFI::Platform::ADDRESS_SIZE == 64
@@ -151,11 +162,11 @@ module GObject
151
162
  GOBJECT_TYPE = g_type_from_name "GObject"
152
163
  end
153
164
 
154
- require 'vips/gobject'
155
- require 'vips/gvalue'
165
+ require "vips/gobject"
166
+ require "vips/gvalue"
156
167
 
157
168
  # This module provides a binding for the [libvips image processing
158
- # library](https://jcupitt.github.io/libvips/).
169
+ # library](https://libvips.github.io/libvips/).
159
170
  #
160
171
  # # Example
161
172
  #
@@ -197,9 +208,10 @@ require 'vips/gvalue'
197
208
  # for full details
198
209
  # on the various modes available.
199
210
  #
200
- # You can also load formatted images from
201
- # memory buffers, create images that wrap C-style memory arrays, or make images
202
- # from constants.
211
+ # You can also load formatted images from memory buffers, create images that
212
+ # wrap C-style memory arrays, or make images from constants. Use {Source}
213
+ # and {Image.new_from_source} to load images from any data source, for
214
+ # example URIs.
203
215
  #
204
216
  # The next line:
205
217
  #
@@ -242,6 +254,9 @@ require 'vips/gvalue'
242
254
  # suffix. You can also write formatted images to memory buffers, or dump
243
255
  # image data to a raw memory array.
244
256
  #
257
+ # Use {Target} and {Image#write_to_target} to write formatted images to
258
+ # any data sink, for example URIs.
259
+ #
245
260
  # # How it works
246
261
  #
247
262
  # The binding uses [ruby-ffi](https://github.com/ffi/ffi) to open the libvips
@@ -392,36 +407,132 @@ require 'vips/gvalue'
392
407
  #
393
408
  # # Automatic YARD documentation
394
409
  #
395
- # The bulk of these API docs are generated automatically by
396
- # {Vips::generate_yard}. It examines
397
- # libvips and writes a summary of each operation and the arguments and options
398
- # that that operation expects.
410
+ # The bulk of these API docs are generated automatically by {Yard#generate}.
411
+ # It examines libvips and writes a summary of each operation and the arguments
412
+ # and options that that operation expects.
399
413
  #
400
- # Use the [C API
401
- # docs](https://jcupitt.github.io/libvips/API/current)
414
+ # Use the [C API # docs](https://libvips.github.io/libvips/API/current)
402
415
  # for more detail.
403
416
  #
404
417
  # # Enums
405
418
  #
406
419
  # The libvips enums, such as `VipsBandFormat` appear in ruby-vips as Symbols
407
420
  # like `:uchar`. They are documented as a set of classes for convenience, see
408
- # the class list.
421
+ # {Vips::BandFormat}, for example.
409
422
  #
410
423
  # # Draw operations
411
424
  #
412
- # Paint operations like {Image#draw_circle} and {Image#draw_line}
413
- # modify their input image. This
414
- # makes them hard to use with the rest of libvips: you need to be very careful
415
- # about the order in which operations execute or you can get nasty crashes.
425
+ # There are two ways of calling the libvips draw operations, like
426
+ # {Image#draw_circle} and {Image#draw_line}.
427
+ #
428
+ # First, you can use them like functions. For example:
416
429
  #
417
- # The wrapper spots operations of this type and makes a private copy of the
418
- # image in memory before calling the operation. This stops crashes, but it does
419
- # make it inefficient. If you draw 100 lines on an image, for example, you'll
420
- # copy the image 100 times. The wrapper does make sure that memory is recycled
421
- # where possible, so you won't have 100 copies in memory.
430
+ # ```ruby
431
+ # y = x.draw_line 255, 0, 0, x.width, x.height
432
+ # ```
433
+ #
434
+ # This will make a new image, `y`, which is a copy of `x` but with a line
435
+ # drawn across it. `x` is unchanged.
436
+ #
437
+ # This is simple, but will be slow if you want to draw many lines, since
438
+ # ruby-vips will make a copy of the whole image each time.
439
+ #
440
+ # You can use {Image#mutate} to make a {MutableImage}. This is an image which
441
+ # is unshared and is only available inside the {Image#mutate} block. Within
442
+ # this block, you can use `!` versions of the draw operations to modify images
443
+ # and avoid the copy. For example:
444
+ #
445
+ # ```ruby
446
+ # image = image.mutate do |mutable|
447
+ # (0 ... 1).step(0.01) do |i|
448
+ # mutable.draw_line! 255, mutable.width * i, 0, 0, mutable.height * (1 - i)
449
+ # end
450
+ # end
451
+ # ```
422
452
  #
423
- # If you want to avoid the copies, you'll need to call drawing operations
424
- # yourself.
453
+ # Now each {Image#draw_line} will directly modify the mutable image, saving
454
+ # the copy. This is much faster and needs much less memory.
455
+ #
456
+ # # Metadata read
457
+ #
458
+ # Use {Image#get_fields} to get a list of the metadata fields that an image
459
+ # supports. ICC profiles, for example, are in a field called
460
+ # `icc-profile-data`. Use `vipsheader -a something.jpg` at the command-line
461
+ # to see all the fields on an image.
462
+ #
463
+ # Use {Image#get_typeof} to get the type of a field. Types are integers, with
464
+ # 0 meaning "no such field". Constants like {GObject::GINT_TYPE} are useful for
465
+ # testing field types.
466
+ #
467
+ # You can read image metadata using {Image#get}. The field value is converted
468
+ # to a Ruby value in the obvious way.
469
+ #
470
+ # # Metadata write
471
+ #
472
+ # You can also set and remove image metadata fields. Images are immutable, so
473
+ # you must make any changes inside a {Image#mutate} block. For example:
474
+ #
475
+ # ```ruby
476
+ # image = image.mutate do |mutable|
477
+ # image.get_fields.each do |field|
478
+ # mutable.remove! field unless field == "icc-profile-data"
479
+ # end
480
+ # end
481
+ # ```
482
+ #
483
+ # To remove all metadata except the icc profile.
484
+ #
485
+ # You can use {MutableImage#set!} to change the value of an existing field,
486
+ # and {MutableImage#set_type!} to create a new field with a specified type.
487
+ #
488
+ # # Progress
489
+ #
490
+ # You can attach signal handlers to images to watch computation progress. For
491
+ # example:
492
+ #
493
+ # ```ruby
494
+ # image = Vips::Image.black 1, 100000
495
+ # image.set_progress true
496
+ #
497
+ # def progress_to_s(name, progress)
498
+ # puts "#{name}:"
499
+ # puts " run = #{progress[:run]}"
500
+ # puts " eta = #{progress[:eta]}"
501
+ # puts " tpels = #{progress[:tpels]}"
502
+ # puts " npels = #{progress[:npels]}"
503
+ # puts " percent = #{progress[:percent]}"
504
+ # end
505
+ #
506
+ # image.signal_connect :preeval do |progress|
507
+ # progress_to_s("preeval", progress)
508
+ # end
509
+ #
510
+ # image.signal_connect :eval do |progress|
511
+ # progress_to_s("eval", progress)
512
+ # image.set_kill(true) if progress[:percent] > 50
513
+ # end
514
+ #
515
+ # image.signal_connect :posteval do |progress|
516
+ # progress_to_s("posteval", progress)
517
+ # end
518
+ #
519
+ # image.avg
520
+ # ```
521
+ #
522
+ # The `:eval` signal will fire for every tile that is processed. You can stop
523
+ # progress with {Image#set_kill} and processing will end with an exception.
524
+ #
525
+ # User streams
526
+ #
527
+ # You can make your own input and output stream objects with {SourceCustom} and
528
+ # {TargetCustom}. For example:
529
+ #
530
+ # ```ruby
531
+ # file = File.open "some/file", "rb"
532
+ # source = Vips::SourceCustom.new
533
+ # source.on_read { |length| file.read length }
534
+ # image = Vips::Image.new_from_source source, "", access: "sequential"
535
+ # ```
425
536
  #
426
537
  # # Overloads
427
538
  #
@@ -459,21 +570,22 @@ require 'vips/gvalue'
459
570
  module Vips
460
571
  extend FFI::Library
461
572
 
462
- if FFI::Platform.windows?
463
- vips_libname = 'libvips-42.dll'
464
- else
465
- vips_libname = File.expand_path(FFI::map_library_name('vips'), __dir__)
466
- end
467
-
468
- ffi_lib vips_libname
573
+ ffi_lib library_name("vips", 42)
469
574
 
470
575
  LOG_DOMAIN = "VIPS"
471
- GLib::set_log_domain LOG_DOMAIN
576
+ GLib.set_log_domain LOG_DOMAIN
472
577
 
473
- typedef :ulong, :GType
578
+ # we can't just use ulong, windows has different int sizing rules
579
+ if FFI::Platform::ADDRESS_SIZE == 64
580
+ typedef :uint64, :GType
581
+ else
582
+ typedef :uint32, :GType
583
+ end
474
584
 
475
585
  attach_function :vips_error_buffer, [], :string
476
586
  attach_function :vips_error_clear, [], :void
587
+ attach_function :vips_error_freeze, [], :void
588
+ attach_function :vips_error_thaw, [], :void
477
589
 
478
590
  # The ruby-vips error class.
479
591
  class Error < RuntimeError
@@ -482,9 +594,9 @@ module Vips
482
594
  def initialize msg = nil
483
595
  if msg
484
596
  @details = msg
485
- elsif Vips::vips_error_buffer != ""
486
- @details = Vips::vips_error_buffer
487
- Vips::vips_error_clear
597
+ elsif Vips.vips_error_buffer != ""
598
+ @details = Vips.vips_error_buffer
599
+ Vips.vips_error_clear
488
600
  else
489
601
  @details = nil
490
602
  end
@@ -494,7 +606,7 @@ module Vips
494
606
  #
495
607
  # @return [String] The error message
496
608
  def to_s
497
- if @details != nil
609
+ if !@details.nil?
498
610
  @details
499
611
  else
500
612
  super.to_s
@@ -504,8 +616,8 @@ module Vips
504
616
 
505
617
  attach_function :vips_init, [:string], :int
506
618
 
507
- if Vips::vips_init($0) != 0
508
- throw Vips::get_error
619
+ if Vips.vips_init($0) != 0
620
+ throw Vips.get_error
509
621
  end
510
622
 
511
623
  # don't use at_exit to call vips_shutdown, it causes problems with fork, and
@@ -569,7 +681,7 @@ module Vips
569
681
  # Don't use this, instead change GLib::logger.level.
570
682
  def self.set_debug debug
571
683
  if debug
572
- GLib::logger.level = Logger::DEBUG
684
+ GLib.logger.level = Logger::DEBUG
573
685
  end
574
686
  end
575
687
 
@@ -591,30 +703,37 @@ module Vips
591
703
  # vips_foreign_get_suffixes() was added in libvips 8.8
592
704
  return [] unless Vips.respond_to? :vips_foreign_get_suffixes
593
705
 
594
- array = Vips::vips_foreign_get_suffixes
706
+ array = Vips.vips_foreign_get_suffixes
595
707
 
596
708
  names = []
597
709
  p = array
598
710
  until (q = p.read_pointer).null?
599
711
  suff = q.read_string
600
- GLib::g_free q
712
+ GLib.g_free q
601
713
  names << suff unless names.include? suff
602
714
  p += FFI::Type::POINTER.size
603
715
  end
604
- GLib::g_free array
716
+ GLib.g_free array
605
717
 
606
718
  names
607
719
  end
608
720
 
609
- LIBRARY_VERSION = Vips::version_string
721
+ LIBRARY_VERSION = Vips.version_string
610
722
 
611
723
  # libvips has this arbitrary number as a sanity-check upper bound on image
612
- # size. It's sometimes useful for know whan calculating image ratios.
724
+ # size. It's sometimes useful to know when calculating scale factors.
613
725
  MAX_COORD = 10000000
614
726
  end
615
727
 
616
- require 'vips/object'
617
- require 'vips/operation'
618
- require 'vips/image'
619
- require 'vips/interpolate'
620
- require 'vips/version'
728
+ require "vips/object"
729
+ require "vips/operation"
730
+ require "vips/image"
731
+ require "vips/mutableimage"
732
+ require "vips/interpolate"
733
+ require "vips/region"
734
+ require "vips/version"
735
+ require "vips/connection"
736
+ require "vips/source"
737
+ require "vips/sourcecustom"
738
+ require "vips/target"
739
+ require "vips/targetcustom"
data/vips.gemspec CHANGED
@@ -22,9 +22,7 @@ Gem::Specification.new do |spec|
22
22
 
23
23
  spec.extensions = %w[ext/Rakefile]
24
24
 
25
- spec.add_runtime_dependency "ffi", ["~> 1.9"]
26
-
27
- spec.add_development_dependency "pry"
25
+ spec.add_runtime_dependency "ffi", ["~> 1.12"]
28
26
 
29
27
  spec.add_development_dependency "yard", "~> 0.8"
30
28
  spec.add_development_dependency "redcarpet", "~> 3.3"
@@ -33,4 +31,6 @@ Gem::Specification.new do |spec|
33
31
  spec.add_development_dependency "bundler"
34
32
  spec.add_development_dependency "rspec", "~> 3.7"
35
33
  spec.add_development_dependency "rake"
34
+
35
+ spec.add_development_dependency "standardrb"
36
36
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vips
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.8.4
4
+ version: 8.12.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Cupitt
8
8
  - Samuel Williams
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-12-17 00:00:00.000000000 Z
12
+ date: 2022-01-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ffi
@@ -17,28 +17,14 @@ dependencies:
17
17
  requirements:
18
18
  - - "~>"
19
19
  - !ruby/object:Gem::Version
20
- version: '1.9'
20
+ version: '1.12'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - "~>"
26
26
  - !ruby/object:Gem::Version
27
- version: '1.9'
28
- - !ruby/object:Gem::Dependency
29
- name: pry
30
- requirement: !ruby/object:Gem::Requirement
31
- requirements:
32
- - - ">="
33
- - !ruby/object:Gem::Version
34
- version: '0'
35
- type: :development
36
- prerelease: false
37
- version_requirements: !ruby/object:Gem::Requirement
38
- requirements:
39
- - - ">="
40
- - !ruby/object:Gem::Version
41
- version: '0'
27
+ version: '1.12'
42
28
  - !ruby/object:Gem::Dependency
43
29
  name: yard
44
30
  requirement: !ruby/object:Gem::Requirement
@@ -123,6 +109,20 @@ dependencies:
123
109
  - - ">="
124
110
  - !ruby/object:Gem::Version
125
111
  version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: standardrb
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
126
  description: Provides pre-compiled binaries for libvips.
127
127
  email:
128
128
  - jcupitt@gmail.com
@@ -132,21 +132,28 @@ extensions:
132
132
  - ext/Rakefile
133
133
  extra_rdoc_files: []
134
134
  files:
135
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
136
+ - ".github/workflows/development.yml"
135
137
  - ".gitignore"
138
+ - ".standard.yml"
136
139
  - ".travis.yml"
137
140
  - ".yardopts"
138
141
  - CHANGELOG.md
139
142
  - Gemfile
140
143
  - README.md
141
144
  - Rakefile
145
+ - TODO
142
146
  - example/annotate.rb
147
+ - example/connection.rb
143
148
  - example/daltonize8.rb
149
+ - example/draw_lines.rb
144
150
  - example/example1.rb
145
151
  - example/example2.rb
146
152
  - example/example3.rb
147
153
  - example/example4.rb
148
154
  - example/example5.rb
149
155
  - example/inheritance_with_refcount.rb
156
+ - example/progress.rb
150
157
  - example/thumb.rb
151
158
  - example/trim8.rb
152
159
  - example/watermark.rb
@@ -161,6 +168,7 @@ files:
161
168
  - lib/vips/blend_mode.rb
162
169
  - lib/vips/coding.rb
163
170
  - lib/vips/compass_direction.rb
171
+ - lib/vips/connection.rb
164
172
  - lib/vips/direction.rb
165
173
  - lib/vips/extend.rb
166
174
  - lib/vips/gobject.rb
@@ -171,6 +179,7 @@ files:
171
179
  - lib/vips/interpretation.rb
172
180
  - lib/vips/kernel.rb
173
181
  - lib/vips/methods.rb
182
+ - lib/vips/mutableimage.rb
174
183
  - lib/vips/object.rb
175
184
  - lib/vips/operation.rb
176
185
  - lib/vips/operationboolean.rb
@@ -181,14 +190,19 @@ files:
181
190
  - lib/vips/operationmath2.rb
182
191
  - lib/vips/operationrelational.rb
183
192
  - lib/vips/operationround.rb
193
+ - lib/vips/region.rb
184
194
  - lib/vips/size.rb
195
+ - lib/vips/source.rb
196
+ - lib/vips/sourcecustom.rb
197
+ - lib/vips/target.rb
198
+ - lib/vips/targetcustom.rb
185
199
  - lib/vips/version.rb
186
200
  - vips.gemspec
187
201
  homepage: https://github.com/ioquatix/vips
188
202
  licenses:
189
203
  - MIT
190
204
  metadata: {}
191
- post_install_message:
205
+ post_install_message:
192
206
  rdoc_options: []
193
207
  require_paths:
194
208
  - lib
@@ -203,8 +217,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
203
217
  - !ruby/object:Gem::Version
204
218
  version: '0'
205
219
  requirements: []
206
- rubygems_version: 3.0.4
207
- signing_key:
220
+ rubygems_version: 3.2.32
221
+ signing_key:
208
222
  specification_version: 4
209
223
  summary: Vips is a high-performance image manipulation library.
210
224
  test_files: []