fastimage 2.3.0 → 2.4.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.
@@ -0,0 +1,69 @@
1
+ module FastImageParsing
2
+ class TypeParser
3
+ def initialize(stream)
4
+ @stream = stream
5
+ end
6
+
7
+ # type will use peek to get enough bytes to determing the type of the image
8
+ def type
9
+ parsed_type = case @stream.peek(2)
10
+ when "BM"
11
+ :bmp
12
+ when "GI"
13
+ :gif
14
+ when 0xff.chr + 0xd8.chr
15
+ :jpeg
16
+ when 0x89.chr + "P"
17
+ :png
18
+ when "II", "MM"
19
+ case @stream.peek(11)[8..10]
20
+ when "APC", "CR\002"
21
+ nil # do not recognise CRW or CR2 as tiff
22
+ else
23
+ :tiff
24
+ end
25
+ when '8B'
26
+ :psd
27
+ when "\xFF\x0A".b
28
+ :jxl
29
+ when "\0\0"
30
+ case @stream.peek(3).bytes.to_a.last
31
+ when 0
32
+ # http://www.ftyps.com/what.html
33
+ case @stream.peek(12)[4..-1]
34
+ when "ftypavif"
35
+ :avif
36
+ when "ftypavis"
37
+ :avif
38
+ when "ftypheic"
39
+ :heic
40
+ when "ftypmif1"
41
+ :heif
42
+ else
43
+ if @stream.peek(7)[4..-1] == 'JXL'
44
+ :jxl
45
+ end
46
+ end
47
+ # ico has either a 1 (for ico format) or 2 (for cursor) at offset 3
48
+ when 1 then :ico
49
+ when 2 then :cur
50
+ end
51
+ when "RI"
52
+ :webp if @stream.peek(12)[8..11] == "WEBP"
53
+ when "<s"
54
+ :svg if @stream.peek(4) == "<svg"
55
+ when /\s\s|\s<|<[?!]/, 0xef.chr + 0xbb.chr
56
+ # Peek 10 more chars each time, and if end of file is reached just raise
57
+ # unknown. We assume the <svg tag cannot be within 10 chars of the end of
58
+ # the file, and is within the first 1000 chars.
59
+ begin
60
+ :svg if (1..100).detect {|n| @stream.peek(10 * n).include?("<svg")}
61
+ rescue FiberError, FastImage::CannotParseImage
62
+ nil
63
+ end
64
+ end
65
+
66
+ parsed_type or raise FastImage::UnknownImageType
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,60 @@
1
+ module FastImageParsing
2
+ class Webp < ImageBase # :nodoc:
3
+ def dimensions
4
+ vp8 = @stream.read(16)[12..15]
5
+ _len = @stream.read(4).unpack("V")
6
+ case vp8
7
+ when "VP8 "
8
+ parse_size_vp8
9
+ when "VP8L"
10
+ parse_size_vp8l
11
+ when "VP8X"
12
+ parse_size_vp8x
13
+ else
14
+ nil
15
+ end
16
+ end
17
+
18
+ def animated?
19
+ vp8 = @stream.read(16)[12..15]
20
+ _len = @stream.read(4).unpack("V")
21
+ case vp8
22
+ when "VP8 "
23
+ false
24
+ when "VP8L"
25
+ false
26
+ when "VP8X"
27
+ flags = @stream.read(4).unpack("C")[0]
28
+ flags & 2 > 0
29
+ else
30
+ nil
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def parse_size_vp8
37
+ w, h = @stream.read(10).unpack("@6vv")
38
+ [w & 0x3fff, h & 0x3fff]
39
+ end
40
+
41
+ def parse_size_vp8l
42
+ @stream.skip(1) # 0x2f
43
+ b1, b2, b3, b4 = @stream.read(4).bytes.to_a
44
+ [1 + (((b2 & 0x3f) << 8) | b1), 1 + (((b4 & 0xF) << 10) | (b3 << 2) | ((b2 & 0xC0) >> 6))]
45
+ end
46
+
47
+ def parse_size_vp8x
48
+ flags = @stream.read(4).unpack("C")[0]
49
+ b1, b2, b3, b4, b5, b6 = @stream.read(6).unpack("CCCCCC")
50
+ width, height = 1 + b1 + (b2 << 8) + (b3 << 16), 1 + b4 + (b5 << 8) + (b6 << 16)
51
+
52
+ if flags & 8 > 0 # exif
53
+ # parse exif for orientation
54
+ # TODO: find or create test images for this
55
+ end
56
+
57
+ [width, height]
58
+ end
59
+ end
60
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class FastImage
4
- VERSION = '2.3.0'
4
+ VERSION = '2.4.0'
5
5
  end