diff --git a/CHANGELOG b/CHANGELOG index e42a6f0..63db57c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +Version 2.2.7 + +23-May-2023 + +- FEATURE: Adds animated? support for webp and avif images + Version 2.2.6 16-December-2021 diff --git a/lib/fastimage.rb b/lib/fastimage.rb index a87d2bb..d8b37c5 100644 --- a/lib/fastimage.rb +++ b/lib/fastimage.rb @@ -435,7 +435,7 @@ class FastImage def parse_animated @type = parse_type unless @type - @type == :gif ? send("parse_animated_for_#{@type}") : nil + %i(gif webp avif).include?(@type) ? send("parse_animated_for_#{@type}") : nil end def fetch_using_base64(uri) @@ -551,6 +551,8 @@ class FastImage case @stream.peek(12)[4..-1] when "ftypavif" :avif + when "ftypavis" + :avif when "ftypheic" :heic when "ftypmif1" @@ -1092,4 +1094,24 @@ class FastImage gif = Gif.new(@stream) gif.animated? end + + def parse_animated_for_webp + vp8 = @stream.read(16)[12..15] + _len = @stream.read(4).unpack("V") + case vp8 + when "VP8 " + false + when "VP8L" + false + when "VP8X" + flags = @stream.read(4).unpack("C")[0] + flags & 2 > 0 + else + nil + end + end + + def parse_animated_for_avif + @stream.peek(12)[4..-1] == "ftypavis" + end end diff --git a/lib/fastimage/version.rb b/lib/fastimage/version.rb index 4fe2862..8975fd1 100644 --- a/lib/fastimage/version.rb +++ b/lib/fastimage/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class FastImage - VERSION = '2.2.6' + VERSION = '2.2.7' end diff --git a/test/fixtures/avif/red_green_flash.avif b/test/fixtures/avif/red_green_flash.avif new file mode 100644 index 0000000..5ac3674 Binary files /dev/null and b/test/fixtures/avif/red_green_flash.avif differ diff --git a/test/fixtures/webp_animated.webp b/test/fixtures/webp_animated.webp new file mode 100644 index 0000000..7a1d3fe Binary files /dev/null and b/test/fixtures/webp_animated.webp differ diff --git a/test/test.rb b/test/test.rb index b9e5e76..0dfa85e 100644 --- a/test/test.rb +++ b/test/test.rb @@ -34,6 +34,7 @@ GoodFixtures = { "webp_vp8x.webp" => [:webp, [386, 395]], "webp_vp8l.webp" => [:webp, [386, 395]], "webp_vp8.webp" => [:webp, [550, 368]], + "webp_animated.webp" => [:webp, [400, 400]], "test.svg" => [:svg, [200, 300]], "test_partial_viewport.svg" => [:svg, [860, 400]], "test2.svg" => [:svg, [366, 271]], @@ -53,6 +54,7 @@ GoodFixtures = { "avif/hato.avif" => [:avif, [3082, 2048]], "avif/fox.avif" => [:avif, [1204, 799]], "avif/kimono.avif" => [:avif, [722, 1024]], + "avif/red_green_flash.avif" => [:avif, [256, 256]], } BadFixtures = [ @@ -124,6 +126,10 @@ class FastImageTest < Test::Unit::TestCase assert_equal false, FastImage.animated?(TestUrl + "test.gif") assert_equal true, FastImage.animated?(TestUrl + "animated.gif") assert_equal true, FastImage.animated?(TestUrl + "animated_without_gct.gif") + assert_equal false, FastImage.animated?(TestUrl + "webp_vp8x.webp") + assert_equal true, FastImage.animated?(TestUrl + "webp_animated.webp") + assert_equal false, FastImage.animated?(TestUrl + "avif/hato.avif") + assert_equal true, FastImage.animated?(TestUrl + "avif/red_green_flash.avif") end def test_should_return_nil_on_fetch_failure