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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4d0b43a481f6a18e76f7cf8325240014d2a1e07a52cfb462be37444e020ff036
4
- data.tar.gz: 21edad5bbdd1a4e4b60953ee2769bd0648e8deb389f220f0dbd120f6a9dee09d
3
+ metadata.gz: d88e4be6d69bedc0f976c9b73544a20ac08ab66d6b44ce1061d1374f9d2a9dc8
4
+ data.tar.gz: 5b2986943b8bbeb339d0c31d0a98c5847a1a86141d5e754adaf0bd01e3d8d60f
5
5
  SHA512:
6
- metadata.gz: 78e9a671390fc80747273ccd6555e2faa915c4186261f473e86aa274f3e93e75c5e26f4674f3fea307d8a94ca21e352dfeb44a2046f20fb453d7e394f56c13b5
7
- data.tar.gz: 3dd7259403bb9aebc0d75834330f8db1b21d68bc619ec9204475e46e4c46b818ce28af2712d57a0c7ef3d7bb1a5922f3d91ba3a6b6779c7421e2fd2d9eaf4182
6
+ metadata.gz: 1b75df7c37cbcca0886eade3e47b082cde0468331c954d0605130cba564bb7718d777628599fea7332e2ae1ef9f15b80ce77072352a109dadbf9749fea049572
7
+ data.tar.gz: ffc57b47280776fc7be3cb2866699f32f90a2e036b2dca703ac4262aa77750032ffb54700437958ba7b4948c934d5ea6e41f2acad4e7e71ddec84a98f18edabf
@@ -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/EmptyCaseCondition:
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/HashEachMethods:
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 #=> :jpec
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-2023 Ivan Kuchin https://github.com/toy/image_size
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.3.0'
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",
@@ -62,11 +62,11 @@ class ImageSize
62
62
  end
63
63
 
64
64
  attributes = {
65
- :type => type,
66
- :offset => offset,
67
- :size => size,
68
- :relative_data_offset => relative_data_offset,
69
- :index => index,
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
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'image_size/uri_reader'
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'image_size'
3
4
  require 'image_size/reader'
4
5
  require 'image_size/chunky_reader'
5
6
 
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' if ir[offset, 1].nil?
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 if packspec[type].nil?
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
- :recurse => %w[jp2h],
343
- :last => %w[jp2h]
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
- :recurse => %w[meta iprp ipco],
374
- :full => %w[meta hdlr pitm ipma ispe],
375
- :last => %w[meta]
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.open('GPL', 'rb', &:read),
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(:type => 'abcd', :data_offset => 8, :data_size => 42),
57
- having_attributes(:type => 'efgh', :data_offset => 58, :data_size => 10)
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(:type => 'test', :data_offset => 8, :data_size => 0)) }
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(:type => 'test', :data_offset => 8, :data_size => 42))
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(:type => 'test', :data_offset => 8, :data_size => nil))
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(:type => 'test', :data_offset => 16, :data_size => 0))
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(:type => 'test', :data_offset => 16, :data_size => 42))
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){ { :full => %w[test] } }
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
- :type => 'test',
145
- :data_offset => 12,
146
- :data_size => 38,
147
- :version => 0x61,
148
- :flags => 0x626364
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){ { :full => %w[test] } }
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
- :type => 'test',
168
- :data_offset => 20,
169
- :data_size => 38,
170
- :version => 0x61,
171
- :flags => 0x626364
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(:type => 'fooo', :data_offset => 16, :data_size => 0),
210
- having_attributes(:type => 'barr', :data_offset => 24, :data_size => 0)
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(:type => 'fooo', :data_offset => 16, :data_size => 0))
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){ { :recurse => %w[fooA barA barB bazA] } }
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(:type => 'fooA', :data_offset => 8, :data_size => 10)
264
+ expect(enum.next).to have_attributes(type: 'fooA', data_offset: 8, data_size: 10)
265
265
 
266
- expect(enum.next).to have_attributes(:type => 'fooB', :data_offset => 16, :data_size => 2)
266
+ expect(enum.next).to have_attributes(type: 'fooB', data_offset: 16, data_size: 2)
267
267
 
268
- expect(enum.next).to have_attributes(:type => 'barA', :data_offset => 26, :data_size => 18)
268
+ expect(enum.next).to have_attributes(type: 'barA', data_offset: 26, data_size: 18)
269
269
 
270
- expect(enum.next).to have_attributes(:type => 'barB', :data_offset => 34, :data_size => 10)
270
+ expect(enum.next).to have_attributes(type: 'barB', data_offset: 34, data_size: 10)
271
271
 
272
- expect(enum.next).to have_attributes(:type => 'barC', :data_offset => 42, :data_size => 2)
272
+ expect(enum.next).to have_attributes(type: 'barC', data_offset: 42, data_size: 2)
273
273
 
274
- expect(enum.next).to have_attributes(:type => 'bazA', :data_offset => 52, :data_size => 10)
274
+ expect(enum.next).to have_attributes(type: 'bazA', data_offset: 52, data_size: 10)
275
275
 
276
- expect(enum.next).to have_attributes(:type => 'bazB', :data_offset => 60, :data_size => 2)
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){ { :recurse => %w[barA] } }
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(:type => 'fooA', :data_offset => 8, :data_size => 10)
292
+ expect(enum.next).to have_attributes(type: 'fooA', data_offset: 8, data_size: 10)
293
293
 
294
- expect(enum.next).to have_attributes(:type => 'barA', :data_offset => 26, :data_size => 18)
294
+ expect(enum.next).to have_attributes(type: 'barA', data_offset: 26, data_size: 18)
295
295
 
296
- expect(enum.next).to have_attributes(:type => 'barB', :data_offset => 34, :data_size => 10)
296
+ expect(enum.next).to have_attributes(type: 'barB', data_offset: 34, data_size: 10)
297
297
 
298
- expect(enum.next).to have_attributes(:type => 'bazA', :data_offset => 52, :data_size => 10)
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(:type => 'fooA', :data_offset => 8, :data_size => 10)
314
+ expect(enum.next).to have_attributes(type: 'fooA', data_offset: 8, data_size: 10)
315
315
 
316
- expect(enum.next).to have_attributes(:type => 'barA', :data_offset => 26, :data_size => 18)
316
+ expect(enum.next).to have_attributes(type: 'barA', data_offset: 26, data_size: 18)
317
317
 
318
- expect(enum.next).to have_attributes(:type => 'bazA', :data_offset => 52, :data_size => 10)
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){ { :recurse => %w[fooA barA barB bazA], :last => %w[barA] } }
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(:type => 'fooA', :data_offset => 8, :data_size => 10)
334
+ expect(enum.next).to have_attributes(type: 'fooA', data_offset: 8, data_size: 10)
335
335
 
336
- expect(enum.next).to have_attributes(:type => 'fooB', :data_offset => 16, :data_size => 2)
336
+ expect(enum.next).to have_attributes(type: 'fooB', data_offset: 16, data_size: 2)
337
337
 
338
- expect(enum.next).to have_attributes(:type => 'barA', :data_offset => 26, :data_size => 18)
338
+ expect(enum.next).to have_attributes(type: 'barA', data_offset: 26, data_size: 18)
339
339
 
340
- expect(enum.next).to have_attributes(:type => 'barB', :data_offset => 34, :data_size => 10)
340
+ expect(enum.next).to have_attributes(type: 'barB', data_offset: 34, data_size: 10)
341
341
 
342
- expect(enum.next).to have_attributes(:type => 'barC', :data_offset => 42, :data_size => 2)
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
@@ -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
- width, height, format = match[1].to_i, match[2].to_i, match[3].to_sym if match
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
- :format => format,
53
- :width => width,
54
- :height => height,
55
- :w => width,
56
- :h => height,
57
- :size => size,
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.open(path, 'rb', &:read) }
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 = ImageSize.url(file_url)
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 = ImageSize.url("#{file_url}?redirect=5")
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
- ImageSize.url("#{file_url}?redirect=6")
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 = ImageSize.url("#{file_url}?ignore_range")
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 = ImageSize.url("#{file_url}?ignore_range&redirect=5")
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
- ImageSize.url("#{file_url}?ignore_range&redirect=6")
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
- :png => "\211PNG\r\n\032\n",
207
- :jpeg => "\377\330",
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
- :Logger => WEBrick::Log.new(StringIO.new),
11
- :AccessLog => [],
12
- :BindAddress => host,
13
- :Port => 0, # get the next available port
14
- :DocumentRoot => '.',
15
- :RequestCallback => proc do |req, res|
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.3.0
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: 2023-05-30 00:00:00.000000000 Z
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.3.0
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: '0'
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.12
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