From 6a23dfbc92ed4dbadacdee6b28a62d13571a3117 Mon Sep 17 00:00:00 2001 From: Lenny Maiorani Date: Sun, 13 Mar 2022 11:58:58 -0600 Subject: LibGfx: Use common class template for PBM/PGM/PPM image loaders PBM, PGM, and PPM image loaders are mostly common. The only difference is how the data is read and the associated magic numbers. The magic numbers are already made common using the loading contexts. Now make the implementations common via a class template which accepts the context to disambiguate. --- Userland/Libraries/LibGfx/PBMLoader.cpp | 89 +--------------- Userland/Libraries/LibGfx/PBMLoader.h | 23 +---- Userland/Libraries/LibGfx/PGMLoader.cpp | 89 +--------------- Userland/Libraries/LibGfx/PGMLoader.h | 23 +---- Userland/Libraries/LibGfx/PPMLoader.cpp | 89 +--------------- Userland/Libraries/LibGfx/PPMLoader.h | 23 +---- Userland/Libraries/LibGfx/PortableImageMapLoader.h | 114 +++++++++++++++++++++ 7 files changed, 123 insertions(+), 327 deletions(-) diff --git a/Userland/Libraries/LibGfx/PBMLoader.cpp b/Userland/Libraries/LibGfx/PBMLoader.cpp index 795437ba8f..8a60c851ff 100644 --- a/Userland/Libraries/LibGfx/PBMLoader.cpp +++ b/Userland/Libraries/LibGfx/PBMLoader.cpp @@ -13,7 +13,7 @@ namespace Gfx { -static bool read_image_data(PBMLoadingContext& context, Streamer& streamer) +bool read_image_data(PBMLoadingContext& context, Streamer& streamer) { u8 byte; Vector color_data; @@ -64,91 +64,4 @@ static bool read_image_data(PBMLoadingContext& context, Streamer& streamer) context.state = PBMLoadingContext::State::Bitmap; return true; } - -PBMImageDecoderPlugin::PBMImageDecoderPlugin(const u8* data, size_t size) -{ - m_context = make(); - m_context->data = data; - m_context->data_size = size; -} - -PBMImageDecoderPlugin::~PBMImageDecoderPlugin() -{ -} - -IntSize PBMImageDecoderPlugin::size() -{ - if (m_context->state == PBMLoadingContext::State::Error) - return {}; - - if (m_context->state < PBMLoadingContext::State::Decoded) { - bool success = decode(*m_context); - if (!success) - return {}; - } - - return { m_context->width, m_context->height }; -} - -void PBMImageDecoderPlugin::set_volatile() -{ - if (m_context->bitmap) - m_context->bitmap->set_volatile(); -} - -bool PBMImageDecoderPlugin::set_nonvolatile(bool& was_purged) -{ - if (!m_context->bitmap) - return false; - - return m_context->bitmap->set_nonvolatile(was_purged); -} - -bool PBMImageDecoderPlugin::sniff() -{ - if (m_context->data_size < 2) - return false; - - if (m_context->data[0] == 'P' && m_context->data[1] == '1') - return true; - - if (m_context->data[0] == 'P' && m_context->data[1] == '4') - return true; - - return false; -} - -bool PBMImageDecoderPlugin::is_animated() -{ - return false; -} - -size_t PBMImageDecoderPlugin::loop_count() -{ - return 0; -} - -size_t PBMImageDecoderPlugin::frame_count() -{ - return 1; -} - -ErrorOr PBMImageDecoderPlugin::frame(size_t index) -{ - if (index > 0) - return Error::from_string_literal("PBMImageDecoderPlugin: Invalid frame index"sv); - - if (m_context->state == PBMLoadingContext::State::Error) - return Error::from_string_literal("PBMImageDecoderPlugin: Decoding failed"sv); - - if (m_context->state < PBMLoadingContext::State::Decoded) { - bool success = decode(*m_context); - if (!success) - return Error::from_string_literal("PBMImageDecoderPlugin: Decoding failed"sv); - } - - VERIFY(m_context->bitmap); - return ImageFrameDescriptor { m_context->bitmap, 0 }; -} - } diff --git a/Userland/Libraries/LibGfx/PBMLoader.h b/Userland/Libraries/LibGfx/PBMLoader.h index db223a11f7..8c402de31f 100644 --- a/Userland/Libraries/LibGfx/PBMLoader.h +++ b/Userland/Libraries/LibGfx/PBMLoader.h @@ -20,26 +20,7 @@ struct PBM { }; using PBMLoadingContext = PortableImageMapLoadingContext; +using PBMImageDecoderPlugin = PortableImageDecoderPlugin; -class PBMImageDecoderPlugin final : public ImageDecoderPlugin { -public: - PBMImageDecoderPlugin(const u8*, size_t); - virtual ~PBMImageDecoderPlugin() override; - - virtual IntSize size() override; - - virtual void set_volatile() override; - [[nodiscard]] virtual bool set_nonvolatile(bool& was_purged) override; - - virtual bool sniff() override; - - virtual bool is_animated() override; - virtual size_t loop_count() override; - virtual size_t frame_count() override; - virtual ErrorOr frame(size_t index) override; - -private: - OwnPtr m_context; -}; - +bool read_image_data(PBMLoadingContext& context, Streamer& streamer); } diff --git a/Userland/Libraries/LibGfx/PGMLoader.cpp b/Userland/Libraries/LibGfx/PGMLoader.cpp index 1550673fea..6e52ef0815 100644 --- a/Userland/Libraries/LibGfx/PGMLoader.cpp +++ b/Userland/Libraries/LibGfx/PGMLoader.cpp @@ -28,7 +28,7 @@ static void set_adjusted_pixels(PGMLoadingContext& context, const Vector color_data; @@ -65,91 +65,4 @@ static bool read_image_data(PGMLoadingContext& context, Streamer& streamer) context.state = PGMLoadingContext::State::Bitmap; return true; } - -PGMImageDecoderPlugin::PGMImageDecoderPlugin(const u8* data, size_t size) -{ - m_context = make(); - m_context->data = data; - m_context->data_size = size; -} - -PGMImageDecoderPlugin::~PGMImageDecoderPlugin() -{ -} - -IntSize PGMImageDecoderPlugin::size() -{ - if (m_context->state == PGMLoadingContext::State::Error) - return {}; - - if (m_context->state < PGMLoadingContext::State::Decoded) { - bool success = decode(*m_context); - if (!success) - return {}; - } - - return { m_context->width, m_context->height }; -} - -void PGMImageDecoderPlugin::set_volatile() -{ - if (m_context->bitmap) - m_context->bitmap->set_volatile(); -} - -bool PGMImageDecoderPlugin::set_nonvolatile(bool& was_purged) -{ - if (!m_context->bitmap) - return false; - - return m_context->bitmap->set_nonvolatile(was_purged); -} - -bool PGMImageDecoderPlugin::sniff() -{ - if (m_context->data_size < 2) - return false; - - if (m_context->data[0] == 'P' && m_context->data[1] == '2') - return true; - - if (m_context->data[0] == 'P' && m_context->data[1] == '5') - return true; - - return false; -} - -bool PGMImageDecoderPlugin::is_animated() -{ - return false; -} - -size_t PGMImageDecoderPlugin::loop_count() -{ - return 0; -} - -size_t PGMImageDecoderPlugin::frame_count() -{ - return 1; -} - -ErrorOr PGMImageDecoderPlugin::frame(size_t index) -{ - if (index > 0) - return Error::from_string_literal("PGMImageDecoderPlugin: Invalid frame index"sv); - - if (m_context->state == PGMLoadingContext::State::Error) - return Error::from_string_literal("PGMImageDecoderPlugin: Decoding failed"sv); - - if (m_context->state < PGMLoadingContext::State::Decoded) { - bool success = decode(*m_context); - if (!success) - return Error::from_string_literal("PGMImageDecoderPlugin: Decoding failed"sv); - } - - VERIFY(m_context->bitmap); - return ImageFrameDescriptor { m_context->bitmap, 0 }; -} - } diff --git a/Userland/Libraries/LibGfx/PGMLoader.h b/Userland/Libraries/LibGfx/PGMLoader.h index 805a9a92b7..5783104dc8 100644 --- a/Userland/Libraries/LibGfx/PGMLoader.h +++ b/Userland/Libraries/LibGfx/PGMLoader.h @@ -21,26 +21,7 @@ struct PGM { }; using PGMLoadingContext = PortableImageMapLoadingContext; +using PGMImageDecoderPlugin = PortableImageDecoderPlugin; -class PGMImageDecoderPlugin final : public ImageDecoderPlugin { -public: - PGMImageDecoderPlugin(const u8*, size_t); - virtual ~PGMImageDecoderPlugin() override; - - virtual IntSize size() override; - - virtual void set_volatile() override; - [[nodiscard]] virtual bool set_nonvolatile(bool& was_purged) override; - - virtual bool sniff() override; - - virtual bool is_animated() override; - virtual size_t loop_count() override; - virtual size_t frame_count() override; - virtual ErrorOr frame(size_t index) override; - -private: - OwnPtr m_context; -}; - +bool read_image_data(PGMLoadingContext& context, Streamer& streamer); } diff --git a/Userland/Libraries/LibGfx/PPMLoader.cpp b/Userland/Libraries/LibGfx/PPMLoader.cpp index 9429869048..720cc7a5e7 100644 --- a/Userland/Libraries/LibGfx/PPMLoader.cpp +++ b/Userland/Libraries/LibGfx/PPMLoader.cpp @@ -16,7 +16,7 @@ namespace Gfx { -static bool read_image_data(PPMLoadingContext& context, Streamer& streamer) +bool read_image_data(PPMLoadingContext& context, Streamer& streamer) { Vector color_data; color_data.ensure_capacity(context.width * context.height); @@ -69,91 +69,4 @@ static bool read_image_data(PPMLoadingContext& context, Streamer& streamer) context.state = PPMLoadingContext::State::Bitmap; return true; } - -PPMImageDecoderPlugin::PPMImageDecoderPlugin(const u8* data, size_t size) -{ - m_context = make(); - m_context->data = data; - m_context->data_size = size; -} - -PPMImageDecoderPlugin::~PPMImageDecoderPlugin() -{ -} - -IntSize PPMImageDecoderPlugin::size() -{ - if (m_context->state == PPMLoadingContext::State::Error) - return {}; - - if (m_context->state < PPMLoadingContext::State::Decoded) { - bool success = decode(*m_context); - if (!success) - return {}; - } - - return { m_context->width, m_context->height }; -} - -void PPMImageDecoderPlugin::set_volatile() -{ - if (m_context->bitmap) - m_context->bitmap->set_volatile(); -} - -bool PPMImageDecoderPlugin::set_nonvolatile(bool& was_purged) -{ - if (!m_context->bitmap) - return false; - - return m_context->bitmap->set_nonvolatile(was_purged); -} - -bool PPMImageDecoderPlugin::sniff() -{ - if (m_context->data_size < 2) - return false; - - if (m_context->data[0] == 'P' && m_context->data[1] == '3') - return true; - - if (m_context->data[0] == 'P' && m_context->data[1] == '6') - return true; - - return false; -} - -bool PPMImageDecoderPlugin::is_animated() -{ - return false; -} - -size_t PPMImageDecoderPlugin::loop_count() -{ - return 0; -} - -size_t PPMImageDecoderPlugin::frame_count() -{ - return 1; -} - -ErrorOr PPMImageDecoderPlugin::frame(size_t index) -{ - if (index > 0) - return Error::from_string_literal("PPMImageDecoderPlugin: Invalid frame index"sv); - - if (m_context->state == PPMLoadingContext::State::Error) - return Error::from_string_literal("PGMImageDecoderPlugin: Decoding failed"sv); - - if (m_context->state < PPMLoadingContext::State::Decoded) { - bool success = decode(*m_context); - if (!success) - return Error::from_string_literal("PGMImageDecoderPlugin: Decoding failed"sv); - } - - VERIFY(m_context->bitmap); - return ImageFrameDescriptor { m_context->bitmap, 0 }; -} - } diff --git a/Userland/Libraries/LibGfx/PPMLoader.h b/Userland/Libraries/LibGfx/PPMLoader.h index 572e2170d3..2d91640005 100644 --- a/Userland/Libraries/LibGfx/PPMLoader.h +++ b/Userland/Libraries/LibGfx/PPMLoader.h @@ -21,26 +21,7 @@ struct PPM { }; using PPMLoadingContext = PortableImageMapLoadingContext; +using PPMImageDecoderPlugin = PortableImageDecoderPlugin; -class PPMImageDecoderPlugin final : public ImageDecoderPlugin { -public: - PPMImageDecoderPlugin(const u8*, size_t); - virtual ~PPMImageDecoderPlugin() override; - - virtual IntSize size() override; - - virtual void set_volatile() override; - [[nodiscard]] virtual bool set_nonvolatile(bool& was_purged) override; - - virtual bool sniff() override; - - virtual bool is_animated() override; - virtual size_t loop_count() override; - virtual size_t frame_count() override; - virtual ErrorOr frame(size_t index) override; - -private: - OwnPtr m_context; -}; - +bool read_image_data(PPMLoadingContext& context, Streamer& streamer); } diff --git a/Userland/Libraries/LibGfx/PortableImageMapLoader.h b/Userland/Libraries/LibGfx/PortableImageMapLoader.h index 0a81f20dc8..f854cd75eb 100644 --- a/Userland/Libraries/LibGfx/PortableImageMapLoader.h +++ b/Userland/Libraries/LibGfx/PortableImageMapLoader.h @@ -11,6 +11,7 @@ #include #include #include +#include namespace Gfx { @@ -45,4 +46,117 @@ struct PortableImageMapLoadingContext { RefPtr bitmap; }; +template +class PortableImageDecoderPlugin final : public ImageDecoderPlugin { +public: + PortableImageDecoderPlugin(const u8*, size_t); + virtual ~PortableImageDecoderPlugin() override = default; + + virtual IntSize size() override; + + virtual void set_volatile() override; + [[nodiscard]] virtual bool set_nonvolatile(bool& was_purged) override; + + virtual bool sniff() override; + + virtual bool is_animated() override; + virtual size_t loop_count() override; + virtual size_t frame_count() override; + virtual ErrorOr frame(size_t index) override; + +private: + OwnPtr m_context; +}; + +template +PortableImageDecoderPlugin::PortableImageDecoderPlugin(const u8* data, size_t size) +{ + m_context = make(); + m_context->data = data; + m_context->data_size = size; +} + +template +IntSize PortableImageDecoderPlugin::size() +{ + if (m_context->state == TContext::State::Error) + return {}; + + if (m_context->state < TContext::State::Decoded) { + bool success = decode(*m_context); + if (!success) + return {}; + } + + return { m_context->width, m_context->height }; +} + +template +void PortableImageDecoderPlugin::set_volatile() +{ + if (m_context->bitmap) + m_context->bitmap->set_volatile(); +} + +template +bool PortableImageDecoderPlugin::set_nonvolatile(bool& was_purged) +{ + if (!m_context->bitmap) + return false; + + return m_context->bitmap->set_nonvolatile(was_purged); +} + +template +bool PortableImageDecoderPlugin::sniff() +{ + using Context = TContext; + if (m_context->data_size < 2) + return false; + + if (m_context->data[0] == 'P' && m_context->data[1] == Context::FormatDetails::ascii_magic_number) + return true; + + if (m_context->data[0] == 'P' && m_context->data[1] == Context::FormatDetails::binary_magic_number) + return true; + + return false; +} + +template +bool PortableImageDecoderPlugin::is_animated() +{ + return false; +} + +template +size_t PortableImageDecoderPlugin::loop_count() +{ + return 0; +} + +template +size_t PortableImageDecoderPlugin::frame_count() +{ + return 1; +} + +template +ErrorOr PortableImageDecoderPlugin::frame(size_t index) +{ + if (index > 0) + return Error::from_string_literal("PortableImageDecoderPlugin: Invalid frame index"sv); + + if (m_context->state == TContext::State::Error) + return Error::from_string_literal("PortableImageDecoderPlugin: Decoding failed"sv); + + if (m_context->state < TContext::State::Decoded) { + bool success = decode(*m_context); + if (!success) + return Error::from_string_literal("PortableImageDecoderPlugin: Decoding failed"sv); + } + + VERIFY(m_context->bitmap); + return ImageFrameDescriptor { m_context->bitmap, 0 }; +} } -- cgit v1.2.3