4 #include "../vorbis/vorbiscomment.h" 6 #include "../exceptions.h" 7 #include "../mediafileinfo.h" 8 #include "../mediaformat.h" 10 #include "resources/config.h" 12 #include <c++utilities/io/copy.h> 33 FlacStream::FlacStream(
MediaFileInfo &mediaFileInfo, uint64 startOffset)
35 , m_mediaFileInfo(mediaFileInfo)
48 if (!m_vorbisComment) {
49 m_vorbisComment = make_unique<VorbisComment>();
51 return m_vorbisComment.get();
60 if (!m_vorbisComment) {
63 m_vorbisComment.reset();
69 static const string context(
"parsing raw FLAC header");
78 if (
m_reader.readUInt32BE() != 0x664C6143) {
88 header.parseHeader(buffer);
94 switch (static_cast<FlacMetaDataBlockType>(header.type())) {
96 if (header.dataSize() >= 0x22) {
99 streamInfo.
parse(buffer);
106 diag.emplace_back(
DiagLevel::Critical,
"\"METADATA_BLOCK_STREAMINFO\" is truncated and will be ignored.", context);
113 if (!m_vorbisComment) {
114 m_vorbisComment = make_unique<VorbisComment>();
133 diag.emplace_back(
DiagLevel::Warning,
"\"METADATA_BLOCK_PICTURE\" contains no picture.", context);
136 if (!m_vorbisComment) {
138 m_vorbisComment = make_unique<VorbisComment>();
141 m_vorbisComment->fields().insert(make_pair(coverField.
id(), move(coverField)));
145 diag.emplace_back(
DiagLevel::Critical,
"\"METADATA_BLOCK_PICTURE\" is truncated and will be ignored.", context);
150 m_paddingSize += 4 + header.dataSize();
178 istream &originalStream = m_mediaFileInfo.
stream();
183 BE::getBytes(static_cast<uint32>(0x664C6143u), copy.buffer());
186 uint32 lastStartOffset = 0;
192 header.parseHeader(copy.buffer());
195 switch (static_cast<FlacMetaDataBlockType>(header.type())) {
199 m_istream->seekg(header.dataSize(), ios_base::cur);
204 copy.copy(originalStream,
outputStream, 4 + header.dataSize());
209 if (!m_vorbisComment) {
210 return lastStartOffset;
226 header.
setDataSize(endOffset - lastStartOffset - 4);
227 header.
setLast(!m_vorbisComment->hasField(coverId));
234 return lastStartOffset;
237 const auto coverFields = m_vorbisComment->fields().equal_range(coverId);
238 for (
auto i = coverFields.first; i != coverFields.second;) {
243 header.
setLast(++i == coverFields.second);
248 return lastStartOffset;
IoUtilities::BinaryReader m_reader
void setTypeInfo(const TypeInfoType &typeInfo)
Sets the type info of the current TagField.
bool removeVorbisComment()
Removes the assigned Vorbis comment if one is assigned; does nothing otherwise.
std::ostream & outputStream()
Returns the associated output stream.
bool isEmpty() const
Returns an indication whether an value is assigned.
uint32 makeHeader(std::ostream &stream, Diagnostics &diag)
Writes the FLAC metadata header to the specified outputStream.
Contains utility classes helping to read and write streams.
uint64 startOffset() const
Returns the start offset of the track in the associated stream.
ChronoUtilities::TimeSpan m_duration
void internalParseHeader(Diagnostics &diag) override
This method is internally called to parse header information.
uint64 size() const
Returns the size in bytes if known; otherwise returns 0.
VorbisComment * createVorbisComment()
Creates a new Vorbis comment for the stream.
const IdentifierType & id() const
Returns the id of the current TagField.
static void makePadding(std::ostream &stream, uint32 size, bool isLast, Diagnostics &diag)
Writes padding of the specified size to the specified stream.
IoUtilities::NativeFileStream & stream()
Returns the std::fstream for the current instance.
uint32 m_samplingFrequency
void setId(const IdentifierType &id)
Sets the id of the current Tag Field.
TagValue & value()
Returns the value of the current TagField.