LibGfx/PNG: Read the cICP chunk

This commit is contained in:
Lucas CHOLLET 2025-02-08 00:13:12 -05:00 committed by Tim Flynn
commit a144481e6c
Notes: github-actions[bot] 2025-02-12 17:26:09 +00:00
10 changed files with 94 additions and 6 deletions

View file

@ -30,6 +30,7 @@ struct PNGLoadingContext {
u32 frame_count { 0 }; u32 frame_count { 0 };
u32 loop_count { 0 }; u32 loop_count { 0 };
Vector<ImageFrameDescriptor> frame_descriptors; Vector<ImageFrameDescriptor> frame_descriptors;
Optional<Media::CodingIndependentCodePoints> cicp;
Optional<ByteBuffer> icc_profile; Optional<ByteBuffer> icc_profile;
OwnPtr<ExifMetadata> exif_metadata; OwnPtr<ExifMetadata> exif_metadata;
@ -111,6 +112,11 @@ ErrorOr<ImageFrameDescriptor> PNGImageDecoderPlugin::frame(size_t index, Optiona
return m_context->frame_descriptors[index]; return m_context->frame_descriptors[index];
} }
ErrorOr<Optional<Media::CodingIndependentCodePoints>> PNGImageDecoderPlugin::cicp()
{
return m_context->cicp;
}
ErrorOr<Optional<ReadonlyBytes>> PNGImageDecoderPlugin::icc_data() ErrorOr<Optional<ReadonlyBytes>> PNGImageDecoderPlugin::icc_data()
{ {
if (m_context->icc_profile.has_value()) if (m_context->icc_profile.has_value())
@ -187,12 +193,24 @@ ErrorOr<void> PNGImageDecoderPlugin::initialize()
png_set_filler(m_context->png_ptr, 0xFF, PNG_FILLER_AFTER); png_set_filler(m_context->png_ptr, 0xFF, PNG_FILLER_AFTER);
png_set_bgr(m_context->png_ptr); png_set_bgr(m_context->png_ptr);
png_byte color_primaries { 0 };
png_byte transfer_function { 0 };
png_byte matrix_coefficients { 0 };
png_byte video_full_range_flag { 0 };
if (png_get_cICP(m_context->png_ptr, m_context->info_ptr, &color_primaries, &transfer_function, &matrix_coefficients, &video_full_range_flag)) {
Media::ColorPrimaries cp { color_primaries };
Media::TransferCharacteristics tc { transfer_function };
Media::MatrixCoefficients mc { matrix_coefficients };
Media::VideoFullRangeFlag rf { video_full_range_flag };
m_context->cicp = Media::CodingIndependentCodePoints { cp, tc, mc, rf };
} else {
char* profile_name = nullptr; char* profile_name = nullptr;
int compression_type = 0; int compression_type = 0;
u8* profile_data = nullptr; u8* profile_data = nullptr;
u32 profile_len = 0; u32 profile_len = 0;
if (png_get_iCCP(m_context->png_ptr, m_context->info_ptr, &profile_name, &compression_type, &profile_data, &profile_len)) if (png_get_iCCP(m_context->png_ptr, m_context->info_ptr, &profile_name, &compression_type, &profile_data, &profile_len))
m_context->icc_profile = TRY(ByteBuffer::copy(profile_data, profile_len)); m_context->icc_profile = TRY(ByteBuffer::copy(profile_data, profile_len));
}
u8* exif_data = nullptr; u8* exif_data = nullptr;
u32 exif_length = 0; u32 exif_length = 0;

View file

@ -27,6 +27,7 @@ public:
virtual size_t first_animated_frame_index() override; virtual size_t first_animated_frame_index() override;
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 Optional<Metadata const&> metadata() override; virtual Optional<Metadata const&> metadata() override;
virtual ErrorOr<Optional<Media::CodingIndependentCodePoints>> cicp() override;
virtual ErrorOr<Optional<ReadonlyBytes>> icc_data() override; virtual ErrorOr<Optional<ReadonlyBytes>> icc_data() override;
private: private:

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>PNG Third Edition: animated PNG</title>
<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
<body>
<p>Test passes if you see a lime green rectangle, and no red.</p>
<div class="test"><img src="support/lime.png" alt=""></div>
</body>

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>PNG Third Edition: Coding Independent Code Points</title>
<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
<style>
.test {
width: 128px;
height: 64px;
background-color: green;
}
</style>
<body>
<p>Test passes if you see a green rectangle, and no red.</p>
<div class="test"><img src="support/srgb_green.png" alt=""></div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

View file

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html class="reftest-wait">
<meta charset="utf-8">
<title>PNG Third Edition: animated PNG, fdAT inherits colorspace from cICP</title>
<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
<link rel="help" href="https://www.w3.org/TR/png-3/#structure">
<link rel="help" href="https://www.w3.org/TR/png-3/#fdAT-chunk">
<link rel="help" href="https://www.w3.org/TR/png-3/#cICP-chunk">
<link rel="match" href="../../../../expected/wpt-import/png/apng/apng-lime-rectangle-ref.html">
<meta name="assert" content="Each frame inherits every property specified by any critical or ancillary chunks before the first IDAT chunk in the file">
<script>
const el = document.querySelector(".reftest-wait");
setTimeout(() => {
el.classList.remove('reftest-wait');
}, 2100);
</script>
<body>
<p>Test passes if you see a lime green rectangle, and no red.</p>
<!-- sRGB lime = color(display-p3 0.4584 0.9853 0.2983) -->
<div class="test"><img src="support/062.png" alt=""></div>
</body>

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

View file

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>PNG Third Edition: Coding Independent Code Points</title>
<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
<link rel="help" href="https://www.w3.org/TR/png-3/#11iCCP">
<link rel="help" href="https://www.w3.org/TR/png-3/#cICP-chunk">
<link rel="match" href="../../../expected/wpt-import/png/cICP-wins-ref.html">
<meta name="assert" content="When the cICP chunk is present, decoders that recognize it SHALL ignore iCCP">
<style>
.test {
width: 128px;
height: 64px;
background-color: red;
}
</style>
<body>
<p>Test passes if you see a green rectangle, and no red.</p>
<div class="test"><img src="support/cICP-and-iCCP.png" alt=""></div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB