fastimage 2.1.7 → 2.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 +4 -4
- data/README.textile +1 -1
- data/lib/fastimage.rb +115 -7
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 53c0966ef5216c189e2950b1ad36c106777175f0d4dca9851abd34472fd9cb61
|
4
|
+
data.tar.gz: 29f5a6bc03623e184166e7f9c5e8c4379011b301904d4c690037d5b7b0ba0b33
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 28e8ec4debe6c2c477da19cafb1ad41e5de4d809136bd86621ae128372c32c1259abea833856f73dfcfe8ef3444bc5e1a148f91b52ee02d3292235c4d95fc542
|
7
|
+
data.tar.gz: ba8b4c6bb42146387b1a8af718fbbaf74a9a94532ee5adce082ff676095dad5d5e0eb613f1ec41d7729709847195fa81c4614f2d9d510d6c7def67f8970f168e
|
data/README.textile
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
!https://img.shields.io/gem/dt/fastimage.svg!:https://rubygems.org/gems/fastimage
|
2
|
-
!https://travis-ci.org/sdsykes/fastimage.
|
2
|
+
!https://travis-ci.org/sdsykes/fastimage.svg?branch=master!:https://travis-ci.org/sdsykes/fastimage
|
3
3
|
|
4
4
|
h1. FastImage
|
5
5
|
|
data/lib/fastimage.rb
CHANGED
@@ -70,7 +70,7 @@ if RUBY_VERSION < "2.2"
|
|
70
70
|
end
|
71
71
|
|
72
72
|
class FastImage
|
73
|
-
attr_reader :size, :type, :content_length, :orientation
|
73
|
+
attr_reader :size, :type, :content_length, :orientation, :animated
|
74
74
|
|
75
75
|
attr_reader :bytes_read
|
76
76
|
|
@@ -179,6 +179,34 @@ class FastImage
|
|
179
179
|
new(uri, options.merge(:type_only=>true)).type
|
180
180
|
end
|
181
181
|
|
182
|
+
# Returns a boolean value indicating the image is animated.
|
183
|
+
# It will return nil if the image could not be fetched, or if the image type was not recognised.
|
184
|
+
#
|
185
|
+
# By default there is a timeout of 2 seconds for opening and reading from a remote server.
|
186
|
+
# This can be changed by passing a :timeout => number_of_seconds in the options.
|
187
|
+
#
|
188
|
+
# If you wish FastImage to raise if it cannot find the type of the image for any reason, then pass
|
189
|
+
# :raise_on_failure => true in the options.
|
190
|
+
#
|
191
|
+
# === Example
|
192
|
+
#
|
193
|
+
# require 'fastimage'
|
194
|
+
#
|
195
|
+
# FastImage.animated?("test/fixtures/test.gif")
|
196
|
+
# => false
|
197
|
+
# FastImage.animated?("test/fixtures/animated.gif")
|
198
|
+
# => true
|
199
|
+
#
|
200
|
+
# === Supported options
|
201
|
+
# [:timeout]
|
202
|
+
# Overrides the default timeout of 2 seconds. Applies both to reading from and opening the http connection.
|
203
|
+
# [:raise_on_failure]
|
204
|
+
# If set to true causes an exception to be raised if the image type cannot be found for any reason.
|
205
|
+
#
|
206
|
+
def self.animated?(uri, options={})
|
207
|
+
new(uri, options.merge(:animated_only=>true)).animated
|
208
|
+
end
|
209
|
+
|
182
210
|
def initialize(uri, options={})
|
183
211
|
@uri = uri
|
184
212
|
@options = {
|
@@ -189,7 +217,13 @@ class FastImage
|
|
189
217
|
:http_header => {}
|
190
218
|
}.merge(options)
|
191
219
|
|
192
|
-
@property = @options[:
|
220
|
+
@property = if @options[:animated_only]
|
221
|
+
:animated
|
222
|
+
elsif @options[:type_only]
|
223
|
+
:type
|
224
|
+
else
|
225
|
+
:size
|
226
|
+
end
|
193
227
|
|
194
228
|
@type, @state = nil
|
195
229
|
|
@@ -248,7 +282,7 @@ class FastImage
|
|
248
282
|
begin
|
249
283
|
URI(location)
|
250
284
|
rescue URI::InvalidURIError
|
251
|
-
URI.escape(location)
|
285
|
+
::URI::DEFAULT_PARSER.escape(location)
|
252
286
|
else
|
253
287
|
location
|
254
288
|
end
|
@@ -262,7 +296,10 @@ class FastImage
|
|
262
296
|
if res.is_a?(Net::HTTPRedirection) && @redirect_count < 4
|
263
297
|
@redirect_count += 1
|
264
298
|
begin
|
265
|
-
|
299
|
+
location = res['Location']
|
300
|
+
raise ImageFetchFailure if location.nil? || location.empty?
|
301
|
+
|
302
|
+
@parsed_uri = URI.join(@parsed_uri, escaped_location(location))
|
266
303
|
rescue URI::InvalidURIError
|
267
304
|
else
|
268
305
|
fetch_using_http_from_parsed_uri
|
@@ -369,7 +406,7 @@ class FastImage
|
|
369
406
|
|
370
407
|
begin
|
371
408
|
result = send("parse_#{@property}")
|
372
|
-
if result
|
409
|
+
if result != nil
|
373
410
|
# extract exif orientation if it was found
|
374
411
|
if @property == :size && result.size == 3
|
375
412
|
@orientation = result.pop
|
@@ -391,6 +428,11 @@ class FastImage
|
|
391
428
|
send("parse_size_for_#{@type}")
|
392
429
|
end
|
393
430
|
|
431
|
+
def parse_animated
|
432
|
+
@type = parse_type unless @type
|
433
|
+
@type == :gif ? send("parse_animated_for_#{@type}") : nil
|
434
|
+
end
|
435
|
+
|
394
436
|
def fetch_using_base64(uri)
|
395
437
|
data = uri.split(',')[1]
|
396
438
|
decoded = Base64.decode64(data)
|
@@ -502,7 +544,7 @@ class FastImage
|
|
502
544
|
when "RI"
|
503
545
|
:webp if @stream.peek(12)[8..11] == "WEBP"
|
504
546
|
when "<s"
|
505
|
-
:svg
|
547
|
+
:svg if @stream.peek(4) == "<svg"
|
506
548
|
when /<[?!]/
|
507
549
|
# Peek 10 more chars each time, and if end of file is reached just raise
|
508
550
|
# unknown. We assume the <svg tag cannot be within 10 chars of the end of
|
@@ -524,8 +566,69 @@ class FastImage
|
|
524
566
|
end
|
525
567
|
alias_method :parse_size_for_cur, :parse_size_for_ico
|
526
568
|
|
569
|
+
class Gif # :nodoc:
|
570
|
+
def initialize(stream)
|
571
|
+
@stream = stream
|
572
|
+
end
|
573
|
+
|
574
|
+
def width_and_height
|
575
|
+
@stream.read(11)[6..10].unpack('SS')
|
576
|
+
end
|
577
|
+
|
578
|
+
# Checks if a delay between frames exists and if it does, then the GIFs is
|
579
|
+
# animated
|
580
|
+
def animated?
|
581
|
+
delay = 0
|
582
|
+
|
583
|
+
@stream.read(10) # "GIF" + version (3) + width (2) + height (2)
|
584
|
+
|
585
|
+
fields = @stream.read(3).unpack("C")[0] # fields (1) + bg color (1) + pixel ratio (1)
|
586
|
+
|
587
|
+
# Skip Global Color Table if it exists
|
588
|
+
if fields & 0x80
|
589
|
+
# 2 * (depth + 1) colors, each occupying 3 bytes (RGB)
|
590
|
+
@stream.skip(3 * 2 ** ((fields & 0x7) + 1))
|
591
|
+
end
|
592
|
+
|
593
|
+
loop do
|
594
|
+
block_type = @stream.read(1).unpack("C")[0]
|
595
|
+
if block_type == 0x21
|
596
|
+
extension_type = @stream.read(1).unpack("C")[0]
|
597
|
+
size = @stream.read(1).unpack("C")[0]
|
598
|
+
if extension_type == 0xF9
|
599
|
+
delay = @stream.read(4).unpack("CSC")[1] # fields (1) + delay (2) + transparent index (1)
|
600
|
+
break
|
601
|
+
elsif extension_type == 0xFF
|
602
|
+
@stream.skip(size) # application ID (8) + version (3)
|
603
|
+
else
|
604
|
+
return # unrecognized extension
|
605
|
+
end
|
606
|
+
skip_sub_blocks
|
607
|
+
else
|
608
|
+
return # unrecognized block
|
609
|
+
end
|
610
|
+
end
|
611
|
+
|
612
|
+
delay > 0
|
613
|
+
end
|
614
|
+
|
615
|
+
private
|
616
|
+
|
617
|
+
def skip_sub_blocks
|
618
|
+
loop do
|
619
|
+
size = @stream.read(1).unpack("C")[0]
|
620
|
+
if size == 0
|
621
|
+
break
|
622
|
+
else
|
623
|
+
@stream.skip(size)
|
624
|
+
end
|
625
|
+
end
|
626
|
+
end
|
627
|
+
end
|
628
|
+
|
527
629
|
def parse_size_for_gif
|
528
|
-
@stream
|
630
|
+
gif = Gif.new(@stream)
|
631
|
+
gif.width_and_height
|
529
632
|
end
|
530
633
|
|
531
634
|
def parse_size_for_png
|
@@ -785,4 +888,9 @@ class FastImage
|
|
785
888
|
svg = Svg.new(@stream)
|
786
889
|
svg.width_and_height
|
787
890
|
end
|
891
|
+
|
892
|
+
def parse_animated_for_gif
|
893
|
+
gif = Gif.new(@stream)
|
894
|
+
gif.animated?
|
895
|
+
end
|
788
896
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastimage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.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: 2020-07-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fakeweb-fi
|
@@ -28,14 +28,14 @@ dependencies:
|
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '10.5'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.5'
|
41
41
|
- !ruby/object:Gem::Dependency
|