From b5b17269c4070144c18fd19d21c12537cb00ede1 Mon Sep 17 00:00:00 2001 From: Lucas CHOLLET Date: Thu, 27 Jul 2023 15:45:23 -0400 Subject: [PATCH] LibGfx/JPEGXL: Support reading LfGroups with an empty ModularLfGroup I recently discovered a bug when we count the number of LfGroups, and it turns out that this number can't be null. So that means that we need to support reading them. The trick is that we only have support for images that contains an empty LfGroup, so this patch implement a dummy reader that just check that we are indeed facing an empty one and `TODO()` otherwise. --- .../LibGfx/ImageFormats/JPEGXLLoader.cpp | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibGfx/ImageFormats/JPEGXLLoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/JPEGXLLoader.cpp index 21890b0fe5..71b7b1eb84 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/JPEGXLLoader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/JPEGXLLoader.cpp @@ -1094,6 +1094,16 @@ public: return m_vshift; } + bool decoded() const + { + return m_decoded; + } + + void set_decoded(bool decoded) + { + m_decoded = decoded; + } + private: u32 m_width {}; u32 m_height {}; @@ -1101,6 +1111,8 @@ private: u32 m_hshift {}; u32 m_vshift {}; + bool m_decoded { false }; + Vector m_pixels {}; }; @@ -1313,6 +1325,8 @@ static ErrorOr read_modular_header(LittleEndianInputBitStream& st image.channels()[i].set(x, y, total); } } + + image.channels()[i].set_decoded(true); } return modular_header; @@ -1389,6 +1403,39 @@ static ErrorOr read_lf_global(LittleEndianInputBitStream& stream, } /// +/// G.2 - LfGroup +static ErrorOr read_lf_group(LittleEndianInputBitStream&, + Image& image, + FrameHeader const& frame_header) +{ + // LF coefficients + if (frame_header.encoding == FrameHeader::Encoding::kVarDCT) { + TODO(); + } + + // ModularLfGroup + for (auto const& channel : image.channels()) { + if (channel.decoded()) + continue; + + if (channel.hshift() < 3 || channel.vshift() < 3) + continue; + + // This code actually only detect that we need to read a null image + // so a no-op. It should be fully rewritten when we add proper support + // for LfGroup. + TODO(); + } + + // HF metadata + if (frame_header.encoding == FrameHeader::Encoding::kVarDCT) { + TODO(); + } + + return {}; +} +/// + /// H.6 - Transformations static void apply_rct(Image& image, TransformInfo const& transformation) { @@ -1534,7 +1581,7 @@ static ErrorOr read_frame(LittleEndianInputBitStream& stream, frame.lf_global = TRY(read_lf_global(stream, image, frame.frame_header, metadata, entropy_decoder)); for (u32 i {}; i < frame.num_lf_groups; ++i) - TODO(); + TRY(read_lf_group(stream, image, frame.frame_header)); if (frame.frame_header.encoding == FrameHeader::Encoding::kVarDCT) { TODO();