fastimage 2.2.3 → 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/lib/fastimage.rb +163 -2
- metadata +2 -2
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/lib/fastimage.rb
CHANGED
@@ -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
|
#
|
@@ -538,8 +540,21 @@ class FastImage
|
|
538
540
|
when '8B'
|
539
541
|
:psd
|
540
542
|
when "\0\0"
|
541
|
-
# ico has either a 1 (for ico format) or 2 (for cursor) at offset 3
|
542
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
|
543
558
|
when 1 then :ico
|
544
559
|
when 2 then :cur
|
545
560
|
end
|
@@ -547,7 +562,7 @@ class FastImage
|
|
547
562
|
:webp if @stream.peek(12)[8..11] == "WEBP"
|
548
563
|
when "<s"
|
549
564
|
:svg if @stream.peek(4) == "<svg"
|
550
|
-
when /\s\s|\s<|<[?!]
|
565
|
+
when /\s\s|\s<|<[?!]/, 0xef.chr + 0xbb.chr
|
551
566
|
# Peek 10 more chars each time, and if end of file is reached just raise
|
552
567
|
# unknown. We assume the <svg tag cannot be within 10 chars of the end of
|
553
568
|
# the file, and is within the first 250 chars.
|
@@ -568,6 +583,152 @@ class FastImage
|
|
568
583
|
end
|
569
584
|
alias_method :parse_size_for_cur, :parse_size_for_ico
|
570
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
|
+
|
571
732
|
class Gif # :nodoc:
|
572
733
|
def initialize(stream)
|
573
734
|
@stream = stream
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastimage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.2.
|
4
|
+
version: 2.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen Sykes
|
@@ -97,7 +97,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
97
97
|
- !ruby/object:Gem::Version
|
98
98
|
version: '0'
|
99
99
|
requirements: []
|
100
|
-
rubygems_version: 3.
|
100
|
+
rubygems_version: 3.1.6
|
101
101
|
signing_key:
|
102
102
|
specification_version: 4
|
103
103
|
summary: FastImage - Image info fast
|