mirror of
https://github.com/taglib/taglib.git
synced 2025-05-25 12:10:26 -04:00
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.
This commit is contained in:
parent
088e063bbb
commit
866802b007
@ -33,6 +33,8 @@
|
||||
#include "tagunion.h"
|
||||
#include "dsdifffile.h"
|
||||
|
||||
#include <array>
|
||||
|
||||
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<ChunkList, 2> childChunks;
|
||||
std::array<int, 2> 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<TagTypes>(AllTags & ~tags));
|
||||
|
||||
// First: save ID3V2 chunk
|
||||
|
||||
ID3v2::Tag *id3v2Tag = d->tag.access<ID3v2::Tag>(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<DSDIFF::DIIN::Tag>(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<int>(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<int>(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<int>(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<unsigned long long>(tell()) + chunkSize > static_cast<unsigned long long>(length())) {
|
||||
if(static_cast<unsigned long long>(tell()) + chunkSize >
|
||||
static_cast<unsigned long long>(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<DSDIFF::DIIN::Tag>(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<ID3v2::Tag>(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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user