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

LibGfx/TIFF: Add support for the ICCProfile tag

This commit is contained in:
Lucas CHOLLET 2023-11-28 21:16:43 -05:00 committed by Andreas Kling
parent 5622e7d77c
commit 4994609af0
5 changed files with 26 additions and 0 deletions

View file

@ -12,6 +12,7 @@
#include <LibGfx/ICC/WellKnownProfiles.h> #include <LibGfx/ICC/WellKnownProfiles.h>
#include <LibGfx/ImageFormats/JPEGLoader.h> #include <LibGfx/ImageFormats/JPEGLoader.h>
#include <LibGfx/ImageFormats/PNGLoader.h> #include <LibGfx/ImageFormats/PNGLoader.h>
#include <LibGfx/ImageFormats/TIFFLoader.h>
#include <LibGfx/ImageFormats/WebPLoader.h> #include <LibGfx/ImageFormats/WebPLoader.h>
#include <LibTest/TestCase.h> #include <LibTest/TestCase.h>
@ -76,6 +77,17 @@ TEST_CASE(webp_extended_lossy)
EXPECT(icc_profile->is_v2()); EXPECT(icc_profile->is_v2());
} }
TEST_CASE(tiff)
{
auto file = MUST(Core::MappedFile::map(TEST_INPUT("icc/icc.tiff"sv)));
auto tiff = MUST(Gfx::TIFFImageDecoderPlugin::create(file->bytes()));
auto icc_bytes = MUST(tiff->icc_data());
EXPECT(icc_bytes.has_value());
auto icc_profile = MUST(Gfx::ICC::Profile::try_load_from_externally_owned_memory(icc_bytes.value()));
EXPECT(icc_profile->is_v4());
}
TEST_CASE(serialize_icc) TEST_CASE(serialize_icc)
{ {
auto file = MUST(Core::MappedFile::map(TEST_INPUT("icc/p3-v4.icc"sv))); auto file = MUST(Core::MappedFile::map(TEST_INPUT("icc/p3-v4.icc"sv)));

Binary file not shown.

View file

@ -55,6 +55,11 @@ public:
return { *m_metadata.image_width(), *m_metadata.image_height() }; return { *m_metadata.image_width(), *m_metadata.image_height() };
} }
Metadata const& metadata() const
{
return m_metadata;
}
State state() const State state() const
{ {
return m_state; return m_state;
@ -482,6 +487,12 @@ ErrorOr<ImageFrameDescriptor> TIFFImageDecoderPlugin::frame(size_t index, Option
return ImageFrameDescriptor { m_context->bitmap(), 0 }; return ImageFrameDescriptor { m_context->bitmap(), 0 };
} }
ErrorOr<Optional<ReadonlyBytes>> TIFFImageDecoderPlugin::icc_data()
{
return m_context->metadata().icc_profile().map([](auto const& buffer) -> ReadonlyBytes { return buffer.bytes(); });
}
} }
template<typename T> template<typename T>

View file

@ -28,6 +28,8 @@ public:
virtual ErrorOr<ImageFrameDescriptor> frame(size_t index, Optional<IntSize> ideal_size = {}) override; virtual ErrorOr<ImageFrameDescriptor> frame(size_t index, Optional<IntSize> ideal_size = {}) override;
virtual ErrorOr<Optional<ReadonlyBytes>> icc_data() override;
private: private:
TIFFImageDecoderPlugin(NonnullOwnPtr<FixedMemoryStream>); TIFFImageDecoderPlugin(NonnullOwnPtr<FixedMemoryStream>);

View file

@ -59,6 +59,7 @@ known_tags: List[Tag] = [
Tag('278', [TIFFType.UnsignedShort, TIFFType.UnsignedLong], [1], None, "RowsPerStrip"), Tag('278', [TIFFType.UnsignedShort, TIFFType.UnsignedLong], [1], None, "RowsPerStrip"),
Tag('279', [TIFFType.UnsignedShort, TIFFType.UnsignedLong], [], None, "StripByteCounts"), Tag('279', [TIFFType.UnsignedShort, TIFFType.UnsignedLong], [], None, "StripByteCounts"),
Tag('317', [TIFFType.UnsignedShort], [1], Predictor.NoPrediction, "Predictor", Predictor), Tag('317', [TIFFType.UnsignedShort], [1], Predictor.NoPrediction, "Predictor", Predictor),
Tag('34675', [TIFFType.Undefined], [], None, "ICCProfile"),
] ]
HANDLE_TAG_SIGNATURE_TEMPLATE = ("ErrorOr<void> {namespace}handle_tag(Metadata& metadata, u16 tag," HANDLE_TAG_SIGNATURE_TEMPLATE = ("ErrorOr<void> {namespace}handle_tag(Metadata& metadata, u16 tag,"