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

LibGFX/PAM: Allow reading CMYK .pam files

These are written by `mutool extract` for CMYK images.

They don't contain color profiles so they're not super convenient.
But `image` can convert them (*) to sRGB as long as you use it with
`--assign-color-profile` pointing to some CMYK icc profile of your
choice.

*: Once #22922 is merged.
This commit is contained in:
Nico Weber 2024-01-24 21:51:22 -05:00 committed by Andreas Kling
parent 187862ebe0
commit 556addc5cb
3 changed files with 70 additions and 18 deletions

View file

@ -62,6 +62,9 @@ public:
virtual ErrorOr<ImageFrameDescriptor> frame(size_t index, Optional<IntSize> ideal_size = {}) override;
virtual NaturalFrameFormat natural_frame_format() const override;
virtual ErrorOr<NonnullRefPtr<CMYKBitmap>> cmyk_frame() override;
private:
PortableImageDecoderPlugin(NonnullOwnPtr<SeekableStream> stream);
@ -126,8 +129,45 @@ ErrorOr<ImageFrameDescriptor> PortableImageDecoderPlugin<TContext>::frame(size_t
}
}
if constexpr (requires { TContext::FormatDetails::cmyk_bitmap; }) {
if (m_context->format_details.cmyk_bitmap.has_value())
m_context->bitmap = TRY(m_context->format_details.cmyk_bitmap.value()->to_low_quality_rgb());
}
VERIFY(m_context->bitmap);
return ImageFrameDescriptor { m_context->bitmap, 0 };
}
template<typename TContext>
NaturalFrameFormat PortableImageDecoderPlugin<TContext>::natural_frame_format() const
{
if constexpr (requires { TContext::FormatDetails::cmyk_bitmap; }) {
if (m_context->format_details.depth == 4 && m_context->format_details.tupl_type == "CMYK"sv)
return NaturalFrameFormat::CMYK;
}
return NaturalFrameFormat::RGB;
}
template<typename TContext>
ErrorOr<NonnullRefPtr<CMYKBitmap>> PortableImageDecoderPlugin<TContext>::cmyk_frame()
{
if constexpr (requires { TContext::FormatDetails::cmyk_bitmap; }) {
VERIFY(natural_frame_format() == NaturalFrameFormat::CMYK);
if (m_context->state == TContext::State::Error)
return Error::from_string_literal("PortableImageDecoderPlugin: Decoding failed");
if (m_context->state < TContext::State::BitmapDecoded) {
if (decode(*m_context).is_error()) {
m_context->state = TContext::State::Error;
return Error::from_string_literal("PortableImageDecoderPlugin: Decoding failed");
}
}
return *m_context->format_details.cmyk_bitmap.value();
}
VERIFY_NOT_REACHED();
}
}