assembly-image 1.8.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 +4 -4
- data/.circleci/config.yml +4 -1
- data/.gitignore +2 -1
- data/.rubocop.yml +23 -5
- data/.rubocop_todo.yml +11 -51
- data/.rvmrc.example +1 -1
- data/Gemfile.lock +105 -0
- data/README.md +15 -58
- data/assembly-image.gemspec +4 -5
- data/bin/console +1 -1
- data/config/boot.rb +2 -2
- data/lib/assembly/image/jp2_creator.rb +127 -0
- data/lib/assembly/image.rb +58 -0
- data/lib/assembly-image.rb +5 -3
- data/profiles/cmyk.icc +0 -0
- data/spec/assembly/image/jp2_creator_spec.rb +327 -38
- data/spec/assembly/image_spec.rb +25 -0
- data/spec/spec_helper.rb +115 -29
- data/spec/test_data/color_rgb_srgb_rot90cw.tif +0 -0
- metadata +39 -38
- data/bin/run_all_tests +0 -3
- data/lib/assembly-image/image.rb +0 -162
- data/lib/assembly-image/images.rb +0 -107
- data/lib/assembly-image/jp2_creator.rb +0 -182
- data/lib/assembly-image/version.rb +0 -10
- data/spec/image_spec.rb +0 -279
- data/spec/images_spec.rb +0 -47
@@ -3,56 +3,345 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
RSpec.describe Assembly::Image::Jp2Creator do
|
6
|
-
|
6
|
+
let(:jp2creator) { described_class.new(assembly_image, output: jp2_output_file) }
|
7
|
+
let(:assembly_image) { Assembly::Image.new(input_path) }
|
8
|
+
let(:jp2_output_file) { File.join(TEST_OUTPUT_DIR, 'test.jp2') }
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
let(:creator) { described_class.new(ai, output: TEST_JP2_OUTPUT_FILE) }
|
10
|
+
describe '.create' do
|
11
|
+
subject(:result) { jp2creator.create }
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
let(:input_path) { TEST_TIF_INPUT_FILE }
|
14
|
+
|
15
|
+
before { cleanup }
|
16
|
+
|
17
|
+
context 'when input path is blank' do
|
18
|
+
let(:input_path) { '' }
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
|
20
|
+
it 'raises error' do
|
21
|
+
expect { assembly_image.create_jp2 }.to raise_error(RuntimeError, 'input file does not exist or is a directory')
|
22
|
+
end
|
21
23
|
end
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
expect(result.path).to eq TEST_JP2_OUTPUT_FILE
|
28
|
-
expect(TEST_JP2_OUTPUT_FILE).to be_a_jp2
|
25
|
+
context 'when tmp folder does not exist' do
|
26
|
+
before do
|
27
|
+
generate_test_image(input_path)
|
28
|
+
end
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
expect(jp2.width).to eq 100
|
30
|
+
it 'raises error' do
|
31
|
+
bogus_folder = '/nonexisting'
|
32
|
+
expect(File).not_to exist bogus_folder
|
33
|
+
expect { assembly_image.create_jp2(tmp_folder: bogus_folder) }.to raise_error(RuntimeError, 'tmp_folder /nonexisting does not exist')
|
34
|
+
end
|
36
35
|
end
|
37
|
-
end
|
38
36
|
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
context 'when no output file is specified' do
|
38
|
+
let(:jp2creator) { described_class.new(assembly_image) }
|
39
|
+
let(:jp2_output_file) { File.join(TEST_INPUT_DIR, File.basename(input_path).gsub('.tif', '.jp2')) }
|
40
|
+
|
41
|
+
before do
|
42
|
+
generate_test_image(input_path)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'creates a jp2 of the same filename and in the same location as the input' do
|
46
|
+
expect(File).to exist input_path # test image was generated
|
47
|
+
expect(File).not_to exist jp2_output_file
|
48
|
+
expect(assembly_image.srgb?).to be true
|
49
|
+
expect(assembly_image.has_profile?).to be false
|
50
|
+
|
51
|
+
expect(result).to be_a_kind_of Assembly::Image
|
52
|
+
expect(result.path).to eq jp2_output_file
|
53
|
+
expect(result.mimetype).to eq 'image/jp2'
|
54
|
+
# check srgb on temporary tiff (due to CI libvips not speaking jp2)
|
55
|
+
tmp_tiff_image = Assembly::Image.new(jp2creator.send(:make_tmp_tiff))
|
56
|
+
expect(tmp_tiff_image.srgb?).to be true
|
57
|
+
expect(tmp_tiff_image.has_profile?).to be false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'when the output file exists and no overwriting' do
|
62
|
+
before do
|
63
|
+
generate_test_image(input_path)
|
64
|
+
FileUtils.touch(jp2_output_file) # just need a file with this name, don't care what
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'raises error' do
|
68
|
+
expect(File).to exist input_path # test image was generated
|
69
|
+
expect { assembly_image.create_jp2(output: jp2_output_file) }.to raise_error(SecurityError, %r{spec/test_data/output/test.jp2 exists, cannot overwrite})
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'when the output file exists and overwriting allowed' do
|
74
|
+
before do
|
75
|
+
generate_test_image(input_path)
|
76
|
+
FileUtils.touch(jp2_output_file) # just need a file with this name, don't care what
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'recreates jp2' do
|
80
|
+
expect(File).to exist input_path # test image was generated
|
81
|
+
expect(File).to exist jp2_output_file
|
82
|
+
expect(assembly_image.srgb?).to be true
|
83
|
+
expect(assembly_image.has_profile?).to be false
|
84
|
+
|
85
|
+
result = assembly_image.create_jp2(output: jp2_output_file, overwrite: true)
|
86
|
+
expect(result).to be_a_kind_of Assembly::Image
|
87
|
+
expect(result.path).to eq jp2_output_file
|
88
|
+
expect(result.mimetype).to eq 'image/jp2'
|
89
|
+
# check srgb on temporary tiff (due to CI libvips not speaking jp2)
|
90
|
+
tmp_tiff_image = Assembly::Image.new(jp2creator.send(:make_tmp_tiff))
|
91
|
+
expect(tmp_tiff_image.srgb?).to be true
|
92
|
+
expect(tmp_tiff_image.has_profile?).to be false
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'when the input file is a jp2' do
|
97
|
+
let(:input_path) { File.join(TEST_INPUT_DIR, 'for_jp2.tif') }
|
98
|
+
|
99
|
+
before do
|
100
|
+
generate_test_image(input_path)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'raises error' do
|
104
|
+
expect(result.path).to eq jp2_output_file
|
105
|
+
expect(result.mimetype).to eq 'image/jp2'
|
106
|
+
|
107
|
+
expect { described_class.new(Assembly::Image.new(jp2_output_file)).create }.to raise_error(RuntimeError, 'input file is not a valid image, or is the wrong mimetype')
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'when given a tiff' do
|
112
|
+
before do
|
113
|
+
generate_test_image(input_path)
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'gets the correct image, creates and cleans up the temporary tiff' do
|
117
|
+
expect(File).to exist input_path # test image was generated
|
118
|
+
expect(File).not_to exist jp2_output_file
|
119
|
+
|
120
|
+
expect(result).to be_a_kind_of Assembly::Image
|
121
|
+
expect(result.path).to eq jp2_output_file
|
122
|
+
expect(result.mimetype).to eq 'image/jp2'
|
123
|
+
# check height and width on temporary tiff (due to CI libvips not speaking jp2)
|
124
|
+
tmp_tiff_image = Assembly::Image.new(jp2creator.send(:make_tmp_tiff))
|
125
|
+
expect(tmp_tiff_image.height).to eq 36
|
126
|
+
expect(tmp_tiff_image.width).to eq 43
|
127
|
+
|
128
|
+
expect(jp2creator.tmp_tiff_path).not_to be_nil # temporary tiff was created
|
129
|
+
expect(File).not_to exist jp2creator.tmp_tiff_path # the temporary tiff path is cleaned up
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context 'when given an LZW compressed RGB tif' do
|
134
|
+
let(:input_path) { File.join(TEST_INPUT_DIR, 'lzw.tif') }
|
135
|
+
|
136
|
+
before do
|
137
|
+
generate_test_image(input_path, compress: 'lzw')
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'creates the jp2' do
|
141
|
+
expect(File).to exist input_path
|
142
|
+
expect(File).not_to exist jp2_output_file
|
143
|
+
|
144
|
+
expect(result.path).to eq jp2_output_file
|
145
|
+
expect(result.mimetype).to eq 'image/jp2'
|
146
|
+
# check height and width on temporary tiff (due to CI libvips not speaking jp2)
|
147
|
+
tmp_tiff_image = Assembly::Image.new(jp2creator.send(:make_tmp_tiff))
|
148
|
+
expect(tmp_tiff_image.height).to eq 36
|
149
|
+
expect(tmp_tiff_image.width).to eq 43
|
150
|
+
end
|
42
151
|
end
|
43
152
|
|
44
|
-
|
153
|
+
context 'when given a cmyk tif' do
|
154
|
+
let(:input_path) { File.join(TEST_INPUT_DIR, 'test-cmyk.tif') }
|
155
|
+
|
156
|
+
before do
|
157
|
+
generate_test_image(input_path, color: 'cmyk', cg_type: 'cmyk', profile: 'cmyk', bands: 4)
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'creates an srgb jp2' do
|
161
|
+
expect(File).to exist input_path
|
162
|
+
expect(File).not_to exist jp2_output_file
|
163
|
+
expect(assembly_image.srgb?).to be false
|
164
|
+
expect(assembly_image.vips_image.interpretation).to eq :cmyk
|
165
|
+
expect(assembly_image.has_profile?).to be true
|
166
|
+
|
167
|
+
expect(result.path).to eq jp2_output_file
|
168
|
+
expect(result.mimetype).to eq 'image/jp2'
|
169
|
+
|
170
|
+
# NOTE: we verify the CMYK has been converted to an SRGB JP2 correctly by using ruby-vips;
|
171
|
+
# we have to verify this on the *temporary tiff because lipvips pkg available for circleci does not speak JP2
|
172
|
+
tmp_tiff_image = Assembly::Image.new(jp2creator.send(:make_tmp_tiff))
|
173
|
+
expect(tmp_tiff_image.srgb?).to be true
|
174
|
+
expect(tmp_tiff_image.has_profile?).to be true
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
context 'when the input file is a JPEG' do
|
179
|
+
let(:input_path) { File.join(TEST_INPUT_DIR, 'test.jpg') }
|
180
|
+
|
181
|
+
before do
|
182
|
+
generate_test_image(input_path)
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'creates jp2 when given a JPEG' do
|
186
|
+
expect(File).to exist input_path # test image was generated
|
187
|
+
expect(File).not_to exist jp2_output_file
|
188
|
+
|
189
|
+
expect(result.path).to eq jp2_output_file
|
190
|
+
expect(result.mimetype).to eq 'image/jp2'
|
191
|
+
# check height and width on temporary tiff (due to CI libvips not speaking jp2)
|
192
|
+
tmp_tiff_image = Assembly::Image.new(jp2creator.send(:make_tmp_tiff))
|
193
|
+
expect(tmp_tiff_image.height).to eq 36
|
194
|
+
expect(tmp_tiff_image.width).to eq 43
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
context 'when the source image has no profile' do
|
199
|
+
let(:input_path) { File.join(TEST_INPUT_DIR, 'no_profile.tif') }
|
200
|
+
|
201
|
+
before do
|
202
|
+
generate_test_image(input_path)
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'creates color jp2 without ICC profile' do
|
206
|
+
expect(File).to exist input_path # test image was generated
|
207
|
+
expect(File).not_to exist jp2_output_file
|
208
|
+
expect(assembly_image.srgb?).to be true
|
209
|
+
expect(assembly_image.has_profile?).to be false
|
210
|
+
|
211
|
+
expect(result.path).to eq jp2_output_file
|
212
|
+
expect(result.mimetype).to eq 'image/jp2'
|
213
|
+
|
214
|
+
# check srgb on temporary tiff (due to CI libvips not speaking jp2)
|
215
|
+
tmp_tiff_image = Assembly::Image.new(jp2creator.send(:make_tmp_tiff))
|
216
|
+
expect(tmp_tiff_image.srgb?).to be true
|
217
|
+
expect(tmp_tiff_image.has_profile?).to be false
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
context 'when given a bitonal tif with bitonal image data' do
|
222
|
+
let(:input_path) { File.join(TEST_INPUT_DIR, 'bitonal.tif') }
|
223
|
+
|
224
|
+
before do
|
225
|
+
# depth of 1 says 1 bit per pixel.
|
226
|
+
generate_test_image(input_path, color: 'bin', bands: 1, depth: 1)
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'creates bitonal jp2 without ICC profile' do
|
230
|
+
expect(File).to exist input_path # test image was generated
|
231
|
+
expect(File).not_to exist jp2_output_file
|
232
|
+
expect(assembly_image.srgb?).to be false
|
233
|
+
expect(assembly_image.vips_image.interpretation).to eq :'b-w'
|
234
|
+
expect(assembly_image.has_profile?).to be false
|
235
|
+
|
236
|
+
expect(result.path).to eq jp2_output_file
|
237
|
+
expect(result.mimetype).to eq 'image/jp2'
|
238
|
+
|
239
|
+
# check srgb on temporary tiff (due to CI libvips not speaking jp2)
|
240
|
+
tmp_tiff_image = Assembly::Image.new(jp2creator.send(:make_tmp_tiff))
|
241
|
+
expect(tmp_tiff_image.srgb?).to be false
|
242
|
+
expect(tmp_tiff_image.has_profile?).to be false
|
243
|
+
vips_for_tmp_tiff = tmp_tiff_image.vips_image
|
244
|
+
expect(vips_for_tmp_tiff.bands).to eq 1
|
245
|
+
expect(vips_for_tmp_tiff.interpretation).to eq :'b-w'
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
context 'when given a color tif but bitonal image data' do
|
250
|
+
# NOTE: this spec was created due to ImageMagick weirdness processing this wrinkle
|
251
|
+
let(:input_path) { File.join(TEST_INPUT_DIR, 'color.tif') }
|
252
|
+
|
253
|
+
before do
|
254
|
+
# from Tony Calavano:
|
255
|
+
# color: bin should threshold the pixel data to 0 or 255, bands: 3 forces it to be rgb.
|
256
|
+
# It should then create a 8 bits per pixel image
|
257
|
+
generate_test_image(input_path, color: 'bin', bands: 3)
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'creates color jp2 without ICC profile' do
|
261
|
+
expect(File).to exist input_path # test image was generated
|
262
|
+
expect(File).not_to exist jp2_output_file
|
263
|
+
expect(assembly_image.srgb?).to be true
|
264
|
+
expect(assembly_image.has_profile?).to be false
|
265
|
+
|
266
|
+
expect(result.path).to eq jp2_output_file
|
267
|
+
expect(result.mimetype).to eq 'image/jp2'
|
268
|
+
|
269
|
+
# check srgb on temporary tiff (due to CI libvips not speaking jp2)
|
270
|
+
tmp_tiff_image = Assembly::Image.new(jp2creator.send(:make_tmp_tiff))
|
271
|
+
expect(tmp_tiff_image.srgb?).to be true
|
272
|
+
expect(tmp_tiff_image.has_profile?).to be false
|
273
|
+
expect(tmp_tiff_image.vips_image.bands).to eq 3
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
context 'when given a grayscale tif but with bitonal image data' do
|
278
|
+
# NOTE: this spec was created due to ImageMagick weirdness processing this wrinkle
|
279
|
+
let(:input_path) { File.join(TEST_INPUT_DIR, 'gray.tif') }
|
280
|
+
|
281
|
+
before do
|
282
|
+
# from Tony Calavano: color: grey, bands: 1 would be a normal grayscale image with 8 bits per pixel
|
283
|
+
generate_test_image(input_path, color: 'bin', bands: 1)
|
284
|
+
end
|
285
|
+
|
286
|
+
it 'creates grayscale jp2 without ICC profile' do
|
287
|
+
expect(File).to exist input_path # test image was generated
|
288
|
+
expect(File).not_to exist jp2_output_file
|
289
|
+
expect(assembly_image.srgb?).to be false
|
290
|
+
expect(assembly_image.has_profile?).to be false
|
291
|
+
expect(assembly_image.vips_image.interpretation).to eq :'b-w'
|
292
|
+
|
293
|
+
expect(result.path).to eq jp2_output_file
|
294
|
+
expect(result.mimetype).to eq 'image/jp2'
|
295
|
+
|
296
|
+
# check srgb on temporary tiff (due to CI libvips not speaking jp2)
|
297
|
+
tmp_tiff_image = Assembly::Image.new(jp2creator.send(:make_tmp_tiff))
|
298
|
+
expect(tmp_tiff_image.srgb?).to be false
|
299
|
+
expect(tmp_tiff_image.has_profile?).to be false
|
300
|
+
vips_for_tmp_tiff = tmp_tiff_image.vips_image
|
301
|
+
expect(vips_for_tmp_tiff.bands).to eq 1
|
302
|
+
expect(vips_for_tmp_tiff.interpretation).to eq :'b-w'
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
context 'when given a color tif but with grayscale image data (3 channels and 8 bits per pixel)' do
|
307
|
+
let(:input_path) { File.join(TEST_INPUT_DIR, 'color_gray.tif') }
|
308
|
+
|
309
|
+
before do
|
310
|
+
# this is bands: 3 with 8 bits per pixel
|
311
|
+
generate_test_image(input_path, color: 'grey')
|
312
|
+
end
|
313
|
+
|
314
|
+
it 'creates color jp2 without ICC profile' do
|
315
|
+
expect(File).to exist input_path # test image was generated
|
316
|
+
expect(File).not_to exist jp2_output_file
|
317
|
+
expect(assembly_image.srgb?).to be true
|
318
|
+
expect(assembly_image.has_profile?).to be false
|
319
|
+
|
320
|
+
expect(result.path).to eq jp2_output_file
|
321
|
+
expect(result.mimetype).to eq 'image/jp2'
|
322
|
+
|
323
|
+
# check srgb on temporary tiff (due to CI libvips not speaking jp2)
|
324
|
+
tmp_tiff_image = Assembly::Image.new(jp2creator.send(:make_tmp_tiff))
|
325
|
+
expect(tmp_tiff_image.srgb?).to be true
|
326
|
+
expect(tmp_tiff_image.has_profile?).to be false
|
327
|
+
vips_for_tmp_tiff = tmp_tiff_image.vips_image
|
328
|
+
expect(vips_for_tmp_tiff.bands).to eq 3
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
describe '#make_tmp_tiff' do
|
334
|
+
subject(:tiff_file) { jp2creator.send(:make_tmp_tiff) }
|
45
335
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
expect(result).to be_a_kind_of Assembly::Image
|
50
|
-
expect(result.path).to eq TEST_JP2_OUTPUT_FILE
|
51
|
-
expect(TEST_JP2_OUTPUT_FILE).to be_a_jp2
|
336
|
+
let(:input_path) { 'spec/test_data/color_rgb_srgb_rot90cw.tif' }
|
337
|
+
let(:vips_output) { Vips::Image.new_from_file(tiff_file) }
|
338
|
+
let(:plum) { [94.0, 58.0, 101.0] }
|
52
339
|
|
53
|
-
|
54
|
-
|
55
|
-
|
340
|
+
context 'when given a tiff with a rotation hint' do
|
341
|
+
it 'rotates it' do
|
342
|
+
expect(Vips::Image.new_from_file(input_path).getpoint(3, 3)).not_to eq plum
|
343
|
+
expect(vips_output.getpoint(3, 3)).to eq plum
|
344
|
+
end
|
56
345
|
end
|
57
346
|
end
|
58
347
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
RSpec.describe Assembly::Image do
|
7
|
+
let(:assembly_image) { described_class.new(input_path) }
|
8
|
+
let(:input_path) { TEST_TIF_INPUT_FILE }
|
9
|
+
|
10
|
+
before { cleanup }
|
11
|
+
|
12
|
+
describe '#jp2_filename' do
|
13
|
+
it 'indicates the default jp2 filename' do
|
14
|
+
expect(assembly_image.jp2_filename).to eq input_path.gsub('.tif', '.jp2')
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'with a file with no extension' do
|
18
|
+
let(:input_path) { '/path/to/a/file_with_no_extension' }
|
19
|
+
|
20
|
+
it 'indicates the default jp2 filename' do
|
21
|
+
expect(assembly_image.jp2_filename).to eq '/path/to/a/file_with_no_extension.jp2'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -5,17 +5,14 @@ SimpleCov.start do
|
|
5
5
|
add_filter 'spec'
|
6
6
|
end
|
7
7
|
|
8
|
-
bootfile = File.expand_path(File.dirname(__FILE__)
|
8
|
+
bootfile = File.expand_path("#{File.dirname(__FILE__)}/../config/boot")
|
9
9
|
require bootfile
|
10
|
+
require 'pry-byebug'
|
10
11
|
|
11
12
|
TEST_INPUT_DIR = File.join(Assembly::PATH_TO_IMAGE_GEM, 'spec', 'test_data', 'input')
|
12
13
|
TEST_OUTPUT_DIR = File.join(Assembly::PATH_TO_IMAGE_GEM, 'spec', 'test_data', 'output')
|
13
14
|
TEST_TIF_INPUT_FILE = File.join(TEST_INPUT_DIR, 'test.tif')
|
14
|
-
TEST_DPG_TIF_INPUT_FILE = File.join(TEST_INPUT_DIR, 'oo000oo0001_00_01.tif')
|
15
15
|
TEST_JPEG_INPUT_FILE = File.join(TEST_INPUT_DIR, 'test.jpg')
|
16
|
-
TEST_JP2_INPUT_FILE = File.join(TEST_INPUT_DIR, 'test.jp2')
|
17
|
-
TEST_JP2_OUTPUT_FILE = File.join(TEST_OUTPUT_DIR, 'test.jp2')
|
18
|
-
TEST_DRUID = 'nx288wh8889'
|
19
16
|
|
20
17
|
RSpec.configure do |config|
|
21
18
|
# rspec-expectations config goes here. You can use an alternate
|
@@ -101,45 +98,134 @@ RSpec.configure do |config|
|
|
101
98
|
Kernel.srand config.seed
|
102
99
|
end
|
103
100
|
|
101
|
+
# rubocop:disable Metrics/MethodLength
|
102
|
+
# Color values for 30-patch ColorGauge color target.
|
103
|
+
def color_gauge_values(type = 'adobeRGB')
|
104
|
+
# rubocop:disable Layout/SpaceInsideArrayLiteralBrackets
|
105
|
+
# rubocop:disable Layout/ExtraSpacing
|
106
|
+
adobe_rgb = [
|
107
|
+
[109, 83, 71], [187, 146, 129], [101, 120, 151], [ 97, 108, 68], [130, 128, 172],
|
108
|
+
[130, 187, 171], [ 64, 134, 165], [241, 242, 237], [231, 232, 229], [216, 217, 215],
|
109
|
+
[203, 204, 203], [202, 125, 55], [172, 87, 147], [174, 176, 175], [148, 150, 149],
|
110
|
+
[116, 119, 118], [ 91, 91, 92], [ 78, 92, 165], [227, 198, 55], [ 68, 70, 69],
|
111
|
+
[ 48, 48, 48], [ 32, 32, 32], [ 23, 23, 23], [175, 85, 97], [157, 60, 61],
|
112
|
+
[100, 148, 80], [ 53, 67, 141], [213, 160, 56], [167, 187, 77], [ 86, 61, 100]
|
113
|
+
]
|
114
|
+
|
115
|
+
srgb = [
|
116
|
+
[118, 82, 69], [202, 147, 129], [ 92, 121, 154], [ 92, 109, 64], [132, 129, 175],
|
117
|
+
[ 96, 188, 172], [ 0, 135, 168], [241, 242, 237], [231, 232, 229], [217, 218, 216],
|
118
|
+
[204, 205, 204], [225, 126, 46], [196, 86, 150], [175, 178, 177], [148, 151, 150],
|
119
|
+
[116, 120, 119], [ 91, 91, 92], [ 70, 92, 169], [238, 199, 27], [ 65, 68, 67],
|
120
|
+
[ 44, 44, 44], [ 26, 26, 26], [ 16, 16, 16], [200, 84, 97], [181, 57, 58],
|
121
|
+
[ 68, 149, 74], [ 42, 65, 145], [231, 161, 41], [160, 188, 65], [ 94, 58, 101]
|
122
|
+
]
|
123
|
+
|
124
|
+
cmyk = [
|
125
|
+
[120, 154, 169, 84], [ 69, 110, 120, 5], [169, 125, 64, 8], [154, 105, 207, 64],
|
126
|
+
[138, 125, 31, 0], [128, 26, 95, 0], [195, 95, 61, 3], [ 10, 5, 13, 0],
|
127
|
+
[ 20, 13, 18, 0], [ 36, 26, 31, 0], [ 51, 38, 41, 0], [ 46, 143, 236, 8],
|
128
|
+
[ 90, 202, 31, 0], [ 84, 64, 69, 0], [115, 90, 95, 0], [143, 115, 120, 28],
|
129
|
+
[161, 141, 136, 69], [205, 182, 8, 0], [ 33, 46, 238, 0], [172, 151, 151, 110],
|
130
|
+
[179, 164, 161, 156], [184, 169, 166, 189], [187, 172, 166, 205], [ 69, 197, 131, 20],
|
131
|
+
[ 69, 220, 189, 51], [161, 59, 223, 15], [241, 223, 28, 5], [ 44, 95, 238, 3],
|
132
|
+
[100, 31, 228, 0], [184, 210, 90, 56]
|
133
|
+
]
|
134
|
+
# rubocop:enable Layout/SpaceInsideArrayLiteralBrackets
|
135
|
+
# rubocop:enable Layout/ExtraSpacing
|
136
|
+
case type
|
137
|
+
when 'adobe_rgb'
|
138
|
+
adobe_rgb
|
139
|
+
when 'srgb'
|
140
|
+
srgb
|
141
|
+
when 'cmyk'
|
142
|
+
cmyk
|
143
|
+
else
|
144
|
+
raise 'Unknown color_gauge_values type.'
|
145
|
+
end
|
146
|
+
end
|
147
|
+
# rubocop:enable Metrics/MethodLength
|
148
|
+
|
104
149
|
# generate a sample image file with a specified profile
|
105
150
|
# rubocop:disable Metrics/AbcSize
|
106
151
|
# rubocop:disable Metrics/CyclomaticComplexity
|
107
152
|
# rubocop:disable Metrics/MethodLength
|
108
153
|
# rubocop:disable Metrics/PerceivedComplexity
|
109
154
|
def generate_test_image(file, params = {})
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
155
|
+
# Set default size for sample test image.
|
156
|
+
line_size = 1
|
157
|
+
box_size = 6
|
158
|
+
width = (box_size * 6) + (line_size * 7)
|
159
|
+
height = (box_size * 5) + (line_size * 6)
|
160
|
+
|
161
|
+
# Set parameters for image creation options.
|
162
|
+
image_type = params[:image_type] || File.extname(file)
|
163
|
+
bands = params[:bands] || 3
|
164
|
+
color = params[:color] || 'rgb'
|
165
|
+
depth = params[:depth] || 8
|
166
|
+
cg_type = params[:cg_type] || 'adobe_rgb'
|
167
|
+
compression = params[:compression]
|
168
|
+
profile = params[:profile]
|
169
|
+
|
170
|
+
temp_array = color_gauge_values(cg_type)
|
171
|
+
temp_image = Vips::Image.black(width, height, bands: temp_array.first.size)
|
172
|
+
(0..4).each do |i|
|
173
|
+
b = (box_size * i) + (line_size * (i + 1))
|
174
|
+
# d = b + box_size - line_size
|
175
|
+
(0...6).each do |j|
|
176
|
+
a = (box_size * j) + (line_size * (j + 1))
|
177
|
+
# c = a + box_size - line_size
|
178
|
+
colors = temp_array.shift
|
179
|
+
temp_image = temp_image.draw_rect(colors, a, b, box_size, box_size, fill: true)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
temp_image = color.eql?('cmyk') ? temp_image.copy(interpretation: :cmyk) : temp_image.copy(interpretation: :srgb)
|
184
|
+
|
185
|
+
temp_image = if color.eql?('grey') && bands == 3
|
186
|
+
mean = temp_image.bandmean
|
187
|
+
Vips::Image.bandjoin([mean, mean, mean])
|
188
|
+
elsif color.eql?('grey') && bands == 1
|
189
|
+
temp_image.bandmean
|
190
|
+
elsif color.eql?('bin') && bands == 3
|
191
|
+
mean = temp_image.bandmean < 128
|
192
|
+
Vips::Image.bandjoin([mean, mean, mean])
|
193
|
+
elsif color.eql?('bin') && bands == 1
|
194
|
+
temp_image.bandmean < 128
|
195
|
+
else
|
196
|
+
temp_image
|
197
|
+
end
|
198
|
+
|
199
|
+
options = {}
|
200
|
+
unless profile.nil?
|
201
|
+
profile_file = File.join(Assembly::PATH_TO_IMAGE_GEM, 'profiles', "#{profile}.icc")
|
202
|
+
options.merge!(profile: profile_file)
|
203
|
+
end
|
204
|
+
|
205
|
+
case image_type
|
206
|
+
when '.tiff', '.tif'
|
207
|
+
options.merge!(compression: compression) unless compression.nil?
|
208
|
+
options.merge!(squash: true) if depth.eql?(1)
|
209
|
+
temp_image.tiffsave(file, **options)
|
210
|
+
when '.jpeg', '.jpg'
|
211
|
+
temp_image.jpegsave(file, **options)
|
212
|
+
else
|
213
|
+
raise "unknown type: #{image_type}"
|
214
|
+
end
|
123
215
|
end
|
124
216
|
# rubocop:enable Metrics/AbcSize
|
125
217
|
# rubocop:enable Metrics/CyclomaticComplexity
|
126
218
|
# rubocop:enable Metrics/MethodLength
|
127
219
|
# rubocop:enable Metrics/PerceivedComplexity
|
128
220
|
|
221
|
+
def cleanup
|
222
|
+
remove_files(TEST_INPUT_DIR)
|
223
|
+
remove_files(TEST_OUTPUT_DIR)
|
224
|
+
end
|
225
|
+
|
129
226
|
def remove_files(dir)
|
130
227
|
Dir.foreach(dir) do |f|
|
131
228
|
fn = File.join(dir, f)
|
132
229
|
File.delete(fn) if !File.directory?(fn) && File.basename(fn) != '.empty'
|
133
230
|
end
|
134
231
|
end
|
135
|
-
|
136
|
-
RSpec::Matchers.define :be_a_jp2 do
|
137
|
-
match do |actual|
|
138
|
-
if File.exist?(actual)
|
139
|
-
exif = MiniExiftool.new actual
|
140
|
-
exif['mimetype'] == 'image/jp2'
|
141
|
-
else
|
142
|
-
false
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
Binary file
|