fastimage 2.0.1 → 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/README.textile +8 -4
- data/lib/fastimage.rb +58 -18
- metadata +14 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8bdd1b1858b1101956c8d27e85509ad1c68a436b
|
4
|
+
data.tar.gz: 54021e4718ed2bf2480dd7972b59a8b6b711061c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf0bfcba525fbacbb09919754faf51e3702bdfba09430601db181485e5626949a0f6ed8797a34e37e1f13d19100fe4bf020e6f3ef7c77aad40efe544f7f3007d
|
7
|
+
data.tar.gz: bc307c6eda1000ad5a60be2bcfd98b18fa7bb33faf4bbf4db20c5fa4db3cb3653b55f39dba1653e83d0a8a8d3ec33ffe3a20da434d539993ae3b3447e8f3dea4
|
data/README.textile
CHANGED
@@ -37,6 +37,8 @@ FastImage accepts additional HTTP headers. This can be used to set a user agent
|
|
37
37
|
|
38
38
|
FastImage can give you information about the parsed display orientation of an image with Exif data (jpeg or tiff).
|
39
39
|
|
40
|
+
FastImage also handles "Data URIs":https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs correctly.
|
41
|
+
|
40
42
|
h2. Security
|
41
43
|
|
42
44
|
As of v1.6.7 FastImage no longer uses @openuri@ to open files, but directly calls @File.open@. Take care to sanitise the strings passed to FastImage; it will try to read from whatever is passed.
|
@@ -62,6 +64,8 @@ FastImage.size("http://stephensykes.com/images/ss.com_x.gif", :http_header => {'
|
|
62
64
|
=> [266, 56]
|
63
65
|
FastImage.new("http://stephensykes.com/images/ExifOrientation3.jpg").orientation
|
64
66
|
=> 3
|
67
|
+
FastImage.size("data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==")
|
68
|
+
=> [1, 1]
|
65
69
|
</code></pre>
|
66
70
|
|
67
71
|
h2. Installation
|
@@ -97,7 +101,7 @@ irb> uri = "http://upload.wikimedia.org/wikipedia/commons/b/b4/Mardin_1350660_13
|
|
97
101
|
irb> puts Benchmark.measure {open(uri, 'rb') {|fh| p ImageSize.new(fh).size}}
|
98
102
|
[9545, 6623]
|
99
103
|
0.680000 0.250000 0.930000 ( 7.571887)
|
100
|
-
|
104
|
+
|
101
105
|
irb> puts Benchmark.measure {p FastImage.size(uri)}
|
102
106
|
[9545, 6623]
|
103
107
|
0.010000 0.000000 0.010000 ( 0.090640)
|
@@ -114,7 +118,7 @@ irb> uri = "http://upload.wikimedia.org/wikipedia/commons/1/11/Shinbutsureijoush
|
|
114
118
|
irb> puts Benchmark.measure {open(uri, 'rb') {|fh| p ImageSize.new(fh).size}}
|
115
119
|
[1120, 1559]
|
116
120
|
1.080000 0.370000 1.450000 ( 13.766962)
|
117
|
-
|
121
|
+
|
118
122
|
irb> puts Benchmark.measure {p FastImage.size(uri)}
|
119
123
|
[1120, 1559]
|
120
124
|
3.490000 3.810000 7.300000 ( 11.754315)
|
@@ -124,8 +128,8 @@ h2. Tests
|
|
124
128
|
|
125
129
|
You'll need to @gem install fakeweb@ and possibly also @gem install test-unit@ to be able to run the tests.
|
126
130
|
|
127
|
-
bc.. $ ruby test.rb
|
128
|
-
Run options:
|
131
|
+
bc.. $ ruby test.rb
|
132
|
+
Run options:
|
129
133
|
|
130
134
|
# Running tests:
|
131
135
|
|
data/lib/fastimage.rb
CHANGED
@@ -28,7 +28,7 @@
|
|
28
28
|
# or referrer which some servers require. Pass an :http_header argument to specify headers,
|
29
29
|
# e.g., :http_header => {'User-Agent' => 'Fake Browser'}.
|
30
30
|
#
|
31
|
-
# FastImage can give you information about the parsed display orientation of an image with Exif
|
31
|
+
# FastImage can give you information about the parsed display orientation of an image with Exif
|
32
32
|
# data (jpeg or tiff).
|
33
33
|
#
|
34
34
|
# === Examples
|
@@ -55,10 +55,18 @@
|
|
55
55
|
#
|
56
56
|
|
57
57
|
require 'net/https'
|
58
|
-
require 'addressable/uri'
|
59
58
|
require 'delegate'
|
60
59
|
require 'pathname'
|
61
60
|
require 'zlib'
|
61
|
+
require 'base64'
|
62
|
+
require 'uri'
|
63
|
+
|
64
|
+
# see http://stackoverflow.com/questions/5208851/i/41048816#41048816
|
65
|
+
if RUBY_VERSION < "2.2"
|
66
|
+
module URI
|
67
|
+
DEFAULT_PARSER = Parser.new(:HOSTNAME => "(?:(?:[a-zA-Z\\d](?:[-\\_a-zA-Z\\d]*[a-zA-Z\\d])?)\\.)*(?:[a-zA-Z](?:[-\\_a-zA-Z\\d]*[a-zA-Z\\d])?)\\.?")
|
68
|
+
end
|
69
|
+
end
|
62
70
|
|
63
71
|
class FastImage
|
64
72
|
attr_reader :size, :type, :content_length, :orientation
|
@@ -184,10 +192,12 @@ class FastImage
|
|
184
192
|
|
185
193
|
if uri.respond_to?(:read)
|
186
194
|
fetch_using_read(uri)
|
195
|
+
elsif uri.start_with?('data:')
|
196
|
+
fetch_using_base64(uri)
|
187
197
|
else
|
188
198
|
begin
|
189
|
-
@parsed_uri =
|
190
|
-
rescue
|
199
|
+
@parsed_uri = URI.parse(uri)
|
200
|
+
rescue URI::InvalidURIError
|
191
201
|
fetch_using_file_open
|
192
202
|
else
|
193
203
|
if @parsed_uri.scheme == "http" || @parsed_uri.scheme == "https"
|
@@ -237,14 +247,16 @@ class FastImage
|
|
237
247
|
if res.is_a?(Net::HTTPRedirection) && @redirect_count < 4
|
238
248
|
@redirect_count += 1
|
239
249
|
begin
|
240
|
-
newly_parsed_uri =
|
250
|
+
newly_parsed_uri = URI.parse(res['Location'])
|
241
251
|
# The new location may be relative - check for that
|
242
|
-
if
|
252
|
+
if protocol_relative_url?(res['Location'])
|
253
|
+
@parsed_uri = URI.parse("#{@parsed_uri.scheme}:#{res['Location']}")
|
254
|
+
elsif newly_parsed_uri.scheme != "http" && newly_parsed_uri.scheme != "https"
|
243
255
|
@parsed_uri.path = res['Location']
|
244
256
|
else
|
245
257
|
@parsed_uri = newly_parsed_uri
|
246
258
|
end
|
247
|
-
rescue
|
259
|
+
rescue URI::InvalidURIError
|
248
260
|
else
|
249
261
|
fetch_using_http_from_parsed_uri
|
250
262
|
break
|
@@ -282,14 +294,18 @@ class FastImage
|
|
282
294
|
end
|
283
295
|
end
|
284
296
|
|
297
|
+
def protocol_relative_url?(url)
|
298
|
+
url.start_with?("//")
|
299
|
+
end
|
300
|
+
|
285
301
|
def proxy_uri
|
286
302
|
begin
|
287
303
|
if @options[:proxy]
|
288
|
-
proxy =
|
304
|
+
proxy = URI.parse(@options[:proxy])
|
289
305
|
else
|
290
|
-
proxy = ENV['http_proxy'] && ENV['http_proxy'] != "" ?
|
306
|
+
proxy = ENV['http_proxy'] && ENV['http_proxy'] != "" ? URI.parse(ENV['http_proxy']) : nil
|
291
307
|
end
|
292
|
-
rescue
|
308
|
+
rescue URI::InvalidURIError
|
293
309
|
proxy = nil
|
294
310
|
end
|
295
311
|
proxy
|
@@ -299,9 +315,9 @@ class FastImage
|
|
299
315
|
proxy = proxy_uri
|
300
316
|
|
301
317
|
if proxy
|
302
|
-
@http = Net::HTTP::Proxy(proxy.host, proxy.port).new(@parsed_uri.host, @parsed_uri.
|
318
|
+
@http = Net::HTTP::Proxy(proxy.host, proxy.port).new(@parsed_uri.host, @parsed_uri.port)
|
303
319
|
else
|
304
|
-
@http = Net::HTTP.new(@parsed_uri.host, @parsed_uri.
|
320
|
+
@http = Net::HTTP.new(@parsed_uri.host, @parsed_uri.port)
|
305
321
|
end
|
306
322
|
@http.use_ssl = (@parsed_uri.scheme == "https")
|
307
323
|
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
@@ -334,6 +350,7 @@ class FastImage
|
|
334
350
|
end
|
335
351
|
|
336
352
|
def fetch_using_file_open
|
353
|
+
@content_length = File.size?(@uri)
|
337
354
|
File.open(@uri) do |s|
|
338
355
|
fetch_using_read(s)
|
339
356
|
end
|
@@ -351,7 +368,7 @@ class FastImage
|
|
351
368
|
else
|
352
369
|
@orientation = 1
|
353
370
|
end
|
354
|
-
|
371
|
+
|
355
372
|
instance_variable_set("@#{@property}", result)
|
356
373
|
else
|
357
374
|
raise CannotParseImage
|
@@ -366,6 +383,11 @@ class FastImage
|
|
366
383
|
send("parse_size_for_#{@type}")
|
367
384
|
end
|
368
385
|
|
386
|
+
def fetch_using_base64(uri)
|
387
|
+
data = uri.split(',')[1]
|
388
|
+
fetch_using_read StringIO.new(Base64.decode64(data))
|
389
|
+
end
|
390
|
+
|
369
391
|
module StreamUtil # :nodoc:
|
370
392
|
def read_byte
|
371
393
|
read(1)[0].ord
|
@@ -395,6 +417,7 @@ class FastImage
|
|
395
417
|
@str = ''
|
396
418
|
end
|
397
419
|
|
420
|
+
# Peeking beyond the end of the input will raise
|
398
421
|
def peek(n)
|
399
422
|
while @strpos + n - 1 >= @str.size
|
400
423
|
unused_str = @str[@strpos..-1]
|
@@ -466,9 +489,16 @@ class FastImage
|
|
466
489
|
when "<s"
|
467
490
|
:svg
|
468
491
|
when "<?"
|
469
|
-
|
492
|
+
# Peek 10 more chars each time, and if end of file is reached just raise
|
493
|
+
# unknown. We assume the <svg tag cannot be within 10 chars of the end of
|
494
|
+
# the file, and is within the first 250 chars.
|
495
|
+
begin
|
496
|
+
:svg if (1..25).detect {|n| @stream.peek(10 * n).include?("<svg")}
|
497
|
+
rescue FiberError
|
498
|
+
nil
|
499
|
+
end
|
470
500
|
end
|
471
|
-
|
501
|
+
|
472
502
|
parsed_type or raise UnknownImageType
|
473
503
|
end
|
474
504
|
|
@@ -644,7 +674,7 @@ class FastImage
|
|
644
674
|
end
|
645
675
|
|
646
676
|
parse_exif_ifd
|
647
|
-
|
677
|
+
|
648
678
|
@orientation ||= 1
|
649
679
|
end
|
650
680
|
|
@@ -676,6 +706,10 @@ class FastImage
|
|
676
706
|
[@width, @width / @ratio]
|
677
707
|
elsif @height && @ratio
|
678
708
|
[@height * @ratio, @height]
|
709
|
+
elsif @viewbox_width && @viewbox_height
|
710
|
+
[@viewbox_width, @viewbox_height]
|
711
|
+
else
|
712
|
+
nil
|
679
713
|
end
|
680
714
|
end
|
681
715
|
|
@@ -698,14 +732,20 @@ class FastImage
|
|
698
732
|
return if @width
|
699
733
|
elsif attr_name.join =~ /viewbox/i
|
700
734
|
values = attr_value.split(/\s/)
|
701
|
-
|
735
|
+
if values[2].to_f > 0 && values[3].to_f > 0
|
736
|
+
@ratio = values[2].to_f / values[3].to_f
|
737
|
+
@viewbox_width = values[2].to_i
|
738
|
+
@viewbox_height = values[3].to_i
|
739
|
+
end
|
702
740
|
end
|
703
741
|
when /\w/
|
704
742
|
attr_name << char
|
743
|
+
when "<"
|
744
|
+
attr_name = [char]
|
705
745
|
when ">"
|
706
746
|
state = :stop if state == :started
|
707
747
|
else
|
708
|
-
state = :started if attr_name.join == "svg"
|
748
|
+
state = :started if attr_name.join == "<svg"
|
709
749
|
attr_name.clear
|
710
750
|
end
|
711
751
|
end
|
metadata
CHANGED
@@ -1,83 +1,69 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastimage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen Sykes
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-02-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: addressable
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '2'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '2'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: fakeweb
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
30
16
|
requirements:
|
31
|
-
- -
|
17
|
+
- - ~>
|
32
18
|
- !ruby/object:Gem::Version
|
33
19
|
version: '1.3'
|
34
20
|
type: :development
|
35
21
|
prerelease: false
|
36
22
|
version_requirements: !ruby/object:Gem::Requirement
|
37
23
|
requirements:
|
38
|
-
- -
|
24
|
+
- - ~>
|
39
25
|
- !ruby/object:Gem::Version
|
40
26
|
version: '1.3'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: rake
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
44
30
|
requirements:
|
45
|
-
- -
|
31
|
+
- - ~>
|
46
32
|
- !ruby/object:Gem::Version
|
47
33
|
version: '10.5'
|
48
34
|
type: :development
|
49
35
|
prerelease: false
|
50
36
|
version_requirements: !ruby/object:Gem::Requirement
|
51
37
|
requirements:
|
52
|
-
- -
|
38
|
+
- - ~>
|
53
39
|
- !ruby/object:Gem::Version
|
54
40
|
version: '10.5'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: rdoc
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
58
44
|
requirements:
|
59
|
-
- -
|
45
|
+
- - '>='
|
60
46
|
- !ruby/object:Gem::Version
|
61
47
|
version: '0'
|
62
48
|
type: :development
|
63
49
|
prerelease: false
|
64
50
|
version_requirements: !ruby/object:Gem::Requirement
|
65
51
|
requirements:
|
66
|
-
- -
|
52
|
+
- - '>='
|
67
53
|
- !ruby/object:Gem::Version
|
68
54
|
version: '0'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
56
|
name: test-unit
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
72
58
|
requirements:
|
73
|
-
- -
|
59
|
+
- - '>='
|
74
60
|
- !ruby/object:Gem::Version
|
75
61
|
version: '0'
|
76
62
|
type: :development
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
80
|
-
- -
|
66
|
+
- - '>='
|
81
67
|
- !ruby/object:Gem::Version
|
82
68
|
version: '0'
|
83
69
|
description: FastImage finds the size or type of an image given its uri by fetching
|
@@ -97,22 +83,22 @@ licenses:
|
|
97
83
|
metadata: {}
|
98
84
|
post_install_message:
|
99
85
|
rdoc_options:
|
100
|
-
-
|
86
|
+
- --charset=UTF-8
|
101
87
|
require_paths:
|
102
88
|
- lib
|
103
89
|
required_ruby_version: !ruby/object:Gem::Requirement
|
104
90
|
requirements:
|
105
|
-
- -
|
91
|
+
- - '>='
|
106
92
|
- !ruby/object:Gem::Version
|
107
93
|
version: 1.9.2
|
108
94
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
95
|
requirements:
|
110
|
-
- -
|
96
|
+
- - '>='
|
111
97
|
- !ruby/object:Gem::Version
|
112
98
|
version: '0'
|
113
99
|
requirements: []
|
114
100
|
rubyforge_project:
|
115
|
-
rubygems_version: 2.
|
101
|
+
rubygems_version: 2.0.14.1
|
116
102
|
signing_key:
|
117
103
|
specification_version: 4
|
118
104
|
summary: FastImage - Image info fast
|