assembly-image 1.7.8 → 2.0.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 +4 -4
- data/.circleci/config.yml +3 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +3 -3
- data/.rubocop_todo.yml +17 -7
- data/README.md +3 -69
- data/assembly-image.gemspec +3 -3
- data/lib/assembly-image/image.rb +3 -16
- data/lib/assembly-image/images.rb +0 -5
- data/lib/assembly-image/jp2_creator.rb +17 -66
- data/lib/assembly-image.rb +3 -0
- data/profiles/cmyk.icc +0 -0
- data/spec/assembly/image/jp2_creator_spec.rb +3 -7
- data/spec/image_spec.rb +157 -112
- data/spec/images_spec.rb +38 -38
- data/spec/spec_helper.rb +117 -14
- 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_srgb_rot90cw.tif +0 -0
- data/spec/test_data/color_rgb_untagged.tif +0 -0
- data/spec/test_data/gray_gray_untagged.tif +0 -0
- metadata +40 -11
- data/bin/run_all_tests +0 -3
- data/lib/assembly-image/version.rb +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9379ec53a26a08578c11910512bd73045366fc337fcafb0c7eb1a247370566b1
|
4
|
+
data.tar.gz: 316fbef312cb027f4061bbe74dc2f8dce993a095d6779da100abeeecbf24b9da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 97cc720649bdc6e0bb6d7453afdefc7abe3f0931a45976d397f1f77fd2f2dacbcbd4991e64c0e4849a2ae61efa51d72d428ce9a8a15e9a125abdeefcb17b0d5b
|
7
|
+
data.tar.gz: 8e6580aaade8302319e7cbf41d56d8ac0ebe1a05db5607bed8580cebe8a3c87b5795cb90f50e2b9eb4b081d9048a600799b0e373badf811ff9a084e5f9af3fcc
|
data/.circleci/config.yml
CHANGED
@@ -12,6 +12,9 @@ workflows:
|
|
12
12
|
- run:
|
13
13
|
name: Install exiftool
|
14
14
|
command: curl -L http://cpanmin.us | perl - --sudo Image::ExifTool
|
15
|
+
- run:
|
16
|
+
name: Install libvips
|
17
|
+
command: sudo apt-get update && sudo apt-get install -y libvips
|
15
18
|
- setup_remote_docker
|
16
19
|
- run:
|
17
20
|
name: Install Kakadu
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -22,9 +22,6 @@ Naming/FileName:
|
|
22
22
|
Exclude:
|
23
23
|
- lib/assembly-image.rb
|
24
24
|
|
25
|
-
RSpec/ExampleLength:
|
26
|
-
Max: 12
|
27
|
-
|
28
25
|
Style/WordArray:
|
29
26
|
Enabled: false
|
30
27
|
|
@@ -166,3 +163,6 @@ RSpec/ChangeByZero: # new in 2.11.0
|
|
166
163
|
Enabled: true
|
167
164
|
RSpec/VerifiedDoubleReference: # new in 2.10.0
|
168
165
|
Enabled: true
|
166
|
+
|
167
|
+
Gemspec/DeprecatedAttributeAssignment: # new in 1.30
|
168
|
+
Enabled: true
|
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-06-16 22:15:07 UTC using RuboCop version 1.30.1.
|
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,13 +13,23 @@ Gemspec/RequiredRubyVersion:
|
|
13
13
|
Exclude:
|
14
14
|
- 'assembly-image.gemspec'
|
15
15
|
|
16
|
-
# Offense count:
|
17
|
-
#
|
16
|
+
# Offense count: 2
|
17
|
+
# This cop supports safe autocorrection (--autocorrect).
|
18
18
|
Lint/RedundantCopDisableDirective:
|
19
19
|
Exclude:
|
20
20
|
- 'lib/assembly-image/image.rb'
|
21
21
|
- 'lib/assembly-image/images.rb'
|
22
22
|
|
23
|
+
# Offense count: 2
|
24
|
+
# Configuration parameters: IgnoredMethods, CountRepeatedAttributes.
|
25
|
+
Metrics/AbcSize:
|
26
|
+
Max: 20
|
27
|
+
|
28
|
+
# Offense count: 14
|
29
|
+
# Configuration parameters: CountAsOne.
|
30
|
+
RSpec/ExampleLength:
|
31
|
+
Max: 15
|
32
|
+
|
23
33
|
# Offense count: 2
|
24
34
|
# Configuration parameters: Include, CustomTransform, IgnoreMethods, SpecSuffixOnly.
|
25
35
|
# Include: **/*_spec*rb*, **/spec/**/*
|
@@ -30,7 +40,7 @@ RSpec/FilePath:
|
|
30
40
|
|
31
41
|
# Offense count: 21
|
32
42
|
RSpec/MultipleExpectations:
|
33
|
-
Max:
|
43
|
+
Max: 13
|
34
44
|
|
35
45
|
# Offense count: 5
|
36
46
|
RSpec/UnspecifiedException:
|
@@ -44,7 +54,7 @@ Style/CombinableLoops:
|
|
44
54
|
- 'spec/images_spec.rb'
|
45
55
|
|
46
56
|
# Offense count: 1
|
47
|
-
#
|
57
|
+
# This cop supports unsafe autocorrection (--autocorrect-all).
|
48
58
|
Style/GlobalStdStream:
|
49
59
|
Exclude:
|
50
60
|
- 'lib/assembly-image/images.rb'
|
@@ -56,8 +66,8 @@ Style/OptionalBooleanParameter:
|
|
56
66
|
Exclude:
|
57
67
|
- 'lib/assembly-image/image.rb'
|
58
68
|
|
59
|
-
# Offense count:
|
60
|
-
#
|
69
|
+
# Offense count: 7
|
70
|
+
# This cop supports unsafe autocorrection (--autocorrect-all).
|
61
71
|
# Configuration parameters: Mode.
|
62
72
|
Style/StringConcatenation:
|
63
73
|
Exclude:
|
data/README.md
CHANGED
@@ -9,52 +9,7 @@
|
|
9
9
|
This gem contains classes used by the Stanford University Digital Library to
|
10
10
|
perform image operations necessary for accessioning of content.
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
* 0.0.1 initial release
|
15
|
-
* 0.0.2 small bug fixes
|
16
|
-
* 0.0.3 more bug fixes
|
17
|
-
* 0.0.4 update jp2 creation method to restrict allowed input types and improve color profile handling
|
18
|
-
* 0.0.5 updated documentation to yard format
|
19
|
-
* 0.0.6 updated dependency declarations
|
20
|
-
* 0.1.0 move color profile extraction to tmp folder instead of gem profiles folder
|
21
|
-
* 0.1.1 fix problem with digest require statement
|
22
|
-
* 0.1.2 move check for file existence to when an action occurs instead of object initialization; more error checking and messages on command execution
|
23
|
-
* 0.1.3 added a filesize attribute to the file object to allow easy access to filesize in bytes
|
24
|
-
* 0.1.4 added a new images class that allows you batch create jp2s from an input TIFF directory
|
25
|
-
* 0.2.0 added a new method to the image class to handle TIFF "sanity-check" -- can be used to ensure TIFFs are valid before JP2 generation
|
26
|
-
* 1.0.0 bump the version number up to an official production level release
|
27
|
-
* 1.1.0 remove common object file behaviors to a separate gem and use that gem as a dependency
|
28
|
-
* 1.1.1 minor changes to spec tests
|
29
|
-
* 1.1.2 remove the addition of 'format' node to file types in content metadata generation
|
30
|
-
* 1.1.3 changes to content metadata generation method: change md5 and sha1 computations so that they come from the assembly-objectfile gem,
|
31
|
-
and set preserve/publish/shelve attributes using mimetype defaults
|
32
|
-
* 1.2.0 support tiffs that have embedded thumbnails when creating jp2
|
33
|
-
* 1.2.1 raise a SecurityError if the user attempts to overwrite an existing jp2 when creating it, to make it easier to catch in assembly
|
34
|
-
* 1.2.2 add height and width methods for an image that gets it from exif
|
35
|
-
* 1.2.4 prepare for release listing on DLSS release board
|
36
|
-
* 1.2.5 small change to use the jp2able method instead of the valid? method when creating jp2s
|
37
|
-
* 1.2.6 update how version number is set to make it easier to show
|
38
|
-
* 1.3.0 added a new method to the Assembly::Images class to allow for batch adding of color profiles to all tiffs in a directory; allow batch methods to run recursively
|
39
|
-
* 1.3.1 remove content metadata generation method and add to assembly-objectfile gem instead
|
40
|
-
* 1.3.3 update gemspec to force use of latest assembly-objectfile gem to allow gem to work in Ruby 1.9 projects
|
41
|
-
* 1.3.4 update to latest version of lyberteam gems
|
42
|
-
* 1.3.5 fix a problem that could occur if there were spaces in input filenames
|
43
|
-
* 1.3.6 add new attribute to give you default jp2 filename that will be used
|
44
|
-
* 1.3.7 add new attribute to give you default dpg jp2 filename
|
45
|
-
* 1.3.8 allow for batch processing of image extensions other than tif
|
46
|
-
* 1.3.9 create new methods for getting a color profile from exif and for force adding color profile to a single image
|
47
|
-
* 1.4.0 and 1.4.1 set the imagemagick tmp folder location environment variable when creating jp2
|
48
|
-
* 1.5.0 allow images with a color profile to have jp2 derivatives generated
|
49
|
-
* 1.5.1 relax nokogiri version requirement
|
50
|
-
* 1.6.1 bump version number of assembly-objectfile required to fix UTF-8 errors during JP2-create
|
51
|
-
* 1.6.2-1.6.3 small change to jp2 generation to try and fix bug with tiffs that have multiple input profile layers
|
52
|
-
* 1.6.4 added in some additional checks to try and create jp2s with mismatching exif data
|
53
|
-
* 1.6.5 fix problem with lack of extension in incoming tif causing a problem when creating jp2
|
54
|
-
* 1.6.7 release to github/rubygems
|
55
|
-
* 1.6.9 update mini_exiftool
|
56
|
-
* 1.7.1 for jp2, only transcode to tiff if not a tiff
|
57
|
-
* 1.7.3 for jp2, only transcode to tiff if not an uncompressed tiff
|
12
|
+
Requires image processing software - see PreRequisites section below.
|
58
13
|
|
59
14
|
## Notes
|
60
15
|
|
@@ -114,33 +69,12 @@ http://kakadusoftware.com/downloads/
|
|
114
69
|
|
115
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.
|
116
71
|
|
117
|
-
###
|
118
|
-
|
119
|
-
#### RHEL 6
|
120
|
-
|
121
|
-
The version of ImageMagick included with RHEL 6 has all of the dependency libraries included:
|
122
|
-
|
123
|
-
```bash
|
124
|
-
yum install ImageMagick
|
125
|
-
```
|
126
|
-
#### RHEL 5
|
127
|
-
|
128
|
-
The version of ImageMagick included with RHEL 5 is too old and does not have all the proper binaries included/built:
|
129
|
-
|
130
|
-
```bash
|
131
|
-
yum install lcms lcms-devel libjpeg libjpeg-devel libpng libpng-devel
|
132
|
-
```
|
133
|
-
Required libraries from source:
|
134
|
-
* libtiff (version 3.9.4 or higher)
|
135
|
-
|
136
|
-
Build Imagemagick from source:
|
137
|
-
http://www.imagemagick.org/download/ImageMagick.tar.gz
|
72
|
+
### Libvips
|
138
73
|
|
139
74
|
#### Mac
|
140
75
|
|
141
76
|
```bash
|
142
|
-
brew install
|
143
|
-
brew install imagemagick --use-tiff --use-jpeg2000
|
77
|
+
brew install libvips
|
144
78
|
```
|
145
79
|
|
146
80
|
### Exiftool
|
data/assembly-image.gemspec
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
$LOAD_PATH.push File.expand_path('lib', __dir__)
|
4
|
-
require 'assembly-image/version'
|
5
4
|
|
6
5
|
Gem::Specification.new do |s|
|
7
6
|
s.name = 'assembly-image'
|
8
|
-
s.version =
|
7
|
+
s.version = '2.0.0'
|
9
8
|
s.authors = ['Peter Mangiafico', 'Renzo Sanchez-Silva', 'Monty Hindman', 'Tony Calavano']
|
10
9
|
s.email = ['pmangiafico@stanford.edu']
|
11
10
|
s.homepage = ''
|
@@ -14,14 +13,15 @@ Gem::Specification.new do |s|
|
|
14
13
|
s.metadata['rubygems_mfa_required'] = 'true'
|
15
14
|
|
16
15
|
s.files = `git ls-files`.split("\n")
|
17
|
-
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
16
|
s.bindir = 'exe'
|
19
17
|
s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
18
|
s.require_paths = ['lib']
|
21
19
|
|
22
20
|
s.add_dependency 'assembly-objectfile', '>= 1.6.4'
|
23
21
|
s.add_dependency 'mini_exiftool', '>= 1.6', '< 3'
|
22
|
+
s.add_dependency 'ruby-vips', '>= 2.0'
|
24
23
|
|
24
|
+
s.add_development_dependency 'pry-byebug'
|
25
25
|
s.add_development_dependency 'rake'
|
26
26
|
s.add_development_dependency 'rspec', '~> 3.0'
|
27
27
|
s.add_development_dependency 'rubocop'
|
data/lib/assembly-image/image.rb
CHANGED
@@ -1,14 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'ruby-vips'
|
3
4
|
require 'assembly-objectfile'
|
4
5
|
require_relative 'jp2_creator'
|
5
6
|
|
6
7
|
module Assembly
|
7
8
|
# The Image class contains methods to operate on an image.
|
8
|
-
class Image
|
9
|
-
# include common behaviors from assembly-objectfile gem
|
10
|
-
include Assembly::ObjectFileable
|
11
|
-
|
9
|
+
class Image < Assembly::ObjectFile
|
12
10
|
# Examines the input image for validity. Used to determine if image is correct and if JP2 generation is likely to succeed.
|
13
11
|
# This method is automatically called before you create a jp2 but it can be called separately earlier as a sanity check.
|
14
12
|
#
|
@@ -77,8 +75,7 @@ module Assembly
|
|
77
75
|
def add_exif_profile_description(profile_name, force = false)
|
78
76
|
if profile.nil? || force
|
79
77
|
input_profile = profile_name.gsub(/[^[:alnum:]]/, '') # remove all non alpha-numeric characters, so we can get to a filename
|
80
|
-
|
81
|
-
input_profile_file = File.join(path_to_profiles, "#{input_profile}.icc")
|
78
|
+
input_profile_file = File.join(PATH_TO_PROFILES, "#{input_profile}.icc")
|
82
79
|
command = "exiftool '-icc_profile<=#{input_profile_file}' #{path}"
|
83
80
|
result = `#{command} 2>&1`
|
84
81
|
raise "profile addition command failed: #{command} with result #{result}" unless $CHILD_STATUS.success?
|
@@ -97,16 +94,6 @@ module Assembly
|
|
97
94
|
File.extname(path).empty? ? "#{path}.jp2" : path.gsub(File.extname(path), '.jp2')
|
98
95
|
end
|
99
96
|
|
100
|
-
# Returns the full DPG equivalent jp2 path and filename that would match with the given image
|
101
|
-
#
|
102
|
-
# @return [string] full DPG equivalent jp2 path and filename
|
103
|
-
# Example:
|
104
|
-
# source_img=Assembly::Image.new('/input/path_to_file.tif')
|
105
|
-
# puts source_img.jp2_filename # gives /input/path_to_file.jp2
|
106
|
-
def dpg_jp2_filename
|
107
|
-
jp2_filename.gsub('_00_', '_05_')
|
108
|
-
end
|
109
|
-
|
110
97
|
# Create a JP2 file for the current image.
|
111
98
|
# Important note: this will not work for multipage TIFFs.
|
112
99
|
#
|
@@ -37,8 +37,6 @@ module Assembly
|
|
37
37
|
|
38
38
|
raise 'Input path does not exist' unless File.directory?(source)
|
39
39
|
|
40
|
-
logger.debug "Source: #{source}"
|
41
|
-
|
42
40
|
# iterate over input directory looking for tifs
|
43
41
|
pattern = recursive ? "**/*.#{extension}" : "*.#{extension}*"
|
44
42
|
Dir.glob(File.join(source, pattern)).each do |file|
|
@@ -81,9 +79,6 @@ module Assembly
|
|
81
79
|
Dir.mkdir(output) unless File.directory?(output) # attemp to make output directory
|
82
80
|
raise 'Output path does not exist or could not be created' unless File.directory?(output)
|
83
81
|
|
84
|
-
logger.debug "Source: #{source}"
|
85
|
-
logger.debug "Destination: #{output}"
|
86
|
-
|
87
82
|
pattern = recursive ? "**/*.#{extension}" : "*.#{extension}*"
|
88
83
|
|
89
84
|
# iterate over input directory looking for tifs
|
@@ -1,12 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'assembly-objectfile'
|
3
4
|
require 'tempfile'
|
4
5
|
require 'English' # see https://github.com/rubocop-hq/rubocop/issues/1747 (not #MAGA related)
|
5
6
|
|
6
7
|
module Assembly
|
7
|
-
class Image
|
8
|
+
class Image < Assembly::ObjectFile
|
8
9
|
# Creates jp2 derivatives
|
9
|
-
class Jp2Creator
|
10
|
+
class Jp2Creator
|
10
11
|
# Create a JP2 file for the current image.
|
11
12
|
# Important note: this will not work for multipage TIFFs.
|
12
13
|
#
|
@@ -42,6 +43,7 @@ module Assembly
|
|
42
43
|
create_jp2_checks
|
43
44
|
|
44
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
|
45
47
|
@tmp_path = make_tmp_tiff(tmp_folder: tmp_folder)
|
46
48
|
|
47
49
|
jp2_command = jp2_create_command(source_path: @tmp_path, output: output_path)
|
@@ -66,6 +68,7 @@ module Assembly
|
|
66
68
|
|
67
69
|
def jp2_create_command(source_path:, output:)
|
68
70
|
options = []
|
71
|
+
# TODO: Consider using ruby-vips to determine the colorspace instead of relying on exif (which is done below)
|
69
72
|
options << '-jp2_space sRGB' if image.samples_per_pixel == 3
|
70
73
|
options += KDU_COMPRESS_DEFAULT_OPTIONS
|
71
74
|
options << "Clayers=#{layers}"
|
@@ -80,20 +83,15 @@ module Assembly
|
|
80
83
|
|
81
84
|
KDU_COMPRESS_DEFAULT_OPTIONS = [
|
82
85
|
'-num_threads 2', # forces Kakadu to only use 2 threads
|
83
|
-
'-precise', # forces the use of 32-bit representations
|
84
|
-
'-no_weights', # minimization of the MSE over all reconstructed colour components
|
85
86
|
'-quiet', # suppress informative messages.
|
86
87
|
'Creversible=no', # Disable reversible compression
|
87
|
-
'Cmodes=BYPASS', #
|
88
88
|
'Corder=RPCL', # R=resolution P=position C=component L=layer
|
89
89
|
'Cblk=\\{64,64\\}', # code-block dimensions; 64x64 happens to also be the default
|
90
90
|
'Cprecincts=\\{256,256\\},\\{256,256\\},\\{128,128\\}', # Precinct dimensions; 256x256 for the 2 highest resolution levels, defaults to 128x128 for the rest
|
91
|
-
'
|
92
|
-
'-rate 1.5', # Ratio of compressed bits to the image size
|
91
|
+
'-rate -', # Ratio of compressed bits to the image size
|
93
92
|
'Clevels=5' # Number of wavelet decomposition levels, or stages
|
94
93
|
].freeze
|
95
94
|
|
96
|
-
# rubocop:disable Metrics/AbcSize
|
97
95
|
def create_jp2_checks
|
98
96
|
image.send(:check_for_file)
|
99
97
|
raise 'input file is not a valid image, or is the wrong mimetype' unless image.jp2able?
|
@@ -102,45 +100,13 @@ module Assembly
|
|
102
100
|
raise SecurityError, 'cannot recreate jp2 over itself' if overwrite? && image.mimetype == 'image/jp2' && output_path == image.path
|
103
101
|
end
|
104
102
|
|
105
|
-
# rubocop:disable Metrics/MethodLength
|
106
|
-
def profile_conversion_switch(profile, tmp_folder:)
|
107
|
-
path_to_profiles = File.join(Assembly::PATH_TO_IMAGE_GEM, 'profiles')
|
108
|
-
# eventually we may allow the user to specify the output_profile...when we do, you can just uncomment this code
|
109
|
-
# and update the tests that check for this
|
110
|
-
output_profile = 'sRGBIEC6196621' # params[:output_profile] || 'sRGBIEC6196621'
|
111
|
-
output_profile_file = File.join(path_to_profiles, "#{output_profile}.icc")
|
112
|
-
|
113
|
-
raise "output profile #{output_profile} invalid" unless File.exist?(output_profile_file)
|
114
|
-
|
115
|
-
return '' if image.profile.nil?
|
116
|
-
|
117
|
-
# if the input color profile exists, contract paths to the profile and setup the command
|
118
|
-
|
119
|
-
input_profile = profile.gsub(/[^[:alnum:]]/, '') # remove all non alpha-numeric characters, so we can get to a filename
|
120
|
-
|
121
|
-
# construct a path to the input profile, which might exist either in the gem itself or in the tmp folder
|
122
|
-
input_profile_file_gem = File.join(path_to_profiles, "#{input_profile}.icc")
|
123
|
-
input_profile_file_tmp = File.join(tmp_folder, "#{input_profile}.icc")
|
124
|
-
input_profile_file = File.exist?(input_profile_file_gem) ? input_profile_file_gem : input_profile_file_tmp
|
125
|
-
|
126
|
-
# if input profile was extracted and does not matches an existing known profile either in the gem or in the tmp folder,
|
127
|
-
# we'll issue an imagicmagick command to extract the profile to the tmp folder
|
128
|
-
unless File.exist?(input_profile_file)
|
129
|
-
input_profile_extract_command = "MAGICK_TEMPORARY_PATH=#{tmp_folder} convert '#{image.path}'[0] #{input_profile_file}" # extract profile from input image
|
130
|
-
result = `#{input_profile_extract_command} 2>&1`
|
131
|
-
raise "input profile extraction command failed: #{input_profile_extract_command} with result #{result}" unless $CHILD_STATUS.success?
|
132
|
-
# if extraction failed or we cannot write the file, throw exception
|
133
|
-
raise 'input profile is not a known profile and could not be extracted from input file' unless File.exist?(input_profile_file)
|
134
|
-
end
|
135
|
-
|
136
|
-
"-profile #{input_profile_file} -profile #{output_profile_file}"
|
137
|
-
end
|
138
|
-
|
139
103
|
# Bigtiff needs to be used if size of image exceeds 2^32 bytes.
|
140
104
|
def need_bigtiff?
|
141
105
|
image.image_data_size >= 2**32
|
142
106
|
end
|
143
107
|
|
108
|
+
# We do this because we need to reliably compress the tiff and KDUcompress doesn’t support arbitrary image types
|
109
|
+
# rubocop:disable Metrics/MethodLength
|
144
110
|
def make_tmp_tiff(tmp_folder: nil)
|
145
111
|
tmp_folder ||= Dir.tmpdir
|
146
112
|
raise "tmp_folder #{tmp_folder} does not exists" unless File.exist?(tmp_folder)
|
@@ -148,35 +114,20 @@ module Assembly
|
|
148
114
|
# make temp tiff filename
|
149
115
|
tmp_tiff_file = Tempfile.new(['assembly-image', '.tif'], tmp_folder)
|
150
116
|
tmp_path = tmp_tiff_file.path
|
117
|
+
vips_image = Vips::Image.new_from_file image.path
|
151
118
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
options << '-type TrueColor'
|
160
|
-
when 1
|
161
|
-
options << '-depth 8' # force the production of a grayscale access derivative
|
162
|
-
options << '-type Grayscale'
|
163
|
-
end
|
164
|
-
|
165
|
-
options << profile_conversion_switch(image.profile, tmp_folder: tmp_folder)
|
166
|
-
|
167
|
-
# The output in the covnert command needs to be prefixed by the image type. By default ImageMagick
|
168
|
-
# will assume TIFF: when the file extension is .tif/.tiff. TIFF64: Needs to be forced when image will
|
169
|
-
# exceed 2^32 bytes in size
|
170
|
-
tiff_type = need_bigtiff? ? 'TIFF64:' : ''
|
171
|
-
|
172
|
-
tiff_command = "MAGICK_TEMPORARY_PATH=#{tmp_folder} convert -quiet -compress none #{options.join(' ')} '#{image.path}[0]' #{tiff_type}'#{tmp_path}'"
|
173
|
-
result = `#{tiff_command} 2>&1`
|
174
|
-
raise "tiff convert command failed: #{tiff_command} with result #{result}" unless $CHILD_STATUS.success?
|
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
|
175
126
|
|
127
|
+
vips_image.tiffsave(tmp_path, bigtiff: need_bigtiff?)
|
176
128
|
tmp_path
|
177
129
|
end
|
178
130
|
# rubocop:enable Metrics/MethodLength
|
179
|
-
# rubocop:enable Metrics/AbcSize
|
180
131
|
end
|
181
132
|
end
|
182
133
|
end
|
data/lib/assembly-image.rb
CHANGED
@@ -3,6 +3,9 @@
|
|
3
3
|
module Assembly
|
4
4
|
# the path to the gem, used to access profiles stored with the gem
|
5
5
|
PATH_TO_IMAGE_GEM = File.expand_path(File.dirname(__FILE__) + '/..')
|
6
|
+
PATH_TO_PROFILES = File.join(Assembly::PATH_TO_IMAGE_GEM, 'profiles')
|
7
|
+
SRGB_ICC = File.join(PATH_TO_PROFILES, 'sRGBIEC6196621.icc')
|
8
|
+
CMYK_ICC = File.join(PATH_TO_PROFILES, 'cmyk.icc')
|
6
9
|
end
|
7
10
|
|
8
11
|
require 'assembly-image/image'
|
data/profiles/cmyk.icc
ADDED
Binary file
|
@@ -9,11 +9,7 @@ RSpec.describe Assembly::Image::Jp2Creator do
|
|
9
9
|
let(:input_path) { TEST_TIF_INPUT_FILE }
|
10
10
|
let(:creator) { described_class.new(ai, output: TEST_JP2_OUTPUT_FILE) }
|
11
11
|
|
12
|
-
|
13
|
-
# after each test, empty out the input and output test directories
|
14
|
-
remove_files(TEST_INPUT_DIR)
|
15
|
-
remove_files(TEST_OUTPUT_DIR)
|
16
|
-
end
|
12
|
+
before { cleanup }
|
17
13
|
|
18
14
|
context 'when given an LZW compressed RGB tif' do
|
19
15
|
before do
|
@@ -31,8 +27,8 @@ RSpec.describe Assembly::Image::Jp2Creator do
|
|
31
27
|
expect(creator.tmp_path).not_to be_nil
|
32
28
|
expect(result.exif.colorspace).to eq 'sRGB'
|
33
29
|
jp2 = Assembly::Image.new(TEST_JP2_OUTPUT_FILE)
|
34
|
-
expect(jp2.height).to eq
|
35
|
-
expect(jp2.width).to eq
|
30
|
+
expect(jp2.height).to eq 36
|
31
|
+
expect(jp2.width).to eq 43
|
36
32
|
end
|
37
33
|
end
|
38
34
|
|