From 1e95c08db528dcfc901b614ddac6fb3122464a73 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Fri, 22 Mar 2024 16:11:56 -0400 Subject: [PATCH] LibGfx/ISOBMFF: Add JPEG2000ChannelDefinitionBox --- .../ImageFormats/ISOBMFF/JPEG2000Boxes.cpp | 35 +++++++++++++++++++ .../ImageFormats/ISOBMFF/JPEG2000Boxes.h | 12 +++++++ 2 files changed, 47 insertions(+) diff --git a/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/JPEG2000Boxes.cpp b/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/JPEG2000Boxes.cpp index 51324d08b9f..9ff4269e726 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/JPEG2000Boxes.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/JPEG2000Boxes.cpp @@ -13,6 +13,8 @@ ErrorOr JPEG2000HeaderBox::read_from_stream(BoxStream& stream) { auto make_subbox = [](BoxType type, BoxStream& stream) -> ErrorOr>> { switch (type) { + case BoxType::JPEG2000ChannelDefinitionBox: + return TRY(JPEG2000ChannelDefinitionBox::create_from_stream(stream)); case BoxType::JPEG2000ColorSpecificationBox: return TRY(JPEG2000ColorSpecificationBox::create_from_stream(stream)); case BoxType::JPEG2000ImageHeaderBox: @@ -89,6 +91,39 @@ void JPEG2000ColorSpecificationBox::dump(String const& prepend) const outln("{}- icc_data = {} bytes", prepend, icc_data.size()); } +ErrorOr JPEG2000ChannelDefinitionBox::read_from_stream(BoxStream& stream) +{ + u16 count = TRY(stream.read_value>()); + for (u32 i = 0; i < count; ++i) { + Channel channel; + channel.channel_index = TRY(stream.read_value>()); + channel.channel_type = TRY(stream.read_value>()); + channel.channel_association = TRY(stream.read_value>()); + channels.append(channel); + } + return {}; +} + +void JPEG2000ChannelDefinitionBox::dump(String const& prepend) const +{ + Box::dump(prepend); + for (auto const& channel : channels) { + outln("{}- channel_index = {}", prepend, channel.channel_index); + + out("{}- channel_type = {}", prepend, channel.channel_type); + if (channel.channel_type == 0) + outln(" (color)"); + else if (channel.channel_type == 1) + outln(" (opacity)"); + else if (channel.channel_type == 2) + outln(" (premultiplied opacity)"); + else + outln(" (unknown)"); + + outln("{}- channel_association = {}", prepend, channel.channel_association); + } +} + ErrorOr JPEG2000ResolutionBox::read_from_stream(BoxStream& stream) { auto make_subbox = [](BoxType type, BoxStream& stream) -> ErrorOr>> { diff --git a/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/JPEG2000Boxes.h b/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/JPEG2000Boxes.h index 6d84a71365b..da2a09b2575 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/JPEG2000Boxes.h +++ b/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/JPEG2000Boxes.h @@ -38,6 +38,18 @@ struct JPEG2000ColorSpecificationBox final : public Box { ByteBuffer icc_data; // Only set if method == 2 }; +// I.5.3.6 Channel Definition box +struct JPEG2000ChannelDefinitionBox final : public Box { + BOX_SUBTYPE(JPEG2000ChannelDefinitionBox); + + struct Channel { + u16 channel_index; + u16 channel_type; + u16 channel_association; + }; + Vector channels; +}; + // I.5.3.7 Resolution box struct JPEG2000ResolutionBox final : public SuperBox { BOX_SUBTYPE(JPEG2000ResolutionBox);