image_size 3.0.2 → 3.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2e594fe6ec7b9018dd68867a5feaf557c6c22e7ed667876089fcbe35d6f3104c
4
- data.tar.gz: a221e99d54a933452712df549e2b8b05ceb85c407b27f482042d35c97dbb95c8
3
+ metadata.gz: f086d46fca698649fed0a23adca9dc67e1fa3317d9f3c209f1fe7f07fcd2cb6b
4
+ data.tar.gz: ff8f5243aadd37691eb7dabaa7e4b0d3b6fb212aba286a10d86165dc174eabff
5
5
  SHA512:
6
- metadata.gz: dbc4b3ec562040c3316edfc7412110eec1eef87028100f156e155a65bb38bccba7199b1094daa5ddc62317229a0fbe7241af0ba2089adf6ee03ab7eb4d85c634
7
- data.tar.gz: db58b0bee4cf294cf44ac5b4afe01c8cd0420b0155e220e378755081ca1a655adb1ac30695966f150b094c648befbd8fb96f31d9a835afbefe1bffbc7ce717b4
6
+ metadata.gz: 6ff23aa12846de6eaeb9a8ae02cde4a152f891e863056cf901732ef1c6cd1a580befab1cb62037feed500906901018cf8cdb64b63dd6538c07f0b84c5e8ce80e
7
+ data.tar.gz: fe6d488afbac72d4a8c16e3d1457c9ae3acf82b87ac9bd6df34e4077f0a0166c47862eac796f71e34084bb7c1314e49f79963eba41ad73de935232b2f2c35bd1
data/CHANGELOG.markdown CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  ## unreleased
4
4
 
5
+ ## v3.2.0 (2022-11-03)
6
+
7
+ * Support `EMF` images [#21](https://github.com/toy/image_size/pull/21) [@opoudjis](https://github.com/opoudjis)
8
+
9
+ ## v3.1.0 (2022-09-17)
10
+
11
+ * Document experimental fetching from http server [#18](https://github.com/toy/image_size/issues/18) [@toy](https://github.com/toy)
12
+ * Improve experimental fetching of image meta from http server by reading only required amount of data when server does not support range header [@toy](https://github.com/toy)
13
+
5
14
  ## v3.0.2 (2022-05-19)
6
15
 
7
16
  * Fix handling empty files [#20](https://github.com/toy/image_size/issues/20) [@toy](https://github.com/toy)
@@ -15,6 +24,7 @@
15
24
  * Read only required chunks of data for files and seekable IOs [@toy](https://github.com/toy)
16
25
  * Raise `FormatError` whenever reading data returns less data than expected [#12](https://github.com/toy/image_size/issues/12) [@toy](https://github.com/toy)
17
26
  * Add `w`/`width` and `h`/`height` accessors to `Size` [@toy](https://github.com/toy)
27
+ * Experimental efficient fetching of image meta from http server supporting range [@toy](https://github.com/toy)
18
28
 
19
29
  ## v2.1.2 (2021-08-21)
20
30
 
data/README.markdown CHANGED
@@ -1,10 +1,11 @@
1
1
  [![Gem Version](https://img.shields.io/gem/v/image_size?logo=rubygems)](https://rubygems.org/gems/image_size)
2
2
  [![Build Status](https://img.shields.io/github/workflow/status/toy/image_size/check/master?logo=github)](https://github.com/toy/image_size/actions/workflows/check.yml)
3
+ [![Rubocop](https://img.shields.io/github/workflow/status/toy/image_size/rubocop/master?label=rubocop&logo=rubocop)](https://github.com/toy/image_size/actions/workflows/rubocop.yml)
3
4
 
4
5
  # image_size
5
6
 
6
7
  Measure image size using pure Ruby.
7
- Formats: `apng`, `bmp`, `cur`, `gif`, `ico`, `j2c`, `jp2`, `jpeg`, `jpx`, `mng`, `pam`, `pbm`, `pcx`, `pgm`, `png`, `ppm`, `psd`, `svg`, `swf`, `tiff`, `webp`, `xbm`, `xpm`.
8
+ Formats: `apng`, `bmp`, `cur`, `emf`, `gif`, `ico`, `j2c`, `jp2`, `jpeg`, `jpx`, `mng`, `pam`, `pbm`, `pcx`, `pgm`, `png`, `ppm`, `psd`, `svg`, `swf`, `tiff`, `webp`, `xbm`, `xpm`.
8
9
 
9
10
  ## Installation
10
11
 
@@ -53,7 +54,7 @@ require 'image_size'
53
54
  image_size = ImageSize.new(ARGF)
54
55
  ```
55
56
 
56
- Works with `open-uri` if needed:
57
+ Works with `open-uri`, see [experimental HTTP server interface below](#experimental-fetch-image-meta-from-http-server):
57
58
 
58
59
  ```ruby
59
60
  require 'image_size'
@@ -89,6 +90,55 @@ File.open('spec/images/jpeg/436x429.jpeg', 'rb') do |fh|
89
90
  end
90
91
  ```
91
92
 
93
+ ### Experimental: fetch image meta from HTTP server
94
+
95
+ If server recognises Range header, only needed chunks will be fetched even for TIFF images, otherwise required amount
96
+ of data will be fetched, in most cases first few kilobytes (TIFF images is an exception).
97
+
98
+ ```ruby
99
+ require 'image_size'
100
+ require 'image_size/uri_reader'
101
+
102
+ url = 'http://upload.wikimedia.org/wikipedia/commons/b/b4/Mardin_1350660_1350692_33_images.jpg'
103
+ p ImageSize.url(url).size
104
+ ```
105
+
106
+ This interface is as fast as dedicated gem fastimage for images with meta information in the header:
107
+
108
+ ```ruby
109
+ url = 'http://upload.wikimedia.org/wikipedia/commons/b/b4/Mardin_1350660_1350692_33_images.jpg'
110
+ puts Benchmark.measure{ p FastImage.size(url) }
111
+ ```
112
+ ```
113
+ [9545, 6623]
114
+ 0.004176 0.001974 0.006150 ( 0.282889)
115
+ ```
116
+ ```ruby
117
+ puts Benchmark.measure{ p ImageSize.url(url).size }
118
+ ```
119
+ ```
120
+ [9545, 6623]
121
+ 0.005604 0.001406 0.007010 ( 0.238629)
122
+ ```
123
+
124
+ And considerably faster for images with meta information at the end of file:
125
+
126
+ ```ruby
127
+ url = "https://upload.wikimedia.org/wikipedia/commons/c/c7/Curiosity%27s_Vehicle_System_Test_Bed_%28VSTB%29_Rover_%28PIA15876%29.tif"
128
+ puts Benchmark.measure{ p FastImage.size(url) }
129
+ ```
130
+ ```
131
+ [7360, 4912]
132
+ 0.331284 0.247295 0.578579 ( 6.027051)
133
+ ```
134
+ ```ruby
135
+ puts Benchmark.measure{ p ImageSize.url(url).size }
136
+ ```
137
+ ```
138
+ [7360, 4912]
139
+ 0.006247 0.001045 0.007292 ( 0.197631)
140
+ ```
141
+
92
142
  ## Licence
93
143
 
94
144
  This code is free to use under the terms of the [Ruby's licence](LICENSE.txt).
data/image_size.gemspec CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'image_size'
5
- s.version = '3.0.2'
5
+ s.version = '3.2.0'
6
6
  s.summary = %q{Measure image size using pure Ruby}
7
- s.description = %q{Measure following file dimensions: apng, bmp, cur, gif, ico, j2c, jp2, jpeg, jpx, mng, pam, pbm, pcx, pgm, png, ppm, psd, svg, swf, tiff, webp, xbm, xpm}
7
+ s.description = %q{Measure following file dimensions: apng, bmp, cur, emf, gif, 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'
@@ -6,67 +6,103 @@ require 'image_size/chunky_reader'
6
6
  require 'net/https'
7
7
  require 'uri'
8
8
 
9
- # This is a hacky experiment and not part of public API
9
+ # Experimental, not yet part of stable API
10
10
  #
11
- # It adds ability to fetch size of image from http server while downloading only
12
- # needed chunks if the server recognises Range header
11
+ # It adds ability to fetch image meta from HTTP server while downloading only
12
+ # needed chunks if the server recognises Range header, otherwise fetches only
13
+ # required amount of data
13
14
  class ImageSize
14
- class URIReader # :nodoc:
15
- include ChunkyReader
16
-
17
- def initialize(uri, redirects = 5)
18
- if !@http || @http.address != uri.host || @http.port != uri.port
19
- @http.finish if @http
20
- @http = Net::HTTP.new(uri.host, uri.port)
21
- @http.use_ssl = true if uri.scheme == 'https'
22
- @http.start
23
- end
15
+ module URIReader # :nodoc:
16
+ module HTTPChunkyReader # :nodoc:
17
+ include ChunkyReader
24
18
 
25
- @request_uri = uri.request_uri
26
- response = request_chunk(0)
27
-
28
- case response
29
- when Net::HTTPRedirection
30
- raise "Too many redirects: #{response['location']}" unless redirects > 0
31
-
32
- initialize(uri + response['location'], redirects - 1)
33
- when Net::HTTPOK
34
- @body = response.body
35
- when Net::HTTPPartialContent
36
- @chunks = { 0 => response.body }
37
- when Net::HTTPRequestedRangeNotSatisfiable
38
- @body = ''
39
- else
40
- raise "Unexpected response: #{response}"
19
+ def chunk_range_header(i)
20
+ { 'Range' => "bytes=#{chunk_size * i}-#{(chunk_size * (i + 1)) - 1}" }
41
21
  end
42
22
  end
43
23
 
44
- def [](offset, length)
45
- if @body
24
+ class BodyReader # :nodoc:
25
+ include ChunkyReader
26
+
27
+ def initialize(response)
28
+ @body = String.new
29
+ @body_reader = response.to_enum(:read_body)
30
+ end
31
+
32
+ def [](offset, length)
33
+ if @body_reader
34
+ begin
35
+ @body << @body_reader.next while @body.length < offset + length
36
+ rescue StopIteration, IOError
37
+ @body_reader = nil
38
+ end
39
+ end
40
+
46
41
  @body[offset, length]
47
- else
48
- super
49
42
  end
50
43
  end
51
44
 
52
- def chunk(i)
53
- unless @chunks.key?(i)
54
- response = request_chunk(i)
55
- case response
56
- when Net::HTTPPartialContent
57
- @chunks[i] = response.body
58
- else
59
- raise "Unexpected response: #{response}"
60
- end
45
+ class RangeReader # :nodoc:
46
+ include HTTPChunkyReader
47
+
48
+ def initialize(http, request_uri, chunk0)
49
+ @http = http
50
+ @request_uri = request_uri
51
+ @chunks = { 0 => chunk0 }
61
52
  end
62
53
 
63
- @chunks[i]
54
+ def chunk(i)
55
+ unless @chunks.key?(i)
56
+ response = @http.get(@request_uri, chunk_range_header(i))
57
+ case response
58
+ when Net::HTTPPartialContent
59
+ @chunks[i] = response.body
60
+ else
61
+ raise "Unexpected response: #{response}"
62
+ end
63
+ end
64
+
65
+ @chunks[i]
66
+ end
64
67
  end
65
68
 
66
- private
69
+ class << self
70
+ include HTTPChunkyReader
71
+
72
+ def open(uri, max_redirects = 5)
73
+ http = nil
74
+ (max_redirects + 1).times do
75
+ unless http && http.address == uri.host && http.port == uri.port
76
+ http.finish if http
77
+
78
+ http = Net::HTTP.new(uri.host, uri.port)
79
+ http.use_ssl = true if uri.scheme == 'https'
80
+ http.start
81
+ end
67
82
 
68
- def request_chunk(i)
69
- @http.get(@request_uri, 'Range' => "bytes=#{chunk_size * i}-#{(chunk_size * (i + 1)) - 1}")
83
+ response = http.request_get(uri.request_uri, chunk_range_header(0)) do |response_with_unread_body|
84
+ case response_with_unread_body
85
+ when Net::HTTPOK
86
+ return yield BodyReader.new(response_with_unread_body)
87
+ end
88
+ end
89
+
90
+ case response
91
+ when Net::HTTPRedirection
92
+ uri += response['location']
93
+ when Net::HTTPPartialContent
94
+ return yield RangeReader.new(http, uri.request_uri, response.body)
95
+ when Net::HTTPRequestedRangeNotSatisfiable
96
+ return yield StringReader.new('')
97
+ else
98
+ raise "Unexpected response: #{response}"
99
+ end
100
+ end
101
+
102
+ raise "Too many redirects: #{uri}"
103
+ ensure
104
+ http.finish if http.started?
105
+ end
70
106
  end
71
107
  end
72
108
 
@@ -74,7 +110,7 @@ class ImageSize
74
110
  class << self
75
111
  def open_with_uri(input, &block)
76
112
  if input.is_a?(URI)
77
- yield URIReader.new(input)
113
+ URIReader.open(input, &block)
78
114
  else
79
115
  open_without_uri(input, &block)
80
116
  end
data/lib/image_size.rb CHANGED
@@ -95,6 +95,7 @@ private
95
95
  when head[0, 4] == "\0\0\2\0" then :cur
96
96
  when head[0, 12] == "\0\0\0\fjP \r\n\207\n" then detect_jpeg2000_type(ir)
97
97
  when head[0, 4] == "\377O\377Q" then :j2c
98
+ when head[0, 4] == "\1\0\0\0" && head[40, 4] == ' EMF' then :emf
98
99
  end
99
100
  end
100
101
 
@@ -374,4 +375,20 @@ private
374
375
  def size_of_j2c(ir)
375
376
  ir.unpack(8, 8, 'NN')
376
377
  end
378
+
379
+ EMF_UMAX = 256**4
380
+ EMF_SMAX = EMF_UMAX / 2
381
+
382
+ def size_of_emf(ir)
383
+ left, top, right, bottom =
384
+ if RUBY_VERSION < '1.9'
385
+ ir.unpack(24, 16, 'V*').map{ |u| u < EMF_SMAX ? u : u - EMF_UMAX }
386
+ else
387
+ ir.unpack(24, 16, 'L<*')
388
+ end
389
+ dpi = self.class.dpi
390
+ [right - left + 1, bottom - top + 1].map do |n|
391
+ (n.to_f * dpi / 2540).round
392
+ end
393
+ end
377
394
  end
@@ -56,9 +56,11 @@ describe ImageSize::ChunkyReader do
56
56
  offsets.each do |offset_b|
57
57
  length = offset_b - offset
58
58
  expect(reader[offset, length]).to eq(data[offset, length]),
59
- "for offset #{offset} and length #{length}\n"\
60
- "expected: #{data[offset, length].inspect}\n"\
61
- " got: #{reader[offset, length].inspect}"
59
+ [
60
+ "for offset #{offset} and length #{length}",
61
+ "expected: #{data[offset, length].inspect}",
62
+ " got: #{reader[offset, length].inspect}",
63
+ ].join("\n")
62
64
  end
63
65
  end
64
66
  end
@@ -7,24 +7,36 @@ require 'image_size/uri_reader'
7
7
 
8
8
  require 'tempfile'
9
9
  require 'shellwords'
10
- require 'webrick'
10
+
11
+ require 'test_server'
11
12
 
12
13
  describe ImageSize do
13
14
  before :all do
14
- @server = WEBrick::HTTPServer.new({
15
- :Logger => WEBrick::Log.new(StringIO.new),
16
- :AccessLog => [],
17
- :BindAddress => '127.0.0.1',
18
- :Port => 0, # get the next available port
19
- :DocumentRoot => '.',
20
- })
21
- @server_thread = Thread.new{ @server.start }
22
- @server_base_url = URI("http://127.0.0.1:#{@server.config[:Port]}/")
15
+ @server = TestServer.new
23
16
  end
24
17
 
25
18
  after :all do
26
- @server.shutdown
27
- @server_thread.join
19
+ @server.finish
20
+ end
21
+
22
+ def supported_formats
23
+ ImageSize.private_instance_methods.map{ |name| name[/\Asize_of_(.*)\z/, 1] }.compact.sort
24
+ end
25
+
26
+ describe 'README' do
27
+ let(:readme){ File.read('README.markdown') }
28
+
29
+ it 'lists all supported formats' do
30
+ expect(readme[/^Formats: .*$/]).to eq("Formats: #{supported_formats.map{ |format| "`#{format}`" }.join(', ')}.")
31
+ end
32
+ end
33
+
34
+ describe 'gemspec' do
35
+ let(:gemspec){ Gem::Specification.load('image_size.gemspec') }
36
+
37
+ it 'lists all supported formats in description' do
38
+ expect(gemspec.description).to eq("Measure following file dimensions: #{supported_formats.join(', ')}")
39
+ end
28
40
  end
29
41
 
30
42
  Dir['spec/**/*'].each do |path|
@@ -131,9 +143,54 @@ describe ImageSize do
131
143
  end
132
144
 
133
145
  context 'fetching from webserver' do
134
- it 'gets format and dimensions' do
135
- image_size = ImageSize.url(@server_base_url + path)
136
- expect(image_size).to have_attributes(attributes)
146
+ let(:file_url){ @server.base_url + path }
147
+
148
+ context 'supporting range' do
149
+ context 'without redirects' do
150
+ it 'gets format and dimensions' do
151
+ image_size = ImageSize.url(file_url)
152
+ expect(image_size).to have_attributes(attributes)
153
+ end
154
+ end
155
+
156
+ context 'with redirects' do
157
+ it 'gets format and dimensions' do
158
+ image_size = ImageSize.url("#{file_url}?redirect=5")
159
+ expect(image_size).to have_attributes(attributes)
160
+ end
161
+ end
162
+
163
+ context 'with too many redirects' do
164
+ it 'gets format and dimensions' do
165
+ expect do
166
+ ImageSize.url("#{file_url}?redirect=6")
167
+ end.to raise_error(/Too many redirects/)
168
+ end
169
+ end
170
+ end
171
+
172
+ context 'not supporting range' do
173
+ context 'without redirects' do
174
+ it 'gets format and dimensions' do
175
+ image_size = ImageSize.url("#{file_url}?ignore_range")
176
+ expect(image_size).to have_attributes(attributes)
177
+ end
178
+ end
179
+
180
+ context 'with redirects' do
181
+ it 'gets format and dimensions' do
182
+ image_size = ImageSize.url("#{file_url}?ignore_range&redirect=5")
183
+ expect(image_size).to have_attributes(attributes)
184
+ end
185
+ end
186
+
187
+ context 'with too many redirects' do
188
+ it 'gets format and dimensions' do
189
+ expect do
190
+ ImageSize.url("#{file_url}?ignore_range&redirect=6")
191
+ end.to raise_error(/Too many redirects/)
192
+ end
193
+ end
137
194
  end
138
195
  end
139
196
  end
Binary file
Binary file
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'webrick'
4
+
5
+ class TestServer
6
+ attr_reader :base_url
7
+
8
+ def initialize(host = '127.0.0.1')
9
+ 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|
16
+ redirect = req.query['redirect'].to_i
17
+ if redirect > 0
18
+ res.set_redirect(
19
+ WEBrick::HTTPStatus::TemporaryRedirect,
20
+ [
21
+ req.request_uri.port == @base_url.port ? @second_url : @base_url,
22
+ req.request_uri.request_uri,
23
+ "?#{encode_www_form(req.query.merge('redirect' => redirect - 1))}",
24
+ ].inject(:+)
25
+ )
26
+ end
27
+
28
+ req.header.delete('range') if req.query['ignore_range']
29
+ end,
30
+ }
31
+
32
+ @server = WEBrick::HTTPServer.new(server_options)
33
+ @server.listen(host, 0) # listen on second port
34
+
35
+ @base_url = URI("http://#{host}:#{@server.listeners[0].addr[1]}/")
36
+ @second_url = URI("http://#{host}:#{@server.listeners[1].addr[1]}/")
37
+
38
+ @thread = Thread.new{ @server.start }
39
+ end
40
+
41
+ def finish
42
+ @server.shutdown
43
+ @thread.join
44
+ end
45
+
46
+ private
47
+
48
+ if URI.respond_to?(:encode_www_form)
49
+ def encode_www_form(h)
50
+ URI.encode_www_form(h)
51
+ end
52
+ else
53
+ require 'cgi'
54
+
55
+ def encode_www_form(h)
56
+ h.map do |k, v|
57
+ "#{CGI.escape(k)}=#{CGI.escape(v.to_s)}"
58
+ end.join('&')
59
+ end
60
+ end
61
+ end
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.0.2
4
+ version: 3.2.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: 2022-05-19 00:00:00.000000000 Z
12
+ date: 2022-11-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -53,8 +53,9 @@ dependencies:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
55
  version: '2.0'
56
- description: 'Measure following file dimensions: apng, bmp, cur, gif, ico, j2c, jp2,
57
- jpeg, jpx, mng, pam, pbm, pcx, pgm, png, ppm, psd, svg, swf, tiff, webp, xbm, xpm'
56
+ description: 'Measure following file dimensions: apng, bmp, cur, emf, gif, ico, j2c,
57
+ jp2, jpeg, jpx, mng, pam, pbm, pcx, pgm, png, ppm, psd, svg, swf, tiff, webp, xbm,
58
+ xpm'
58
59
  email:
59
60
  executables: []
60
61
  extensions: []
@@ -86,6 +87,8 @@ files:
86
87
  - spec/images/bmp/v3-bottom2top.42x50.bmp
87
88
  - spec/images/bmp/v3-top2bottom.42x50.bmp
88
89
  - spec/images/cur/32x256.cur
90
+ - spec/images/emf/74x77.emf
91
+ - spec/images/emf/77x77.emf
89
92
  - spec/images/empty
90
93
  - spec/images/gif/668x481.gif
91
94
  - spec/images/ico/32x256.ico
@@ -120,13 +123,14 @@ files:
120
123
  - spec/images/xbm/crlf.16x32.xbm
121
124
  - spec/images/xpm/24x32.xpm
122
125
  - spec/images/xpm/crlf.24x32.xpm
126
+ - spec/test_server.rb
123
127
  homepage: https://github.com/toy/image_size
124
128
  licenses:
125
129
  - Ruby
126
130
  metadata:
127
131
  bug_tracker_uri: https://github.com/toy/image_size/issues
128
132
  changelog_uri: https://github.com/toy/image_size/blob/master/CHANGELOG.markdown
129
- documentation_uri: https://www.rubydoc.info/gems/image_size/3.0.2
133
+ documentation_uri: https://www.rubydoc.info/gems/image_size/3.2.0
130
134
  source_code_uri: https://github.com/toy/image_size
131
135
  post_install_message:
132
136
  rdoc_options: []
@@ -156,6 +160,8 @@ test_files:
156
160
  - spec/images/bmp/v3-bottom2top.42x50.bmp
157
161
  - spec/images/bmp/v3-top2bottom.42x50.bmp
158
162
  - spec/images/cur/32x256.cur
163
+ - spec/images/emf/74x77.emf
164
+ - spec/images/emf/77x77.emf
159
165
  - spec/images/empty
160
166
  - spec/images/gif/668x481.gif
161
167
  - spec/images/ico/32x256.ico
@@ -190,3 +196,4 @@ test_files:
190
196
  - spec/images/xbm/crlf.16x32.xbm
191
197
  - spec/images/xpm/24x32.xpm
192
198
  - spec/images/xpm/crlf.24x32.xpm
199
+ - spec/test_server.rb