From 866802b0071c41a03ea387dd828cee98b6c5bd80 Mon Sep 17 00:00:00 2001 From: Scott Wheeler Date: Thu, 12 Sep 2019 07:15:39 +0200 Subject: [PATCH] Clean up formatting The only non-pure-formatting changes are: - Switch from `if(foo != NULL)` to `if(foo)` - Switch from C arrays to std::array This also moves a file-static function into the anonymous namespace This style of formatting update would need to be done on the other files as well before this branch is merged back to master. --- taglib/dsdiff/dsdifffile.cpp | 136 ++++++++++++++++++++++++----------- 1 file changed, 93 insertions(+), 43 deletions(-) diff --git a/taglib/dsdiff/dsdifffile.cpp b/taglib/dsdiff/dsdifffile.cpp index fa993ce5..55fbe54e 100644 --- a/taglib/dsdiff/dsdifffile.cpp +++ b/taglib/dsdiff/dsdifffile.cpp @@ -33,6 +33,8 @@ #include "tagunion.h" #include "dsdifffile.h" +#include + using namespace TagLib; namespace @@ -57,6 +59,19 @@ namespace return -1; } + bool isValidChunkID(const ByteVector &name) + { + if(name.size() != 4) + return false; + + for(int i = 0; i < 4; i++) { + if(name[i] < 32 || name[i] > 127) + return false; + } + + return true; + } + enum { ID3v2Index = 0, DIINIndex = 1 @@ -71,14 +86,14 @@ class DSDIFF::File::FilePrivate { public: FilePrivate() : - endianness(BigEndian), - size(0), - isID3InPropChunk(false), - duplicateID3V2chunkIndex(-1), - properties(0), - id3v2TagChunkID("ID3 "), - hasID3v2(false), - hasDiin(false) + endianness(BigEndian), + size(0), + isID3InPropChunk(false), + duplicateID3V2chunkIndex(-1), + properties(0), + id3v2TagChunkID("ID3 "), + hasID3v2(false), + hasDiin(false) { childChunkIndex[ID3v2Index] = -1; childChunkIndex[DIINIndex] = -1; @@ -94,11 +109,17 @@ public: unsigned long long size; ByteVector format; ChunkList chunks; - ChunkList childChunks[2]; - int childChunkIndex[2]; - bool isID3InPropChunk; // Two possibilities can be found: ID3V2 chunk inside PROP chunk or at root level - int duplicateID3V2chunkIndex; // 2 ID3 chunks are present. This is then the index of the one in - // PROP chunk that will be removed upon next save to remove duplicates. + std::array childChunks; + std::array childChunkIndex; + /* + * Two possibilities can be found: ID3V2 chunk inside PROP chunk or at root level + */ + bool isID3InPropChunk; + /* + * ID3 chunks are present. This is then the index of the one in PROP chunk that + * will be removed upon next save to remove duplicates. + */ + int duplicateID3V2chunkIndex; Properties *properties; @@ -222,11 +243,12 @@ bool DSDIFF::File::save(TagTypes tags, StripTags strip, ID3v2::Version version) File::strip(static_cast(AllTags & ~tags)); // First: save ID3V2 chunk + ID3v2::Tag *id3v2Tag = d->tag.access(ID3v2Index, false); if(tags & ID3v2 && id3v2Tag) { if(d->isID3InPropChunk) { - if(id3v2Tag != NULL && !id3v2Tag->isEmpty()) { + if(id3v2Tag && !id3v2Tag->isEmpty()) { setChildChunkData(d->id3v2TagChunkID, id3v2Tag->render(version), PROPChunk); d->hasID3v2 = true; } @@ -237,7 +259,7 @@ bool DSDIFF::File::save(TagTypes tags, StripTags strip, ID3v2::Version version) } } else { - if(id3v2Tag != NULL && !id3v2Tag->isEmpty()) { + if(id3v2Tag && !id3v2Tag->isEmpty()) { setRootChunkData(d->id3v2TagChunkID, id3v2Tag->render(version)); d->hasID3v2 = true; } @@ -250,6 +272,7 @@ bool DSDIFF::File::save(TagTypes tags, StripTags strip, ID3v2::Version version) } // Second: save the DIIN chunk + DSDIFF::DIIN::Tag *diinTag = d->tag.access(DIINIndex, false); if(tags & DIIN && diinTag) { @@ -338,10 +361,12 @@ void DSDIFF::File::setRootChunkData(unsigned int i, const ByteVector &data) // Non null data: update chunk // First we update the global size + d->size += ((data.size() + 1) & ~1) - (d->chunks[i].size + d->chunks[i].padding); insert(ByteVector::fromLongLong(d->size, d->endianness == BigEndian), 4, 8); // Now update the specific chunk + writeChunk(d->chunks[i].name, data, d->chunks[i].offset - 12, @@ -351,6 +376,7 @@ void DSDIFF::File::setRootChunkData(unsigned int i, const ByteVector &data) d->chunks[i].padding = (data.size() & 0x01) ? 1 : 0; // Finally update the internal offsets + updateRootChunksStructure(i + 1); } @@ -401,16 +427,20 @@ void DSDIFF::File::removeChildChunk(unsigned int i, unsigned int childChunkNum) unsigned long long removedChunkTotalSize = childChunks[i].size + childChunks[i].padding + 12; d->size -= removedChunkTotalSize; insert(ByteVector::fromLongLong(d->size, d->endianness == BigEndian), 4, 8); + // Update child chunk size + d->chunks[d->childChunkIndex[childChunkNum]].size -= removedChunkTotalSize; insert(ByteVector::fromLongLong(d->chunks[d->childChunkIndex[childChunkNum]].size, d->endianness == BigEndian), d->chunks[d->childChunkIndex[childChunkNum]].offset - 8, 8); // Remove the chunk + removeBlock(childChunks[i].offset - 12, removedChunkTotalSize); // Update the internal offsets // For child chunks + if((i + 1) < childChunks.size()) { childChunks[i + 1].offset = childChunks[i].offset; i++; @@ -420,6 +450,7 @@ void DSDIFF::File::removeChildChunk(unsigned int i, unsigned int childChunkNum) } // And for root chunks + for(i = d->childChunkIndex[childChunkNum] + 1; i < d->chunks.size(); i++) d->chunks[i].offset = d->chunks[i - 1].offset + 12 + d->chunks[i - 1].size + d->chunks[i - 1].padding; @@ -440,16 +471,21 @@ void DSDIFF::File::setChildChunkData(unsigned int i, // Non null data: update chunk // First we update the global size + d->size += ((data.size() + 1) & ~1) - (childChunks[i].size + childChunks[i].padding); + insert(ByteVector::fromLongLong(d->size, d->endianness == BigEndian), 4, 8); + // And the PROP chunk size - d->chunks[d->childChunkIndex[childChunkNum]].size += ((data.size() + 1) & ~1) - - (childChunks[i].size + childChunks[i].padding); + + d->chunks[d->childChunkIndex[childChunkNum]].size += + ((data.size() + 1) & ~1) - (childChunks[i].size + childChunks[i].padding); insert(ByteVector::fromLongLong(d->chunks[d->childChunkIndex[childChunkNum]].size, d->endianness == BigEndian), d->chunks[d->childChunkIndex[childChunkNum]].offset - 8, 8); // Now update the specific chunk + writeChunk(childChunks[i].name, data, childChunks[i].offset - 12, @@ -487,17 +523,22 @@ void DSDIFF::File::setChildChunkData(const ByteVector &name, } // Do not attempt to remove a non existing chunk + if(data.isEmpty()) return; // Couldn't find an existing chunk, so let's create a new one. + unsigned int i = childChunks.size() - 1; unsigned long offset = childChunks[i].offset + childChunks[i].size + childChunks[i].padding; // First we update the global size + d->size += (offset & 1) + ((data.size() + 1) & ~1) + 12; insert(ByteVector::fromLongLong(d->size, d->endianness == BigEndian), 4, 8); + // And the child chunk size + d->chunks[d->childChunkIndex[childChunkNum]].size += (offset & 1) + ((data.size() + 1) & ~1) + 12; insert(ByteVector::fromLongLong(d->chunks[d->childChunkIndex[childChunkNum]].size, @@ -505,6 +546,7 @@ void DSDIFF::File::setChildChunkData(const ByteVector &name, d->chunks[d->childChunkIndex[childChunkNum]].offset - 8, 8); // Now add the chunk to the file + unsigned long long nextRootChunkIdx = length(); if((d->childChunkIndex[childChunkNum] + 1) < static_cast(d->chunks.size())) nextRootChunkIdx = d->chunks[d->childChunkIndex[childChunkNum] + 1].offset - 12; @@ -514,6 +556,7 @@ void DSDIFF::File::setChildChunkData(const ByteVector &name, (offset & 1) ? 1 : 0); // For root chunks + updateRootChunksStructure(d->childChunkIndex[childChunkNum] + 1); Chunk64 chunk; @@ -525,19 +568,6 @@ void DSDIFF::File::setChildChunkData(const ByteVector &name, childChunks.push_back(chunk); } -static bool isValidChunkID(const ByteVector &name) -{ - if(name.size() != 4) - return false; - - for(int i = 0; i < 4; i++) { - if(name[i] < 32 || name[i] > 127) - return false; - } - - return true; -} - void DSDIFF::File::updateRootChunksStructure(unsigned int startingChunk) { for(unsigned int i = startingChunk; i < d->chunks.size(); i++) @@ -545,6 +575,7 @@ void DSDIFF::File::updateRootChunksStructure(unsigned int startingChunk) + d->chunks[i - 1].size + d->chunks[i - 1].padding; // Update childchunks structure as well + if(d->childChunkIndex[PROPChunk] >= static_cast(startingChunk)) { ChunkList &childChunksToUpdate = d->childChunks[PROPChunk]; if(childChunksToUpdate.size() > 0) { @@ -553,6 +584,7 @@ void DSDIFF::File::updateRootChunksStructure(unsigned int startingChunk) childChunksToUpdate[i].offset = childChunksToUpdate[i - 1].offset + 12 + childChunksToUpdate[i - 1].size + childChunksToUpdate[i - 1].padding; } + } if(d->childChunkIndex[DIINChunk] >= static_cast(startingChunk)) { ChunkList &childChunksToUpdate = d->childChunks[DIINChunk]; @@ -574,6 +606,7 @@ void DSDIFF::File::read(bool readProperties, Properties::ReadStyle propertiesSty d->format = readBlock(4); // + 12: chunk header at least, fix for additional junk bytes + while(tell() + 12 <= length()) { ByteVector chunkName = readBlock(4); unsigned long long chunkSize = readBlock(8).toLongLong(bigEndian); @@ -584,7 +617,8 @@ void DSDIFF::File::read(bool readProperties, Properties::ReadStyle propertiesSty break; } - if(static_cast(tell()) + chunkSize > static_cast(length())) { + if(static_cast(tell()) + chunkSize > + static_cast(length())) { debug("DSDIFF::File::read() -- Chunk '" + chunkName + "' has invalid size (larger than the file size)"); setValid(false); @@ -599,6 +633,7 @@ void DSDIFF::File::read(bool readProperties, Properties::ReadStyle propertiesSty seek(chunk.size, Current); // Check padding + chunk.padding = 0; long uPosNotPadded = tell(); if((uPosNotPadded & 0x01) != 0) { @@ -612,10 +647,14 @@ void DSDIFF::File::read(bool readProperties, Properties::ReadStyle propertiesSty d->chunks.push_back(chunk); } - unsigned long long lengthDSDSamplesTimeChannels = 0; // For DSD uncompressed - unsigned long long audioDataSizeinBytes = 0; // For computing bitrate - unsigned long dstNumFrames = 0; // For DST compressed frames - unsigned short dstFrameRate = 0; // For DST compressed frames + // For DSD uncompressed + unsigned long long lengthDSDSamplesTimeChannels = 0; + // For computing bitrate + unsigned long long audioDataSizeinBytes = 0; + // For DST compressed frames + unsigned long dstNumFrames = 0; + // For DST compressed frames + unsigned short dstFrameRate = 0; for(unsigned int i = 0; i < d->chunks.size(); i++) { if(d->chunks[i].name == "DSD ") { @@ -650,7 +689,8 @@ void DSDIFF::File::read(bool readProperties, Properties::ReadStyle propertiesSty // Found the DST frame information chunk dstNumFrames = readBlock(4).toUInt(bigEndian); dstFrameRate = readBlock(2).toUShort(bigEndian); - break; // Found the wanted one, no need to look at the others + // Found the wanted one, no need to look at the others + break; } seek(dstChunkSize, Current); @@ -669,7 +709,8 @@ void DSDIFF::File::read(bool readProperties, Properties::ReadStyle propertiesSty d->childChunkIndex[PROPChunk] = i; // Now decodes the chunks inside the PROP chunk long long propChunkEnd = d->chunks[i].offset + d->chunks[i].size; - seek(d->chunks[i].offset + 4); // +4 to remove the 'SND ' marker at beginning of 'PROP' chunk + // +4 to remove the 'SND ' marker at beginning of 'PROP' chunk + seek(d->chunks[i].offset + 4); while(tell() + 12 <= propChunkEnd) { ByteVector propChunkName = readBlock(4); long long propChunkSize = readBlock(8).toLongLong(bigEndian); @@ -711,7 +752,9 @@ void DSDIFF::File::read(bool readProperties, Properties::ReadStyle propertiesSty else if(d->chunks[i].name == "DIIN") { d->childChunkIndex[DIINChunk] = i; d->hasDiin = true; + // Now decode the chunks inside the DIIN chunk + long long diinChunkEnd = d->chunks[i].offset + d->chunks[i].size; seek(d->chunks[i].offset); @@ -740,8 +783,10 @@ void DSDIFF::File::read(bool readProperties, Properties::ReadStyle propertiesSty seek(chunk.size, Current); // Check padding + chunk.padding = 0; long uPosNotPadded = tell(); + if((uPosNotPadded & 0x01) != 0) { ByteVector iByte = readBlock(1); if((iByte.size() != 1) || (iByte[0] != 0)) @@ -776,10 +821,12 @@ void DSDIFF::File::read(bool readProperties, Properties::ReadStyle propertiesSty unsigned short channels=0; for(unsigned int i = 0; i < d->childChunks[PROPChunk].size(); i++) { - if(d->childChunks[PROPChunk][i].name == "ID3 " || d->childChunks[PROPChunk][i].name == "id3 ") { + if(d->childChunks[PROPChunk][i].name == "ID3 " || + d->childChunks[PROPChunk][i].name == "id3 ") { if(d->hasID3v2) { d->duplicateID3V2chunkIndex = i; - continue; // ID3V2 tag has already been found at root level + // ID3V2 tag has already been found at root level + continue; } d->id3v2TagChunkID = d->childChunks[PROPChunk][i].name; d->tag.set(ID3v2Index, new ID3v2::Tag(this, d->childChunks[PROPChunk][i].offset)); @@ -799,6 +846,7 @@ void DSDIFF::File::read(bool readProperties, Properties::ReadStyle propertiesSty } // Read title & artist from DIIN chunk + d->tag.access(DIINIndex, true); if(d->hasDiin) { @@ -826,8 +874,9 @@ void DSDIFF::File::read(bool readProperties, Properties::ReadStyle propertiesSty if(lengthDSDSamplesTimeChannels == 0) { // DST compressed signal : need to compute length of DSD uncompressed frames if(dstFrameRate > 0) - lengthDSDSamplesTimeChannels = (unsigned long long)dstNumFrames - * (unsigned long long)sampleRate / (unsigned long long)dstFrameRate; + lengthDSDSamplesTimeChannels = (unsigned long long) dstNumFrames * + (unsigned long long) sampleRate / + (unsigned long long) dstFrameRate; else lengthDSDSamplesTimeChannels = 0; } @@ -838,7 +887,7 @@ void DSDIFF::File::read(bool readProperties, Properties::ReadStyle propertiesSty } int bitrate = 0; if(lengthDSDSamplesTimeChannels > 0) - bitrate = (audioDataSizeinBytes*8*sampleRate) / lengthDSDSamplesTimeChannels / 1000; + bitrate = (audioDataSizeinBytes * 8 * sampleRate) / lengthDSDSamplesTimeChannels / 1000; d->properties = new Properties(sampleRate, channels, @@ -849,7 +898,8 @@ void DSDIFF::File::read(bool readProperties, Properties::ReadStyle propertiesSty if(!ID3v2Tag()) { d->tag.access(ID3v2Index, true); - d->isID3InPropChunk = false; // By default, ID3 chunk is at root level + // By default, ID3 chunk is at root level + d->isID3InPropChunk = false; d->hasID3v2 = false; } }