Reader.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. /*
  2. * Copyright (c) 2023, Gregory Bertilson <Zaggy1024@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "Reader.h"
  7. #include "JPEG2000Boxes.h"
  8. #include <AK/Function.h>
  9. namespace Gfx::ISOBMFF {
  10. ErrorOr<Reader> Reader::create(MaybeOwned<SeekableStream> stream)
  11. {
  12. size_t size = TRY(stream->size());
  13. return Reader(make<BoxStream>(move(stream), size));
  14. }
  15. ErrorOr<Reader> Reader::create(MaybeOwned<BoxStream> stream)
  16. {
  17. return Reader(move(stream));
  18. }
  19. ErrorOr<BoxList> Reader::read_entire_file()
  20. {
  21. auto make_top_level_box = [](BoxType type, BoxStream& stream) -> ErrorOr<Optional<NonnullOwnPtr<Box>>> {
  22. switch (type) {
  23. case BoxType::FileTypeBox:
  24. return TRY(FileTypeBox::create_from_stream(stream));
  25. case BoxType::JPEG2000ContiguousCodestreamBox:
  26. return TRY(JPEG2000ContiguousCodestreamBox::create_from_stream(stream));
  27. case BoxType::JPEG2000HeaderBox:
  28. return TRY(JPEG2000HeaderBox::create_from_stream(stream));
  29. case BoxType::JPEG2000SignatureBox:
  30. return TRY(JPEG2000SignatureBox::create_from_stream(stream));
  31. case BoxType::JPEG2000UUIDInfoBox:
  32. return TRY(JPEG2000UUIDInfoBox::create_from_stream(stream));
  33. case BoxType::UserExtensionBox:
  34. return TRY(UserExtensionBox::create_from_stream(stream));
  35. default:
  36. return OptionalNone {};
  37. }
  38. };
  39. return read_entire_file((ErrorOr<Optional<NonnullOwnPtr<Box>>>(*)(BoxType, BoxStream&))(make_top_level_box));
  40. }
  41. ErrorOr<BoxList> Reader::read_entire_file(BoxCallback box_factory)
  42. {
  43. BoxList top_level_boxes;
  44. while (!m_box_stream->is_eof()) {
  45. auto box_header = TRY(read_box_header(*m_box_stream));
  46. BoxStream box_stream { MaybeOwned<Stream> { *m_box_stream }, static_cast<size_t>(box_header.contents_size) };
  47. auto maybe_box = TRY(box_factory(box_header.type, box_stream));
  48. if (maybe_box.has_value()) {
  49. TRY(top_level_boxes.try_append(move(maybe_box.value())));
  50. } else {
  51. TRY(top_level_boxes.try_append(TRY(UnknownBox::create_from_stream(box_header.type, box_stream))));
  52. }
  53. if (!box_stream.is_eof())
  54. return Error::from_string_literal("Reader did not consume all data");
  55. }
  56. return top_level_boxes;
  57. }
  58. }