fastimage 2.1.7 → 2.2.4
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 +3 -2
- data/lib/fastimage.rb +297 -19
- metadata +8 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 074e776db55bfd4766292bca262afc562d4d38d07d86f56f1299a666b4dc3e30
|
|
4
|
+
data.tar.gz: 7e079013cbd7802773119a5a6b7f25377e2878c1afbeb610c68d8a8a069ad0a1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4c82693c20723bc22b41e9839104097b0cb435c392e8ddd19edff93aeaa1802f3319c6ad49f1b82ba3926bd1bdcc5e04870d02401ff20e745e61d26a81473c6b
|
|
7
|
+
data.tar.gz: 230fbfd667aab5c59ce7bc53909454d2d9134fdb3c6705173d5df264a3c8a36df2d879c959df1ab4662d5e216a554ada7ba482ba3e0872b9c000d087c91e5b29
|
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
|
|
|
@@ -132,7 +132,7 @@ h2. Tests
|
|
|
132
132
|
|
|
133
133
|
You'll need to @gem install fakeweb@ and possibly also @gem install test-unit@ to be able to run the tests.
|
|
134
134
|
|
|
135
|
-
bc.. $ ruby test.rb
|
|
135
|
+
bc.. $ ruby test/test.rb
|
|
136
136
|
Run options:
|
|
137
137
|
|
|
138
138
|
# Running tests:
|
|
@@ -156,6 +156,7 @@ h2. FastImage in other languages
|
|
|
156
156
|
* "Node.js by ShogunPanda":https://github.com/ShogunPanda/fastimage
|
|
157
157
|
* "Objective C by kylehickinson":https://github.com/kylehickinson/FastImage
|
|
158
158
|
* "Android by qstumn":https://github.com/qstumn/FastImageSize
|
|
159
|
+
* "Flutter by ky1vstar":https://github.com/ky1vstar/fastimage.dart
|
|
159
160
|
|
|
160
161
|
h2. Licence
|
|
161
162
|
|
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
|
|
|
@@ -89,6 +89,8 @@ class FastImage
|
|
|
89
89
|
|
|
90
90
|
LocalFileChunkSize = 256 unless const_defined?(:LocalFileChunkSize)
|
|
91
91
|
|
|
92
|
+
SUPPORTED_IMAGE_TYPES = [:bmp, :gif, :jpeg, :png, :tiff, :psd, :heic, :heif, :webp, :svg, :ico, :cur].freeze
|
|
93
|
+
|
|
92
94
|
# Returns an array containing the width and height of the image.
|
|
93
95
|
# It will return nil if the image could not be fetched, or if the image type was not recognised.
|
|
94
96
|
#
|
|
@@ -179,6 +181,34 @@ class FastImage
|
|
|
179
181
|
new(uri, options.merge(:type_only=>true)).type
|
|
180
182
|
end
|
|
181
183
|
|
|
184
|
+
# Returns a boolean value indicating the image is animated.
|
|
185
|
+
# It will return nil if the image could not be fetched, or if the image type was not recognised.
|
|
186
|
+
#
|
|
187
|
+
# By default there is a timeout of 2 seconds for opening and reading from a remote server.
|
|
188
|
+
# This can be changed by passing a :timeout => number_of_seconds in the options.
|
|
189
|
+
#
|
|
190
|
+
# If you wish FastImage to raise if it cannot find the type of the image for any reason, then pass
|
|
191
|
+
# :raise_on_failure => true in the options.
|
|
192
|
+
#
|
|
193
|
+
# === Example
|
|
194
|
+
#
|
|
195
|
+
# require 'fastimage'
|
|
196
|
+
#
|
|
197
|
+
# FastImage.animated?("test/fixtures/test.gif")
|
|
198
|
+
# => false
|
|
199
|
+
# FastImage.animated?("test/fixtures/animated.gif")
|
|
200
|
+
# => true
|
|
201
|
+
#
|
|
202
|
+
# === Supported options
|
|
203
|
+
# [:timeout]
|
|
204
|
+
# Overrides the default timeout of 2 seconds. Applies both to reading from and opening the http connection.
|
|
205
|
+
# [:raise_on_failure]
|
|
206
|
+
# If set to true causes an exception to be raised if the image type cannot be found for any reason.
|
|
207
|
+
#
|
|
208
|
+
def self.animated?(uri, options={})
|
|
209
|
+
new(uri, options.merge(:animated_only=>true)).animated
|
|
210
|
+
end
|
|
211
|
+
|
|
182
212
|
def initialize(uri, options={})
|
|
183
213
|
@uri = uri
|
|
184
214
|
@options = {
|
|
@@ -189,7 +219,13 @@ class FastImage
|
|
|
189
219
|
:http_header => {}
|
|
190
220
|
}.merge(options)
|
|
191
221
|
|
|
192
|
-
@property = @options[:
|
|
222
|
+
@property = if @options[:animated_only]
|
|
223
|
+
:animated
|
|
224
|
+
elsif @options[:type_only]
|
|
225
|
+
:type
|
|
226
|
+
else
|
|
227
|
+
:size
|
|
228
|
+
end
|
|
193
229
|
|
|
194
230
|
@type, @state = nil
|
|
195
231
|
|
|
@@ -217,10 +253,8 @@ class FastImage
|
|
|
217
253
|
Errno::ENETUNREACH, ImageFetchFailure, Net::HTTPBadResponse, EOFError, Errno::ENOENT,
|
|
218
254
|
OpenSSL::SSL::SSLError
|
|
219
255
|
raise ImageFetchFailure if @options[:raise_on_failure]
|
|
220
|
-
rescue NoMethodError # 1.8.7p248 can raise this due to a net/http bug
|
|
221
|
-
raise ImageFetchFailure if @options[:raise_on_failure]
|
|
222
256
|
rescue UnknownImageType
|
|
223
|
-
raise
|
|
257
|
+
raise if @options[:raise_on_failure]
|
|
224
258
|
rescue CannotParseImage
|
|
225
259
|
if @options[:raise_on_failure]
|
|
226
260
|
if @property == :size
|
|
@@ -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,9 +428,17 @@ 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
|
-
|
|
396
|
-
|
|
437
|
+
decoded = begin
|
|
438
|
+
Base64.decode64(uri.split(',')[1])
|
|
439
|
+
rescue
|
|
440
|
+
raise CannotParseImage
|
|
441
|
+
end
|
|
397
442
|
@content_length = decoded.size
|
|
398
443
|
fetch_using_read StringIO.new(decoded)
|
|
399
444
|
end
|
|
@@ -429,19 +474,20 @@ class FastImage
|
|
|
429
474
|
|
|
430
475
|
# Peeking beyond the end of the input will raise
|
|
431
476
|
def peek(n)
|
|
432
|
-
while @strpos + n
|
|
477
|
+
while @strpos + n > @str.size
|
|
433
478
|
unused_str = @str[@strpos..-1]
|
|
479
|
+
|
|
434
480
|
new_string = @read_fiber.resume
|
|
481
|
+
new_string = @read_fiber.resume if new_string.is_a? Net::ReadAdapter
|
|
435
482
|
raise CannotParseImage if !new_string
|
|
436
|
-
|
|
437
483
|
# we are dealing with bytes here, so force the encoding
|
|
438
|
-
new_string.force_encoding("ASCII-8BIT") if
|
|
484
|
+
new_string.force_encoding("ASCII-8BIT") if new_string.respond_to? :force_encoding
|
|
439
485
|
|
|
440
486
|
@str = unused_str + new_string
|
|
441
487
|
@strpos = 0
|
|
442
488
|
end
|
|
443
489
|
|
|
444
|
-
@str[@strpos
|
|
490
|
+
@str[@strpos, n]
|
|
445
491
|
end
|
|
446
492
|
|
|
447
493
|
def read(n)
|
|
@@ -459,7 +505,7 @@ class FastImage
|
|
|
459
505
|
new_string = @read_fiber.resume
|
|
460
506
|
raise CannotParseImage if !new_string
|
|
461
507
|
|
|
462
|
-
new_string.force_encoding("ASCII-8BIT") if
|
|
508
|
+
new_string.force_encoding("ASCII-8BIT") if new_string.respond_to? :force_encoding
|
|
463
509
|
|
|
464
510
|
fetched += new_string.size
|
|
465
511
|
@str = new_string
|
|
@@ -494,16 +540,29 @@ class FastImage
|
|
|
494
540
|
when '8B'
|
|
495
541
|
:psd
|
|
496
542
|
when "\0\0"
|
|
497
|
-
# ico has either a 1 (for ico format) or 2 (for cursor) at offset 3
|
|
498
543
|
case @stream.peek(3).bytes.to_a.last
|
|
544
|
+
when 0
|
|
545
|
+
# http://www.ftyps.com/what.html
|
|
546
|
+
# HEIC is composed of nested "boxes". Each box has a header composed of
|
|
547
|
+
# - Size (32 bit integer)
|
|
548
|
+
# - Box type (4 chars)
|
|
549
|
+
# - Extended size: only if size === 1, the type field is followed by 64 bit integer of extended size
|
|
550
|
+
# - Payload: Type-dependent
|
|
551
|
+
case @stream.peek(12)[4..-1]
|
|
552
|
+
when "ftypheic"
|
|
553
|
+
:heic
|
|
554
|
+
when "ftypmif1"
|
|
555
|
+
:heif
|
|
556
|
+
end
|
|
557
|
+
# ico has either a 1 (for ico format) or 2 (for cursor) at offset 3
|
|
499
558
|
when 1 then :ico
|
|
500
559
|
when 2 then :cur
|
|
501
560
|
end
|
|
502
561
|
when "RI"
|
|
503
562
|
:webp if @stream.peek(12)[8..11] == "WEBP"
|
|
504
563
|
when "<s"
|
|
505
|
-
:svg
|
|
506
|
-
when
|
|
564
|
+
:svg if @stream.peek(4) == "<svg"
|
|
565
|
+
when /\s\s|\s<|<[?!]/, 0xef.chr + 0xbb.chr
|
|
507
566
|
# Peek 10 more chars each time, and if end of file is reached just raise
|
|
508
567
|
# unknown. We assume the <svg tag cannot be within 10 chars of the end of
|
|
509
568
|
# the file, and is within the first 250 chars.
|
|
@@ -524,8 +583,222 @@ class FastImage
|
|
|
524
583
|
end
|
|
525
584
|
alias_method :parse_size_for_cur, :parse_size_for_ico
|
|
526
585
|
|
|
586
|
+
class Heic # :nodoc:
|
|
587
|
+
def initialize(stream)
|
|
588
|
+
@stream = stream
|
|
589
|
+
end
|
|
590
|
+
|
|
591
|
+
def width_and_height
|
|
592
|
+
@max_size = nil
|
|
593
|
+
@primary_box = nil
|
|
594
|
+
@ipma_boxes = []
|
|
595
|
+
@ispe_boxes = []
|
|
596
|
+
@final_size = nil
|
|
597
|
+
|
|
598
|
+
catch :finish do
|
|
599
|
+
read_boxes!
|
|
600
|
+
end
|
|
601
|
+
|
|
602
|
+
@final_size
|
|
603
|
+
end
|
|
604
|
+
|
|
605
|
+
private
|
|
606
|
+
|
|
607
|
+
def read_boxes!(max_read_bytes = nil)
|
|
608
|
+
end_pos = max_read_bytes.nil? ? nil : @stream.pos + max_read_bytes
|
|
609
|
+
index = 0
|
|
610
|
+
|
|
611
|
+
loop do
|
|
612
|
+
return if end_pos && @stream.pos >= end_pos
|
|
613
|
+
|
|
614
|
+
box_type, box_size = read_box_header!
|
|
615
|
+
|
|
616
|
+
case box_type
|
|
617
|
+
when "meta"
|
|
618
|
+
handle_meta_box(box_size)
|
|
619
|
+
when "pitm"
|
|
620
|
+
handle_pitm_box(box_size)
|
|
621
|
+
when "ipma"
|
|
622
|
+
handle_ipma_box(box_size)
|
|
623
|
+
when "hdlr"
|
|
624
|
+
handle_hdlr_box(box_size)
|
|
625
|
+
when "iprp", "ipco"
|
|
626
|
+
read_boxes!(box_size)
|
|
627
|
+
when "ispe"
|
|
628
|
+
handle_ispe_box(box_size, index)
|
|
629
|
+
when "mdat"
|
|
630
|
+
throw :finish
|
|
631
|
+
else
|
|
632
|
+
@stream.read(box_size)
|
|
633
|
+
end
|
|
634
|
+
|
|
635
|
+
index += 1
|
|
636
|
+
end
|
|
637
|
+
end
|
|
638
|
+
|
|
639
|
+
def handle_ispe_box(box_size, index)
|
|
640
|
+
throw :finish if box_size < 12
|
|
641
|
+
|
|
642
|
+
data = @stream.read(box_size)
|
|
643
|
+
width, height = data[4...12].unpack("N2")
|
|
644
|
+
@ispe_boxes << { index: index, size: [width, height] }
|
|
645
|
+
end
|
|
646
|
+
|
|
647
|
+
def handle_hdlr_box(box_size)
|
|
648
|
+
throw :finish if box_size < 12
|
|
649
|
+
|
|
650
|
+
data = @stream.read(box_size)
|
|
651
|
+
throw :finish if data[8...12] != "pict"
|
|
652
|
+
end
|
|
653
|
+
|
|
654
|
+
def handle_ipma_box(box_size)
|
|
655
|
+
@stream.read(3)
|
|
656
|
+
flags3 = read_uint8!
|
|
657
|
+
entries_count = read_uint32!
|
|
658
|
+
|
|
659
|
+
entries_count.times do
|
|
660
|
+
id = read_uint16!
|
|
661
|
+
essen_count = read_uint8!
|
|
662
|
+
|
|
663
|
+
essen_count.times do
|
|
664
|
+
property_index = read_uint8! & 0x7F
|
|
665
|
+
|
|
666
|
+
if flags3 & 1 == 1
|
|
667
|
+
property_index = (property_index << 7) + read_uint8!
|
|
668
|
+
end
|
|
669
|
+
|
|
670
|
+
@ipma_boxes << { id: id, property_index: property_index - 1 }
|
|
671
|
+
end
|
|
672
|
+
end
|
|
673
|
+
end
|
|
674
|
+
|
|
675
|
+
def handle_pitm_box(box_size)
|
|
676
|
+
data = @stream.read(box_size)
|
|
677
|
+
@primary_box = data[4...6].unpack("S>")[0]
|
|
678
|
+
end
|
|
679
|
+
|
|
680
|
+
def handle_meta_box(box_size)
|
|
681
|
+
throw :finish if box_size < 4
|
|
682
|
+
|
|
683
|
+
@stream.read(4)
|
|
684
|
+
read_boxes!(box_size - 4)
|
|
685
|
+
|
|
686
|
+
throw :finish if !@primary_box
|
|
687
|
+
|
|
688
|
+
primary_indices = @ipma_boxes
|
|
689
|
+
.select { |box| box[:id] == @primary_box }
|
|
690
|
+
.map { |box| box[:property_index] }
|
|
691
|
+
|
|
692
|
+
ispe_box = @ispe_boxes.find do |box|
|
|
693
|
+
primary_indices.include?(box[:index])
|
|
694
|
+
end
|
|
695
|
+
|
|
696
|
+
if ispe_box
|
|
697
|
+
@final_size = ispe_box[:size]
|
|
698
|
+
end
|
|
699
|
+
|
|
700
|
+
throw :finish
|
|
701
|
+
end
|
|
702
|
+
|
|
703
|
+
def read_box_header!
|
|
704
|
+
size = read_uint32!
|
|
705
|
+
type = @stream.read(4)
|
|
706
|
+
[type, size - 8]
|
|
707
|
+
end
|
|
708
|
+
|
|
709
|
+
def read_uint8!
|
|
710
|
+
@stream.read(1).unpack("C")[0]
|
|
711
|
+
end
|
|
712
|
+
|
|
713
|
+
def read_uint16!
|
|
714
|
+
@stream.read(2).unpack("S>")[0]
|
|
715
|
+
end
|
|
716
|
+
|
|
717
|
+
def read_uint32!
|
|
718
|
+
@stream.read(4).unpack("N")[0]
|
|
719
|
+
end
|
|
720
|
+
end
|
|
721
|
+
|
|
722
|
+
def parse_size_for_heic
|
|
723
|
+
heic = Heic.new(@stream)
|
|
724
|
+
heic.width_and_height
|
|
725
|
+
end
|
|
726
|
+
|
|
727
|
+
def parse_size_for_heif
|
|
728
|
+
heic = Heic.new(@stream)
|
|
729
|
+
heic.width_and_height
|
|
730
|
+
end
|
|
731
|
+
|
|
732
|
+
class Gif # :nodoc:
|
|
733
|
+
def initialize(stream)
|
|
734
|
+
@stream = stream
|
|
735
|
+
end
|
|
736
|
+
|
|
737
|
+
def width_and_height
|
|
738
|
+
@stream.read(11)[6..10].unpack('SS')
|
|
739
|
+
end
|
|
740
|
+
|
|
741
|
+
# Checks if a delay between frames exists and if it does, then the GIFs is
|
|
742
|
+
# animated
|
|
743
|
+
def animated?
|
|
744
|
+
frames = 0
|
|
745
|
+
|
|
746
|
+
# "GIF" + version (3) + width (2) + height (2)
|
|
747
|
+
@stream.skip(10)
|
|
748
|
+
|
|
749
|
+
# fields (1) + bg color (1) + pixel ratio (1)
|
|
750
|
+
fields = @stream.read(3).unpack("CCC")[0]
|
|
751
|
+
if fields & 0x80 != 0 # Global Color Table
|
|
752
|
+
# 2 * (depth + 1) colors, each occupying 3 bytes (RGB)
|
|
753
|
+
@stream.skip(3 * 2 ** ((fields & 0x7) + 1))
|
|
754
|
+
end
|
|
755
|
+
|
|
756
|
+
loop do
|
|
757
|
+
block_type = @stream.read(1).unpack("C")[0]
|
|
758
|
+
|
|
759
|
+
if block_type == 0x21 # Graphic Control Extension
|
|
760
|
+
# extension type (1) + size (1)
|
|
761
|
+
size = @stream.read(2).unpack("CC")[1]
|
|
762
|
+
@stream.skip(size)
|
|
763
|
+
skip_sub_blocks
|
|
764
|
+
elsif block_type == 0x2C # Image Descriptor
|
|
765
|
+
frames += 1
|
|
766
|
+
return true if frames > 1
|
|
767
|
+
|
|
768
|
+
# left position (2) + top position (2) + width (2) + height (2) + fields (1)
|
|
769
|
+
fields = @stream.read(9).unpack("SSSSC")[4]
|
|
770
|
+
if fields & 0x80 != 0 # Local Color Table
|
|
771
|
+
# 2 * (depth + 1) colors, each occupying 3 bytes (RGB)
|
|
772
|
+
@stream.skip(3 * 2 ** ((fields & 0x7) + 1))
|
|
773
|
+
end
|
|
774
|
+
|
|
775
|
+
@stream.skip(1) # LZW min code size (1)
|
|
776
|
+
skip_sub_blocks
|
|
777
|
+
else
|
|
778
|
+
break # unrecognized block
|
|
779
|
+
end
|
|
780
|
+
end
|
|
781
|
+
|
|
782
|
+
false
|
|
783
|
+
end
|
|
784
|
+
|
|
785
|
+
private
|
|
786
|
+
|
|
787
|
+
def skip_sub_blocks
|
|
788
|
+
loop do
|
|
789
|
+
size = @stream.read(1).unpack("C")[0]
|
|
790
|
+
if size == 0
|
|
791
|
+
break
|
|
792
|
+
else
|
|
793
|
+
@stream.skip(size)
|
|
794
|
+
end
|
|
795
|
+
end
|
|
796
|
+
end
|
|
797
|
+
end
|
|
798
|
+
|
|
527
799
|
def parse_size_for_gif
|
|
528
|
-
@stream
|
|
800
|
+
gif = Gif.new(@stream)
|
|
801
|
+
gif.width_and_height
|
|
529
802
|
end
|
|
530
803
|
|
|
531
804
|
def parse_size_for_png
|
|
@@ -785,4 +1058,9 @@ class FastImage
|
|
|
785
1058
|
svg = Svg.new(@stream)
|
|
786
1059
|
svg.width_and_height
|
|
787
1060
|
end
|
|
1061
|
+
|
|
1062
|
+
def parse_animated_for_gif
|
|
1063
|
+
gif = Gif.new(@stream)
|
|
1064
|
+
gif.animated?
|
|
1065
|
+
end
|
|
788
1066
|
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.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Stephen Sykes
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-02-28 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
|
|
@@ -81,7 +81,7 @@ homepage: http://github.com/sdsykes/fastimage
|
|
|
81
81
|
licenses:
|
|
82
82
|
- MIT
|
|
83
83
|
metadata: {}
|
|
84
|
-
post_install_message:
|
|
84
|
+
post_install_message:
|
|
85
85
|
rdoc_options:
|
|
86
86
|
- "--charset=UTF-8"
|
|
87
87
|
require_paths:
|
|
@@ -97,8 +97,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
97
97
|
- !ruby/object:Gem::Version
|
|
98
98
|
version: '0'
|
|
99
99
|
requirements: []
|
|
100
|
-
rubygems_version: 3.
|
|
101
|
-
signing_key:
|
|
100
|
+
rubygems_version: 3.1.6
|
|
101
|
+
signing_key:
|
|
102
102
|
specification_version: 4
|
|
103
103
|
summary: FastImage - Image info fast
|
|
104
104
|
test_files: []
|