mirror of
https://github.com/taglib/taglib.git
synced 2025-05-27 21:20:26 -04:00
Use flac padding.
Updated patch from Toby Dickenson BUG:107659 git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@995518 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
This commit is contained in:
parent
7f0f90b4ea
commit
097ae0d785
@ -42,6 +42,7 @@ namespace
|
||||
{
|
||||
enum { XiphIndex = 0, ID3v2Index = 1, ID3v1Index = 2 };
|
||||
enum { StreamInfo = 0, Padding, Application, SeekTable, VorbisComment, CueSheet };
|
||||
enum { MinPaddingLength = 4096 };
|
||||
}
|
||||
|
||||
class FLAC::File::FilePrivate
|
||||
@ -167,9 +168,49 @@ bool FLAC::File::save()
|
||||
uint blockLength = header.mid(1, 3).toUInt();
|
||||
|
||||
if(blockType == VorbisComment) {
|
||||
data[0] = header[0];
|
||||
insert(data, nextBlockOffset, blockLength + 4);
|
||||
break;
|
||||
|
||||
long paddingBreak = 0;
|
||||
|
||||
if(!isLastBlock) {
|
||||
paddingBreak = findPaddingBreak(nextBlockOffset + blockLength + 4,
|
||||
nextBlockOffset + d->xiphCommentData.size() + 8,
|
||||
&isLastBlock);
|
||||
}
|
||||
|
||||
uint paddingLength = 0;
|
||||
|
||||
if(paddingBreak) {
|
||||
|
||||
// There is space for comment and padding blocks without rewriting the
|
||||
// whole file. Note: This cannot overflow.
|
||||
|
||||
paddingLength = paddingBreak - (nextBlockOffset + d->xiphCommentData.size() + 8);
|
||||
}
|
||||
else {
|
||||
|
||||
// Not enough space, so we will have to rewrite the whole file
|
||||
// following this block
|
||||
|
||||
paddingLength = d->xiphCommentData.size();
|
||||
|
||||
if(paddingLength < MinPaddingLength)
|
||||
paddingLength = MinPaddingLength;
|
||||
|
||||
paddingBreak = nextBlockOffset + blockLength + 4;
|
||||
}
|
||||
|
||||
ByteVector padding = ByteVector::fromUInt(paddingLength);
|
||||
|
||||
padding[0] = 1;
|
||||
|
||||
if(isLastBlock)
|
||||
padding[0] |= 0x80;
|
||||
|
||||
padding.resize(paddingLength + 4);
|
||||
ByteVector pair(data);
|
||||
pair.append(padding);
|
||||
insert(pair, nextBlockOffset, paddingBreak - nextBlockOffset);
|
||||
break;
|
||||
}
|
||||
|
||||
nextBlockOffset += blockLength + 4;
|
||||
@ -373,11 +414,8 @@ void FLAC::File::scan()
|
||||
isLastBlock = (header[0] & 0x80) != 0;
|
||||
length = header.mid(1, 3).toUInt();
|
||||
|
||||
if(blockType == Padding) {
|
||||
// debug("FLAC::File::scan() -- Padding found");
|
||||
}
|
||||
// Found the vorbis-comment
|
||||
else if(blockType == VorbisComment) {
|
||||
if(blockType == VorbisComment) {
|
||||
d->xiphCommentData = readBlock(length);
|
||||
d->hasXiphComment = true;
|
||||
}
|
||||
@ -429,3 +467,34 @@ long FLAC::File::findID3v2()
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
long FLAC::File::findPaddingBreak(long nextBlockOffset, long targetOffset, bool *isLast)
|
||||
{
|
||||
// Starting from nextBlockOffset, step over padding blocks to find the
|
||||
// address of a block which is after targetOffset. Return zero if
|
||||
// a non-padding block occurs before that point.
|
||||
|
||||
while(true) {
|
||||
seek(nextBlockOffset);
|
||||
|
||||
ByteVector header = readBlock(4);
|
||||
char blockType = header[0] & 0x7f;
|
||||
bool isLastBlock = header[0] & 0x80;
|
||||
uint length = header.mid(1, 3).toUInt();
|
||||
|
||||
if(blockType != Padding)
|
||||
break;
|
||||
|
||||
nextBlockOffset += 4 + length;
|
||||
|
||||
if(nextBlockOffset >= targetOffset) {
|
||||
*isLast = isLastBlock;
|
||||
return nextBlockOffset;
|
||||
}
|
||||
|
||||
if(isLastBlock)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -191,6 +191,7 @@ namespace TagLib {
|
||||
long findID3v2();
|
||||
long findID3v1();
|
||||
ByteVector xiphCommentData() const;
|
||||
long findPaddingBreak(long nextPageOffset, long targetOffset, bool *isLast);
|
||||
|
||||
class FilePrivate;
|
||||
FilePrivate *d;
|
||||
|
Loading…
Reference in New Issue
Block a user