ruby-vips 2.1.0 → 2.1.4

Sign up to get free protection for your applications and to get access to all the features.
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 ["