image_size 3.3.0 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/check.yml +2 -2
- data/.rubocop.yml +2 -32
- data/CHANGELOG.markdown +7 -0
- data/README.markdown +5 -4
- data/image_size.gemspec +3 -1
- data/lib/image_size/isobmff.rb +5 -5
- data/lib/image_size/media_types.rb +32 -0
- data/lib/image_size/uri.rb +3 -0
- data/lib/image_size/uri_reader.rb +1 -0
- data/lib/image_size.rb +25 -19
- data/spec/image_size/chunky_reader_spec.rb +1 -1
- data/spec/image_size/isobmff_spec.rb +44 -44
- data/spec/image_size_spec.rb +53 -17
- data/spec/test_server.rb +7 -6
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d88e4be6d69bedc0f976c9b73544a20ac08ab66d6b44ce1061d1374f9d2a9dc8
|
4
|
+
data.tar.gz: 5b2986943b8bbeb339d0c31d0a98c5847a1a86141d5e754adaf0bd01e3d8d60f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b75df7c37cbcca0886eade3e47b082cde0468331c954d0605130cba564bb7718d777628599fea7332e2ae1ef9f15b80ce77072352a109dadbf9749fea049572
|
7
|
+
data.tar.gz: ffc57b47280776fc7be3cb2866699f32f90a2e036b2dca703ac4262aa77750032ffb54700437958ba7b4948c934d5ea6e41f2acad4e7e71ddec84a98f18edabf
|
data/.github/workflows/check.yml
CHANGED
@@ -18,6 +18,7 @@ jobs:
|
|
18
18
|
- '3.0'
|
19
19
|
- '3.1'
|
20
20
|
- '3.2'
|
21
|
+
- '3.3'
|
21
22
|
- jruby-9.3
|
22
23
|
- jruby-9.4
|
23
24
|
fail-fast: false
|
@@ -34,7 +35,6 @@ jobs:
|
|
34
35
|
strategy:
|
35
36
|
matrix:
|
36
37
|
container:
|
37
|
-
- rspec/ci:1.8.7
|
38
38
|
- rspec/ci:1.9.3
|
39
39
|
- ruby:2.0
|
40
40
|
- ruby:2.1
|
@@ -54,8 +54,8 @@ jobs:
|
|
54
54
|
- '3.0'
|
55
55
|
- '3.1'
|
56
56
|
- '3.2'
|
57
|
+
- '3.3'
|
57
58
|
fail-fast: false
|
58
|
-
continue-on-error: ${{ matrix.ruby == '3.2' }}
|
59
59
|
steps:
|
60
60
|
- uses: actions/checkout@v3
|
61
61
|
- uses: ruby/setup-ruby@v1
|
data/.rubocop.yml
CHANGED
@@ -15,9 +15,6 @@ Layout/CaseIndentation:
|
|
15
15
|
Layout/EndAlignment:
|
16
16
|
EnforcedStyleAlignWith: variable
|
17
17
|
|
18
|
-
Layout/FirstHashElementIndentation:
|
19
|
-
EnforcedStyle: consistent
|
20
|
-
|
21
18
|
Layout/LineLength:
|
22
19
|
Max: 120
|
23
20
|
|
@@ -25,9 +22,6 @@ Layout/SpaceBeforeBlockBraces:
|
|
25
22
|
EnforcedStyle: no_space
|
26
23
|
EnforcedStyleForEmptyBraces: no_space
|
27
24
|
|
28
|
-
Lint/PercentStringArray: # broken in rubocop 0.55.0
|
29
|
-
Enabled: false
|
30
|
-
|
31
25
|
Metrics/BlockLength:
|
32
26
|
Exclude:
|
33
27
|
- 'spec/**/*.rb'
|
@@ -41,42 +35,18 @@ Metrics/MethodLength:
|
|
41
35
|
Naming/MethodParameterName:
|
42
36
|
Enabled: false
|
43
37
|
|
44
|
-
Style/AccessorGrouping:
|
45
|
-
Enabled: false
|
46
|
-
|
47
38
|
Style/Alias:
|
48
39
|
EnforcedStyle: prefer_alias_method
|
49
40
|
|
50
|
-
Style/
|
51
|
-
Enabled: false
|
52
|
-
|
53
|
-
Style/Encoding:
|
54
|
-
Enabled: false
|
55
|
-
|
56
|
-
Style/FileRead:
|
41
|
+
Style/ArgumentsForwarding:
|
57
42
|
Enabled: false
|
58
43
|
|
59
|
-
Style/
|
60
|
-
Enabled: true
|
61
|
-
|
62
|
-
Style/HashSyntax:
|
63
|
-
EnforcedStyle: hash_rockets
|
64
|
-
|
65
|
-
Style/HashTransformKeys:
|
66
|
-
Enabled: false
|
67
|
-
|
68
|
-
Style/HashTransformValues:
|
69
|
-
Enabled: false
|
70
|
-
|
71
|
-
Style/IfUnlessModifier:
|
44
|
+
Style/EmptyCaseCondition:
|
72
45
|
Enabled: false
|
73
46
|
|
74
47
|
Style/NumericPredicate:
|
75
48
|
Enabled: false
|
76
49
|
|
77
|
-
Style/ParallelAssignment:
|
78
|
-
Enabled: false
|
79
|
-
|
80
50
|
Style/SafeNavigation:
|
81
51
|
Enabled: false
|
82
52
|
|
data/CHANGELOG.markdown
CHANGED
@@ -2,6 +2,13 @@
|
|
2
2
|
|
3
3
|
## unreleased
|
4
4
|
|
5
|
+
## v3.4.0 (2024-01-16)
|
6
|
+
|
7
|
+
* Provide access to media types using media_type and media_types methods [#22](https://github.com/toy/image_size/issues/22) [@toy](https://github.com/toy)
|
8
|
+
* Allow fetching from HTTP server by requiring image_size/uri [@toy](https://github.com/toy)
|
9
|
+
* Fix for ArgumentError when requiring only image_size/uri_reader (without image_size) [@toy](https://github.com/toy)
|
10
|
+
* Require ruby 1.9.3 [@toy](https://github.com/toy)
|
11
|
+
|
5
12
|
## v3.3.0 (2023-05-30)
|
6
13
|
|
7
14
|
* Support `HEIF` (`HEIC` and `AVIF`) images [#19](https://github.com/toy/image_size/issues/19) [@toy](https://github.com/toy)
|
data/README.markdown
CHANGED
@@ -26,7 +26,7 @@ gem 'image_size', '~> 3.0'
|
|
26
26
|
```ruby
|
27
27
|
image_size = ImageSize.path('spec/images/jpeg/436x429.jpeg')
|
28
28
|
|
29
|
-
image_size.format #=> :
|
29
|
+
image_size.format #=> :jpeg
|
30
30
|
image_size.width #=> 436
|
31
31
|
image_size.height #=> 429
|
32
32
|
image_size.w #=> 436
|
@@ -38,6 +38,8 @@ image_size.size.width #=> 436
|
|
38
38
|
image_size.size.height #=> 429
|
39
39
|
image_size.size.w #=> 436
|
40
40
|
image_size.size.h #=> 429
|
41
|
+
image_size.media_type #=> "image/jpeg"
|
42
|
+
image_size.media_types #=> ["image/jpeg"]
|
41
43
|
```
|
42
44
|
|
43
45
|
Or using `IO` object:
|
@@ -96,8 +98,7 @@ If server recognises Range header, only needed chunks will be fetched even for T
|
|
96
98
|
of data will be fetched, in most cases first few kilobytes (TIFF images is an exception).
|
97
99
|
|
98
100
|
```ruby
|
99
|
-
require 'image_size'
|
100
|
-
require 'image_size/uri_reader'
|
101
|
+
require 'image_size/uri'
|
101
102
|
|
102
103
|
url = 'http://upload.wikimedia.org/wikipedia/commons/b/b4/Mardin_1350660_1350692_33_images.jpg'
|
103
104
|
p ImageSize.url(url).size
|
@@ -144,4 +145,4 @@ puts Benchmark.measure{ p ImageSize.url(url).size }
|
|
144
145
|
This code is free to use under the terms of the [Ruby's licence](LICENSE.txt).
|
145
146
|
|
146
147
|
Original author: Keisuke Minami <keisuke@rccn.com>.\
|
147
|
-
Further development 2010-
|
148
|
+
Further development 2010-2024 Ivan Kuchin https://github.com/toy/image_size
|
data/image_size.gemspec
CHANGED
@@ -2,13 +2,15 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = 'image_size'
|
5
|
-
s.version = '3.
|
5
|
+
s.version = '3.4.0'
|
6
6
|
s.summary = %q{Measure image size/dimensions using pure Ruby}
|
7
7
|
s.description = %q{Measure following file dimensions: apng, avif, bmp, cur, emf, gif, heic, heif, ico, j2c, jp2, jpeg, jpx, mng, pam, pbm, pcx, pgm, png, ppm, psd, svg, swf, tiff, webp, xbm, xpm}
|
8
8
|
s.homepage = "https://github.com/toy/#{s.name}"
|
9
9
|
s.authors = ['Keisuke Minami', 'Ivan Kuchin']
|
10
10
|
s.license = 'Ruby'
|
11
11
|
|
12
|
+
s.required_ruby_version = '>= 1.9.3'
|
13
|
+
|
12
14
|
s.metadata = {
|
13
15
|
'bug_tracker_uri' => "https://github.com/toy/#{s.name}/issues",
|
14
16
|
'changelog_uri' => "https://github.com/toy/#{s.name}/blob/master/CHANGELOG.markdown",
|
data/lib/image_size/isobmff.rb
CHANGED
@@ -62,11 +62,11 @@ class ImageSize
|
|
62
62
|
end
|
63
63
|
|
64
64
|
attributes = {
|
65
|
-
:
|
66
|
-
:
|
67
|
-
:
|
68
|
-
:
|
69
|
-
:
|
65
|
+
type: type,
|
66
|
+
offset: offset,
|
67
|
+
size: size,
|
68
|
+
relative_data_offset: relative_data_offset,
|
69
|
+
index: index,
|
70
70
|
}
|
71
71
|
|
72
72
|
if @full.include?(type)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class ImageSize
|
4
|
+
MEDIA_TYPES = {
|
5
|
+
apng: %w[image/apng image/vnd.mozilla.apng],
|
6
|
+
avif: %w[image/avif],
|
7
|
+
bmp: %w[image/bmp],
|
8
|
+
cur: %w[image/vnd.microsoft.icon],
|
9
|
+
emf: %w[image/emf],
|
10
|
+
gif: %w[image/gif],
|
11
|
+
heic: %w[image/heic image/heif],
|
12
|
+
ico: %w[image/x-icon image/vnd.microsoft.icon],
|
13
|
+
j2c: %w[image/j2c],
|
14
|
+
jp2: %w[image/jp2],
|
15
|
+
jpeg: %w[image/jpeg],
|
16
|
+
jpx: %w[image/jpx],
|
17
|
+
mng: %w[video/x-mng image/x-mng],
|
18
|
+
pam: %w[image/x-portable-arbitrarymap],
|
19
|
+
pbm: %w[image/x-portable-bitmap image/x-portable-anymap],
|
20
|
+
pcx: %w[image/x-pcx image/vnd.zbrush.pcx],
|
21
|
+
pgm: %w[image/x-portable-graymap image/x-portable-anymap],
|
22
|
+
png: %w[image/png],
|
23
|
+
ppm: %w[image/x-portable-pixmap image/x-portable-anymap],
|
24
|
+
psd: %w[image/vnd.adobe.photoshop],
|
25
|
+
svg: %w[image/svg+xml],
|
26
|
+
swf: %w[application/x-shockwave-flash application/vnd.adobe.flash.movie],
|
27
|
+
tiff: %w[image/tiff],
|
28
|
+
webp: %w[image/webp],
|
29
|
+
xbm: %w[image/x-xbitmap],
|
30
|
+
xpm: %w[image/x-xpixmap],
|
31
|
+
}.freeze
|
32
|
+
end
|
data/lib/image_size.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
require 'image_size/isobmff'
|
5
5
|
require 'image_size/format_error'
|
6
|
+
require 'image_size/media_types'
|
6
7
|
require 'image_size/reader'
|
7
8
|
require 'image_size/seekable_io_reader'
|
8
9
|
require 'image_size/stream_io_reader'
|
@@ -69,6 +70,19 @@ class ImageSize
|
|
69
70
|
Size.new([width, height]) if format
|
70
71
|
end
|
71
72
|
|
73
|
+
# Media type (formerly known as a MIME type)
|
74
|
+
def media_type
|
75
|
+
MEDIA_TYPES.fetch(format, []).first
|
76
|
+
end
|
77
|
+
|
78
|
+
# All media types:
|
79
|
+
# * commonly used and official like for apng and ico
|
80
|
+
# * main and compatible like for heic and pnm (pbm, pgm, ppm)
|
81
|
+
# * multiple unregistered like for mng
|
82
|
+
def media_types
|
83
|
+
MEDIA_TYPES.fetch(format, [])
|
84
|
+
end
|
85
|
+
|
72
86
|
private
|
73
87
|
|
74
88
|
SVG_R = /<svg\b([^>]*)>/.freeze
|
@@ -139,17 +153,13 @@ private
|
|
139
153
|
end
|
140
154
|
|
141
155
|
def size_of_mng(ir)
|
142
|
-
unless ir[12, 4] == 'MHDR'
|
143
|
-
raise FormatError, 'MHDR not in place for MNG'
|
144
|
-
end
|
156
|
+
raise FormatError, 'MHDR not in place for MNG' unless ir[12, 4] == 'MHDR'
|
145
157
|
|
146
158
|
ir.unpack(16, 8, 'NN')
|
147
159
|
end
|
148
160
|
|
149
161
|
def size_of_png(ir)
|
150
|
-
unless ir[12, 4] == 'IHDR'
|
151
|
-
raise FormatError, 'IHDR not in place for PNG'
|
152
|
-
end
|
162
|
+
raise FormatError, 'IHDR not in place for PNG' unless ir[12, 4] == 'IHDR'
|
153
163
|
|
154
164
|
ir.unpack(16, 8, 'NN')
|
155
165
|
end
|
@@ -167,14 +177,12 @@ private
|
|
167
177
|
loop do
|
168
178
|
offset += 1 until [nil, section_marker].include? ir[offset, 1]
|
169
179
|
offset += 1 until section_marker != ir[offset + 1, 1]
|
170
|
-
raise FormatError, 'EOF in JPEG'
|
180
|
+
raise FormatError, 'EOF in JPEG' unless ir[offset, 1]
|
171
181
|
|
172
182
|
code, length = ir.unpack(offset, 4, 'xCn')
|
173
183
|
offset += 4
|
174
184
|
|
175
|
-
if JPEG_CODE_CHECK.include?(code)
|
176
|
-
return ir.unpack(offset + 1, 4, 'nn').reverse
|
177
|
-
end
|
185
|
+
return ir.unpack(offset + 1, 4, 'nn').reverse if JPEG_CODE_CHECK.include?(code)
|
178
186
|
|
179
187
|
offset += length - 2
|
180
188
|
end
|
@@ -239,9 +247,7 @@ private
|
|
239
247
|
def size_of_xpm(ir)
|
240
248
|
length = 1024
|
241
249
|
until (data = ir[0, length]) =~ /"\s*(\d+)\s+(\d+)(\s+\d+\s+\d+){1,2}\s*"/m
|
242
|
-
if data.length != length
|
243
|
-
raise FormatError, 'XPM size not found'
|
244
|
-
end
|
250
|
+
raise FormatError, 'XPM size not found' if data.length != length
|
245
251
|
|
246
252
|
length += 1024
|
247
253
|
end
|
@@ -270,7 +276,7 @@ private
|
|
270
276
|
tag, type = ifd.unpack(endian2b * 2)
|
271
277
|
offset += 12
|
272
278
|
|
273
|
-
next
|
279
|
+
next unless packspec[type]
|
274
280
|
|
275
281
|
value = ifd[8, 4].unpack(packspec[type])[0]
|
276
282
|
case tag
|
@@ -339,8 +345,8 @@ private
|
|
339
345
|
end
|
340
346
|
|
341
347
|
JP2_WALKER = ImageSize::ISOBMFF.new(
|
342
|
-
:
|
343
|
-
:
|
348
|
+
recurse: %w[jp2h],
|
349
|
+
last: %w[jp2h]
|
344
350
|
)
|
345
351
|
def size_of_jp2(ir)
|
346
352
|
JP2_WALKER.recurse(ir) do |box|
|
@@ -370,9 +376,9 @@ private
|
|
370
376
|
end
|
371
377
|
|
372
378
|
HEIF_WALKER = ImageSize::ISOBMFF.new(
|
373
|
-
:
|
374
|
-
:
|
375
|
-
:
|
379
|
+
recurse: %w[meta iprp ipco],
|
380
|
+
full: %w[meta hdlr pitm ipma ispe],
|
381
|
+
last: %w[meta]
|
376
382
|
)
|
377
383
|
def size_of_heif(ir)
|
378
384
|
pitm = nil
|
@@ -29,7 +29,7 @@ describe ImageSize::ChunkyReader do
|
|
29
29
|
{
|
30
30
|
'empty string' => '',
|
31
31
|
'a bit of data' => 'foo bar baz',
|
32
|
-
'a lot of data' => File.
|
32
|
+
'a lot of data' => File.binread('GPL'),
|
33
33
|
}.each do |data_description, data|
|
34
34
|
{
|
35
35
|
'default' => test_reader.new(data),
|
@@ -53,8 +53,8 @@ describe ImageSize::ISOBMFF do
|
|
53
53
|
|
54
54
|
it do
|
55
55
|
is_expected.to yield_successive_args(
|
56
|
-
having_attributes(:
|
57
|
-
having_attributes(:
|
56
|
+
having_attributes(type: 'abcd', data_offset: 8, data_size: 42),
|
57
|
+
having_attributes(type: 'efgh', data_offset: 58, data_size: 10)
|
58
58
|
)
|
59
59
|
end
|
60
60
|
end
|
@@ -74,14 +74,14 @@ describe ImageSize::ISOBMFF do
|
|
74
74
|
describe 'for a box without content' do
|
75
75
|
let(:data){ boxes.build{ box('test', 8) } }
|
76
76
|
|
77
|
-
it{ is_expected.to yield_successive_args(having_attributes(:
|
77
|
+
it{ is_expected.to yield_successive_args(having_attributes(type: 'test', data_offset: 8, data_size: 0)) }
|
78
78
|
end
|
79
79
|
|
80
80
|
describe 'for a box with content' do
|
81
81
|
let(:data){ boxes.build{ box('test', 8 + 42) } }
|
82
82
|
|
83
83
|
it do
|
84
|
-
is_expected.to yield_successive_args(having_attributes(:
|
84
|
+
is_expected.to yield_successive_args(having_attributes(type: 'test', data_offset: 8, data_size: 42))
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
@@ -100,7 +100,7 @@ describe ImageSize::ISOBMFF do
|
|
100
100
|
let(:data){ boxes.build{ box('test', 0) } }
|
101
101
|
|
102
102
|
it do
|
103
|
-
is_expected.to yield_successive_args(having_attributes(:
|
103
|
+
is_expected.to yield_successive_args(having_attributes(type: 'test', data_offset: 8, data_size: nil))
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
@@ -116,7 +116,7 @@ describe ImageSize::ISOBMFF do
|
|
116
116
|
let(:data){ boxes.build{ box('test', 1, 16) } }
|
117
117
|
|
118
118
|
it do
|
119
|
-
is_expected.to yield_successive_args(having_attributes(:
|
119
|
+
is_expected.to yield_successive_args(having_attributes(type: 'test', data_offset: 16, data_size: 0))
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
@@ -124,12 +124,12 @@ describe ImageSize::ISOBMFF do
|
|
124
124
|
let(:data){ boxes.build{ box('test', 1, 16 + 42) } }
|
125
125
|
|
126
126
|
it do
|
127
|
-
is_expected.to yield_successive_args(having_attributes(:
|
127
|
+
is_expected.to yield_successive_args(having_attributes(type: 'test', data_offset: 16, data_size: 42))
|
128
128
|
end
|
129
129
|
end
|
130
130
|
|
131
131
|
describe 'for a full box' do
|
132
|
-
let(:options){ { :
|
132
|
+
let(:options){ { full: %w[test] } }
|
133
133
|
|
134
134
|
let(:data) do
|
135
135
|
boxes.build do
|
@@ -141,18 +141,18 @@ describe ImageSize::ISOBMFF do
|
|
141
141
|
it do
|
142
142
|
is_expected.to yield_successive_args(
|
143
143
|
having_attributes(
|
144
|
-
:
|
145
|
-
:
|
146
|
-
:
|
147
|
-
:
|
148
|
-
:
|
144
|
+
type: 'test',
|
145
|
+
data_offset: 12,
|
146
|
+
data_size: 38,
|
147
|
+
version: 0x61,
|
148
|
+
flags: 0x626364
|
149
149
|
)
|
150
150
|
)
|
151
151
|
end
|
152
152
|
end
|
153
153
|
|
154
154
|
describe 'for a big full box' do
|
155
|
-
let(:options){ { :
|
155
|
+
let(:options){ { full: %w[test] } }
|
156
156
|
|
157
157
|
let(:data) do
|
158
158
|
boxes.build do
|
@@ -164,11 +164,11 @@ describe ImageSize::ISOBMFF do
|
|
164
164
|
it do
|
165
165
|
is_expected.to yield_successive_args(
|
166
166
|
having_attributes(
|
167
|
-
:
|
168
|
-
:
|
169
|
-
:
|
170
|
-
:
|
171
|
-
:
|
167
|
+
type: 'test',
|
168
|
+
data_offset: 20,
|
169
|
+
data_size: 38,
|
170
|
+
version: 0x61,
|
171
|
+
flags: 0x626364
|
172
172
|
)
|
173
173
|
)
|
174
174
|
end
|
@@ -206,8 +206,8 @@ describe ImageSize::ISOBMFF do
|
|
206
206
|
|
207
207
|
it do
|
208
208
|
is_expected.to yield_successive_args(
|
209
|
-
having_attributes(:
|
210
|
-
having_attributes(:
|
209
|
+
having_attributes(type: 'fooo', data_offset: 16, data_size: 0),
|
210
|
+
having_attributes(type: 'barr', data_offset: 24, data_size: 0)
|
211
211
|
)
|
212
212
|
end
|
213
213
|
end
|
@@ -230,7 +230,7 @@ describe ImageSize::ISOBMFF do
|
|
230
230
|
let(:length){ 8 }
|
231
231
|
|
232
232
|
it do
|
233
|
-
is_expected.to yield_successive_args(having_attributes(:
|
233
|
+
is_expected.to yield_successive_args(having_attributes(type: 'fooo', data_offset: 16, data_size: 0))
|
234
234
|
end
|
235
235
|
end
|
236
236
|
end
|
@@ -256,24 +256,24 @@ describe ImageSize::ISOBMFF do
|
|
256
256
|
end
|
257
257
|
|
258
258
|
context 'when configured to recures all' do
|
259
|
-
let(:options){ { :
|
259
|
+
let(:options){ { recurse: %w[fooA barA barB bazA] } }
|
260
260
|
|
261
261
|
it 'recurses complete tree' do
|
262
262
|
enum = instance.to_enum(:recurse, string_reader)
|
263
263
|
|
264
|
-
expect(enum.next).to have_attributes(:
|
264
|
+
expect(enum.next).to have_attributes(type: 'fooA', data_offset: 8, data_size: 10)
|
265
265
|
|
266
|
-
expect(enum.next).to have_attributes(:
|
266
|
+
expect(enum.next).to have_attributes(type: 'fooB', data_offset: 16, data_size: 2)
|
267
267
|
|
268
|
-
expect(enum.next).to have_attributes(:
|
268
|
+
expect(enum.next).to have_attributes(type: 'barA', data_offset: 26, data_size: 18)
|
269
269
|
|
270
|
-
expect(enum.next).to have_attributes(:
|
270
|
+
expect(enum.next).to have_attributes(type: 'barB', data_offset: 34, data_size: 10)
|
271
271
|
|
272
|
-
expect(enum.next).to have_attributes(:
|
272
|
+
expect(enum.next).to have_attributes(type: 'barC', data_offset: 42, data_size: 2)
|
273
273
|
|
274
|
-
expect(enum.next).to have_attributes(:
|
274
|
+
expect(enum.next).to have_attributes(type: 'bazA', data_offset: 52, data_size: 10)
|
275
275
|
|
276
|
-
expect(enum.next).to have_attributes(:
|
276
|
+
expect(enum.next).to have_attributes(type: 'bazB', data_offset: 60, data_size: 2)
|
277
277
|
|
278
278
|
expect{ enum.next }.to raise_exception(StopIteration)
|
279
279
|
end
|
@@ -284,18 +284,18 @@ describe ImageSize::ISOBMFF do
|
|
284
284
|
end
|
285
285
|
|
286
286
|
context 'when configured to recurse part' do
|
287
|
-
let(:options){ { :
|
287
|
+
let(:options){ { recurse: %w[barA] } }
|
288
288
|
|
289
289
|
it 'recurses requested part' do
|
290
290
|
enum = instance.to_enum(:recurse, string_reader)
|
291
291
|
|
292
|
-
expect(enum.next).to have_attributes(:
|
292
|
+
expect(enum.next).to have_attributes(type: 'fooA', data_offset: 8, data_size: 10)
|
293
293
|
|
294
|
-
expect(enum.next).to have_attributes(:
|
294
|
+
expect(enum.next).to have_attributes(type: 'barA', data_offset: 26, data_size: 18)
|
295
295
|
|
296
|
-
expect(enum.next).to have_attributes(:
|
296
|
+
expect(enum.next).to have_attributes(type: 'barB', data_offset: 34, data_size: 10)
|
297
297
|
|
298
|
-
expect(enum.next).to have_attributes(:
|
298
|
+
expect(enum.next).to have_attributes(type: 'bazA', data_offset: 52, data_size: 10)
|
299
299
|
|
300
300
|
expect{ enum.next }.to raise_exception(StopIteration)
|
301
301
|
end
|
@@ -311,11 +311,11 @@ describe ImageSize::ISOBMFF do
|
|
311
311
|
it 'does not recurse' do
|
312
312
|
enum = instance.to_enum(:recurse, string_reader)
|
313
313
|
|
314
|
-
expect(enum.next).to have_attributes(:
|
314
|
+
expect(enum.next).to have_attributes(type: 'fooA', data_offset: 8, data_size: 10)
|
315
315
|
|
316
|
-
expect(enum.next).to have_attributes(:
|
316
|
+
expect(enum.next).to have_attributes(type: 'barA', data_offset: 26, data_size: 18)
|
317
317
|
|
318
|
-
expect(enum.next).to have_attributes(:
|
318
|
+
expect(enum.next).to have_attributes(type: 'bazA', data_offset: 52, data_size: 10)
|
319
319
|
|
320
320
|
expect{ enum.next }.to raise_exception(StopIteration)
|
321
321
|
end
|
@@ -326,20 +326,20 @@ describe ImageSize::ISOBMFF do
|
|
326
326
|
end
|
327
327
|
|
328
328
|
context 'when configured to stop' do
|
329
|
-
let(:options){ { :
|
329
|
+
let(:options){ { recurse: %w[fooA barA barB bazA], last: %w[barA] } }
|
330
330
|
|
331
331
|
it 'recurses complete tree' do
|
332
332
|
enum = instance.to_enum(:recurse, string_reader)
|
333
333
|
|
334
|
-
expect(enum.next).to have_attributes(:
|
334
|
+
expect(enum.next).to have_attributes(type: 'fooA', data_offset: 8, data_size: 10)
|
335
335
|
|
336
|
-
expect(enum.next).to have_attributes(:
|
336
|
+
expect(enum.next).to have_attributes(type: 'fooB', data_offset: 16, data_size: 2)
|
337
337
|
|
338
|
-
expect(enum.next).to have_attributes(:
|
338
|
+
expect(enum.next).to have_attributes(type: 'barA', data_offset: 26, data_size: 18)
|
339
339
|
|
340
|
-
expect(enum.next).to have_attributes(:
|
340
|
+
expect(enum.next).to have_attributes(type: 'barB', data_offset: 34, data_size: 10)
|
341
341
|
|
342
|
-
expect(enum.next).to have_attributes(:
|
342
|
+
expect(enum.next).to have_attributes(type: 'barC', data_offset: 42, data_size: 2)
|
343
343
|
|
344
344
|
expect{ enum.next }.to raise_exception(StopIteration)
|
345
345
|
end
|
data/spec/image_size_spec.rb
CHANGED
@@ -10,6 +10,10 @@ require 'shellwords'
|
|
10
10
|
|
11
11
|
require 'test_server'
|
12
12
|
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.order = :random
|
15
|
+
end
|
16
|
+
|
13
17
|
describe ImageSize do
|
14
18
|
before :all do
|
15
19
|
@server = TestServer.new
|
@@ -19,6 +23,19 @@ describe ImageSize do
|
|
19
23
|
@server.finish
|
20
24
|
end
|
21
25
|
|
26
|
+
def retry_on(exception_class)
|
27
|
+
attempt = 1
|
28
|
+
begin
|
29
|
+
yield
|
30
|
+
rescue exception_class => e
|
31
|
+
warn "Attempt #{attempt}: #{e.inspect}"
|
32
|
+
raise unless attempt < 3
|
33
|
+
|
34
|
+
attempt += 1
|
35
|
+
retry
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
22
39
|
def supported_formats
|
23
40
|
ImageSize.private_instance_methods.map{ |name| name[/\Asize_of_(.*)\z/, 1] }.compact.sort
|
24
41
|
end
|
@@ -45,19 +62,26 @@ describe ImageSize do
|
|
45
62
|
describe "for #{path}" do
|
46
63
|
let(:name){ File.basename(path) }
|
47
64
|
let(:attributes) do
|
48
|
-
match = /(\d+)x(\d+)\.([^.]+)$/.match(name)
|
49
|
-
|
65
|
+
if (match = /(\d+)x(\d+)\.([^.]+)$/.match(name))
|
66
|
+
width = match[1].to_i
|
67
|
+
height = match[2].to_i
|
68
|
+
format = match[3].to_sym
|
69
|
+
end
|
50
70
|
size = format && [width, height]
|
71
|
+
media_types = ImageSize::MEDIA_TYPES[format] || []
|
72
|
+
media_type = format && media_types.first.to_s
|
51
73
|
{
|
52
|
-
:
|
53
|
-
:
|
54
|
-
:
|
55
|
-
:
|
56
|
-
:
|
57
|
-
:
|
74
|
+
format: format,
|
75
|
+
width: width,
|
76
|
+
height: height,
|
77
|
+
w: width,
|
78
|
+
h: height,
|
79
|
+
size: size,
|
80
|
+
media_type: media_type,
|
81
|
+
media_types: media_types,
|
58
82
|
}
|
59
83
|
end
|
60
|
-
let(:file_data){ File.
|
84
|
+
let(:file_data){ File.binread(path) }
|
61
85
|
let(:file_size){ file_data.length }
|
62
86
|
|
63
87
|
before do
|
@@ -148,14 +172,18 @@ describe ImageSize do
|
|
148
172
|
context 'supporting range' do
|
149
173
|
context 'without redirects' do
|
150
174
|
it 'gets format and dimensions' do
|
151
|
-
image_size =
|
175
|
+
image_size = retry_on Timeout::Error do
|
176
|
+
ImageSize.url(file_url)
|
177
|
+
end
|
152
178
|
expect(image_size).to have_attributes(attributes)
|
153
179
|
end
|
154
180
|
end
|
155
181
|
|
156
182
|
context 'with redirects' do
|
157
183
|
it 'gets format and dimensions' do
|
158
|
-
image_size =
|
184
|
+
image_size = retry_on Timeout::Error do
|
185
|
+
ImageSize.url("#{file_url}?redirect=5")
|
186
|
+
end
|
159
187
|
expect(image_size).to have_attributes(attributes)
|
160
188
|
end
|
161
189
|
end
|
@@ -163,7 +191,9 @@ describe ImageSize do
|
|
163
191
|
context 'with too many redirects' do
|
164
192
|
it 'gets format and dimensions' do
|
165
193
|
expect do
|
166
|
-
|
194
|
+
retry_on Timeout::Error do
|
195
|
+
ImageSize.url("#{file_url}?redirect=6")
|
196
|
+
end
|
167
197
|
end.to raise_error(/Too many redirects/)
|
168
198
|
end
|
169
199
|
end
|
@@ -172,14 +202,18 @@ describe ImageSize do
|
|
172
202
|
context 'not supporting range' do
|
173
203
|
context 'without redirects' do
|
174
204
|
it 'gets format and dimensions' do
|
175
|
-
image_size =
|
205
|
+
image_size = retry_on Timeout::Error do
|
206
|
+
ImageSize.url("#{file_url}?ignore_range")
|
207
|
+
end
|
176
208
|
expect(image_size).to have_attributes(attributes)
|
177
209
|
end
|
178
210
|
end
|
179
211
|
|
180
212
|
context 'with redirects' do
|
181
213
|
it 'gets format and dimensions' do
|
182
|
-
image_size =
|
214
|
+
image_size = retry_on Timeout::Error do
|
215
|
+
ImageSize.url("#{file_url}?ignore_range&redirect=5")
|
216
|
+
end
|
183
217
|
expect(image_size).to have_attributes(attributes)
|
184
218
|
end
|
185
219
|
end
|
@@ -187,7 +221,9 @@ describe ImageSize do
|
|
187
221
|
context 'with too many redirects' do
|
188
222
|
it 'gets format and dimensions' do
|
189
223
|
expect do
|
190
|
-
|
224
|
+
retry_on Timeout::Error do
|
225
|
+
ImageSize.url("#{file_url}?ignore_range&redirect=6")
|
226
|
+
end
|
191
227
|
end.to raise_error(/Too many redirects/)
|
192
228
|
end
|
193
229
|
end
|
@@ -203,8 +239,8 @@ describe ImageSize do
|
|
203
239
|
end
|
204
240
|
|
205
241
|
{
|
206
|
-
:
|
207
|
-
:
|
242
|
+
png: "\211PNG\r\n\032\n",
|
243
|
+
jpeg: "\377\330",
|
208
244
|
}.each do |type, data|
|
209
245
|
it "raises FormatError if invalid #{type} given" do
|
210
246
|
expect do
|
data/spec/test_server.rb
CHANGED
@@ -1,18 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'webrick'
|
4
|
+
require 'stringio'
|
4
5
|
|
5
6
|
class TestServer
|
6
7
|
attr_reader :base_url
|
7
8
|
|
8
9
|
def initialize(host = '127.0.0.1')
|
9
10
|
server_options = {
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:
|
11
|
+
Logger: WEBrick::Log.new(StringIO.new),
|
12
|
+
AccessLog: [],
|
13
|
+
BindAddress: host,
|
14
|
+
Port: 0, # get the next available port
|
15
|
+
DocumentRoot: '.',
|
16
|
+
RequestCallback: proc do |req, res|
|
16
17
|
redirect = req.query['redirect'].to_i
|
17
18
|
if redirect > 0
|
18
19
|
res.set_redirect(
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: image_size
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Keisuke Minami
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2024-01-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -76,10 +76,12 @@ files:
|
|
76
76
|
- lib/image_size/chunky_reader.rb
|
77
77
|
- lib/image_size/format_error.rb
|
78
78
|
- lib/image_size/isobmff.rb
|
79
|
+
- lib/image_size/media_types.rb
|
79
80
|
- lib/image_size/reader.rb
|
80
81
|
- lib/image_size/seekable_io_reader.rb
|
81
82
|
- lib/image_size/stream_io_reader.rb
|
82
83
|
- lib/image_size/string_reader.rb
|
84
|
+
- lib/image_size/uri.rb
|
83
85
|
- lib/image_size/uri_reader.rb
|
84
86
|
- spec/image_size/chunky_reader_spec.rb
|
85
87
|
- spec/image_size/isobmff_spec.rb
|
@@ -138,7 +140,7 @@ licenses:
|
|
138
140
|
metadata:
|
139
141
|
bug_tracker_uri: https://github.com/toy/image_size/issues
|
140
142
|
changelog_uri: https://github.com/toy/image_size/blob/master/CHANGELOG.markdown
|
141
|
-
documentation_uri: https://www.rubydoc.info/gems/image_size/3.
|
143
|
+
documentation_uri: https://www.rubydoc.info/gems/image_size/3.4.0
|
142
144
|
source_code_uri: https://github.com/toy/image_size
|
143
145
|
post_install_message:
|
144
146
|
rdoc_options: []
|
@@ -148,14 +150,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
148
150
|
requirements:
|
149
151
|
- - ">="
|
150
152
|
- !ruby/object:Gem::Version
|
151
|
-
version:
|
153
|
+
version: 1.9.3
|
152
154
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
153
155
|
requirements:
|
154
156
|
- - ">="
|
155
157
|
- !ruby/object:Gem::Version
|
156
158
|
version: '0'
|
157
159
|
requirements: []
|
158
|
-
rubygems_version: 3.4.
|
160
|
+
rubygems_version: 3.4.20
|
159
161
|
signing_key:
|
160
162
|
specification_version: 4
|
161
163
|
summary: Measure image size/dimensions using pure Ruby
|