Details.h 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. /*
  2. * Copyright (c) 2023, kleines Filmröllchen <filmroellchen@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/ByteBuffer.h>
  8. #include <AK/MemoryStream.h>
  9. #include <LibRIFF/ChunkID.h>
  10. // Despite the name, this header contains details for both RIFF and IFF
  11. namespace RIFF::Detail {
  12. // http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/riffmci.pdf page 11 (Chunks)
  13. template<typename WordType>
  14. struct ChunkHeader {
  15. static ErrorOr<ChunkHeader> read_from_stream(Stream& stream);
  16. RIFF::ChunkID id;
  17. u32 size;
  18. };
  19. // Standard RIFF/IFF file formats use a global chunk with a chunk ID (magic bytes) such as "RIFF" or "FORM".
  20. // A chunk ID right at the start of the global chunk specifies the subformat specific to the file type.
  21. // Example for RIFF from WebP: https://developers.google.com/speed/webp/docs/riff_container#webp_file_header
  22. template<typename HeaderType>
  23. struct FileHeader {
  24. HeaderType global_header;
  25. RIFF::ChunkID subformat;
  26. static ErrorOr<FileHeader> read_from_stream(Stream& stream);
  27. constexpr ChunkID magic() const { return global_header.id; }
  28. constexpr u32 file_size() const { return global_header.size; }
  29. };
  30. // An RIFF or IFF chunk.
  31. template<typename HeaderType>
  32. class Chunk {
  33. public:
  34. Chunk(HeaderType header, ReadonlyBytes data);
  35. // Note that the resulting chunk will refer to the provided data.
  36. static ErrorOr<Chunk> decode(ReadonlyBytes data);
  37. static ErrorOr<Chunk> decode_and_advance(ReadonlyBytes& data);
  38. RIFF::ChunkID id() const { return m_header.id; }
  39. u32 size() const { return m_header.size; }
  40. ReadonlyBytes data() const { return m_data; }
  41. FixedMemoryStream data_stream() const;
  42. u8 operator[](size_t index) const { return data()[index]; }
  43. private:
  44. HeaderType m_header;
  45. ReadonlyBytes m_data;
  46. };
  47. // Owns the chunk data and can therefore be parsed from a stream.
  48. template<typename HeaderType>
  49. class OwnedChunk : public Chunk<HeaderType> {
  50. public:
  51. using Buffer = AK::Detail::ByteBuffer<0>;
  52. OwnedChunk(HeaderType, Buffer);
  53. static ErrorOr<OwnedChunk> read_from_stream(Stream& stream);
  54. private:
  55. Buffer m_backing_data;
  56. };
  57. }