assembly-image 2.0.0 → 2.1.0

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: 9379ec53a26a08578c11910512bd73045366fc337fcafb0c7eb1a247370566b1
4
- data.tar.gz: 316fbef312cb027f4061bbe74dc2f8dce993a095d6779da100abeeecbf24b9da
3
+ metadata.gz: '088a4b9c59b50f893f7b50c16898321770006b4ab22dc08a8ddd70cdba9a15da'
4
+ data.tar.gz: f22bf6d6acbd4d6885e2102526e7c5e0ac76b93af71eff0d2237d32334afd223
5
5
  SHA512:
6
- metadata.gz: 97cc720649bdc6e0bb6d7453afdefc7abe3f0931a45976d397f1f77fd2f2dacbcbd4991e64c0e4849a2ae61efa51d72d428ce9a8a15e9a125abdeefcb17b0d5b
7
- data.tar.gz: 8e6580aaade8302319e7cbf41d56d8ac0ebe1a05db5607bed8580cebe8a3c87b5795cb90f50e2b9eb4b081d9048a600799b0e373badf811ff9a084e5f9af3fcc
6
+ metadata.gz: 91f0be3622982ad69823a45eca8111d05756e0442cd7d7aa16cb8099e71ee2e95c21f17c7f14b7ccab04c11724233c9a9739e24f8b8302f07f42b16738c6400e
7
+ data.tar.gz: d1ab206c475413496a6add9376cb246705df18a3142bdc32189b202e31af698b8cfded84464d00e94357fc08396ab142270043b3b862cc0d68cd57834863b649
data/.circleci/config.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  version: 2.1
2
2
  orbs:
3
- ruby-rails: sul-dlss/ruby-rails@3.0.1
3
+ ruby-rails: sul-dlss/ruby-rails@3.1.2
4
4
  workflows:
5
5
  build:
6
6
  jobs:
data/.gitignore CHANGED
@@ -2,7 +2,6 @@
2
2
  *.gem
3
3
  .DS_Store
4
4
  .bundle
5
- Gemfile.lock
6
5
  config/certs/*
7
6
  config/environments/*
8
7
  doc/*
data/.rubocop.yml CHANGED
@@ -22,11 +22,16 @@ Naming/FileName:
22
22
  Exclude:
23
23
  - lib/assembly-image.rb
24
24
 
25
+ Naming/PredicateName:
26
+ ForbiddenPrefixes:
27
+ - is_
28
+
29
+ RSpec/MultipleMemoizedHelpers:
30
+ Enabled: false
31
+
25
32
  Style/WordArray:
26
33
  Enabled: false
27
34
 
28
- Gemspec/DateAssignment: # new in 1.10
29
- Enabled: true
30
35
  Gemspec/RequireMFA: # new in 1.23
31
36
  Enabled: true
32
37
  Layout/LineEndStringConcatenationIndentation: # new in 1.18
@@ -141,7 +146,7 @@ RSpec/SubjectDeclaration: # new in 2.5
141
146
  RSpec/FactoryBot/SyntaxMethods: # new in 2.7
142
147
  Enabled: true
143
148
  RSpec/Rails/AvoidSetupHook: # new in 2.4
144
- Enabled: true
149
+ Enabled: false
145
150
 
146
151
  Lint/RefinementImportMethods: # new in 1.27
147
152
  Enabled: true
@@ -166,3 +171,16 @@ RSpec/VerifiedDoubleReference: # new in 2.10.0
166
171
 
167
172
  Gemspec/DeprecatedAttributeAssignment: # new in 1.30
168
173
  Enabled: true
174
+ Layout/LineContinuationLeadingSpace: # new in 1.31
175
+ Enabled: true
176
+ Layout/LineContinuationSpacing: # new in 1.31
177
+ Enabled: true
178
+ Lint/ConstantOverwrittenInRescue: # new in 1.31
179
+ Enabled: true
180
+ Lint/NonAtomicFileOperation: # new in 1.31
181
+ Enabled: true
182
+
183
+ RSpec/Capybara/SpecificMatcher: # new in 2.12
184
+ Enabled: true
185
+ RSpec/Rails/HaveHttpStatus: # new in 2.12
186
+ Enabled: false
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2022-06-16 22:15:07 UTC using RuboCop version 1.30.1.
3
+ # on 2022-07-19 17:18:47 UTC using RuboCop version 1.31.2.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
@@ -13,66 +13,16 @@ Gemspec/RequiredRubyVersion:
13
13
  Exclude:
14
14
  - 'assembly-image.gemspec'
15
15
 
16
- # Offense count: 2
17
- # This cop supports safe autocorrection (--autocorrect).
18
- Lint/RedundantCopDisableDirective:
19
- Exclude:
20
- - 'lib/assembly-image/image.rb'
21
- - 'lib/assembly-image/images.rb'
22
-
23
16
  # Offense count: 2
24
17
  # Configuration parameters: IgnoredMethods, CountRepeatedAttributes.
25
18
  Metrics/AbcSize:
26
19
  Max: 20
27
20
 
28
- # Offense count: 14
21
+ # Offense count: 11
29
22
  # Configuration parameters: CountAsOne.
30
23
  RSpec/ExampleLength:
31
- Max: 15
32
-
33
- # Offense count: 2
34
- # Configuration parameters: Include, CustomTransform, IgnoreMethods, SpecSuffixOnly.
35
- # Include: **/*_spec*rb*, **/spec/**/*
36
- RSpec/FilePath:
37
- Exclude:
38
- - 'spec/image_spec.rb'
39
- - 'spec/images_spec.rb'
40
-
41
- # Offense count: 21
42
- RSpec/MultipleExpectations:
43
24
  Max: 13
44
25
 
45
- # Offense count: 5
46
- RSpec/UnspecifiedException:
47
- Exclude:
48
- - 'spec/image_spec.rb'
49
- - 'spec/images_spec.rb'
50
-
51
- # Offense count: 3
52
- Style/CombinableLoops:
53
- Exclude:
54
- - 'spec/images_spec.rb'
55
-
56
- # Offense count: 1
57
- # This cop supports unsafe autocorrection (--autocorrect-all).
58
- Style/GlobalStdStream:
59
- Exclude:
60
- - 'lib/assembly-image/images.rb'
61
-
62
- # Offense count: 1
63
- # Configuration parameters: AllowedMethods.
64
- # AllowedMethods: respond_to_missing?
65
- Style/OptionalBooleanParameter:
66
- Exclude:
67
- - 'lib/assembly-image/image.rb'
68
-
69
- # Offense count: 7
70
- # This cop supports unsafe autocorrection (--autocorrect-all).
71
- # Configuration parameters: Mode.
72
- Style/StringConcatenation:
73
- Exclude:
74
- - 'bin/console'
75
- - 'config/boot.rb'
76
- - 'lib/assembly-image.rb'
77
- - 'lib/assembly-image/images.rb'
78
- - 'spec/spec_helper.rb'
26
+ # Offense count: 15
27
+ RSpec/MultipleExpectations:
28
+ Max: 11
data/.rvmrc.example CHANGED
@@ -1 +1 @@
1
- rvm use 1.9.3@assembly-image --create
1
+ rvm use 3.1.0@assembly-image --create
data/Gemfile.lock ADDED
@@ -0,0 +1,105 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ assembly-image (2.1.0)
5
+ activesupport (> 6.1)
6
+ assembly-objectfile (>= 1.6.4)
7
+ ruby-vips (>= 2.0)
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ activesupport (7.0.3.1)
13
+ concurrent-ruby (~> 1.0, >= 1.0.2)
14
+ i18n (>= 1.6, < 2)
15
+ minitest (>= 5.1)
16
+ tzinfo (~> 2.0)
17
+ assembly-objectfile (2.1.0)
18
+ activesupport (>= 5.2.0)
19
+ mime-types (> 3)
20
+ mini_exiftool
21
+ ast (2.4.2)
22
+ byebug (11.1.3)
23
+ coderay (1.1.3)
24
+ concurrent-ruby (1.1.10)
25
+ diff-lcs (1.5.0)
26
+ docile (1.4.0)
27
+ ffi (1.15.5)
28
+ i18n (1.12.0)
29
+ concurrent-ruby (~> 1.0)
30
+ json (2.6.2)
31
+ method_source (1.0.0)
32
+ mime-types (3.4.1)
33
+ mime-types-data (~> 3.2015)
34
+ mime-types-data (3.2022.0105)
35
+ mini_exiftool (2.10.2)
36
+ minitest (5.16.2)
37
+ parallel (1.22.1)
38
+ parser (3.1.2.0)
39
+ ast (~> 2.4.1)
40
+ pry (0.13.1)
41
+ coderay (~> 1.1)
42
+ method_source (~> 1.0)
43
+ pry-byebug (3.9.0)
44
+ byebug (~> 11.0)
45
+ pry (~> 0.13.0)
46
+ rainbow (3.1.1)
47
+ rake (13.0.6)
48
+ regexp_parser (2.5.0)
49
+ rexml (3.2.5)
50
+ rspec (3.11.0)
51
+ rspec-core (~> 3.11.0)
52
+ rspec-expectations (~> 3.11.0)
53
+ rspec-mocks (~> 3.11.0)
54
+ rspec-core (3.11.0)
55
+ rspec-support (~> 3.11.0)
56
+ rspec-expectations (3.11.0)
57
+ diff-lcs (>= 1.2.0, < 2.0)
58
+ rspec-support (~> 3.11.0)
59
+ rspec-mocks (3.11.1)
60
+ diff-lcs (>= 1.2.0, < 2.0)
61
+ rspec-support (~> 3.11.0)
62
+ rspec-support (3.11.0)
63
+ rubocop (1.31.2)
64
+ json (~> 2.3)
65
+ parallel (~> 1.10)
66
+ parser (>= 3.1.0.0)
67
+ rainbow (>= 2.2.2, < 4.0)
68
+ regexp_parser (>= 1.8, < 3.0)
69
+ rexml (>= 3.2.5, < 4.0)
70
+ rubocop-ast (>= 1.18.0, < 2.0)
71
+ ruby-progressbar (~> 1.7)
72
+ unicode-display_width (>= 1.4.0, < 3.0)
73
+ rubocop-ast (1.19.1)
74
+ parser (>= 3.1.1.0)
75
+ rubocop-rspec (2.12.1)
76
+ rubocop (~> 1.31)
77
+ ruby-progressbar (1.11.0)
78
+ ruby-vips (2.1.4)
79
+ ffi (~> 1.12)
80
+ simplecov (0.21.2)
81
+ docile (~> 1.1)
82
+ simplecov-html (~> 0.11)
83
+ simplecov_json_formatter (~> 0.1)
84
+ simplecov-html (0.12.3)
85
+ simplecov_json_formatter (0.1.4)
86
+ tzinfo (2.0.5)
87
+ concurrent-ruby (~> 1.0)
88
+ unicode-display_width (2.2.0)
89
+
90
+ PLATFORMS
91
+ x86_64-darwin-19
92
+ x86_64-darwin-21
93
+ x86_64-linux
94
+
95
+ DEPENDENCIES
96
+ assembly-image!
97
+ pry-byebug
98
+ rake
99
+ rspec (~> 3.0)
100
+ rubocop
101
+ rubocop-rspec
102
+ simplecov
103
+
104
+ BUNDLED WITH
105
+ 2.3.17
data/README.md CHANGED
@@ -6,24 +6,16 @@
6
6
  # Assembly Image Gem
7
7
 
8
8
  ## Overview
9
- This gem contains classes used by the Stanford University Digital Library to
10
- perform image operations necessary for accessioning of content.
9
+ This gem contains classes used by the Stanford University Digital Library to create JP2 image derivatives.
11
10
 
12
- Requires image processing software - see PreRequisites section below.
11
+ Requires image processing software - see [prerequisites section](#prerequisites) below.
13
12
 
14
13
  ## Notes
15
14
 
16
15
  1. The gem assumes that the user context in which it is executed has write access to the 'tmp' folder.
17
- This is because color profiles can be extracted from images during the JP2
18
- creation process, and these profiles need to be stored as local files, and it
19
- is beneficial to cache them for later usage by images with the same color profile.
20
- If you know there are color profiles which are commonly used, it is better to
21
- capture them in the gem itself in the profile folder so they can be re-used
22
- and do not need to be extracted.
23
- 1. If any errors occur during JP2 generation for any reason, a runtime exception will be thrown with a description of the error.
24
- 2. If an image is passed in with a color profile that cannot be determined by examining the exif header data, an exception will be thrown.
25
-
26
- This can commonly occur in basic test TIFs that are black/white and have no profile, so beware during testing.
16
+ This is to create the temporary tiffs used; we need temporary tiffs to reliably compress the image using KDUcompress, which doesn’t support arbitrary image types
17
+ 2. If any errors occur during JP2 generation for any reason, a runtime exception will be thrown with a description of the error.
18
+ 3. If an image is passed in with a color profile that cannot be determined, an exception will be thrown. This can commonly occur in basic test TIFs that are black/white and have no profile, so beware during testing.
27
19
 
28
20
  ## Usage
29
21
 
@@ -31,45 +23,29 @@ To use the JP2 creation method, you first instantiate the image object with an i
31
23
 
32
24
  ```ruby
33
25
  require 'assembly-image'
34
- input = Assembly::Image.new('/full/path/to/file.tif')
35
- puts input.exif # show exif header information for the TIF
36
- output = input.create_jp2(:output=>'/full/path/to/output.jp2') # generate a new JP2 in the specified location
37
- puts output.exif # show exif header information for the JP2
26
+ input_image = Assembly::Image.new('/full/path/to/file.tif')
27
+ output = input_image.create_jp2(output: '/full/path/to/output.jp2') # generate a new JP2 in the specified location
38
28
  ```
39
29
 
40
30
  ## Running tests
41
31
 
42
32
  ```bash
43
- bundle exec rake
44
- ```
45
-
46
- ## Generate documentation
47
- To generate documentation into the "doc" folder:
48
-
49
- ```bash
50
- yard
51
- ```
52
-
53
- To keep a local server running with up to date code documentation that you can view in your browser:
54
-
55
- ```bash
56
- yard server --reload
33
+ bundle exec rspec
57
34
  ```
58
35
 
59
36
  ## Prerequisites
60
37
 
61
38
  1. Kakadu Proprietary Software Binaries - for JP2 generation
62
- 1. ImageMagick 6.5.4 or higher
63
- 1. Exiftool
39
+ 1. Libvips
40
+ 1. Exiftool - upstream dependency of assembly-objectfile (used by specs to check mimetype of produced jp2, and because there is no libvips package available for circleci that speaks jp2)
64
41
 
65
42
  ### Kakadu
66
43
 
67
44
  Download and install demonstration binaries from Kakadu:
68
45
  http://kakadusoftware.com/downloads/
69
46
 
70
- NOTE: If you have upgrade to El Capitan on OS X, you will need to donwload and re-install the latest version of Kakadu, due to changes made with SIP. These changes moved the old executable binaries to an inaccessible location.
71
-
72
47
  ### Libvips
48
+ Note: libvips may require a significant amount of space for temporary files. The location for this can be controlled by the TMPDIR environment variable.
73
49
 
74
50
  #### Mac
75
51
 
@@ -79,7 +55,7 @@ brew install libvips
79
55
 
80
56
  ### Exiftool
81
57
 
82
- #### RHEL
58
+ #### Linux
83
59
  Download latest version from: http://www.sno.phy.queensu.ca/~phil/exiftool
84
60
 
85
61
  ```bash
@@ -4,7 +4,7 @@ $LOAD_PATH.push File.expand_path('lib', __dir__)
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = 'assembly-image'
7
- s.version = '2.0.0'
7
+ s.version = '2.1.0'
8
8
  s.authors = ['Peter Mangiafico', 'Renzo Sanchez-Silva', 'Monty Hindman', 'Tony Calavano']
9
9
  s.email = ['pmangiafico@stanford.edu']
10
10
  s.homepage = ''
@@ -17,8 +17,8 @@ Gem::Specification.new do |s|
17
17
  s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
18
  s.require_paths = ['lib']
19
19
 
20
+ s.add_dependency 'activesupport', '> 6.1'
20
21
  s.add_dependency 'assembly-objectfile', '>= 1.6.4'
21
- s.add_dependency 'mini_exiftool', '>= 1.6', '< 3'
22
22
  s.add_dependency 'ruby-vips', '>= 2.0'
23
23
 
24
24
  s.add_development_dependency 'pry-byebug'
@@ -27,5 +27,4 @@ Gem::Specification.new do |s|
27
27
  s.add_development_dependency 'rubocop'
28
28
  s.add_development_dependency 'rubocop-rspec'
29
29
  s.add_development_dependency 'simplecov'
30
- s.add_development_dependency 'yard'
31
30
  end
data/bin/console CHANGED
@@ -4,6 +4,6 @@
4
4
  require 'rubygems'
5
5
  require 'irb'
6
6
 
7
- require File.expand_path(File.dirname(__FILE__) + '/../config/boot')
7
+ require File.expand_path("#{File.dirname(__FILE__)}/../config/boot")
8
8
 
9
9
  IRB.start
data/config/boot.rb CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  require 'rubygems'
4
4
 
5
- project_root = File.expand_path(File.dirname(__FILE__) + '/..')
5
+ project_root = File.expand_path("#{File.dirname(__FILE__)}/..")
6
6
 
7
7
  # Load config for current environment.
8
- $LOAD_PATH.unshift(project_root + '/lib')
8
+ $LOAD_PATH.unshift("#{project_root}/lib")
9
9
 
10
10
  require 'assembly-image'
@@ -3,6 +3,7 @@
3
3
  require 'assembly-objectfile'
4
4
  require 'tempfile'
5
5
  require 'English' # see https://github.com/rubocop-hq/rubocop/issues/1747 (not #MAGA related)
6
+ require 'active_support/core_ext/module/delegation'
6
7
 
7
8
  module Assembly
8
9
  class Image < Assembly::ObjectFile
@@ -14,47 +15,46 @@ module Assembly
14
15
  # @return [Assembly::Image] object containing the generated JP2 file
15
16
  #
16
17
  # @param [Assembly::Image] the image file
17
- # @param [Hash] params Optional parameters specified as a hash, using symbols for options:
18
- # * :output => path to the output JP2 file (default: mirrors the source file name and path, but with a .jp2 extension)
19
- # * :overwrite => if set to false, an existing JP2 file with the same name won't be overwritten (default: false)
20
- # * :tmp_folder => the temporary folder to use when creating the jp2 (default: '/tmp'); also used by imagemagick
18
+ # @param [String] output path to the output JP2 file (default: mirrors the source file name and path, but with a .jp2 extension)
19
+ # @param [Boolean] overwrite if set to false, an existing JP2 file with the same name won't be overwritten (default: false)
20
+ # @param [Dir] tmp_folder the temporary folder to use when creating the jp2 (default: '/tmp'); also used by imagemagick
21
21
  #
22
22
  # Example:
23
23
  # source_img = Assembly::Image.new('/input/path_to_file.tif')
24
- # derivative_img = source_img.create_jp2(:overwrite=>true)
24
+ # derivative_img = source_img.create_jp2(overwrite: true)
25
25
  # puts derivative_img.mimetype # 'image/jp2'
26
26
  # puts derivative_image.path # '/input/path_to_file.jp2'
27
- def self.create(image, params = {})
28
- new(image, params).create
27
+ def self.create(image, **args)
28
+ new(image, **args).create
29
29
  end
30
30
 
31
- def initialize(image, params)
31
+ def initialize(image, overwrite: false, output: image.jp2_filename, tmp_folder: Dir.tmpdir)
32
32
  @image = image
33
- @output_path = params.fetch(:output, image.jp2_filename)
34
- @tmp_folder = params[:tmp_folder]
35
- @overwrite = params[:overwrite]
36
- @params = params
33
+ @output_path = output
34
+ @tmp_folder = tmp_folder
35
+ @overwrite = overwrite
37
36
  end
38
37
 
39
- attr_reader :image, :output_path, :tmp_folder, :tmp_path
38
+ attr_reader :image, :output_path, :tmp_folder, :tmp_tiff_path
39
+
40
+ delegate :vips_image, to: :image
40
41
 
41
42
  # @return [Assembly::Image] object containing the generated JP2 file
42
43
  def create
43
44
  create_jp2_checks
44
45
 
45
- # Using instance variable so that can check in tests.
46
- # We do this because we need to reliably compress the tiff and KDUcompress doesn’t support arbitrary image types
47
- @tmp_path = make_tmp_tiff(tmp_folder: tmp_folder)
46
+ # KDUcompress doesn’t support arbitrary image types, so we make a temporary tiff
47
+ @tmp_tiff_path = make_tmp_tiff
48
48
 
49
- jp2_command = jp2_create_command(source_path: @tmp_path, output: output_path)
49
+ jp2_command = jp2_create_command(source_path: tmp_tiff_path, output: output_path)
50
50
  result = `#{jp2_command}`
51
51
  unless $CHILD_STATUS.success?
52
52
  # Clean up any partial result
53
- File.delete(output_path) if File.exist?(output_path)
53
+ FileUtils.rm_rf(output_path)
54
54
  raise "JP2 creation command failed: #{jp2_command} with result #{result}"
55
55
  end
56
56
 
57
- File.delete(@tmp_path) unless @tmp_path.nil?
57
+ File.delete(tmp_tiff_path) unless tmp_tiff_path.nil?
58
58
 
59
59
  # create output response object, which is an Assembly::Image type object
60
60
  Image.new(output_path)
@@ -68,8 +68,10 @@ module Assembly
68
68
 
69
69
  def jp2_create_command(source_path:, output:)
70
70
  options = []
71
- # TODO: Consider using ruby-vips to determine the colorspace instead of relying on exif (which is done below)
72
- options << '-jp2_space sRGB' if image.samples_per_pixel == 3
71
+ # CMYK becomes sRGB in make_tmp_tiff, so jp2_space option will be set for sRGB and CMYK
72
+ # TODO: we're not sure at this time what happens for grayscale (or what Tony C. wants for grayscale)
73
+ # see https://github.com/sul-dlss/assembly-image/issues/98
74
+ options << '-jp2_space sRGB' if image.srgb?
73
75
  options += KDU_COMPRESS_DEFAULT_OPTIONS
74
76
  options << "Clayers=#{layers}"
75
77
  "kdu_compress #{options.join(' ')} -i '#{source_path}' -o '#{output}' 2>&1"
@@ -100,32 +102,24 @@ module Assembly
100
102
  raise SecurityError, 'cannot recreate jp2 over itself' if overwrite? && image.mimetype == 'image/jp2' && output_path == image.path
101
103
  end
102
104
 
103
- # Bigtiff needs to be used if size of image exceeds 2^32 bytes.
104
- def need_bigtiff?
105
- image.image_data_size >= 2**32
106
- end
107
-
108
105
  # We do this because we need to reliably compress the tiff and KDUcompress doesn’t support arbitrary image types
109
106
  # rubocop:disable Metrics/MethodLength
110
- def make_tmp_tiff(tmp_folder: nil)
111
- tmp_folder ||= Dir.tmpdir
112
- raise "tmp_folder #{tmp_folder} does not exists" unless File.exist?(tmp_folder)
107
+ def make_tmp_tiff
108
+ raise "tmp_folder #{tmp_folder} does not exist" unless File.exist?(tmp_folder)
113
109
 
114
110
  # make temp tiff filename
115
111
  tmp_tiff_file = Tempfile.new(['assembly-image', '.tif'], tmp_folder)
116
- tmp_path = tmp_tiff_file.path
117
- vips_image = Vips::Image.new_from_file image.path
118
-
119
- vips_image = if vips_image.interpretation.eql?(:cmyk)
120
- vips_image.icc_transform(SRGB_ICC, input_profile: CMYK_ICC)
121
- elsif !image.profile.nil?
122
- vips_image.icc_transform(SRGB_ICC, embedded: true)
123
- else
124
- vips_image
125
- end
126
-
127
- vips_image.tiffsave(tmp_path, bigtiff: need_bigtiff?)
128
- tmp_path
112
+ result_path = tmp_tiff_file.path
113
+ tmp_tiff_image = if vips_image.interpretation.eql?(:cmyk)
114
+ vips_image.icc_transform(SRGB_ICC, input_profile: CMYK_ICC)
115
+ elsif image.has_profile?
116
+ vips_image.icc_transform(SRGB_ICC, embedded: true)
117
+ else
118
+ vips_image
119
+ end
120
+
121
+ tmp_tiff_image.tiffsave(result_path, bigtiff: true) # Use bigtiff so we can support images > 4GB
122
+ result_path
129
123
  end
130
124
  # rubocop:enable Metrics/MethodLength
131
125
  end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'vips'
4
+ require 'assembly-objectfile'
5
+ require_relative 'image/jp2_creator'
6
+
7
+ module Assembly
8
+ # The Image class contains methods to operate on an image.
9
+ class Image < Assembly::ObjectFile
10
+ # @return [integer] image height in pixels
11
+ def height
12
+ vips_image.height
13
+ end
14
+
15
+ # @return [integer] image width in pixels
16
+ def width
17
+ vips_image.width
18
+ end
19
+
20
+ # @return [string] full default jp2 path and filename that will be created from the given image
21
+ # Example: given original file of '/dir/path_to_file.tif', gives '/dir/path_to_file.jp2'
22
+ def jp2_filename
23
+ # path is a property on Assembly::ObjectFile
24
+ File.extname(path).empty? ? "#{path}.jp2" : path.gsub(File.extname(path), '.jp2')
25
+ end
26
+
27
+ # Create a JP2 file for the current image.
28
+ # Important note: this will not work for multipage TIFFs.
29
+ #
30
+ # @param [String] output path to the output JP2 file (default: mirrors the source file name and path, but with a .jp2 extension)
31
+ # @param [Boolean] overwrite if set to false, an existing JP2 file with the same name won't be overwritten (default: false)
32
+ # @param [Dir] tmp_folder the temporary folder to use when creating the jp2 (default: '/tmp'); also used by imagemagick
33
+ # @return [Assembly::Image] object containing the generated JP2 file
34
+ #
35
+ # Example:
36
+ # source_img = Assembly::Image.new('/dir/path_to_file.tif')
37
+ # jp2_img = source_img.create_jp2(overwrite: true)
38
+ # jp2_img.mimetype # 'image/jp2'
39
+ # jp2_img.path # '/dir/path_to_file.jp2'
40
+ def create_jp2(**params)
41
+ Jp2Creator.create(self, **params)
42
+ end
43
+
44
+ def vips_image
45
+ # autorot will only affect images that need rotation: https://www.libvips.org/API/current/libvips-conversion.html#vips-autorot
46
+ @vips_image ||= Vips::Image.new_from_file(path).autorot
47
+ end
48
+
49
+ def srgb?
50
+ vips_image.interpretation == :srgb
51
+ end
52
+
53
+ # Does the image include an ICC profile?
54
+ def has_profile?
55
+ vips_image.get_fields.include?('icc-profile-data')
56
+ end
57
+ end
58
+ end
@@ -2,11 +2,10 @@
2
2
 
3
3
  module Assembly
4
4
  # the path to the gem, used to access profiles stored with the gem
5
- PATH_TO_IMAGE_GEM = File.expand_path(File.dirname(__FILE__) + '/..')
5
+ PATH_TO_IMAGE_GEM = File.expand_path("#{File.dirname(__FILE__)}/..")
6
6
  PATH_TO_PROFILES = File.join(Assembly::PATH_TO_IMAGE_GEM, 'profiles')
7
7
  SRGB_ICC = File.join(PATH_TO_PROFILES, 'sRGBIEC6196621.icc')
8
8
  CMYK_ICC = File.join(PATH_TO_PROFILES, 'cmyk.icc')
9
9
  end
10
10
 
11
- require 'assembly-image/image'
12
- require 'assembly-image/images'
11
+ require 'assembly/image'