Tag Parser 12.1.0
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
Loading...
Searching...
No Matches
flacmetadata.cpp
Go to the documentation of this file.
1#include "./flacmetadata.h"
2
3#include "../exceptions.h"
4#include "../tagvalue.h"
5
6#include <c++utilities/conversion/binaryconversion.h>
7#include <c++utilities/io/binaryreader.h>
8#include <c++utilities/io/binarywriter.h>
9#include <c++utilities/io/bitreader.h>
10
11#include <cstring>
12#include <memory>
13
14using namespace std;
15using namespace CppUtilities;
16
17namespace TagParser {
18
29void FlacMetaDataBlockHeader::parseHeader(std::string_view buffer)
30{
31 m_last = static_cast<std::uint8_t>(buffer[0] & 0x80);
32 m_type = static_cast<std::uint8_t>(buffer[0] & (0x80 - 1));
33 m_dataSize = BE::toUInt24(buffer.data() + 1);
34}
35
40void FlacMetaDataBlockHeader::makeHeader(std::ostream &outputStream)
41{
42 std::uint8_t buff[4];
43 *buff = (m_last ? (0x80 | m_type) : m_type);
44 BE::getBytes24(m_dataSize, reinterpret_cast<char *>(buff) + 1);
45 outputStream.write(reinterpret_cast<char *>(buff), sizeof(buff));
46}
47
58void FlacMetaDataBlockStreamInfo::parse(std::string_view buffer)
59{
60 auto reader = BitReader(buffer.data(), 0x22);
61 m_minBlockSize = reader.readBits<std::uint16_t>(16);
62 m_maxBlockSize = reader.readBits<std::uint16_t>(16);
63 m_minFrameSize = reader.readBits<std::uint32_t>(24);
64 m_maxFrameSize = reader.readBits<std::uint32_t>(24);
65 m_samplingFrequency = reader.readBits<std::uint32_t>(20);
66 m_channelCount = reader.readBits<std::uint8_t>(3) + 1;
67 m_bitsPerSample = reader.readBits<std::uint8_t>(5) + 1;
68 m_totalSampleCount = reader.readBits<std::uint64_t>(36);
69 std::memcpy(m_md5Sum, buffer.data() + 0x22u - sizeof(m_md5Sum), sizeof(m_md5Sum));
70}
71
83void FlacMetaDataBlockPicture::parse(istream &inputStream, std::uint32_t maxSize)
84{
86 BinaryReader reader(&inputStream);
87 m_pictureType = reader.readUInt32BE();
88 std::uint32_t size = reader.readUInt32BE();
89 CHECK_MAX_SIZE(size);
90 m_value.setMimeType(reader.readString(size));
91 size = reader.readUInt32BE();
92 CHECK_MAX_SIZE(size);
93 m_value.setDescription(reader.readString(size));
94 // skip width, height, color depth, number of colors used
95 inputStream.seekg(4 * 4, ios_base::cur);
96 size = reader.readUInt32BE();
97 CHECK_MAX_SIZE(size);
98 if (size) {
99 auto data = make_unique<char[]>(size);
100 inputStream.read(data.get(), size);
101 m_value.assignData(std::move(data), size, TagDataType::Picture);
102 } else {
103 m_value.clearData();
104 }
105}
106
113{
114 const auto requiredSize(32 + m_value.mimeType().size() + m_value.description().size() + m_value.dataSize());
115 if (requiredSize > numeric_limits<std::uint32_t>::max()) {
116 throw InvalidDataException();
117 }
118 return static_cast<std::uint32_t>(requiredSize);
119}
120
125void FlacMetaDataBlockPicture::make(ostream &outputStream)
126{
127 if (m_value.mimeType().size() > numeric_limits<std::uint32_t>::max() || m_value.description().size() > numeric_limits<std::uint32_t>::max()
128 || m_value.dataSize() > numeric_limits<std::uint32_t>::max()) {
129 throw InvalidDataException();
130 }
131 BinaryWriter writer(&outputStream);
132 writer.writeUInt32BE(pictureType());
133 writer.writeUInt32BE(static_cast<std::uint32_t>(m_value.mimeType().size()));
134 writer.writeString(m_value.mimeType());
135 writer.writeUInt32BE(static_cast<std::uint32_t>(m_value.description().size()));
136 writer.writeString(m_value.description());
137 writer.writeUInt32BE(0); // skip width
138 writer.writeUInt32BE(0); // skip height
139 writer.writeUInt32BE(0); // skip color depth
140 writer.writeUInt32BE(0); // skip number of colors used
141 writer.writeUInt32BE(static_cast<std::uint32_t>(m_value.dataSize()));
142 writer.write(value().dataPointer(), static_cast<streamoff>(m_value.dataSize()));
143}
144
145} // namespace TagParser
void parseHeader(std::string_view buffer)
Parses the FLAC "METADATA_BLOCK_HEADER" which is read using the specified iterator.
void makeHeader(std::ostream &outputStream)
Writes the header to the specified outputStream.
std::uint32_t requiredSize() const
Returns the number of bytes make() will write.
void make(std::ostream &outputStream)
Makes the FLAC "METADATA_BLOCK_PICTURE".
void parse(std::istream &inputStream, std::uint32_t maxSize)
Parses the FLAC "METADATA_BLOCK_PICTURE".
std::uint32_t pictureType() const
Returns the picture type according to the ID3v2 APIC frame.
TagValue & value()
Returns the tag value the picture is read from/stored to.
void parse(std::string_view buffer)
Parses the FLAC "METADATA_BLOCK_STREAMINFO" which is read using the specified iterator.
The exception that is thrown when the data to be parsed or to be made seems invalid and therefore can...
Definition exceptions.h:25
void setMimeType(std::string_view mimeType)
Sets the MIME type.
Definition tagvalue.h:602
const std::string & mimeType() const
Returns the MIME type.
Definition tagvalue.h:590
void assignData(const char *data, std::size_t length, TagDataType type=TagDataType::Binary, TagTextEncoding encoding=TagTextEncoding::Latin1)
void setDescription(std::string_view value, TagTextEncoding encoding=TagTextEncoding::Latin1)
Sets the description.
Definition tagvalue.h:577
std::size_t dataSize() const
Returns the size of the assigned value in bytes.
Definition tagvalue.h:522
void clearData()
Clears the assigned data.
Definition tagvalue.h:501
const std::string & description() const
Returns the description.
Definition tagvalue.h:561
#define CHECK_MAX_SIZE(sizeDenotation)
Throws TruncatedDataException() if the specified sizeDenotation exceeds maxSize; otherwise maxSize is...
Definition exceptions.h:70
Contains all classes and functions of the TagInfo library.
Definition aaccodebook.h:10