Ver Fonte

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.
Peter Nelson há 5 anos atrás
pai
commit
d22bb92764

+ 24 - 0
Libraries/LibGfx/GIFLoader.cpp

@@ -528,4 +528,28 @@ bool GIFImageDecoderPlugin::sniff()
     BufferStream stream(buffer);
     BufferStream stream(buffer);
     return decode_gif_header(stream).has_value();
     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 {};
+}
+
 }
 }

+ 4 - 0
Libraries/LibGfx/GIFLoader.h

@@ -46,6 +46,10 @@ public:
     virtual void set_volatile() override;
     virtual void set_volatile() override;
     [[nodiscard]] virtual bool set_nonvolatile() override;
     [[nodiscard]] virtual bool set_nonvolatile() override;
     virtual bool sniff() 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:
 private:
     OwnPtr<GIFLoadingContext> m_context;
     OwnPtr<GIFLoadingContext> m_context;

+ 16 - 2
Libraries/LibGfx/ImageDecoder.h

@@ -26,15 +26,20 @@
 
 
 #pragma once
 #pragma once
 
 
-#include <AK/NonnullRefPtr.h>
 #include <AK/OwnPtr.h>
 #include <AK/OwnPtr.h>
 #include <AK/RefCounted.h>
 #include <AK/RefCounted.h>
+#include <AK/RefPtr.h>
 #include <LibGfx/Size.h>
 #include <LibGfx/Size.h>
 
 
 namespace Gfx {
 namespace Gfx {
 
 
 class Bitmap;
 class Bitmap;
 
 
+struct ImageFrameDescriptor {
+    RefPtr<Bitmap> image;
+    int duration { 0 };
+};
+
 class ImageDecoderPlugin {
 class ImageDecoderPlugin {
 public:
 public:
     virtual ~ImageDecoderPlugin() {}
     virtual ~ImageDecoderPlugin() {}
@@ -47,6 +52,11 @@ public:
 
 
     virtual bool sniff() = 0;
     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:
 protected:
     ImageDecoderPlugin() {}
     ImageDecoderPlugin() {}
 };
 };
@@ -62,7 +72,11 @@ public:
     RefPtr<Gfx::Bitmap> bitmap() const;
     RefPtr<Gfx::Bitmap> bitmap() const;
     void set_volatile() { m_plugin->set_volatile(); }
     void set_volatile() { m_plugin->set_volatile(); }
     [[nodiscard]] bool set_nonvolatile() { return m_plugin->set_nonvolatile(); }
     [[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:
 private:
     ImageDecoder(const u8*, size_t);
     ImageDecoder(const u8*, size_t);

+ 23 - 0
Libraries/LibGfx/PNGLoader.cpp

@@ -834,4 +834,27 @@ bool PNGImageDecoderPlugin::sniff()
     return decode_png_header(*m_context);
     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 {};
+}
+
 }
 }

+ 4 - 0
Libraries/LibGfx/PNGLoader.h

@@ -46,6 +46,10 @@ public:
     virtual void set_volatile() override;
     virtual void set_volatile() override;
     [[nodiscard]] virtual bool set_nonvolatile() override;
     [[nodiscard]] virtual bool set_nonvolatile() override;
     virtual bool sniff() 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:
 private:
     OwnPtr<PNGLoadingContext> m_context;
     OwnPtr<PNGLoadingContext> m_context;