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

LibGfx/BMP: Decode the header in create() and remove initialize()

This is done as a part of #19893.
This commit is contained in:
Lucas CHOLLET 2023-07-16 21:55:07 -04:00 committed by Sam Atkins
parent 7b72bf2910
commit c336cef065
2 changed files with 11 additions and 28 deletions

View file

@ -191,7 +191,6 @@ enum class DIBType {
struct BMPLoadingContext { struct BMPLoadingContext {
enum class State { enum class State {
NotDecoded = 0, NotDecoded = 0,
HeaderDecoded,
DIBDecoded, DIBDecoded,
ColorTableDecoded, ColorTableDecoded,
PixelDataDecoded, PixelDataDecoded,
@ -494,12 +493,6 @@ static bool set_dib_bitmasks(BMPLoadingContext& context, InputStreamer& streamer
static ErrorOr<void> decode_bmp_header(BMPLoadingContext& context) static ErrorOr<void> decode_bmp_header(BMPLoadingContext& context)
{ {
if (context.state == BMPLoadingContext::State::Error)
return Error::from_string_literal("Error before starting decode_bmp_header");
if (context.state >= BMPLoadingContext::State::HeaderDecoded)
return {};
if (!context.file_bytes || context.file_size < bmp_header_size) { if (!context.file_bytes || context.file_size < bmp_header_size) {
dbgln_if(BMP_DEBUG, "Missing BMP header"); dbgln_if(BMP_DEBUG, "Missing BMP header");
context.state = BMPLoadingContext::State::Error; context.state = BMPLoadingContext::State::Error;
@ -536,7 +529,6 @@ static ErrorOr<void> decode_bmp_header(BMPLoadingContext& context)
return Error::from_string_literal("BMP data offset is beyond file end"); return Error::from_string_literal("BMP data offset is beyond file end");
} }
context.state = BMPLoadingContext::State::HeaderDecoded;
return {}; return {};
} }
@ -823,7 +815,7 @@ static ErrorOr<void> decode_bmp_dib(BMPLoadingContext& context)
if (context.state >= BMPLoadingContext::State::DIBDecoded) if (context.state >= BMPLoadingContext::State::DIBDecoded)
return {}; return {};
if (!context.is_included_in_ico && context.state < BMPLoadingContext::State::HeaderDecoded) if (!context.is_included_in_ico)
TRY(decode_bmp_header(context)); TRY(decode_bmp_header(context));
u8 header_size = context.is_included_in_ico ? 0 : bmp_header_size; u8 header_size = context.is_included_in_ico ? 0 : bmp_header_size;
@ -936,9 +928,6 @@ static ErrorOr<void> decode_bmp_color_table(BMPLoadingContext& context)
if (context.state == BMPLoadingContext::State::Error) if (context.state == BMPLoadingContext::State::Error)
return Error::from_string_literal("Error before starting decode_bmp_color_table"); return Error::from_string_literal("Error before starting decode_bmp_color_table");
if (context.state < BMPLoadingContext::State::DIBDecoded)
TRY(decode_bmp_dib(context));
if (context.state >= BMPLoadingContext::State::ColorTableDecoded) if (context.state >= BMPLoadingContext::State::ColorTableDecoded)
return {}; return {};
@ -1478,20 +1467,9 @@ BMPImageDecoderPlugin::~BMPImageDecoderPlugin() = default;
IntSize BMPImageDecoderPlugin::size() IntSize BMPImageDecoderPlugin::size()
{ {
if (m_context->state == BMPLoadingContext::State::Error)
return {};
if (m_context->state < BMPLoadingContext::State::DIBDecoded && decode_bmp_dib(*m_context).is_error())
return {};
return { m_context->dib.core.width, abs(m_context->dib.core.height) }; return { m_context->dib.core.width, abs(m_context->dib.core.height) };
} }
ErrorOr<void> BMPImageDecoderPlugin::initialize()
{
return decode_bmp_header(*m_context);
}
bool BMPImageDecoderPlugin::sniff(ReadonlyBytes data) bool BMPImageDecoderPlugin::sniff(ReadonlyBytes data)
{ {
BMPLoadingContext context; BMPLoadingContext context;
@ -1500,14 +1478,21 @@ bool BMPImageDecoderPlugin::sniff(ReadonlyBytes data)
return !decode_bmp_header(context).is_error(); return !decode_bmp_header(context).is_error();
} }
ErrorOr<NonnullOwnPtr<BMPImageDecoderPlugin>> BMPImageDecoderPlugin::create_impl(ReadonlyBytes data, IncludedInICO included_in_ico)
{
auto plugin = TRY(adopt_nonnull_own_or_enomem(new (nothrow) BMPImageDecoderPlugin(data.data(), data.size(), included_in_ico)));
TRY(decode_bmp_dib(*plugin->m_context));
return plugin;
}
ErrorOr<NonnullOwnPtr<ImageDecoderPlugin>> BMPImageDecoderPlugin::create(ReadonlyBytes data) ErrorOr<NonnullOwnPtr<ImageDecoderPlugin>> BMPImageDecoderPlugin::create(ReadonlyBytes data)
{ {
return adopt_nonnull_own_or_enomem(new (nothrow) BMPImageDecoderPlugin(data.data(), data.size())); return create_impl(data, IncludedInICO::No);
} }
ErrorOr<NonnullOwnPtr<BMPImageDecoderPlugin>> BMPImageDecoderPlugin::create_as_included_in_ico(Badge<ICOImageDecoderPlugin>, ReadonlyBytes data) ErrorOr<NonnullOwnPtr<BMPImageDecoderPlugin>> BMPImageDecoderPlugin::create_as_included_in_ico(Badge<ICOImageDecoderPlugin>, ReadonlyBytes data)
{ {
return adopt_nonnull_own_or_enomem(new (nothrow) BMPImageDecoderPlugin(data.data(), data.size(), IncludedInICO::Yes)); return create_impl(data, IncludedInICO::Yes);
} }
bool BMPImageDecoderPlugin::sniff_dib() bool BMPImageDecoderPlugin::sniff_dib()
@ -1552,8 +1537,6 @@ ErrorOr<ImageFrameDescriptor> BMPImageDecoderPlugin::frame(size_t index, Optiona
ErrorOr<Optional<ReadonlyBytes>> BMPImageDecoderPlugin::icc_data() ErrorOr<Optional<ReadonlyBytes>> BMPImageDecoderPlugin::icc_data()
{ {
TRY(decode_bmp_dib(*m_context));
if (m_context->dib_type != DIBType::V5) if (m_context->dib_type != DIBType::V5)
return OptionalNone {}; return OptionalNone {};

View file

@ -29,7 +29,6 @@ public:
virtual IntSize size() override; virtual IntSize size() override;
virtual ErrorOr<void> initialize() override;
bool sniff_dib(); bool sniff_dib();
virtual bool is_animated() override; virtual bool is_animated() override;
virtual size_t loop_count() override; virtual size_t loop_count() override;
@ -40,6 +39,7 @@ public:
private: private:
BMPImageDecoderPlugin(u8 const*, size_t, IncludedInICO included_in_ico = IncludedInICO::No); BMPImageDecoderPlugin(u8 const*, size_t, IncludedInICO included_in_ico = IncludedInICO::No);
static ErrorOr<NonnullOwnPtr<BMPImageDecoderPlugin>> create_impl(ReadonlyBytes, IncludedInICO);
OwnPtr<BMPLoadingContext> m_context; OwnPtr<BMPLoadingContext> m_context;
}; };