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