1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 17:27:35 +00:00

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. :^)
This commit is contained in:
Andreas Kling 2020-06-13 15:28:04 +02:00
parent e46ee46ed6
commit dc0ed5c860
2 changed files with 20 additions and 12 deletions

View file

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

View file

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