assembly-image 2.1.1 → 2.1.2
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/Gemfile.lock +1 -1
- data/assembly-image.gemspec +1 -1
- data/lib/assembly/image/jp2_creator.rb +27 -21
- data/spec/assembly/image/jp2_creator_spec.rb +94 -50
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46a8b192fe259bee51df21215e413dc0a570012b441f530cabb73a172dfb6e13
|
4
|
+
data.tar.gz: a87eb5df0582c60e74c182e8711758df11388a4aaaf9084149a0b1b3bcdaf5a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cdbb16145c19623c462b5a0121dafe614e09d6f37dfd5ca1cde1ea4b38eb3829c0cf33300dbde92f64a3c678e2c313bd5241352a52510499c084061058a2204a
|
7
|
+
data.tar.gz: 56d878d05722d07fbb0fe42e8ae04bdb39772ada0c94d03808ba066ef89719a0af0419ceaa667db53030b7385139226ef77a1c3d97bb8d76640f58e3e848a7c0
|
data/Gemfile.lock
CHANGED
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.1.
|
7
|
+
s.version = '2.1.2'
|
8
8
|
s.authors = ['Peter Mangiafico', 'Renzo Sanchez-Silva', 'Monty Hindman', 'Tony Calavano']
|
9
9
|
s.email = ['pmangiafico@stanford.edu']
|
10
10
|
s.homepage = ''
|
@@ -35,7 +35,7 @@ module Assembly
|
|
35
35
|
@overwrite = overwrite
|
36
36
|
end
|
37
37
|
|
38
|
-
attr_reader :image, :output_path, :tmp_folder
|
38
|
+
attr_reader :image, :output_path, :tmp_folder
|
39
39
|
|
40
40
|
delegate :vips_image, to: :image
|
41
41
|
|
@@ -43,19 +43,14 @@ module Assembly
|
|
43
43
|
def create
|
44
44
|
create_jp2_checks
|
45
45
|
|
46
|
-
|
47
|
-
|
46
|
+
Dir.mktmpdir('assembly-image', tmp_folder) do |tmp_tiff_dir|
|
47
|
+
tmp_tiff_path = File.join(tmp_tiff_dir, 'temp.tif')
|
48
48
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
# Clean up any partial result
|
53
|
-
FileUtils.rm_rf(output_path)
|
54
|
-
raise "JP2 creation command failed: #{jp2_command} with result #{result}"
|
49
|
+
# KDUcompress doesn’t support arbitrary image types, so we make a temporary tiff
|
50
|
+
make_tmp_tiff(tmp_tiff_path)
|
51
|
+
make_jp2(tmp_tiff_path)
|
55
52
|
end
|
56
53
|
|
57
|
-
File.delete(tmp_tiff_path) unless tmp_tiff_path.nil?
|
58
|
-
|
59
54
|
# create output response object, which is an Assembly::Image type object
|
60
55
|
Image.new(output_path)
|
61
56
|
end
|
@@ -94,22 +89,22 @@ module Assembly
|
|
94
89
|
'Clevels=5' # Number of wavelet decomposition levels, or stages
|
95
90
|
].freeze
|
96
91
|
|
92
|
+
# rubocop:disable Metrics/AbcSize
|
93
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
97
94
|
def create_jp2_checks
|
95
|
+
raise "tmp_folder #{tmp_folder} does not exist" unless File.exist?(tmp_folder)
|
96
|
+
|
98
97
|
image.send(:check_for_file)
|
99
98
|
raise 'input file is not a valid image, or is the wrong mimetype' unless image.jp2able?
|
100
99
|
|
101
100
|
raise SecurityError, "output #{output_path} exists, cannot overwrite" if !overwrite? && File.exist?(output_path)
|
102
101
|
raise SecurityError, 'cannot recreate jp2 over itself' if overwrite? && image.mimetype == 'image/jp2' && output_path == image.path
|
103
102
|
end
|
103
|
+
# rubocop:enable Metrics/AbcSize
|
104
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
104
105
|
|
105
106
|
# We do this because we need to reliably compress the tiff and KDUcompress doesn’t support arbitrary image types
|
106
|
-
|
107
|
-
def make_tmp_tiff
|
108
|
-
raise "tmp_folder #{tmp_folder} does not exist" unless File.exist?(tmp_folder)
|
109
|
-
|
110
|
-
# make temp tiff filename
|
111
|
-
tmp_tiff_file = Tempfile.new(['assembly-image', '.tif'], tmp_folder)
|
112
|
-
result_path = tmp_tiff_file.path
|
107
|
+
def make_tmp_tiff(tmp_tiff_path)
|
113
108
|
tmp_tiff_image = if vips_image.interpretation.eql?(:cmyk)
|
114
109
|
vips_image.icc_transform(SRGB_ICC, input_profile: CMYK_ICC)
|
115
110
|
elsif image.has_profile?
|
@@ -118,10 +113,21 @@ module Assembly
|
|
118
113
|
vips_image
|
119
114
|
end
|
120
115
|
|
121
|
-
tmp_tiff_image.tiffsave(
|
122
|
-
|
116
|
+
tmp_tiff_image.tiffsave(tmp_tiff_path, bigtiff: true) # Use bigtiff so we can support images > 4GB
|
117
|
+
|
118
|
+
# For troublshooting JP2 creation problems. See https://github.com/sul-dlss/common-accessioning/issues/1079
|
119
|
+
raise "Temp tiff files #{tmp_tiff_path} does not exist" unless File.exist?(tmp_tiff_path)
|
120
|
+
end
|
121
|
+
|
122
|
+
def make_jp2(tmp_tiff_path)
|
123
|
+
jp2_command = jp2_create_command(source_path: tmp_tiff_path, output: output_path)
|
124
|
+
result = `#{jp2_command}`
|
125
|
+
return if $CHILD_STATUS.success?
|
126
|
+
|
127
|
+
# Clean up any partial result
|
128
|
+
FileUtils.rm_rf(output_path)
|
129
|
+
raise "JP2 creation command failed: #{jp2_command} with result #{result}"
|
123
130
|
end
|
124
|
-
# rubocop:enable Metrics/MethodLength
|
125
131
|
end
|
126
132
|
end
|
127
133
|
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
+
# rubocop:disable RSpec/ExampleLength
|
5
6
|
RSpec.describe Assembly::Image::Jp2Creator do
|
6
7
|
let(:jp2creator) { described_class.new(assembly_image, output: jp2_output_file) }
|
7
8
|
let(:assembly_image) { Assembly::Image.new(input_path) }
|
@@ -52,9 +53,13 @@ RSpec.describe Assembly::Image::Jp2Creator do
|
|
52
53
|
expect(result.path).to eq jp2_output_file
|
53
54
|
expect(result.mimetype).to eq 'image/jp2'
|
54
55
|
# check srgb on temporary tiff (due to CI libvips not speaking jp2)
|
55
|
-
|
56
|
-
|
57
|
-
|
56
|
+
Dir.mktmpdir('assembly-image-test') do |tmp_tiff_dir|
|
57
|
+
tmp_tiff_path = File.join(tmp_tiff_dir, 'temp.tif')
|
58
|
+
jp2creator.send(:make_tmp_tiff, tmp_tiff_path)
|
59
|
+
tmp_tiff_image = Assembly::Image.new(tmp_tiff_path)
|
60
|
+
expect(tmp_tiff_image.srgb?).to be true
|
61
|
+
expect(tmp_tiff_image.has_profile?).to be false
|
62
|
+
end
|
58
63
|
end
|
59
64
|
end
|
60
65
|
|
@@ -87,9 +92,13 @@ RSpec.describe Assembly::Image::Jp2Creator do
|
|
87
92
|
expect(result.path).to eq jp2_output_file
|
88
93
|
expect(result.mimetype).to eq 'image/jp2'
|
89
94
|
# check srgb on temporary tiff (due to CI libvips not speaking jp2)
|
90
|
-
|
91
|
-
|
92
|
-
|
95
|
+
Dir.mktmpdir('assembly-image-test') do |tmp_tiff_dir|
|
96
|
+
tmp_tiff_path = File.join(tmp_tiff_dir, 'temp.tif')
|
97
|
+
jp2creator.send(:make_tmp_tiff, tmp_tiff_path)
|
98
|
+
tmp_tiff_image = Assembly::Image.new(tmp_tiff_path)
|
99
|
+
expect(tmp_tiff_image.srgb?).to be true
|
100
|
+
expect(tmp_tiff_image.has_profile?).to be false
|
101
|
+
end
|
93
102
|
end
|
94
103
|
end
|
95
104
|
|
@@ -113,7 +122,7 @@ RSpec.describe Assembly::Image::Jp2Creator do
|
|
113
122
|
generate_test_image(input_path)
|
114
123
|
end
|
115
124
|
|
116
|
-
it 'gets the correct image, creates
|
125
|
+
it 'gets the correct image, creates the temporary tiff' do
|
117
126
|
expect(File).to exist input_path # test image was generated
|
118
127
|
expect(File).not_to exist jp2_output_file
|
119
128
|
|
@@ -121,12 +130,13 @@ RSpec.describe Assembly::Image::Jp2Creator do
|
|
121
130
|
expect(result.path).to eq jp2_output_file
|
122
131
|
expect(result.mimetype).to eq 'image/jp2'
|
123
132
|
# check height and width on temporary tiff (due to CI libvips not speaking jp2)
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
133
|
+
Dir.mktmpdir('assembly-image-test') do |tmp_tiff_dir|
|
134
|
+
tmp_tiff_path = File.join(tmp_tiff_dir, 'temp.tif')
|
135
|
+
jp2creator.send(:make_tmp_tiff, tmp_tiff_path)
|
136
|
+
tmp_tiff_image = Assembly::Image.new(tmp_tiff_path)
|
137
|
+
expect(tmp_tiff_image.height).to eq 36
|
138
|
+
expect(tmp_tiff_image.width).to eq 43
|
139
|
+
end
|
130
140
|
end
|
131
141
|
end
|
132
142
|
|
@@ -144,9 +154,13 @@ RSpec.describe Assembly::Image::Jp2Creator do
|
|
144
154
|
expect(result.path).to eq jp2_output_file
|
145
155
|
expect(result.mimetype).to eq 'image/jp2'
|
146
156
|
# check height and width on temporary tiff (due to CI libvips not speaking jp2)
|
147
|
-
|
148
|
-
|
149
|
-
|
157
|
+
Dir.mktmpdir('assembly-image-test') do |tmp_tiff_dir|
|
158
|
+
tmp_tiff_path = File.join(tmp_tiff_dir, 'temp.tif')
|
159
|
+
jp2creator.send(:make_tmp_tiff, tmp_tiff_path)
|
160
|
+
tmp_tiff_image = Assembly::Image.new(tmp_tiff_path)
|
161
|
+
expect(tmp_tiff_image.height).to eq 36
|
162
|
+
expect(tmp_tiff_image.width).to eq 43
|
163
|
+
end
|
150
164
|
end
|
151
165
|
end
|
152
166
|
|
@@ -169,9 +183,13 @@ RSpec.describe Assembly::Image::Jp2Creator do
|
|
169
183
|
|
170
184
|
# NOTE: we verify the CMYK has been converted to an SRGB JP2 correctly by using ruby-vips;
|
171
185
|
# we have to verify this on the *temporary tiff because lipvips pkg available for circleci does not speak JP2
|
172
|
-
|
173
|
-
|
174
|
-
|
186
|
+
Dir.mktmpdir('assembly-image-test') do |tmp_tiff_dir|
|
187
|
+
tmp_tiff_path = File.join(tmp_tiff_dir, 'temp.tif')
|
188
|
+
jp2creator.send(:make_tmp_tiff, tmp_tiff_path)
|
189
|
+
tmp_tiff_image = Assembly::Image.new(tmp_tiff_path)
|
190
|
+
expect(tmp_tiff_image.srgb?).to be true
|
191
|
+
expect(tmp_tiff_image.has_profile?).to be true
|
192
|
+
end
|
175
193
|
end
|
176
194
|
end
|
177
195
|
|
@@ -189,9 +207,13 @@ RSpec.describe Assembly::Image::Jp2Creator do
|
|
189
207
|
expect(result.path).to eq jp2_output_file
|
190
208
|
expect(result.mimetype).to eq 'image/jp2'
|
191
209
|
# check height and width on temporary tiff (due to CI libvips not speaking jp2)
|
192
|
-
|
193
|
-
|
194
|
-
|
210
|
+
Dir.mktmpdir('assembly-image-test') do |tmp_tiff_dir|
|
211
|
+
tmp_tiff_path = File.join(tmp_tiff_dir, 'temp.tif')
|
212
|
+
jp2creator.send(:make_tmp_tiff, tmp_tiff_path)
|
213
|
+
tmp_tiff_image = Assembly::Image.new(tmp_tiff_path)
|
214
|
+
expect(tmp_tiff_image.height).to eq 36
|
215
|
+
expect(tmp_tiff_image.width).to eq 43
|
216
|
+
end
|
195
217
|
end
|
196
218
|
end
|
197
219
|
|
@@ -212,9 +234,13 @@ RSpec.describe Assembly::Image::Jp2Creator do
|
|
212
234
|
expect(result.mimetype).to eq 'image/jp2'
|
213
235
|
|
214
236
|
# check srgb on temporary tiff (due to CI libvips not speaking jp2)
|
215
|
-
|
216
|
-
|
217
|
-
|
237
|
+
Dir.mktmpdir('assembly-image-test') do |tmp_tiff_dir|
|
238
|
+
tmp_tiff_path = File.join(tmp_tiff_dir, 'temp.tif')
|
239
|
+
jp2creator.send(:make_tmp_tiff, tmp_tiff_path)
|
240
|
+
tmp_tiff_image = Assembly::Image.new(tmp_tiff_path)
|
241
|
+
expect(tmp_tiff_image.srgb?).to be true
|
242
|
+
expect(tmp_tiff_image.has_profile?).to be false
|
243
|
+
end
|
218
244
|
end
|
219
245
|
end
|
220
246
|
|
@@ -237,12 +263,16 @@ RSpec.describe Assembly::Image::Jp2Creator do
|
|
237
263
|
expect(result.mimetype).to eq 'image/jp2'
|
238
264
|
|
239
265
|
# check srgb on temporary tiff (due to CI libvips not speaking jp2)
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
266
|
+
Dir.mktmpdir('assembly-image-test') do |tmp_tiff_dir|
|
267
|
+
tmp_tiff_path = File.join(tmp_tiff_dir, 'temp.tif')
|
268
|
+
jp2creator.send(:make_tmp_tiff, tmp_tiff_path)
|
269
|
+
tmp_tiff_image = Assembly::Image.new(tmp_tiff_path)
|
270
|
+
expect(tmp_tiff_image.srgb?).to be false
|
271
|
+
expect(tmp_tiff_image.has_profile?).to be false
|
272
|
+
vips_for_tmp_tiff = tmp_tiff_image.vips_image
|
273
|
+
expect(vips_for_tmp_tiff.bands).to eq 1
|
274
|
+
expect(vips_for_tmp_tiff.interpretation).to eq :'b-w'
|
275
|
+
end
|
246
276
|
end
|
247
277
|
end
|
248
278
|
|
@@ -267,10 +297,14 @@ RSpec.describe Assembly::Image::Jp2Creator do
|
|
267
297
|
expect(result.mimetype).to eq 'image/jp2'
|
268
298
|
|
269
299
|
# check srgb on temporary tiff (due to CI libvips not speaking jp2)
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
300
|
+
Dir.mktmpdir('assembly-image-test') do |tmp_tiff_dir|
|
301
|
+
tmp_tiff_path = File.join(tmp_tiff_dir, 'temp.tif')
|
302
|
+
jp2creator.send(:make_tmp_tiff, tmp_tiff_path)
|
303
|
+
tmp_tiff_image = Assembly::Image.new(tmp_tiff_path)
|
304
|
+
expect(tmp_tiff_image.srgb?).to be true
|
305
|
+
expect(tmp_tiff_image.has_profile?).to be false
|
306
|
+
expect(tmp_tiff_image.vips_image.bands).to eq 3
|
307
|
+
end
|
274
308
|
end
|
275
309
|
end
|
276
310
|
|
@@ -294,12 +328,16 @@ RSpec.describe Assembly::Image::Jp2Creator do
|
|
294
328
|
expect(result.mimetype).to eq 'image/jp2'
|
295
329
|
|
296
330
|
# check srgb on temporary tiff (due to CI libvips not speaking jp2)
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
331
|
+
Dir.mktmpdir('assembly-image-test') do |tmp_tiff_dir|
|
332
|
+
tmp_tiff_path = File.join(tmp_tiff_dir, 'temp.tif')
|
333
|
+
jp2creator.send(:make_tmp_tiff, tmp_tiff_path)
|
334
|
+
tmp_tiff_image = Assembly::Image.new(tmp_tiff_path)
|
335
|
+
expect(tmp_tiff_image.srgb?).to be false
|
336
|
+
expect(tmp_tiff_image.has_profile?).to be false
|
337
|
+
vips_for_tmp_tiff = tmp_tiff_image.vips_image
|
338
|
+
expect(vips_for_tmp_tiff.bands).to eq 1
|
339
|
+
expect(vips_for_tmp_tiff.interpretation).to eq :'b-w'
|
340
|
+
end
|
303
341
|
end
|
304
342
|
end
|
305
343
|
|
@@ -321,27 +359,33 @@ RSpec.describe Assembly::Image::Jp2Creator do
|
|
321
359
|
expect(result.mimetype).to eq 'image/jp2'
|
322
360
|
|
323
361
|
# check srgb on temporary tiff (due to CI libvips not speaking jp2)
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
362
|
+
Dir.mktmpdir('assembly-image-test') do |tmp_tiff_dir|
|
363
|
+
tmp_tiff_path = File.join(tmp_tiff_dir, 'temp.tif')
|
364
|
+
jp2creator.send(:make_tmp_tiff, tmp_tiff_path)
|
365
|
+
tmp_tiff_image = Assembly::Image.new(tmp_tiff_path)
|
366
|
+
expect(tmp_tiff_image.srgb?).to be true
|
367
|
+
expect(tmp_tiff_image.has_profile?).to be false
|
368
|
+
vips_for_tmp_tiff = tmp_tiff_image.vips_image
|
369
|
+
expect(vips_for_tmp_tiff.bands).to eq 3
|
370
|
+
end
|
329
371
|
end
|
330
372
|
end
|
331
373
|
end
|
332
374
|
|
333
375
|
describe '#make_tmp_tiff' do
|
334
|
-
subject(:tiff_file) { jp2creator.send(:make_tmp_tiff) }
|
335
|
-
|
336
376
|
let(:input_path) { 'spec/test_data/color_rgb_srgb_rot90cw.tif' }
|
337
|
-
let(:vips_output) { Vips::Image.new_from_file(tiff_file) }
|
338
377
|
let(:plum) { [94.0, 58.0, 101.0] }
|
339
378
|
|
340
379
|
context 'when given a tiff with a rotation hint' do
|
341
380
|
it 'rotates it' do
|
342
381
|
expect(Vips::Image.new_from_file(input_path).getpoint(3, 3)).not_to eq plum
|
343
|
-
|
382
|
+
Dir.mktmpdir('assembly-image-test') do |tmp_tiff_dir|
|
383
|
+
tmp_tiff_path = File.join(tmp_tiff_dir, 'temp.tif')
|
384
|
+
jp2creator.send(:make_tmp_tiff, tmp_tiff_path)
|
385
|
+
expect(Vips::Image.new_from_file(tmp_tiff_path).getpoint(3, 3)).to eq plum
|
386
|
+
end
|
344
387
|
end
|
345
388
|
end
|
346
389
|
end
|
347
390
|
end
|
391
|
+
# rubocop:enable RSpec/ExampleLength
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: assembly-image
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Mangiafico
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: exe
|
13
13
|
cert_chain: []
|
14
|
-
date: 2023-09-
|
14
|
+
date: 2023-09-25 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: activesupport
|