From 3c5450b8beb01b19a54dbc70080e1373bd7d57b7 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Sat, 25 Feb 2023 22:15:34 -0500 Subject: [PATCH] LibGfx: Implement is_animated() and frame_count() for webp plugin --- Tests/LibGfx/TestImageDecoder.cpp | 7 ++++--- Userland/Libraries/LibGfx/WebPLoader.cpp | 22 ++++++++++++++++++---- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/Tests/LibGfx/TestImageDecoder.cpp b/Tests/LibGfx/TestImageDecoder.cpp index f7b8d6dd62..97ff6a4aac 100644 --- a/Tests/LibGfx/TestImageDecoder.cpp +++ b/Tests/LibGfx/TestImageDecoder.cpp @@ -284,9 +284,10 @@ TEST_CASE(test_webp_extended_lossless_animated) auto plugin_decoder = MUST(Gfx::WebPImageDecoderPlugin::create(file->bytes())); EXPECT(plugin_decoder->initialize()); - // FIXME: These three lines are wrong. - EXPECT_EQ(plugin_decoder->frame_count(), 1u); - EXPECT(!plugin_decoder->is_animated()); + EXPECT_EQ(plugin_decoder->frame_count(), 8u); + EXPECT(plugin_decoder->is_animated()); + + // FIXME: This is wrong. EXPECT(!plugin_decoder->loop_count()); EXPECT_EQ(plugin_decoder->size(), Gfx::IntSize(990, 1050)); diff --git a/Userland/Libraries/LibGfx/WebPLoader.cpp b/Userland/Libraries/LibGfx/WebPLoader.cpp index 646b6efb42..93a40361ae 100644 --- a/Userland/Libraries/LibGfx/WebPLoader.cpp +++ b/Userland/Libraries/LibGfx/WebPLoader.cpp @@ -519,8 +519,15 @@ ErrorOr> WebPImageDecoderPlugin::create(Readon bool WebPImageDecoderPlugin::is_animated() { - // FIXME - return false; + if (m_context->state == WebPLoadingContext::State::Error) + return false; + + if (m_context->state < WebPLoadingContext::State::FirstChunkDecoded) { + if (decode_webp_first_chunk(*m_context).is_error()) + return false; + } + + return m_context->first_chunk->type == FourCC("VP8X") && m_context->vp8x_header.has_animation; } size_t WebPImageDecoderPlugin::loop_count() @@ -531,8 +538,15 @@ size_t WebPImageDecoderPlugin::loop_count() size_t WebPImageDecoderPlugin::frame_count() { - // FIXME - return 1; + if (!is_animated()) + return 1; + + if (m_context->state < WebPLoadingContext::State::ChunksDecoded) { + if (decode_webp_chunks(*m_context).is_error()) + return 1; + } + + return m_context->animation_frame_chunks.size(); } ErrorOr WebPImageDecoderPlugin::frame(size_t index)