ruby-vips 2.1.0 → 2.1.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b632e0e44fa32da791e46806757e9b6a1a9901d92e2de9b02e16682bc3f3e6b2
4
- data.tar.gz: 5d3841b9a656d13003b1b2668c05ab89cf5b65c76a52dad070a67b9a6856fe60
3
+ metadata.gz: ff74e4e7a8b781e9fd56602fddc00adaa0355276532821a953bac3175e649534
4
+ data.tar.gz: 199957dacc1c47208a5d8a379080b76676fe3f98ba684a76fdbe5e08370d535b
5
5
  SHA512:
6
- metadata.gz: 11c11a729818aa279cf5a157cda6e810174da9089b9ae3a0e92b3c7e6080362dfca5a970b07f3881aa7f31e5aa4acf3cd1a9a05a2e3ef09dc86d7464fe8987fe
7
- data.tar.gz: 41bae93d0c491699e0042acfe687bc86766af576c9ffe57da1c20a26de548e08c73c0d7685855a155630ed5d47a3a2e2e60f982df48df2a59d4a9f4bd6ccfd34
6
+ metadata.gz: 9d585d3440f75759e1c07cefd6d43371db62706e0c2e9ada3512f661870f7f4c410d6dbeed138c45e16438112cc8179bae2d4477c318ac6fcf9e31487822cb63
7
+ data.tar.gz: a62254d063cd35b521e74a86377d3e83d2b2345a10186e044b2e91992bc6ff49611d6bde916cd8c530d0b2ba4da7ba4a23ca10c922be99463ab71371538cf1cf
data/CHANGELOG.md CHANGED
@@ -2,6 +2,26 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## Version 2.1.4 (2021-10-28)
6
+
7
+ * `write_to_buffer` tries to use the new target API, then falls back to the old
8
+ buffer system [jcupitt]
9
+ * don't generate yard docs for deprecated args [jcupitt]
10
+ * add hyperbolic trig functions [jcupitt]
11
+
12
+ ## Version 2.1.3 (2021-8-23)
13
+
14
+ * fix a gtype size error on win64 [danini-the-panini]
15
+
16
+ ## Version 2.1.2 (2021-5-3)
17
+
18
+ * allow `FFI::Pointer` as an argument to `new_from_memory` etc. [sled]
19
+
20
+ ## Version 2.1.1 (2021-5-3)
21
+
22
+ * fix "mutate" with libvips 8.9 [jcupitt]
23
+ * update autodocs for libvips 8.11 [jcupitt]
24
+
5
25
  ## Version 2.1.0 (2021-3-8)
6
26
 
7
27
  * add "mutate" system [jcupitt]
data/README.md CHANGED
@@ -6,12 +6,13 @@
6
6
  This gem is a Ruby binding for the [libvips image processing
7
7
  library](https://libvips.github.io/libvips).
8
8
 
9
- Programs that use `ruby-vips` don't manipulate images directly, instead
10
- they create pipelines of image processing operations building on a source
11
- image. When the end of the pipe is connected to a destination, the whole
12
- pipeline executes at once, streaming the image in parallel from source to
13
- destination a section at a time. Because `ruby-vips` is parallel, it's quick,
14
- and because it doesn't need to keep entire images in memory, it's light.
9
+ libvips is a [demand-driven, horizontally
10
+ threaded](https://github.com/libvips/libvips/wiki/Why-is-libvips-quick)
11
+ image processing library. Compared to similar
12
+ libraries, [libvips runs quickly and uses little
13
+ memory](https://github.com/libvips/libvips/wiki/Speed-and-memory-use).
14
+ libvips is licensed under the [LGPL
15
+ 2.1+](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html).
15
16
 
16
17
  ## Requirements
17
18
 
@@ -25,7 +26,7 @@ and because it doesn't need to keep entire images in memory, it's light.
25
26
 
26
27
  ## Install
27
28
 
28
- It's just:
29
+ [Install libvips](https://libvips.github.io/libvips/install.html), then:
29
30
 
30
31
  ```
31
32
  $ gem install ruby-vips
@@ -40,7 +41,7 @@ gem "ruby-vips"
40
41
  On Windows, you'll need to set the `RUBY_DLL_PATH` environment variable to
41
42
  point to the libvips bin directory.
42
43
 
43
- # Example
44
+ ## Example
44
45
 
45
46
  ```ruby
46
47
  require "vips"
@@ -67,19 +68,24 @@ im = im.conv mask, precision: :integer
67
68
  im.write_to_file output_filename
68
69
  ```
69
70
 
70
- The `Vips` section in the API docs has a [tutorial introduction with
71
+ ## Documentation
72
+
73
+ There are [full API docs for ruby-vips on
74
+ rubydoc](https://www.rubydoc.info/gems/ruby-vips). This sometimes has issues
75
+ updating, so we have a [copy on the gh-pages for this site as
76
+ well](http://libvips.github.io/ruby-vips), which
77
+ should always work.
78
+
79
+ See the `Vips` section in the docs for a [tutorial introduction with
71
80
  examples](https://www.rubydoc.info/gems/ruby-vips/Vips).
72
81
 
73
- ruby-vips has [API
74
- documentation](http://www.rubydoc.info/gems/ruby-vips). The [libvips
75
- reference manual](https://libvips.github.io/libvips/API/current/) has a
76
- complete explanation of every method.
82
+ The [libvips reference manual](https://libvips.github.io/libvips/API/current/)
83
+ has a complete explanation of every method.
77
84
 
78
- The
79
- [`example/`](https://github.com/libvips/ruby-vips/tree/master/example)
85
+ The [`example/`](https://github.com/libvips/ruby-vips/tree/master/example)
80
86
  directory has some simple example programs.
81
87
 
82
- # Benchmarks
88
+ ## Benchmarks
83
89
 
84
90
  The benchmark at [vips-benchmarks](https://github.com/jcupitt/vips-benchmarks)
85
91
  loads a large image, crops, shrinks, sharpens and saves again, and repeats
data/TODO CHANGED
@@ -37,9 +37,8 @@
37
37
 
38
38
  - Push new gem to rubygems, tag repository with version.
39
39
 
40
- gem2.5 signin --otp 111111 / enter username and passwd
40
+ gem signin --otp 111111
41
41
  bundle exec rake release
42
42
 
43
- There's an invisible prompt for the authenticator code. Enter eg. 123456,
44
- press return and the upload should work.
43
+ The otp is from authy / google authenticator / etc.
45
44
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.1.0
1
+ 2.1.4
@@ -132,8 +132,12 @@ module GLib
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
@@ -144,7 +148,11 @@ module Vips
144
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
data/lib/vips/image.rb CHANGED
@@ -78,6 +78,11 @@ module Vips
78
78
  class Image < Vips::Object
79
79
  alias_method :parent_get_typeof, :get_typeof
80
80
 
81
+ # FFI sets a pointer's size to this magic value if the size of the memory
82
+ # chunk the pointer points to is unknown to FFI.
83
+ UNKNOWN_POINTER_SIZE = FFI::Pointer.new(1).size
84
+ private_constant :UNKNOWN_POINTER_SIZE
85
+
81
86
  private
82
87
 
83
88
  # the layout of the VipsImage struct
@@ -326,6 +331,24 @@ module Vips
326
331
  # image.width, image.height, image.bands, image.format
327
332
  # ```
328
333
  #
334
+ # Creating a new image from a memory pointer:
335
+ #
336
+ # ```
337
+ # ptr = FFI::MemoryPointer.new(:uchar, 10*10)
338
+ # # => #<FFI::MemoryPointer address=0x00007fc236db31d0 size=100>
339
+ # x = Vips::Image.new_from_memory(ptr, 10, 10, 1, :uchar)
340
+ # ```
341
+ #
342
+ # Creating a new image from an address only pointer:
343
+ #
344
+ # ```
345
+ # ptr = call_to_external_c_library(w: 10, h: 10)
346
+ # # => #<FFI::Pointer address=0x00007f9780813a00>
347
+ # ptr_slice = ptr.slice(0, 10*10)
348
+ # # => #<FFI::Pointer address=0x00007f9780813a00 size=100>
349
+ # x = Vips::Image.new_from_memory(ptr_slice, 10, 10, 1, :uchar)
350
+ # ```
351
+ #
329
352
  # {new_from_memory} keeps a reference to the array of pixels you pass in
330
353
  # to try to prevent that memory from being freed by the Ruby GC while it
331
354
  # is being used.
@@ -340,13 +363,23 @@ module Vips
340
363
  # @param format [Symbol] band format
341
364
  # @return [Image] the loaded image
342
365
  def self.new_from_memory data, width, height, bands, format
343
- size = data.bytesize
344
-
345
366
  # prevent data from being freed with JRuby FFI
346
367
  if defined?(JRUBY_VERSION) && !data.is_a?(FFI::Pointer)
347
368
  data = ::FFI::MemoryPointer.new(:char, data.bytesize).write_bytes data
348
369
  end
349
370
 
371
+ if data.is_a?(FFI::Pointer)
372
+ # A pointer needs to know about the size of the memory it points to.
373
+ # If you have an address-only pointer, use the .slice method to wrap
374
+ # the pointer in a size aware pointer.
375
+ if data.size == UNKNOWN_POINTER_SIZE
376
+ raise Vips::Error, "size of memory is unknown"
377
+ end
378
+ size = data.size
379
+ else
380
+ size = data.bytesize
381
+ end
382
+
350
383
  format_number = GObject::GValue.from_nick BAND_FORMAT_TYPE, format
351
384
  vi = Vips.vips_image_new_from_memory data, size,
352
385
  width, height, bands, format_number
@@ -373,7 +406,17 @@ module Vips
373
406
  # @return [Image] the loaded image
374
407
  def self.new_from_memory_copy data, width, height, bands, format
375
408
  format_number = GObject::GValue.from_nick BAND_FORMAT_TYPE, format
376
- vi = Vips.vips_image_new_from_memory_copy data, data.bytesize,
409
+
410
+ if data.is_a?(FFI::Pointer)
411
+ if data.size == UNKNOWN_POINTER_SIZE
412
+ raise Vips::Error, "size of memory is unknown"
413
+ end
414
+ size = data.size
415
+ else
416
+ size = data.bytesize
417
+ end
418
+
419
+ vi = Vips.vips_image_new_from_memory_copy data, size,
377
420
  width, height, bands, format_number
378
421
  raise Vips::Error if vi.null?
379
422
  new(vi)
@@ -506,7 +549,7 @@ module Vips
506
549
  pixel = (Vips::Image.black(1, 1) + value).cast(format)
507
550
  image = pixel.embed 0, 0, width, height, extend: :copy
508
551
  image.copy interpretation: interpretation, xres: xres, yres: yres,
509
- xoffset: xoffset, yoffset: yoffset
552
+ xoffset: xoffset, yoffset: yoffset
510
553
  end
511
554
 
512
555
  # Write this image to a file. Save options may be encoded in the
@@ -580,11 +623,27 @@ module Vips
580
623
  raise Vips::Error, "filename is nil" if format_string.nil?
581
624
  filename = Vips.p2str(Vips.vips_filename_get_filename(format_string))
582
625
  option_string = Vips.p2str(Vips.vips_filename_get_options(format_string))
583
- saver = Vips.vips_foreign_find_save_buffer filename
584
- raise Vips::Error if saver.nil?
585
626
 
586
- buffer = Vips::Operation.call saver, [self], opts, option_string
587
- raise Vips::Error if buffer.nil?
627
+ # try to save with the new target API first, only fall back to the old
628
+ # buffer API if there's no target save for this filetype
629
+ saver = nil
630
+ if Vips.at_least_libvips?(8, 9)
631
+ Vips.vips_error_freeze
632
+ saver = Vips.vips_foreign_find_save_target filename
633
+ Vips.vips_error_thaw
634
+ end
635
+
636
+ if !saver.nil?
637
+ target = Vips::Target.new_to_memory
638
+ Vips::Operation.call saver, [self, target], opts, option_string
639
+ buffer = target.get("blob")
640
+ else
641
+ saver = Vips.vips_foreign_find_save_buffer filename
642
+ raise Vips::Error if saver.nil?
643
+
644
+ buffer = Vips::Operation.call saver, [self], opts, option_string
645
+ raise Vips::Error if buffer.nil?
646
+ end
588
647
 
589
648
  write_gc
590
649
 
@@ -1129,14 +1188,10 @@ module Vips
1129
1188
  end
1130
1189
  end
1131
1190
 
1132
- # Convert to an Array. This will be slow for large images.
1191
+ # Convert to an Enumerator. Similar to `#to_a` but lazier.
1133
1192
  #
1134
- # @return [Array] array of Fixnum
1135
- def to_a
1136
- # we render the image to a big string, then unpack
1137
- # as a Ruby array of the correct type
1138
- memory = write_to_memory
1139
-
1193
+ # @return [Enumerator] Enumerator of Enumerators of Arrays of Numerics
1194
+ def to_enum
1140
1195
  # make the template for unpack
1141
1196
  template = {
1142
1197
  char: "c",
@@ -1151,14 +1206,22 @@ module Vips
1151
1206
  dpcomplex: "d"
1152
1207
  }[format] + "*"
1153
1208
 
1154
- # and unpack into something like [1, 2, 3, 4 ..]
1155
- array = memory.unpack(template)
1209
+ # we render the image to a big string, then unpack into
1210
+ # one-dimensional array as a Ruby array of the correct type
1211
+ array = write_to_memory.unpack template
1156
1212
 
1157
- # gather band elements together
1158
- pixel_array = array.each_slice(bands).to_a
1213
+ # gather bands of a pixel together
1214
+ pixel_array = array.each_slice bands
1159
1215
 
1160
- # build rows
1161
- pixel_array.each_slice(width).to_a
1216
+ # gather pixels of a row together
1217
+ pixel_array.each_slice width
1218
+ end
1219
+
1220
+ # Convert to an Array. This will be slow for large images.
1221
+ #
1222
+ # @return [Array] Array of Arrays of Arrays of Numerics
1223
+ def to_a
1224
+ to_enum.to_a
1162
1225
  end
1163
1226
 
1164
1227
  # Return the largest integral value not greater than the argument.
@@ -1387,6 +1450,48 @@ module Vips
1387
1450
  math :atan
1388
1451
  end
1389
1452
 
1453
+ # Return the hyperbolic sine of an image in radians.
1454
+ #
1455
+ # @return [Image] sine of each pixel
1456
+ def sinh
1457
+ math :sinh
1458
+ end
1459
+
1460
+ # Return the hyperbolic cosine of an image in radians.
1461
+ #
1462
+ # @return [Image] cosine of each pixel
1463
+ def cosh
1464
+ math :cosh
1465
+ end
1466
+
1467
+ # Return the hyperbolic tangent of an image in radians.
1468
+ #
1469
+ # @return [Image] tangent of each pixel
1470
+ def tanh
1471
+ math :tanh
1472
+ end
1473
+
1474
+ # Return the inverse hyperbolic sine of an image in radians.
1475
+ #
1476
+ # @return [Image] inverse sine of each pixel
1477
+ def asinh
1478
+ math :asinh
1479
+ end
1480
+
1481
+ # Return the inverse hyperbolic cosine of an image in radians.
1482
+ #
1483
+ # @return [Image] inverse cosine of each pixel
1484
+ def acosh
1485
+ math :acosh
1486
+ end
1487
+
1488
+ # Return the inverse hyperbolic tangent of an image in radians.
1489
+ #
1490
+ # @return [Image] inverse tangent of each pixel
1491
+ def atanh
1492
+ math :atanh
1493
+ end
1494
+
1390
1495
  # Return the natural log of an image.
1391
1496
  #
1392
1497
  # @return [Image] natural log of each pixel
@@ -1569,8 +1674,8 @@ module Vips
1569
1674
 
1570
1675
  method_args = introspect.method_args
1571
1676
  required_output = introspect.required_output
1572
- optional_input = introspect.optional_input
1573
- optional_output = introspect.optional_output
1677
+ optional_input = introspect.doc_optional_input
1678
+ optional_output = introspect.doc_optional_output
1574
1679
 
1575
1680
  print "# @!method "
1576
1681
  print "self." unless introspect.member_x
@@ -1593,17 +1698,18 @@ module Vips
1593
1698
  optional_input.each do |arg_name, details|
1594
1699
  yard_name = details[:yard_name]
1595
1700
  gtype = details[:gtype]
1701
+ rtype = gtype_to_ruby gtype
1596
1702
  blurb = details[:blurb]
1597
1703
 
1598
- puts "# @option opts [#{gtype_to_ruby(gtype)}] :#{yard_name} #{blurb}"
1704
+ puts "# @option opts [#{rtype}] :#{yard_name} #{blurb}"
1599
1705
  end
1600
1706
  optional_output.each do |arg_name, details|
1601
1707
  yard_name = details[:yard_name]
1602
1708
  gtype = details[:gtype]
1709
+ rtype = gtype_to_ruby gtype
1603
1710
  blurb = details[:blurb]
1604
1711
 
1605
- print "# @option opts [#{gtype_to_ruby(gtype)}] :#{yard_name}"
1606
- puts " Output #{blurb}"
1712
+ puts "# @option opts [#{rtype}] :#{yard_name} Output #{blurb}"
1607
1713
  end
1608
1714
 
1609
1715
  print "# @return ["