Tag Parser  9.1.0
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
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 
14 using namespace std;
15 using namespace CppUtilities;
16 
17 namespace TagParser {
18 
29 void FlacMetaDataBlockHeader::parseHeader(const char *buffer)
30 {
31  m_last = *buffer & 0x80;
32  m_type = *buffer & (0x80 - 1);
33  m_dataSize = BE::toUInt24(buffer + 1);
34 }
35 
40 void 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 
58 void FlacMetaDataBlockStreamInfo::parse(const char *buffer)
59 {
60  BitReader reader(buffer, 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  memcpy(m_md5Sum, buffer + 0x22 - sizeof(m_md5Sum), sizeof(m_md5Sum));
70 }
71 
83 void FlacMetaDataBlockPicture::parse(istream &inputStream, std::uint32_t maxSize)
84 {
85  CHECK_MAX_SIZE(32);
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(move(data), size, TagDataType::Picture);
102  } else {
103  m_value.clearData();
104  }
105 }
106 
112 std::uint32_t FlacMetaDataBlockPicture::requiredSize() const
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 
125 void 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
CHECK_MAX_SIZE
#define CHECK_MAX_SIZE(sizeDenotation)
Throws TruncatedDataException() if the specified sizeDenotation exceeds maxSize; otherwise maxSize is...
Definition: exceptions.h:70
TagParser
Contains all classes and functions of the TagInfo library.
Definition: aaccodebook.h:10
CppUtilities
Definition: abstractcontainer.h:15
TagParser::InvalidDataException
The exception that is thrown when the data to be parsed or to be made seems invalid and therefore can...
Definition: exceptions.h:25
flacmetadata.h