assembly-image 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +1 -1
- data/.gitignore +0 -1
- data/.rubocop.yml +21 -3
- data/.rubocop_todo.yml +5 -55
- data/.rvmrc.example +1 -1
- data/Gemfile.lock +105 -0
- data/README.md +12 -36
- data/assembly-image.gemspec +2 -3
- data/bin/console +1 -1
- data/config/boot.rb +2 -2
- data/lib/{assembly-image → assembly/image}/jp2_creator.rb +36 -42
- data/lib/assembly/image.rb +58 -0
- data/lib/assembly-image.rb +2 -3
- data/spec/assembly/image/jp2_creator_spec.rb +327 -34
- data/spec/assembly/image_spec.rb +25 -0
- data/spec/spec_helper.rb +2 -19
- metadata +14 -42
- data/lib/assembly-image/image.rb +0 -149
- data/lib/assembly-image/images.rb +0 -102
- data/spec/image_spec.rb +0 -324
- data/spec/images_spec.rb +0 -47
- data/spec/test_data/color_cmyk_tagged.tif +0 -0
- data/spec/test_data/color_cmyk_untagged.tif +0 -0
- data/spec/test_data/color_rgb_adobergb1998_lzw.tif +0 -0
- data/spec/test_data/color_rgb_srgb.jpg +0 -0
- data/spec/test_data/color_rgb_srgb.tif +0 -0
- data/spec/test_data/color_rgb_untagged.tif +0 -0
- data/spec/test_data/gray_gray_untagged.tif +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '088a4b9c59b50f893f7b50c16898321770006b4ab22dc08a8ddd70cdba9a15da'
|
4
|
+
data.tar.gz: f22bf6d6acbd4d6885e2102526e7c5e0ac76b93af71eff0d2237d32334afd223
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 91f0be3622982ad69823a45eca8111d05756e0442cd7d7aa16cb8099e71ee2e95c21f17c7f14b7ccab04c11724233c9a9739e24f8b8302f07f42b16738c6400e
|
7
|
+
data.tar.gz: d1ab206c475413496a6add9376cb246705df18a3142bdc32189b202e31af698b8cfded84464d00e94357fc08396ab142270043b3b862cc0d68cd57834863b649
|
data/.circleci/config.yml
CHANGED
data/.gitignore
CHANGED
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:
|
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-
|
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:
|
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:
|
46
|
-
RSpec/
|
47
|
-
|
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.
|
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
|
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
|
18
|
-
|
19
|
-
is
|
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
|
-
|
35
|
-
|
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
|
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.
|
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
|
-
####
|
58
|
+
#### Linux
|
83
59
|
Download latest version from: http://www.sno.phy.queensu.ca/~phil/exiftool
|
84
60
|
|
85
61
|
```bash
|
data/assembly-image.gemspec
CHANGED
@@ -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.
|
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
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
|
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 [
|
18
|
-
#
|
19
|
-
#
|
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(:
|
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,
|
28
|
-
new(image,
|
27
|
+
def self.create(image, **args)
|
28
|
+
new(image, **args).create
|
29
29
|
end
|
30
30
|
|
31
|
-
def initialize(image,
|
31
|
+
def initialize(image, overwrite: false, output: image.jp2_filename, tmp_folder: Dir.tmpdir)
|
32
32
|
@image = image
|
33
|
-
@output_path =
|
34
|
-
@tmp_folder =
|
35
|
-
@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, :
|
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
|
-
#
|
46
|
-
|
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:
|
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
|
-
|
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(
|
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
|
-
#
|
72
|
-
|
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
|
111
|
-
tmp_folder
|
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
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
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
|
data/lib/assembly-image.rb
CHANGED
@@ -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
|
12
|
-
require 'assembly-image/images'
|
11
|
+
require 'assembly/image'
|