From d22bb9276454937aa19a9bc867839e02434b0c30 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 3 May 2020 17:12:54 +0100 Subject: [PATCH] LibGfx: Add support for animated images to ImageDecoder{Plugin} Adds methods to determine whether an image is animated, how many times the animation loops, the number of frames, and to get individual frames. Implements stubs of these methods for PNGImageDecoderPlugin and GIFImageDecoderPlugin. --- Libraries/LibGfx/GIFLoader.cpp | 24 ++++++++++++++++++++++++ Libraries/LibGfx/GIFLoader.h | 4 ++++ Libraries/LibGfx/ImageDecoder.h | 18 ++++++++++++++++-- Libraries/LibGfx/PNGLoader.cpp | 23 +++++++++++++++++++++++ Libraries/LibGfx/PNGLoader.h | 4 ++++ 5 files changed, 71 insertions(+), 2 deletions(-) diff --git a/Libraries/LibGfx/GIFLoader.cpp b/Libraries/LibGfx/GIFLoader.cpp index df792891dc4..559946cc774 100644 --- a/Libraries/LibGfx/GIFLoader.cpp +++ b/Libraries/LibGfx/GIFLoader.cpp @@ -528,4 +528,28 @@ bool GIFImageDecoderPlugin::sniff() BufferStream stream(buffer); return decode_gif_header(stream).has_value(); } + +bool GIFImageDecoderPlugin::is_animated() +{ + return false; +} + +size_t GIFImageDecoderPlugin::loop_count() +{ + return 0; +} + +size_t GIFImageDecoderPlugin::frame_count() +{ + return 1; +} + +ImageFrameDescriptor GIFImageDecoderPlugin::frame(size_t i) +{ + if (i > 0) { + return { bitmap(), 0 }; + } + return {}; +} + } diff --git a/Libraries/LibGfx/GIFLoader.h b/Libraries/LibGfx/GIFLoader.h index b6599e4b7bd..b76b131d19b 100644 --- a/Libraries/LibGfx/GIFLoader.h +++ b/Libraries/LibGfx/GIFLoader.h @@ -46,6 +46,10 @@ public: virtual void set_volatile() override; [[nodiscard]] virtual bool set_nonvolatile() override; virtual bool sniff() override; + virtual bool is_animated() override; + virtual size_t loop_count() override; + virtual size_t frame_count() override; + virtual ImageFrameDescriptor frame(size_t i) override; private: OwnPtr m_context; diff --git a/Libraries/LibGfx/ImageDecoder.h b/Libraries/LibGfx/ImageDecoder.h index f300cb4871e..bcc08c675cf 100644 --- a/Libraries/LibGfx/ImageDecoder.h +++ b/Libraries/LibGfx/ImageDecoder.h @@ -26,15 +26,20 @@ #pragma once -#include #include #include +#include #include namespace Gfx { class Bitmap; +struct ImageFrameDescriptor { + RefPtr image; + int duration { 0 }; +}; + class ImageDecoderPlugin { public: virtual ~ImageDecoderPlugin() {} @@ -47,6 +52,11 @@ public: virtual bool sniff() = 0; + virtual bool is_animated() = 0; + virtual size_t loop_count() = 0; + virtual size_t frame_count() = 0; + virtual ImageFrameDescriptor frame(size_t i) = 0; + protected: ImageDecoderPlugin() {} }; @@ -62,7 +72,11 @@ public: RefPtr bitmap() const; void set_volatile() { m_plugin->set_volatile(); } [[nodiscard]] bool set_nonvolatile() { return m_plugin->set_nonvolatile(); } - bool sniff() { return m_plugin->sniff(); }; + bool sniff() const { return m_plugin->sniff(); } + 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(); } + ImageFrameDescriptor frame(size_t i) const { return m_plugin->frame(i); } private: ImageDecoder(const u8*, size_t); diff --git a/Libraries/LibGfx/PNGLoader.cpp b/Libraries/LibGfx/PNGLoader.cpp index 78a3b5a73ae..ca7d5136b49 100644 --- a/Libraries/LibGfx/PNGLoader.cpp +++ b/Libraries/LibGfx/PNGLoader.cpp @@ -834,4 +834,27 @@ bool PNGImageDecoderPlugin::sniff() return decode_png_header(*m_context); } +bool PNGImageDecoderPlugin::is_animated() +{ + return false; +} + +size_t PNGImageDecoderPlugin::loop_count() +{ + return 0; +} + +size_t PNGImageDecoderPlugin::frame_count() +{ + return 1; +} + +ImageFrameDescriptor PNGImageDecoderPlugin::frame(size_t i) +{ + if (i > 0) { + return { bitmap(), 0 }; + } + return {}; +} + } diff --git a/Libraries/LibGfx/PNGLoader.h b/Libraries/LibGfx/PNGLoader.h index 7403cdeba55..d6820b931d6 100644 --- a/Libraries/LibGfx/PNGLoader.h +++ b/Libraries/LibGfx/PNGLoader.h @@ -46,6 +46,10 @@ public: virtual void set_volatile() override; [[nodiscard]] virtual bool set_nonvolatile() override; virtual bool sniff() override; + virtual bool is_animated() override; + virtual size_t loop_count() override; + virtual size_t frame_count() override; + virtual ImageFrameDescriptor frame(size_t i) override; private: OwnPtr m_context;