From 9bf29356a29931fd1459ad061d8063adc936a7a8 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Fri, 22 Mar 2024 09:10:58 -0400 Subject: [PATCH] LibGfx/ISOBMFF: Support box header size 0 to mean "until end of data" JPEG2000 uses this, and as far as I can tell it's also part of ISO/IEC 14496-12. --- .../LibGfx/ImageFormats/ISOBMFF/Boxes.cpp | 16 ++++++++++------ .../LibGfx/ImageFormats/ISOBMFF/Boxes.h | 2 +- .../LibGfx/ImageFormats/ISOBMFF/Reader.cpp | 7 ++++--- .../LibGfx/ImageFormats/ISOBMFF/Reader.h | 4 +++- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/Boxes.cpp b/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/Boxes.cpp index ad9413527c3..56d3668af4a 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/Boxes.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/Boxes.cpp @@ -8,7 +8,7 @@ namespace Gfx::ISOBMFF { -ErrorOr read_box_header(Stream& stream) +ErrorOr read_box_header(BoxStream& stream) { BoxHeader header; u64 total_size = TRY(stream.read_value>()); @@ -16,12 +16,16 @@ ErrorOr read_box_header(Stream& stream) u64 data_size_read = sizeof(u32) + sizeof(BoxType); - if (total_size == 1) { - total_size = TRY(stream.read_value>()); - data_size_read += sizeof(u64); - } + if (total_size == 0) { + header.contents_size = stream.remaining(); + } else { + if (total_size == 1) { + total_size = TRY(stream.read_value>()); + data_size_read += sizeof(u64); + } - header.contents_size = total_size - data_size_read; + header.contents_size = total_size - data_size_read; + } return header; } diff --git a/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/Boxes.h b/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/Boxes.h index c5234b826fa..a01fffcd14b 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/Boxes.h +++ b/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/Boxes.h @@ -26,7 +26,7 @@ struct BoxHeader { u64 contents_size { 0 }; }; -ErrorOr read_box_header(Stream& stream); +ErrorOr read_box_header(BoxStream& stream); struct Box { Box() = default; diff --git a/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/Reader.cpp b/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/Reader.cpp index 9b383dc00e9..11188688b66 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/Reader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/Reader.cpp @@ -10,7 +10,8 @@ namespace Gfx::ISOBMFF { ErrorOr Reader::create(MaybeOwned stream) { - return Reader(move(stream)); + size_t size = TRY(stream->size()); + return Reader(move(stream), size); } ErrorOr Reader::read_entire_file() @@ -18,8 +19,8 @@ ErrorOr Reader::read_entire_file() BoxList top_level_boxes; while (!m_stream->is_eof()) { - auto box_header = TRY(read_box_header(*m_stream)); - BoxStream box_stream { *m_stream, static_cast(box_header.contents_size) }; + auto box_header = TRY(read_box_header(m_box_stream)); + BoxStream box_stream { m_box_stream, static_cast(box_header.contents_size) }; switch (box_header.type) { case BoxType::FileTypeBox: diff --git a/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/Reader.h b/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/Reader.h index 196fdb226ce..9333b3b9605 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/Reader.h +++ b/Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/Reader.h @@ -23,14 +23,16 @@ public: ErrorOr> get_minor_brands(); private: - Reader(MaybeOwned stream) + Reader(MaybeOwned stream, size_t size) : m_stream(move(stream)) + , m_box_stream(*m_stream, size) { } ErrorOr parse_initial_data(); MaybeOwned m_stream; + BoxStream m_box_stream; }; }