From e7921cfe14c1c2d23c97c8f85a198c0df04ec14f Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 7 Apr 2023 20:41:22 -0600 Subject: LibGfx: Add first_animated_frame_index method to ImageDecoder Some image formats such as APNG may not use the first frame for animations. --- Userland/Libraries/LibGUI/ImageWidget.cpp | 10 ++++++---- Userland/Libraries/LibGfx/ImageFormats/BMPLoader.cpp | 5 +++++ Userland/Libraries/LibGfx/ImageFormats/BMPLoader.h | 1 + Userland/Libraries/LibGfx/ImageFormats/DDSLoader.cpp | 5 +++++ Userland/Libraries/LibGfx/ImageFormats/DDSLoader.h | 1 + Userland/Libraries/LibGfx/ImageFormats/GIFLoader.cpp | 5 +++++ Userland/Libraries/LibGfx/ImageFormats/GIFLoader.h | 1 + Userland/Libraries/LibGfx/ImageFormats/ICOLoader.cpp | 5 +++++ Userland/Libraries/LibGfx/ImageFormats/ICOLoader.h | 1 + Userland/Libraries/LibGfx/ImageFormats/ImageDecoder.h | 2 ++ Userland/Libraries/LibGfx/ImageFormats/JPEGLoader.cpp | 5 +++++ Userland/Libraries/LibGfx/ImageFormats/JPEGLoader.h | 1 + Userland/Libraries/LibGfx/ImageFormats/PNGLoader.cpp | 5 +++++ Userland/Libraries/LibGfx/ImageFormats/PNGLoader.h | 1 + .../Libraries/LibGfx/ImageFormats/PortableImageMapLoader.h | 7 +++++++ Userland/Libraries/LibGfx/ImageFormats/QOILoader.h | 1 + Userland/Libraries/LibGfx/ImageFormats/TGALoader.cpp | 5 +++++ Userland/Libraries/LibGfx/ImageFormats/TGALoader.h | 1 + Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp | 5 +++++ Userland/Libraries/LibGfx/ImageFormats/WebPLoader.h | 1 + 20 files changed, 64 insertions(+), 4 deletions(-) diff --git a/Userland/Libraries/LibGUI/ImageWidget.cpp b/Userland/Libraries/LibGUI/ImageWidget.cpp index 4b422b0f76..d262a9b981 100644 --- a/Userland/Libraries/LibGUI/ImageWidget.cpp +++ b/Userland/Libraries/LibGUI/ImageWidget.cpp @@ -52,18 +52,20 @@ void ImageWidget::set_auto_resize(bool value) // Same as ImageViewer::ViewWidget::animate(), you probably want to keep any changes in sync void ImageWidget::animate() { - m_current_frame_index = (m_current_frame_index + 1) % m_image_decoder->frame_count(); + auto first_animated_frame_index = m_image_decoder->first_animated_frame_index(); + auto total_animated_frames = m_image_decoder->frame_count() - first_animated_frame_index; + m_current_frame_index = (m_current_frame_index + 1) % total_animated_frames; - auto current_frame = m_image_decoder->frame(m_current_frame_index).release_value_but_fixme_should_propagate_errors(); + auto current_frame = m_image_decoder->frame(first_animated_frame_index + m_current_frame_index).release_value_but_fixme_should_propagate_errors(); set_bitmap(current_frame.image); if (current_frame.duration != m_timer->interval()) { m_timer->restart(current_frame.duration); } - if (m_current_frame_index == m_image_decoder->frame_count() - 1) { + if (m_current_frame_index == total_animated_frames - 1) { ++m_loops_completed; - if (m_loops_completed > 0 && m_loops_completed == m_image_decoder->loop_count()) { + if (m_image_decoder->loop_count() > 0 && m_loops_completed == m_image_decoder->loop_count()) { m_timer->stop(); } } diff --git a/Userland/Libraries/LibGfx/ImageFormats/BMPLoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/BMPLoader.cpp index 76c9e25d88..66ab1f715b 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/BMPLoader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/BMPLoader.cpp @@ -1544,6 +1544,11 @@ size_t BMPImageDecoderPlugin::frame_count() return 1; } +size_t BMPImageDecoderPlugin::first_animated_frame_index() +{ + return 0; +} + ErrorOr BMPImageDecoderPlugin::frame(size_t index) { if (index > 0) diff --git a/Userland/Libraries/LibGfx/ImageFormats/BMPLoader.h b/Userland/Libraries/LibGfx/ImageFormats/BMPLoader.h index 7999a4a76e..c0b8a2f9b1 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/BMPLoader.h +++ b/Userland/Libraries/LibGfx/ImageFormats/BMPLoader.h @@ -35,6 +35,7 @@ public: virtual bool is_animated() override; virtual size_t loop_count() override; virtual size_t frame_count() override; + virtual size_t first_animated_frame_index() override; virtual ErrorOr frame(size_t index) override; virtual ErrorOr> icc_data() override; diff --git a/Userland/Libraries/LibGfx/ImageFormats/DDSLoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/DDSLoader.cpp index 294ee6a6de..b11dfd2b6d 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/DDSLoader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/DDSLoader.cpp @@ -685,6 +685,11 @@ size_t DDSImageDecoderPlugin::frame_count() return 1; } +size_t DDSImageDecoderPlugin::first_animated_frame_index() +{ + return 0; +} + ErrorOr DDSImageDecoderPlugin::frame(size_t index) { if (index > 0) diff --git a/Userland/Libraries/LibGfx/ImageFormats/DDSLoader.h b/Userland/Libraries/LibGfx/ImageFormats/DDSLoader.h index 4e7d213add..904592be4b 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/DDSLoader.h +++ b/Userland/Libraries/LibGfx/ImageFormats/DDSLoader.h @@ -247,6 +247,7 @@ public: virtual bool is_animated() override; virtual size_t loop_count() override; virtual size_t frame_count() override; + virtual size_t first_animated_frame_index() override; virtual ErrorOr frame(size_t index) override; virtual ErrorOr> icc_data() override; diff --git a/Userland/Libraries/LibGfx/ImageFormats/GIFLoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/GIFLoader.cpp index 79da2033d0..591305862b 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/GIFLoader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/GIFLoader.cpp @@ -627,6 +627,11 @@ size_t GIFImageDecoderPlugin::frame_count() return m_context->images.size(); } +size_t GIFImageDecoderPlugin::first_animated_frame_index() +{ + return 0; +} + ErrorOr GIFImageDecoderPlugin::frame(size_t index) { if (m_context->error_state >= GIFLoadingContext::ErrorState::FailedToDecodeAnyFrame) { diff --git a/Userland/Libraries/LibGfx/ImageFormats/GIFLoader.h b/Userland/Libraries/LibGfx/ImageFormats/GIFLoader.h index 88975716be..7b46a214eb 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/GIFLoader.h +++ b/Userland/Libraries/LibGfx/ImageFormats/GIFLoader.h @@ -27,6 +27,7 @@ public: virtual bool is_animated() override; virtual size_t loop_count() override; virtual size_t frame_count() override; + virtual size_t first_animated_frame_index() override; virtual ErrorOr frame(size_t index) override; virtual ErrorOr> icc_data() override; diff --git a/Userland/Libraries/LibGfx/ImageFormats/ICOLoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/ICOLoader.cpp index 87aa56ffe8..6ebc5a6d10 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/ICOLoader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/ICOLoader.cpp @@ -251,6 +251,11 @@ size_t ICOImageDecoderPlugin::frame_count() return 1; } +size_t ICOImageDecoderPlugin::first_animated_frame_index() +{ + return 0; +} + ErrorOr ICOImageDecoderPlugin::frame(size_t index) { if (index > 0) diff --git a/Userland/Libraries/LibGfx/ImageFormats/ICOLoader.h b/Userland/Libraries/LibGfx/ImageFormats/ICOLoader.h index bef1c4cf87..7e2e92bbd9 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/ICOLoader.h +++ b/Userland/Libraries/LibGfx/ImageFormats/ICOLoader.h @@ -26,6 +26,7 @@ public: virtual bool is_animated() override; virtual size_t loop_count() override; virtual size_t frame_count() override; + virtual size_t first_animated_frame_index() override; virtual ErrorOr frame(size_t index) override; virtual ErrorOr> icc_data() override; diff --git a/Userland/Libraries/LibGfx/ImageFormats/ImageDecoder.h b/Userland/Libraries/LibGfx/ImageFormats/ImageDecoder.h index f44248ee92..b00259177d 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/ImageDecoder.h +++ b/Userland/Libraries/LibGfx/ImageFormats/ImageDecoder.h @@ -39,6 +39,7 @@ public: virtual bool is_animated() = 0; virtual size_t loop_count() = 0; virtual size_t frame_count() = 0; + virtual size_t first_animated_frame_index() = 0; virtual ErrorOr frame(size_t index) = 0; virtual ErrorOr> icc_data() = 0; @@ -59,6 +60,7 @@ public: bool is_animated() const { return m_plugin->is_animated(); } size_t loop_count() const { return m_plugin->loop_count(); } size_t frame_count() const { return m_plugin->frame_count(); } + size_t first_animated_frame_index() const { return m_plugin->first_animated_frame_index(); } ErrorOr frame(size_t index) const { return m_plugin->frame(index); } ErrorOr> icc_data() const { return m_plugin->icc_data(); } diff --git a/Userland/Libraries/LibGfx/ImageFormats/JPEGLoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/JPEGLoader.cpp index 5341c5d16d..aa59cb3e1a 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/JPEGLoader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/JPEGLoader.cpp @@ -1801,6 +1801,11 @@ size_t JPEGImageDecoderPlugin::frame_count() return 1; } +size_t JPEGImageDecoderPlugin::first_animated_frame_index() +{ + return 0; +} + ErrorOr JPEGImageDecoderPlugin::frame(size_t index) { if (index > 0) diff --git a/Userland/Libraries/LibGfx/ImageFormats/JPEGLoader.h b/Userland/Libraries/LibGfx/ImageFormats/JPEGLoader.h index 08186f52af..d78fbb52da 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/JPEGLoader.h +++ b/Userland/Libraries/LibGfx/ImageFormats/JPEGLoader.h @@ -29,6 +29,7 @@ public: virtual bool is_animated() override; virtual size_t loop_count() override; virtual size_t frame_count() override; + virtual size_t first_animated_frame_index() override; virtual ErrorOr frame(size_t index) override; virtual ErrorOr> icc_data() override; diff --git a/Userland/Libraries/LibGfx/ImageFormats/PNGLoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/PNGLoader.cpp index 2ec92ef34f..7ea4e2e6a7 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/PNGLoader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/PNGLoader.cpp @@ -1062,6 +1062,11 @@ size_t PNGImageDecoderPlugin::frame_count() return 1; } +size_t PNGImageDecoderPlugin::first_animated_frame_index() +{ + return 0; +} + ErrorOr PNGImageDecoderPlugin::frame(size_t index) { if (index > 0) diff --git a/Userland/Libraries/LibGfx/ImageFormats/PNGLoader.h b/Userland/Libraries/LibGfx/ImageFormats/PNGLoader.h index b8f7b6097f..1894f006a8 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/PNGLoader.h +++ b/Userland/Libraries/LibGfx/ImageFormats/PNGLoader.h @@ -26,6 +26,7 @@ public: virtual bool is_animated() override; virtual size_t loop_count() override; virtual size_t frame_count() override; + virtual size_t first_animated_frame_index() override; virtual ErrorOr frame(size_t index) override; virtual ErrorOr> icc_data() override; diff --git a/Userland/Libraries/LibGfx/ImageFormats/PortableImageMapLoader.h b/Userland/Libraries/LibGfx/ImageFormats/PortableImageMapLoader.h index 0fff8600de..00df0355b0 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/PortableImageMapLoader.h +++ b/Userland/Libraries/LibGfx/ImageFormats/PortableImageMapLoader.h @@ -71,6 +71,7 @@ public: virtual bool is_animated() override; virtual size_t loop_count() override; virtual size_t frame_count() override; + virtual size_t first_animated_frame_index() override; virtual ErrorOr frame(size_t index) override; virtual ErrorOr> icc_data() override; @@ -160,6 +161,12 @@ size_t PortableImageDecoderPlugin::frame_count() return 1; } +template +size_t PortableImageDecoderPlugin::first_animated_frame_index() +{ + return 0; +} + template ErrorOr PortableImageDecoderPlugin::frame(size_t index) { diff --git a/Userland/Libraries/LibGfx/ImageFormats/QOILoader.h b/Userland/Libraries/LibGfx/ImageFormats/QOILoader.h index e072828018..b48a43e4d3 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/QOILoader.h +++ b/Userland/Libraries/LibGfx/ImageFormats/QOILoader.h @@ -50,6 +50,7 @@ public: virtual bool is_animated() override { return false; } virtual size_t loop_count() override { return 0; } virtual size_t frame_count() override { return 1; } + virtual size_t first_animated_frame_index() override { return 0; } virtual ErrorOr frame(size_t index) override; virtual ErrorOr> icc_data() override; diff --git a/Userland/Libraries/LibGfx/ImageFormats/TGALoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/TGALoader.cpp index 0d5a8e1fea..c388148a62 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/TGALoader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/TGALoader.cpp @@ -257,6 +257,11 @@ size_t TGAImageDecoderPlugin::frame_count() return 1; } +size_t TGAImageDecoderPlugin::first_animated_frame_index() +{ + return 0; +} + ErrorOr TGAImageDecoderPlugin::frame(size_t index) { auto bits_per_pixel = m_context->header.bits_per_pixel; diff --git a/Userland/Libraries/LibGfx/ImageFormats/TGALoader.h b/Userland/Libraries/LibGfx/ImageFormats/TGALoader.h index 70f2719aa1..c33498ecdd 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/TGALoader.h +++ b/Userland/Libraries/LibGfx/ImageFormats/TGALoader.h @@ -27,6 +27,7 @@ public: virtual bool is_animated() override; virtual size_t loop_count() override; virtual size_t frame_count() override; + virtual size_t first_animated_frame_index() override; virtual ErrorOr frame(size_t index) override; virtual ErrorOr> icc_data() override; diff --git a/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp index ac7decce13..26950c116a 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp @@ -1555,6 +1555,11 @@ size_t WebPImageDecoderPlugin::frame_count() return m_context->animation_frame_chunks.size(); } +size_t WebPImageDecoderPlugin::first_animated_frame_index() +{ + return 0; +} + ErrorOr WebPImageDecoderPlugin::frame(size_t index) { if (index >= frame_count()) diff --git a/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.h b/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.h index f7f07a458c..50fd90bb56 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.h +++ b/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.h @@ -26,6 +26,7 @@ public: virtual bool is_animated() override; virtual size_t loop_count() override; virtual size_t frame_count() override; + virtual size_t first_animated_frame_index() override; virtual ErrorOr frame(size_t index) override; virtual ErrorOr> icc_data() override; -- cgit v1.2.3