Boxes.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. * Copyright (c) 2023, Gregory Bertilson <Zaggy1024@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "Boxes.h"
  7. namespace Gfx::ISOBMFF {
  8. ErrorOr<BoxHeader> read_box_header(Stream& stream)
  9. {
  10. BoxHeader header;
  11. u64 total_size = TRY(stream.read_value<BigEndian<u32>>());
  12. header.type = TRY(stream.read_value<BoxType>());
  13. u64 data_size_read = sizeof(u32) + sizeof(BoxType);
  14. if (total_size == 1) {
  15. total_size = TRY(stream.read_value<BigEndian<u64>>());
  16. data_size_read += sizeof(u64);
  17. }
  18. header.contents_size = total_size - data_size_read;
  19. return header;
  20. }
  21. void Box::dump(String const& prepend) const
  22. {
  23. outln("{}{}", prepend, box_type());
  24. }
  25. ErrorOr<void> FullBox::read_from_stream(BoxStream& stream)
  26. {
  27. u32 data = TRY(stream.read_value<BigEndian<u32>>());
  28. // unsigned int(8) version
  29. version = static_cast<u8>(data >> 24);
  30. // unsigned int(24) flags
  31. flags = data & 0xFFF;
  32. return {};
  33. }
  34. void FullBox::dump(String const& prepend) const
  35. {
  36. outln("{}{} (version = {}, flags = {:#x})", prepend, box_type(), version, flags);
  37. }
  38. static String add_indent(String const& string)
  39. {
  40. return MUST(String::formatted("{} ", string));
  41. }
  42. ErrorOr<void> UnknownBox::read_from_stream(BoxStream& stream)
  43. {
  44. m_contents_size = stream.remaining();
  45. TRY(stream.discard_remaining());
  46. return {};
  47. }
  48. void UnknownBox::dump(String const& prepend) const
  49. {
  50. Box::dump(prepend);
  51. auto indented_prepend = add_indent(prepend);
  52. outln("{}[ {} bytes ]", prepend, m_contents_size);
  53. }
  54. ErrorOr<void> FileTypeBox::read_from_stream(BoxStream& stream)
  55. {
  56. // unsigned int(32) major_brand;
  57. major_brand = TRY(stream.read_value<BrandIdentifier>());
  58. // unsigned int(32) minor_version;
  59. minor_version = TRY(stream.read_value<BigEndian<u32>>());
  60. // unsigned int(32) compatible_brands[]; // to end of the box
  61. if (stream.remaining() % sizeof(BrandIdentifier) != 0)
  62. return Error::from_string_literal("FileTypeBox compatible_brands contains a partial brand");
  63. for (auto minor_brand_count = stream.remaining() / sizeof(BrandIdentifier); minor_brand_count > 0; minor_brand_count--)
  64. TRY(compatible_brands.try_append(TRY(stream.read_value<BrandIdentifier>())));
  65. return {};
  66. }
  67. void FileTypeBox::dump(String const& prepend) const
  68. {
  69. FullBox::dump(prepend);
  70. auto indented_prepend = add_indent(prepend);
  71. outln("{}- major_brand = {}", prepend, major_brand);
  72. outln("{}- minor_version = {}", prepend, minor_version);
  73. StringBuilder compatible_brands_string;
  74. compatible_brands_string.append("- compatible_brands = { "sv);
  75. for (size_t i = 0; i < compatible_brands.size() - 1; i++)
  76. compatible_brands_string.appendff("{}, ", compatible_brands[i]);
  77. compatible_brands_string.appendff("{} }}", compatible_brands[compatible_brands.size() - 1]);
  78. outln("{}{}", prepend, compatible_brands_string.string_view());
  79. }
  80. }