assembly-image 2.1.1 → 2.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|