Browse Source

LibGfx: Don't keep an unused GIF decoder plugin in failed ImageDecoders

If we can't decode the input data, just have a null decoder. In this
state we simply return a null bitmap and whatever empty values make
sense for each API.

This way, we don't try to decode the same thing over and over since
it's not gonna work anyway. :^)
Andreas Kling 5 năm trước cách đây
mục cha
commit
dc0ed5c860
2 tập tin đã thay đổi với 20 bổ sung12 xóa
  1. 6 4
      Libraries/LibGfx/ImageDecoder.cpp
  2. 14 8
      Libraries/LibGfx/ImageDecoder.h

+ 6 - 4
Libraries/LibGfx/ImageDecoder.cpp

@@ -33,14 +33,14 @@ namespace Gfx {
 ImageDecoder::ImageDecoder(const u8* data, size_t size)
 {
     m_plugin = make<PNGImageDecoderPlugin>(data, size);
-    if (m_plugin->sniff()) {
+    if (m_plugin->sniff())
         return;
-    }
 
     m_plugin = make<GIFImageDecoderPlugin>(data, size);
-    if (m_plugin->sniff()) {
+    if (m_plugin->sniff())
         return;
-    }
+
+    m_plugin = nullptr;
 }
 
 ImageDecoder::~ImageDecoder()
@@ -49,6 +49,8 @@ ImageDecoder::~ImageDecoder()
 
 RefPtr<Gfx::Bitmap> ImageDecoder::bitmap() const
 {
+    if (!m_plugin)
+        return nullptr;
     return m_plugin->bitmap();
 }
 

+ 14 - 8
Libraries/LibGfx/ImageDecoder.h

@@ -68,17 +68,23 @@ public:
     static NonnullRefPtr<ImageDecoder> create(const ByteBuffer& data) { return adopt(*new ImageDecoder(data.data(), data.size())); }
     ~ImageDecoder();
 
-    IntSize size() const { return m_plugin->size(); }
+    bool is_valid() const { return m_plugin; }
+
+    IntSize size() const { return m_plugin ? m_plugin->size() : IntSize(); }
     int width() const { return size().width(); }
     int height() const { return size().height(); }
     RefPtr<Gfx::Bitmap> bitmap() const;
-    void set_volatile() { m_plugin->set_volatile(); }
-    [[nodiscard]] bool set_nonvolatile() { return m_plugin->set_nonvolatile(); }
-    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); }
+    void set_volatile()
+    {
+        if (m_plugin)
+            m_plugin->set_volatile();
+    }
+    [[nodiscard]] bool set_nonvolatile() { return m_plugin ? m_plugin->set_nonvolatile() : false; }
+    bool sniff() const { return m_plugin ? m_plugin->sniff() : false; }
+    bool is_animated() const { return m_plugin ? m_plugin->is_animated() : false; }
+    size_t loop_count() const { return m_plugin ? m_plugin->loop_count() : 0; }
+    size_t frame_count() const { return m_plugin ? m_plugin->frame_count() : 0; }
+    ImageFrameDescriptor frame(size_t i) const { return m_plugin ? m_plugin->frame(i) : ImageFrameDescriptor(); }
 
 private:
     ImageDecoder(const u8*, size_t);