Skip to content

Commit

Permalink
LibGfx/PNG: Read the cICP chunk
Browse files Browse the repository at this point in the history
  • Loading branch information
LucasChollet authored and trflynn89 committed Feb 12, 2025
1 parent cffc867 commit a144481
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 6 deletions.
30 changes: 24 additions & 6 deletions Libraries/LibGfx/ImageFormats/PNGLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ struct PNGLoadingContext {
u32 frame_count { 0 };
u32 loop_count { 0 };
Vector<ImageFrameDescriptor> frame_descriptors;
Optional<Media::CodingIndependentCodePoints> cicp;
Optional<ByteBuffer> icc_profile;
OwnPtr<ExifMetadata> exif_metadata;

Expand Down Expand Up @@ -111,6 +112,11 @@ ErrorOr<ImageFrameDescriptor> PNGImageDecoderPlugin::frame(size_t index, Optiona
return m_context->frame_descriptors[index];
}

ErrorOr<Optional<Media::CodingIndependentCodePoints>> PNGImageDecoderPlugin::cicp()
{
return m_context->cicp;
}

ErrorOr<Optional<ReadonlyBytes>> PNGImageDecoderPlugin::icc_data()
{
if (m_context->icc_profile.has_value())
Expand Down Expand Up @@ -187,12 +193,24 @@ ErrorOr<void> PNGImageDecoderPlugin::initialize()
png_set_filler(m_context->png_ptr, 0xFF, PNG_FILLER_AFTER);
png_set_bgr(m_context->png_ptr);

char* profile_name = nullptr;
int compression_type = 0;
u8* profile_data = nullptr;
u32 profile_len = 0;
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));
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;
int compression_type = 0;
u8* profile_data = nullptr;
u32 profile_len = 0;
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));
}

u8* exif_data = nullptr;
u32 exif_length = 0;
Expand Down
1 change: 1 addition & 0 deletions Libraries/LibGfx/ImageFormats/PNGLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class PNGImageDecoderPlugin final : public ImageDecoderPlugin {
virtual size_t first_animated_frame_index() override;
virtual ErrorOr<ImageFrameDescriptor> frame(size_t index, Optional<IntSize> ideal_size = {}) override;
virtual Optional<Metadata const&> metadata() override;
virtual ErrorOr<Optional<Media::CodingIndependentCodePoints>> cicp() override;
virtual ErrorOr<Optional<ReadonlyBytes>> icc_data() override;

private:
Expand Down
Original file line number Diff line number Diff line change
@@ -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:[email protected]">
<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>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions Tests/LibWeb/Ref/expected/wpt-import/png/cICP-wins-ref.html
Original file line number Diff line number Diff line change
@@ -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:[email protected]">
<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>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions Tests/LibWeb/Ref/input/wpt-import/png/apng/fDAT-inherits-cICP.html
Original file line number Diff line number Diff line change
@@ -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:[email protected]">
<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>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions Tests/LibWeb/Ref/input/wpt-import/png/cICP-wins.html
Original file line number Diff line number Diff line change
@@ -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:[email protected]">
<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>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit a144481

Please sign in to comment.