fastimage 2.0.1 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|