Преглед на файлове

LibGfx/ISOBMFF: Give Reader::read_entire_file() a factory callback

This will allow creating different child boxes in different containers.
Nico Weber преди 1 година
родител
ревизия
78deac3dca

+ 3 - 2
Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/Boxes.cpp

@@ -6,6 +6,7 @@
 
 #include "Boxes.h"
 #include "Reader.h"
+#include <AK/Function.h>
 
 namespace Gfx::ISOBMFF {
 
@@ -104,10 +105,10 @@ void FileTypeBox::dump(String const& prepend) const
     outln("{}{}", prepend, compatible_brands_string.string_view());
 }
 
-ErrorOr<void> SuperBox::read_from_stream(BoxStream& stream)
+ErrorOr<void> SuperBox::read_from_stream(BoxStream& stream, BoxCallback box_factory)
 {
     auto reader = TRY(Gfx::ISOBMFF::Reader::create(MaybeOwned { stream }));
-    m_child_boxes = TRY(reader.read_entire_file());
+    m_child_boxes = TRY(reader.read_entire_file(move(box_factory)));
     return {};
 }
 

+ 3 - 1
Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/Boxes.h

@@ -95,7 +95,9 @@ struct FileTypeBox final : public Box {
 // A box that contains other boxes.
 struct SuperBox : public Box {
     SuperBox() = default;
-    ErrorOr<void> read_from_stream(BoxStream&);
+
+    using BoxCallback = Function<ErrorOr<Optional<NonnullOwnPtr<Box>>>(BoxType, BoxStream&)>;
+    ErrorOr<void> read_from_stream(BoxStream&, BoxCallback);
     virtual void dump(String const& prepend = {}) const override;
 
 private:

+ 6 - 1
Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/JPEG2000Boxes.cpp

@@ -5,12 +5,17 @@
  */
 
 #include "JPEG2000Boxes.h"
+#include <AK/Function.h>
 
 namespace Gfx::ISOBMFF {
 
 ErrorOr<void> JPEG2000HeaderBox::read_from_stream(BoxStream& stream)
 {
-    TRY(SuperBox::read_from_stream(stream));
+    auto make_subbox = [](BoxType, BoxStream&) -> ErrorOr<Optional<NonnullOwnPtr<Box>>> {
+        return OptionalNone {};
+    };
+
+    TRY(SuperBox::read_from_stream(stream, move(make_subbox)));
     return {};
 }
 

+ 21 - 12
Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/Reader.cpp

@@ -22,6 +22,23 @@ ErrorOr<Reader> Reader::create(MaybeOwned<BoxStream> stream)
 }
 
 ErrorOr<BoxList> Reader::read_entire_file()
+{
+    auto make_top_level_box = [](BoxType type, BoxStream& stream) -> ErrorOr<Optional<NonnullOwnPtr<Box>>> {
+        switch (type) {
+        case BoxType::FileTypeBox:
+            return TRY(FileTypeBox::create_from_stream(stream));
+        case BoxType::JPEG2000HeaderBox:
+            return TRY(JPEG2000HeaderBox::create_from_stream(stream));
+        case BoxType::JPEG2000SignatureBox:
+            return TRY(JPEG2000SignatureBox::create_from_stream(stream));
+        default:
+            return OptionalNone {};
+        }
+    };
+    return read_entire_file((ErrorOr<Optional<NonnullOwnPtr<Box>>>(*)(BoxType, BoxStream&))(make_top_level_box));
+}
+
+ErrorOr<BoxList> Reader::read_entire_file(BoxCallback box_factory)
 {
     BoxList top_level_boxes;
 
@@ -29,19 +46,11 @@ ErrorOr<BoxList> Reader::read_entire_file()
         auto box_header = TRY(read_box_header(*m_box_stream));
         BoxStream box_stream { MaybeOwned<Stream> { *m_box_stream }, static_cast<size_t>(box_header.contents_size) };
 
-        switch (box_header.type) {
-        case BoxType::FileTypeBox:
-            TRY(top_level_boxes.try_append(TRY(FileTypeBox::create_from_stream(box_stream))));
-            break;
-        case BoxType::JPEG2000HeaderBox:
-            TRY(top_level_boxes.try_append(TRY(JPEG2000HeaderBox::create_from_stream(box_stream))));
-            break;
-        case BoxType::JPEG2000SignatureBox:
-            TRY(top_level_boxes.try_append(TRY(JPEG2000SignatureBox::create_from_stream(box_stream))));
-            break;
-        default:
+        auto maybe_box = TRY(box_factory(box_header.type, box_stream));
+        if (maybe_box.has_value()) {
+            TRY(top_level_boxes.try_append(move(maybe_box.value())));
+        } else {
             TRY(top_level_boxes.try_append(TRY(UnknownBox::create_from_stream(box_header.type, box_stream))));
-            break;
         }
 
         if (!box_stream.is_eof())

+ 3 - 0
Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/Reader.h

@@ -20,6 +20,9 @@ public:
 
     ErrorOr<BoxList> read_entire_file();
 
+    using BoxCallback = Function<ErrorOr<Optional<NonnullOwnPtr<Box>>>(BoxType, BoxStream&)>;
+    ErrorOr<BoxList> read_entire_file(BoxCallback);
+
 private:
     Reader(MaybeOwned<BoxStream> stream)
         : m_box_stream(move(stream))