Tag Parser 12.4.0
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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...
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