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

LibGfx: Improve ImageDecoder construction

Previously, ImageDecoder::create() would return a NonnullRefPtr and
could not "fail", although the returned decoder may be "invalid" which
you then had to check anyway.

The new interface looks like this:

    static RefPtr<Gfx::ImageDecoder> try_create(ReadonlyBytes);

This simplifies ImageDecoder since it no longer has to worry about its
validity. Client code gets slightly clearer as well.
This commit is contained in:
Andreas Kling 2021-07-27 01:12:53 +02:00
parent c6f4ecced9
commit d01b4327fa
6 changed files with 77 additions and 58 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -17,45 +17,61 @@
namespace Gfx {
ImageDecoder::ImageDecoder(const u8* data, size_t size)
RefPtr<ImageDecoder> ImageDecoder::try_create(ReadonlyBytes bytes)
{
m_plugin = make<PNGImageDecoderPlugin>(data, size);
if (m_plugin->sniff())
return;
auto* data = bytes.data();
auto size = bytes.size();
m_plugin = make<GIFImageDecoderPlugin>(data, size);
if (m_plugin->sniff())
return;
auto plugin = [](auto* data, auto size) -> OwnPtr<ImageDecoderPlugin> {
OwnPtr<ImageDecoderPlugin> plugin;
m_plugin = make<BMPImageDecoderPlugin>(data, size);
if (m_plugin->sniff())
return;
plugin = make<PNGImageDecoderPlugin>(data, size);
if (plugin->sniff())
return plugin;
m_plugin = make<PBMImageDecoderPlugin>(data, size);
if (m_plugin->sniff())
return;
plugin = make<GIFImageDecoderPlugin>(data, size);
if (plugin->sniff())
return plugin;
m_plugin = make<PGMImageDecoderPlugin>(data, size);
if (m_plugin->sniff())
return;
plugin = make<BMPImageDecoderPlugin>(data, size);
if (plugin->sniff())
return plugin;
m_plugin = make<PPMImageDecoderPlugin>(data, size);
if (m_plugin->sniff())
return;
plugin = make<PBMImageDecoderPlugin>(data, size);
if (plugin->sniff())
return plugin;
m_plugin = make<ICOImageDecoderPlugin>(data, size);
if (m_plugin->sniff())
return;
plugin = make<PGMImageDecoderPlugin>(data, size);
if (plugin->sniff())
return plugin;
m_plugin = make<JPGImageDecoderPlugin>(data, size);
if (m_plugin->sniff())
return;
plugin = make<PPMImageDecoderPlugin>(data, size);
if (plugin->sniff())
return plugin;
m_plugin = make<DDSImageDecoderPlugin>(data, size);
if (m_plugin->sniff())
return;
plugin = make<ICOImageDecoderPlugin>(data, size);
if (plugin->sniff())
return plugin;
m_plugin = nullptr;
plugin = make<JPGImageDecoderPlugin>(data, size);
if (plugin->sniff())
return plugin;
plugin = make<DDSImageDecoderPlugin>(data, size);
if (plugin->sniff())
return plugin;
return {};
}(data, size);
if (!plugin)
return {};
return adopt_ref_if_nonnull(new (nothrow) ImageDecoder(plugin.release_nonnull()));
}
ImageDecoder::ImageDecoder(NonnullOwnPtr<ImageDecoderPlugin> plugin)
: m_plugin(move(plugin))
{
}
ImageDecoder::~ImageDecoder()
@ -64,8 +80,6 @@ ImageDecoder::~ImageDecoder()
RefPtr<Gfx::Bitmap> ImageDecoder::bitmap() const
{
if (!m_plugin)
return nullptr;
return m_plugin->bitmap();
}