LibGfx/JPEGXL: Support images encoded with the YCbCr color space
While being way less frequent than for classical JPEG images, JPEG XL images can use the YCbCr color space. Supporting it makes us properly decode the "The Smoke Machine" image on https://jpegxl.info/jxl-art.html
This commit is contained in:
parent
b34b80104f
commit
f2c60b7716
Notes:
sideshowbarker
2024-07-16 19:17:47 +09:00
Author: https://github.com/LucasChollet Commit: https://github.com/SerenityOS/serenity/commit/f2c60b7716 Pull-request: https://github.com/SerenityOS/serenity/pull/20486 Reviewed-by: https://github.com/gmta ✅
1 changed files with 37 additions and 3 deletions
|
@ -2453,6 +2453,42 @@ static ErrorOr<void> apply_image_features(Image& image, ImageMetadata const& met
|
|||
}
|
||||
///
|
||||
|
||||
/// L.2 - XYB + L.3 - YCbCr
|
||||
static void ycbcr_to_rgb(Image& image, u8 bits_per_sample)
|
||||
{
|
||||
auto& channels = image.channels();
|
||||
VERIFY(channels.size() >= 3);
|
||||
|
||||
VERIFY(channels[0].width() == channels[1].width() && channels[1].width() == channels[2].width());
|
||||
VERIFY(channels[0].height() == channels[1].height() && channels[1].height() == channels[2].height());
|
||||
|
||||
auto const half_range_offset = (1 << bits_per_sample) / 2;
|
||||
for (u32 y = 0; y < channels[0].height(); ++y) {
|
||||
for (u32 x = 0; x < channels[0].width(); ++x) {
|
||||
auto const cb = channels[0].get(x, y);
|
||||
auto const luma = channels[1].get(x, y);
|
||||
auto const cr = channels[2].get(x, y);
|
||||
|
||||
channels[0].set(x, y, luma + half_range_offset + 1.402 * cr);
|
||||
channels[1].set(x, y, luma + half_range_offset - 0.344136 * cb - 0.714136 * cr);
|
||||
channels[2].set(x, y, luma + half_range_offset + 1.772 * cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void apply_colour_transformation(Image& image, ImageMetadata const& metadata, Frame const& frame)
|
||||
{
|
||||
if (frame.frame_header.do_YCbCr)
|
||||
ycbcr_to_rgb(image, metadata.bit_depth.bits_per_sample);
|
||||
|
||||
if (metadata.xyb_encoded) {
|
||||
TODO();
|
||||
} else {
|
||||
// FIXME: Do a proper color transformation with metadata.colour_encoding
|
||||
}
|
||||
}
|
||||
///
|
||||
|
||||
/// L.4 - Extra channel rendering
|
||||
static ErrorOr<void> render_extra_channels(Image&, ImageMetadata const& metadata)
|
||||
{
|
||||
|
@ -2500,9 +2536,7 @@ public:
|
|||
|
||||
TRY(apply_image_features(image, m_metadata, frame));
|
||||
|
||||
// FIXME: Do a proper color transformation with metadata.colour_encoding
|
||||
if (m_metadata.xyb_encoded || frame.frame_header.do_YCbCr)
|
||||
TODO();
|
||||
apply_colour_transformation(image, m_metadata, frame);
|
||||
|
||||
TRY(render_extra_channels(image, m_metadata));
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue