瀏覽代碼

LibGfx/ISOBMFF: Add JPEG2000ChannelDefinitionBox

Nico Weber 1 年之前
父節點
當前提交
1e95c08db5

+ 35 - 0
Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/JPEG2000Boxes.cpp

@@ -13,6 +13,8 @@ ErrorOr<void> JPEG2000HeaderBox::read_from_stream(BoxStream& stream)
 {
 {
     auto make_subbox = [](BoxType type, BoxStream& stream) -> ErrorOr<Optional<NonnullOwnPtr<Box>>> {
     auto make_subbox = [](BoxType type, BoxStream& stream) -> ErrorOr<Optional<NonnullOwnPtr<Box>>> {
         switch (type) {
         switch (type) {
+        case BoxType::JPEG2000ChannelDefinitionBox:
+            return TRY(JPEG2000ChannelDefinitionBox::create_from_stream(stream));
         case BoxType::JPEG2000ColorSpecificationBox:
         case BoxType::JPEG2000ColorSpecificationBox:
             return TRY(JPEG2000ColorSpecificationBox::create_from_stream(stream));
             return TRY(JPEG2000ColorSpecificationBox::create_from_stream(stream));
         case BoxType::JPEG2000ImageHeaderBox:
         case BoxType::JPEG2000ImageHeaderBox:
@@ -89,6 +91,39 @@ void JPEG2000ColorSpecificationBox::dump(String const& prepend) const
         outln("{}- icc_data = {} bytes", prepend, icc_data.size());
         outln("{}- icc_data = {} bytes", prepend, icc_data.size());
 }
 }
 
 
+ErrorOr<void> JPEG2000ChannelDefinitionBox::read_from_stream(BoxStream& stream)
+{
+    u16 count = TRY(stream.read_value<BigEndian<u16>>());
+    for (u32 i = 0; i < count; ++i) {
+        Channel channel;
+        channel.channel_index = TRY(stream.read_value<BigEndian<u16>>());
+        channel.channel_type = TRY(stream.read_value<BigEndian<u16>>());
+        channel.channel_association = TRY(stream.read_value<BigEndian<u16>>());
+        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<void> JPEG2000ResolutionBox::read_from_stream(BoxStream& stream)
 ErrorOr<void> JPEG2000ResolutionBox::read_from_stream(BoxStream& stream)
 {
 {
     auto make_subbox = [](BoxType type, BoxStream& stream) -> ErrorOr<Optional<NonnullOwnPtr<Box>>> {
     auto make_subbox = [](BoxType type, BoxStream& stream) -> ErrorOr<Optional<NonnullOwnPtr<Box>>> {

+ 12 - 0
Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/JPEG2000Boxes.h

@@ -38,6 +38,18 @@ struct JPEG2000ColorSpecificationBox final : public Box {
     ByteBuffer icc_data;              // Only set if method == 2
     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<Channel> channels;
+};
+
 // I.5.3.7 Resolution box
 // I.5.3.7 Resolution box
 struct JPEG2000ResolutionBox final : public SuperBox {
 struct JPEG2000ResolutionBox final : public SuperBox {
     BOX_SUBTYPE(JPEG2000ResolutionBox);
     BOX_SUBTYPE(JPEG2000ResolutionBox);