dragonfly_libvips 2.3.0 → 2.4.1

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: e4b64d88420b228e976b7c0d5792e803ea538862d8b6fa4ad6cd48351f88c7e6
4
- data.tar.gz: 827caa0406199bc7ae5911346a378762e3a293c1be3481a69461ea5b5109cd13
3
+ metadata.gz: 46c101441cc8dcf749651080e1697e2a31eab69dde06a9aae0856bc37df6f0ba
4
+ data.tar.gz: 2ef729e0df1f12951dc09e5b492165593fd434fb79edce33a5f57bfae143c9c9
5
5
  SHA512:
6
- metadata.gz: 714d74358f8d176013dc78b7c89fd25e328b3d94816ad0acc82c86ee84110884a4713f8312802de727b9ecc62498976a141751683bf2157e2b0ca27bc7d94367
7
- data.tar.gz: 6a2fe288e736019d108262b17fd0bcae88cfc4d7428508042309f0204adef8e157ed7b4dadde3c32aff42f9d99a8337d961e6a697ec280d9986d747aef73478d
6
+ metadata.gz: f62cdad7d98c0c107acd337883a02356fea0579fb622ca3d4b8c4a98696d3fd2ba5ab83ffac20eaca9d6e44f55fba446bf21d2bba4d9d04f4e444cf9dc71c8ae
7
+ data.tar.gz: 2c40316d19404f9271c28d88982643c2f94fceffff7c51b4deca294c4194974d87778dfc1dd0a877906d01730d862a86e8f07fd6da409d0673d5908b2178b7b3
@@ -0,0 +1 @@
1
+ 2.6.3
@@ -0,0 +1 @@
1
+ ruby 2.6.3
@@ -1,18 +1,19 @@
1
1
  # libvips build instructions taken from https://github.com/marcbachmann/dockerfile-libvips
2
2
 
3
3
  language: ruby
4
+ cache: bundler
4
5
  script: 'bundle exec rake'
5
6
  sudo: required
6
7
  dist: trusty
7
8
  rvm:
8
- - 2.2.5
9
+ - 2.6.3
9
10
 
10
11
  before_install:
11
- - gem install bundler -v 1.12.5
12
+ - gem update bundler
12
13
  - sudo apt-get update
13
- - sudo apt-get install -y gobject-introspection libgirepository1.0-dev libglib2.0-dev libpoppler-glib-dev
14
- - curl -OL https://github.com/jcupitt/libvips/releases/download/v8.5.8/vips-8.5.8.tar.gz
15
- - tar zvxf vips-8.5.8.tar.gz && cd vips-8.5.8 && ./configure && sudo make && sudo make install
14
+ - sudo apt-get install -y gobject-introspection libgirepository1.0-dev libglib2.0-dev libpoppler-glib-dev libgif-dev
15
+ - curl -OL https://github.com/libvips/libvips/releases/download/v8.7.4/vips-8.7.4.tar.gz
16
+ - tar zxvf vips-8.7.4.tar.gz && cd vips-8.7.4 && ./configure $1 && sudo make && sudo make install
16
17
  - export GI_TYPELIB_PATH=/usr/local/lib/girepository-1.0/
17
18
  - sudo ldconfig
18
19
 
@@ -1,5 +1,27 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 2.4.1
4
+
5
+ * Fix misspelled UnsupportedOutputFormat (#13) by @asgerb
6
+ * Fix broken links in README (#12) by @NARKOZ
7
+
8
+ ## 2.4.0
9
+
10
+ * symbolize `input_options` and `output_options` to avoid argument errors coming from `ruby-vips`
11
+
12
+ ## 2.3.3
13
+
14
+ * locks `ruby-vips` to `< 2.0.14`
15
+ * adds support for `libvips` `8.8.0`
16
+
17
+ ## 2.3.2
18
+
19
+ * FIX: support for .gif
20
+
21
+ ## 2.3.1
22
+
23
+ * improved `SUPPORTED_FORMATS` matching that ignores case
24
+
3
25
  ## 2.3.0
4
26
 
5
27
  * add support for progressive JPEGs
data/README.md CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  [![Build Status](https://travis-ci.org/tomasc/dragonfly_libvips.svg)](https://travis-ci.org/tomasc/dragonfly_libvips) [![Gem Version](https://badge.fury.io/rb/dragonfly_libvips.svg)](http://badge.fury.io/rb/dragonfly_libvips) [![Coverage Status](https://img.shields.io/coveralls/tomasc/dragonfly_libvips.svg)](https://coveralls.io/r/tomasc/dragonfly_libvips)
4
4
 
5
- Dragonfly analysers and processors for [libvips](https://github.com/jcupitt/libvips) image processing library
5
+ Dragonfly analysers and processors for [libvips](https://github.com/libvips/libvips) image processing library
6
6
 
7
7
  From the libvips README:
8
8
 
9
- > libvips is a 2D image processing library. Compared to similar libraries, [libvips runs quickly and uses little memory](http://www.vips.ecs.soton.ac.uk/index.php?title=Speed_and_Memory_Use). libvips is licensed under the LGPL 2.1+.
9
+ > libvips is a 2D image processing library. Compared to similar libraries, [libvips runs quickly and uses little memory](https://github.com/libvips/libvips/wiki/Speed-and-memory-use). libvips is licensed under the LGPL 2.1+.
10
10
 
11
11
  ## Installation
12
12
 
@@ -34,7 +34,7 @@ If you run into trouble installing `libvips` with Ruby introspection on Linux, f
34
34
 
35
35
  ## Dependencies
36
36
 
37
- The [vips](http://www.vips.ecs.soton.ac.uk/index.php?title=Supported) library and its [dependencies](https://github.com/jcupitt/libvips#dependencies).
37
+ The [vips](http://www.vips.ecs.soton.ac.uk/index.php?title=Supported) library and its [dependencies](https://github.com/libvips/libvips#dependencies).
38
38
 
39
39
  ## Usage
40
40
 
@@ -19,9 +19,10 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ['lib']
20
20
 
21
21
  spec.add_dependency 'dragonfly', '~> 1.0'
22
- spec.add_dependency 'ruby-vips', '~> 2.0', '>= 2.0.6'
22
+ spec.add_dependency 'ruby-vips', '~> 2.0', '>= 2.0.16'
23
23
 
24
- spec.add_development_dependency 'bundler', '~> 1.12'
24
+ spec.add_development_dependency 'bundler'#, '~> 2.0'
25
+ spec.add_development_dependency 'rb-readline'
25
26
  spec.add_development_dependency 'guard'
26
27
  spec.add_development_dependency 'guard-minitest'
27
28
  spec.add_development_dependency 'minitest', '~> 5.0'
@@ -6,21 +6,24 @@ require 'vips'
6
6
 
7
7
  module DragonflyLibvips
8
8
  class UnsupportedFormat < RuntimeError; end
9
- class UnsupportedOutputormat < RuntimeError; end
9
+ class UnsupportedOutputFormat < RuntimeError; end
10
10
 
11
11
  CMYK_PROFILE_PATH = File.expand_path('../vendor/cmyk.icm', __dir__)
12
12
  EPROFILE_PATH = File.expand_path('../vendor/sRGB_v4_ICC_preference.icc', __dir__)
13
13
 
14
14
  SUPPORTED_FORMATS = begin
15
15
  output = `vips -l | grep -i ForeignLoad`
16
- output.scan(/\.(\w{1,4})/).flatten.sort.uniq
16
+ output.scan(/\.(\w{1,4})/).flatten.compact.sort.map(&:downcase).uniq
17
17
  end
18
18
 
19
19
  SUPPORTED_OUTPUT_FORMATS = begin
20
20
  output = `vips -l | grep -i ForeignSave`
21
- output.scan(/\.(\w{1,4})/).flatten.sort.uniq
21
+ output.scan(/\.(\w{1,4})/).flatten.compact.sort.map(&:downcase).uniq
22
22
  end - %w[
23
23
  csv
24
+ fit
25
+ fits
26
+ fts
24
27
  mat
25
28
  pbm
26
29
  pfm
@@ -30,4 +33,16 @@ module DragonflyLibvips
30
33
  vips
31
34
  webp
32
35
  ]
36
+
37
+ FORMATS_WITHOUT_PROFILE_SUPPORT = %w[bmp dz gif hdr webp heic]
38
+
39
+ private
40
+
41
+ def self.stringify_keys(hash = {})
42
+ hash.each_with_object({}) { |(k, v), memo| memo[k.to_s] = v }
43
+ end
44
+
45
+ def self.symbolize_keys(hash = {})
46
+ hash.each_with_object({}) { |(k, v), memo| memo[k.to_sym] = v }
47
+ end
33
48
  end
@@ -6,14 +6,15 @@ module DragonflyLibvips
6
6
  DPI = 300
7
7
 
8
8
  def call(content)
9
- return {} unless SUPPORTED_FORMATS.include?(content.ext)
9
+ return {} unless content.ext
10
+ return {} unless SUPPORTED_FORMATS.include?(content.ext.downcase)
10
11
 
11
12
  input_options = {}
12
13
  input_options['access'] = 'sequential'
13
14
  input_options['autorotate'] = true if content.mime_type == 'image/jpeg'
14
15
  input_options['dpi'] = DPI if content.mime_type == 'application/pdf'
15
16
 
16
- img = ::Vips::Image.new_from_file(content.path, input_options)
17
+ img = ::Vips::Image.new_from_file(content.path, DragonflyLibvips.symbolize_keys(input_options))
17
18
 
18
19
  width = img.width
19
20
  height = img.height
@@ -1,16 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'vips'
4
+
1
5
  module DragonflyLibvips
2
6
  module Processors
3
7
  class Encode
4
- FORMATS_WITHOUT_PROFILE_SUPPORT = %w[dz webp hdr]
5
-
6
8
  def call(content, format, options = {})
7
- raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext)
9
+ raise UnsupportedFormat unless content.ext
10
+ raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext.downcase)
8
11
 
9
12
  format = format.to_s
10
13
  format = 'tif' if format == 'tiff'
11
14
  format = 'jpg' if format == 'jpeg'
12
15
 
13
- raise UnsupportedOutputFormat unless SUPPORTED_OUTPUT_FORMATS.include?(format)
16
+ raise UnsupportedOutputFormat unless SUPPORTED_OUTPUT_FORMATS.include?(format.downcase)
14
17
 
15
18
  if content.mime_type == Rack::Mime.mime_type(".#{format}")
16
19
  content.ext ||= format
@@ -18,31 +21,34 @@ module DragonflyLibvips
18
21
  return
19
22
  end
20
23
 
21
- options = options.each_with_object({}) { |(k, v), memo| memo[k.to_s] = v } # stringify keys
24
+ options = DragonflyLibvips.stringify_keys(options)
22
25
 
23
26
  input_options = options.fetch('input_options', {})
24
- output_options = options.fetch('output_options', {})
25
-
26
27
  input_options['access'] ||= 'sequential'
27
28
  if content.mime_type == 'image/jpeg'
28
- input_options['autorotate'] = true unless input_options.has_key?('autorotate')
29
+ input_options['autorotate'] = true unless input_options.key?('autorotate')
29
30
  end
30
31
 
31
- output_options['profile'] ||= EPROFILE_PATH
32
- output_options.delete('profile') if FORMATS_WITHOUT_PROFILE_SUPPORT.include?(format)
32
+ output_options = options.fetch('output_options', {})
33
+ if FORMATS_WITHOUT_PROFILE_SUPPORT.include?(format)
34
+ output_options.delete('profile')
35
+ else
36
+ output_options['profile'] ||= input_options.fetch('profile', EPROFILE_PATH)
37
+ end
38
+ output_options.delete('Q') unless format.to_s =~ /jpg|jpeg/i
39
+ output_options['format'] ||= format.to_s if format.to_s =~ /gif|bmp/i
33
40
 
34
- require 'vips'
35
- img = ::Vips::Image.new_from_file(content.path, input_options)
41
+ img = ::Vips::Image.new_from_file(content.path, DragonflyLibvips.symbolize_keys(input_options))
36
42
 
37
43
  content.update(
38
- img.write_to_buffer(".#{format}", output_options),
44
+ img.write_to_buffer(".#{format}", DragonflyLibvips.symbolize_keys(output_options)),
39
45
  'name' => "temp.#{format}",
40
46
  'format' => format
41
47
  )
42
48
  content.ext = format
43
49
  end
44
50
 
45
- def update_url(url_attributes, format, options = {})
51
+ def update_url(url_attributes, format, _options = {})
46
52
  url_attributes.ext = format.to_s
47
53
  end
48
54
  end
@@ -1,28 +1,36 @@
1
+ require 'vips'
2
+
1
3
  module DragonflyLibvips
2
4
  module Processors
3
5
  class ExtractArea
4
6
  def call(content, x, y, width, height, options = {})
5
- raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext)
7
+ raise UnsupportedFormat unless content.ext
8
+ raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext.downcase)
6
9
 
7
- options = options.each_with_object({}) { |(k, v), memo| memo[k.to_s] = v } # stringify keys
10
+ options = DragonflyLibvips.stringify_keys(options)
8
11
  format = options.fetch('format', content.ext)
9
12
 
10
13
  input_options = options.fetch('input_options', {})
11
- output_options = options.fetch('output_options', {})
12
14
 
13
15
  # input_options['access'] ||= 'sequential'
14
16
  if content.mime_type == 'image/jpeg'
15
17
  input_options['autorotate'] = true unless input_options.has_key?('autorotate')
16
18
  end
17
- output_options['profile'] ||= EPROFILE_PATH
18
19
 
19
- require 'vips'
20
- img = ::Vips::Image.new_from_file(content.path, input_options)
20
+ output_options = options.fetch('output_options', {})
21
+ if FORMATS_WITHOUT_PROFILE_SUPPORT.include?(format)
22
+ output_options.delete('profile')
23
+ else
24
+ output_options['profile'] ||= input_options.fetch('profile', EPROFILE_PATH)
25
+ end
26
+ output_options.delete('Q') unless format.to_s =~ /jpg|jpeg/i
27
+ output_options['format'] ||= format.to_s if format.to_s =~ /gif|bmp/i
21
28
 
29
+ img = ::Vips::Image.new_from_file(content.path, DragonflyLibvips.symbolize_keys(input_options))
22
30
  img = img.extract_area(x, y, width, height)
23
31
 
24
32
  content.update(
25
- img.write_to_buffer(".#{format}", output_options),
33
+ img.write_to_buffer(".#{format}", DragonflyLibvips.symbolize_keys(output_options)),
26
34
  'name' => "temp.#{format}",
27
35
  'format' => format
28
36
  )
@@ -1,28 +1,36 @@
1
+ require 'vips'
2
+
1
3
  module DragonflyLibvips
2
4
  module Processors
3
5
  class Rotate
4
6
  def call(content, rotate, options = {})
5
- raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext)
7
+ raise UnsupportedFormat unless content.ext
8
+ raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext.downcase)
6
9
 
7
- options = options.each_with_object({}) { |(k, v), memo| memo[k.to_s] = v } # stringify keys
10
+ options = DragonflyLibvips.stringify_keys(options)
8
11
  format = options.fetch('format', content.ext)
9
12
 
10
13
  input_options = options.fetch('input_options', {})
11
- output_options = options.fetch('output_options', {})
12
14
 
13
15
  # input_options['access'] ||= 'sequential'
14
16
  if content.mime_type == 'image/jpeg'
15
17
  input_options['autorotate'] = true unless input_options.has_key?('autorotate')
16
18
  end
17
- output_options['profile'] ||= EPROFILE_PATH
18
19
 
19
- require 'vips'
20
- img = ::Vips::Image.new_from_file(content.path, input_options)
20
+ output_options = options.fetch('output_options', {})
21
+ if FORMATS_WITHOUT_PROFILE_SUPPORT.include?(format)
22
+ output_options.delete('profile')
23
+ else
24
+ output_options['profile'] ||= input_options.fetch('profile', EPROFILE_PATH)
25
+ end
26
+ output_options.delete('Q') unless format.to_s =~ /jpg|jpeg/i
27
+ output_options['format'] ||= format.to_s if format.to_s =~ /gif|bmp/i
21
28
 
29
+ img = ::Vips::Image.new_from_file(content.path, DragonflyLibvips.symbolize_keys(input_options))
22
30
  img = img.rot("d#{rotate}")
23
31
 
24
32
  content.update(
25
- img.write_to_buffer(".#{format}", output_options),
33
+ img.write_to_buffer(".#{format}", DragonflyLibvips.symbolize_keys(output_options)),
26
34
  'name' => "temp.#{format}",
27
35
  'format' => format
28
36
  )
@@ -9,9 +9,10 @@ module DragonflyLibvips
9
9
  DPI = 300
10
10
 
11
11
  def call(content, geometry, options = {})
12
- raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext)
12
+ raise UnsupportedFormat unless content.ext
13
+ raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext.downcase)
13
14
 
14
- options = options.each_with_object({}) { |(k, v), memo| memo[k.to_s] = v } # stringify keys
15
+ options = DragonflyLibvips.stringify_keys(options)
15
16
 
16
17
  filename = content.path
17
18
  format = options.fetch('format', content.ext).to_s
@@ -29,10 +30,16 @@ module DragonflyLibvips
29
30
  end
30
31
 
31
32
  output_options = options.fetch('output_options', {})
32
- output_options['profile'] = input_options.fetch('profile', EPROFILE_PATH)
33
+ if FORMATS_WITHOUT_PROFILE_SUPPORT.include?(format)
34
+ output_options.delete('profile')
35
+ else
36
+ output_options['profile'] ||= input_options.fetch('profile', EPROFILE_PATH)
37
+ end
38
+ output_options.delete('Q') unless format.to_s =~ /jpg|jpeg/i
39
+ output_options['format'] ||= format.to_s if format.to_s =~ /gif|bmp/i
33
40
 
34
41
  input_options = input_options.each_with_object({}) { |(k, v), memo| memo[k.to_sym] = v } # symbolize
35
- img = ::Vips::Image.new_from_file(filename, input_options)
42
+ img = ::Vips::Image.new_from_file(filename, DragonflyLibvips.symbolize_keys(input_options))
36
43
 
37
44
  dimensions = case geometry
38
45
  when RESIZE_GEOMETRY then Dimensions.call(geometry, img.width, img.height)
@@ -40,7 +47,11 @@ module DragonflyLibvips
40
47
  end
41
48
 
42
49
  thumbnail_options = options.fetch('thumbnail_options', {})
43
- thumbnail_options['auto_rotate'] = input_options.fetch('autorotate', true) if content.mime_type == 'image/jpeg'
50
+ if Vips.at_least_libvips?(8, 8)
51
+ thumbnail_options['no_rotate'] = input_options.fetch('no_rotate', false) if content.mime_type == 'image/jpeg'
52
+ else
53
+ thumbnail_options['auto_rotate'] = input_options.fetch('autorotate', true) if content.mime_type == 'image/jpeg'
54
+ end
44
55
  thumbnail_options['height'] = thumbnail_options.fetch('height', dimensions.height.ceil)
45
56
  thumbnail_options['import_profile'] = CMYK_PROFILE_PATH if img.get('interpretation') == :cmyk
46
57
  thumbnail_options['size'] ||= case geometry
@@ -52,10 +63,10 @@ module DragonflyLibvips
52
63
  filename += "[page=#{input_options[:page]}]" if content.mime_type == 'application/pdf'
53
64
 
54
65
  thumbnail_options = thumbnail_options.each_with_object({}) { |(k, v), memo| memo[k.to_sym] = v } # symbolize
55
- thumb = ::Vips::Image.thumbnail(filename, dimensions.width.ceil, thumbnail_options)
66
+ thumb = ::Vips::Image.thumbnail(filename, dimensions.width.ceil, DragonflyLibvips.symbolize_keys(thumbnail_options))
56
67
 
57
68
  content.update(
58
- thumb.write_to_buffer(".#{format}", output_options),
69
+ thumb.write_to_buffer(".#{format}", DragonflyLibvips.symbolize_keys(output_options)),
59
70
  'name' => "temp.#{format}",
60
71
  'format' => format
61
72
  )
@@ -1,3 +1,3 @@
1
1
  module DragonflyLibvips
2
- VERSION = '2.3.0'.freeze
2
+ VERSION = '2.4.1'.freeze
3
3
  end
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dragonfly_libvips
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomas Celizna
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-09-18 00:00:00.000000000 Z
11
+ date: 2020-08-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dragonfly
@@ -33,7 +33,7 @@ dependencies:
33
33
  version: '2.0'
34
34
  - - ">="
35
35
  - !ruby/object:Gem::Version
36
- version: 2.0.6
36
+ version: 2.0.16
37
37
  type: :runtime
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
@@ -43,21 +43,35 @@ dependencies:
43
43
  version: '2.0'
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
- version: 2.0.6
46
+ version: 2.0.16
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: bundler
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - "~>"
51
+ - - ">="
52
52
  - !ruby/object:Gem::Version
53
- version: '1.12'
53
+ version: '0'
54
54
  type: :development
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
- - - "~>"
58
+ - - ">="
59
59
  - !ruby/object:Gem::Version
60
- version: '1.12'
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rb-readline
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
61
75
  - !ruby/object:Gem::Dependency
62
76
  name: guard
63
77
  requirement: !ruby/object:Gem::Requirement
@@ -136,6 +150,8 @@ extensions: []
136
150
  extra_rdoc_files: []
137
151
  files:
138
152
  - ".gitignore"
153
+ - ".ruby-version"
154
+ - ".tool-versions"
139
155
  - ".travis.yml"
140
156
  - CHANGELOG.md
141
157
  - Gemfile
@@ -162,6 +178,7 @@ files:
162
178
  - samples/sample.png
163
179
  - samples/sample.svg
164
180
  - samples/sample.tif
181
+ - samples/sample_anim.gif
165
182
  - samples/sample_cmyk.jpg
166
183
  - samples/white pixel.png
167
184
  - vendor/cmyk.icm
@@ -185,8 +202,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
185
202
  - !ruby/object:Gem::Version
186
203
  version: '0'
187
204
  requirements: []
188
- rubyforge_project:
189
- rubygems_version: 2.7.6
205
+ rubygems_version: 3.0.3
190
206
  signing_key:
191
207
  specification_version: 4
192
208
  summary: Dragonfly analysers and processors for libvips image processing library.