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

LibGfx: Add a .pam loader

.pam is a "portrable arbitrarymap" as documented at
https://netpbm.sourceforge.net/doc/pam.html

It's very similar to .pbm, .pgm, and .ppm, so this uses the
PortableImageMapLoader framework. The header is slightly different,
so this has a custom header parsing function.

Also, .pam only exixts in binary form, so the ascii form support
becomes optional.
This commit is contained in:
Nico Weber 2024-01-24 21:27:24 -05:00 committed by Andreas Kling
parent 0d76a9da17
commit 187862ebe0
9 changed files with 173 additions and 9 deletions

View file

@ -29,7 +29,7 @@ static constexpr Color adjust_color(u16 max_val, Color color)
return color;
}
static inline ErrorOr<u16> read_number(SeekableStream& stream)
inline ErrorOr<String> read_token(SeekableStream& stream)
{
StringBuilder sb {};
u8 byte {};
@ -43,7 +43,12 @@ static inline ErrorOr<u16> read_number(SeekableStream& stream)
sb.append(byte);
}
auto const maybe_value = TRY(sb.to_string()).to_number<u16>();
return TRY(sb.to_string());
}
static inline ErrorOr<u16> read_number(SeekableStream& stream)
{
auto const maybe_value = TRY(read_token(stream)).to_number<u16>();
if (!maybe_value.has_value())
return Error::from_string_literal("Can't convert bytes to a number");
@ -81,9 +86,11 @@ static ErrorOr<void> read_magic_number(TContext& context)
Array<u8, 2> magic_number {};
TRY(context.stream->read_until_filled(Bytes { magic_number }));
if (magic_number[0] == 'P' && magic_number[1] == TContext::FormatDetails::ascii_magic_number) {
context.type = TContext::Type::ASCII;
return {};
if constexpr (requires { TContext::FormatDetails::ascii_magic_number; }) {
if (magic_number[0] == 'P' && magic_number[1] == TContext::FormatDetails::ascii_magic_number) {
context.type = TContext::Type::ASCII;
return {};
}
}
if (magic_number[0] == 'P' && magic_number[1] == TContext::FormatDetails::binary_magic_number) {
@ -187,6 +194,9 @@ static ErrorOr<void> read_header(Context& context)
return {};
}
template<typename Context>
static ErrorOr<void> read_pam_header(Context& context);
template<typename TContext>
static ErrorOr<void> decode(TContext& context)
{