mirror of
https://github.com/taglib/taglib.git
synced 2025-06-04 01:28:21 -04:00
Improve behavoir:
* use setValid(false) to indicate broken files * avoid reading over file-end in case of truncated files * subtract size of ID3v1 from streamSize * skip known ID3v2 tag when scanning for first FLAC-frame CCMAIL: 83924-done@bugs.kde.org CCMAIL: 85356@bugs.kde.org git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@330951 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
This commit is contained in:
parent
f650edc81d
commit
2fd6401354
@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2003 by Allan Sandfeld Jensen
|
||||
copyright : (C) 2003-2004 by Allan Sandfeld Jensen
|
||||
email : kde@carewolf.org
|
||||
***************************************************************************/
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
|
||||
#include <tbytevector.h>
|
||||
#include <tstring.h>
|
||||
#include <tlist.h>
|
||||
#include <tdebug.h>
|
||||
|
||||
#include <id3v2header.h>
|
||||
@ -32,6 +33,11 @@
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
namespace TagLib {
|
||||
namespace FLAC {
|
||||
enum BLOCK_TYPE { STREAMINFO = 0, PADDING, APPLICATION, SEEKTABLE, VORBISCOMMENT, CUESHEET };
|
||||
}}
|
||||
|
||||
class FLAC::File::FilePrivate
|
||||
{
|
||||
public:
|
||||
@ -73,6 +79,7 @@ public:
|
||||
FLAC::Tag *tag;
|
||||
|
||||
Properties *properties;
|
||||
// Map<BLOCK_TYPE, ByteVector> metaData;
|
||||
ByteVector streamInfoData;
|
||||
ByteVector xiphCommentData;
|
||||
long flacStart;
|
||||
@ -148,7 +155,7 @@ bool FLAC::File::save()
|
||||
|
||||
|
||||
// If file already have comment => find and update it
|
||||
// if not => insert one
|
||||
// if not => insert one
|
||||
// TODO: Search for padding and use that
|
||||
|
||||
if(d->hasXiphComment) {
|
||||
@ -194,7 +201,7 @@ bool FLAC::File::save()
|
||||
|
||||
// If last block was last, make this one last
|
||||
|
||||
if(lastBlock) {
|
||||
if(lastBlock) {
|
||||
|
||||
// Copy the bottom seven bits into the new value
|
||||
|
||||
@ -209,13 +216,20 @@ bool FLAC::File::save()
|
||||
d->hasXiphComment = true;
|
||||
}
|
||||
|
||||
// Update ID3 tag
|
||||
// Update ID3 tags
|
||||
|
||||
if(d->hasID3v2 && d->ID3v2Tag)
|
||||
insert(d->ID3v2Tag->render(), d->ID3v2Location, d->ID3v2OriginalSize);
|
||||
if(d->ID3v2Tag) {
|
||||
if(d->hasID3v2)
|
||||
insert(d->ID3v2Tag->render(), d->ID3v2Location, d->ID3v2OriginalSize);
|
||||
else
|
||||
insert(d->ID3v2Tag->render(), 0, 0);
|
||||
}
|
||||
|
||||
if(d->hasID3v1 && d->ID3v1Tag) {
|
||||
seek(-128, End);
|
||||
if(d->ID3v1Tag) {
|
||||
if(d->hasID3v1)
|
||||
seek(-128, End);
|
||||
else
|
||||
seek(0, End);
|
||||
writeBlock(d->ID3v1Tag->render());
|
||||
}
|
||||
|
||||
@ -254,6 +268,7 @@ Ogg::XiphComment *FLAC::File::xiphComment(bool create)
|
||||
d->comment = new Ogg::XiphComment;
|
||||
return d->comment;
|
||||
}
|
||||
|
||||
void FLAC::File::setID3v2FrameFactory(const ID3v2::FrameFactory *factory)
|
||||
{
|
||||
d->ID3v2FrameFactory = factory;
|
||||
@ -297,6 +312,8 @@ void FLAC::File::read(bool readProperties, Properties::ReadStyle propertiesStyle
|
||||
|
||||
scan();
|
||||
|
||||
if (!isValid()) return;
|
||||
|
||||
if(d->hasXiphComment)
|
||||
d->comment = new Ogg::XiphComment(xiphCommentData());
|
||||
|
||||
@ -311,14 +328,20 @@ void FLAC::File::read(bool readProperties, Properties::ReadStyle propertiesStyle
|
||||
|
||||
ByteVector FLAC::File::streamInfoData()
|
||||
{
|
||||
scan();
|
||||
return d->streamInfoData;
|
||||
if (isValid())
|
||||
return d->streamInfoData;
|
||||
// return d->metaData[STREAMINFO];
|
||||
else
|
||||
return ByteVector();
|
||||
}
|
||||
|
||||
ByteVector FLAC::File::xiphCommentData()
|
||||
{
|
||||
scan();
|
||||
return d->xiphCommentData;
|
||||
if (isValid() && d->hasXiphComment)
|
||||
return d->xiphCommentData;
|
||||
// return d->metaData[VORBISCOMMENT];
|
||||
else
|
||||
return ByteVector();
|
||||
}
|
||||
|
||||
long FLAC::File::streamLength()
|
||||
@ -336,12 +359,17 @@ void FLAC::File::scan()
|
||||
if(!isValid())
|
||||
return;
|
||||
|
||||
// Optimization: Use ID3v2 size and only skip that
|
||||
long nextPageOffset;
|
||||
long fileSize = length();
|
||||
|
||||
long nextPageOffset = find("fLaC");
|
||||
if (d->hasID3v2)
|
||||
nextPageOffset = find("fLaC", d->ID3v2Location+d->ID3v2OriginalSize);
|
||||
else
|
||||
nextPageOffset = find("fLaC");
|
||||
|
||||
if(nextPageOffset < 0) {
|
||||
debug("FLAC::File::scan() -- FLAC stream not found");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -367,37 +395,47 @@ void FLAC::File::scan()
|
||||
uint length = header.mid(1, 3).toUInt();
|
||||
|
||||
// First block should be the stream_info metadata
|
||||
if(blockType != 0) {
|
||||
if(blockType != 0) {
|
||||
debug("FLAC::File::scan() -- invalid FLAC stream");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
|
||||
d->streamInfoData = readBlock(length);
|
||||
// d->metadata.insert(STREAMINFO, readBlock(length));
|
||||
nextPageOffset += length + 4;
|
||||
|
||||
// Search through the remaining metadata
|
||||
|
||||
while(!lastBlock) {
|
||||
|
||||
header = readBlock(4);
|
||||
blockType = header[0] & 0x7f;
|
||||
lastBlock = header[0] & 0x80;
|
||||
length = header.mid(1, 3).toUInt();
|
||||
|
||||
if(blockType == 1) {
|
||||
// debug("FLAC::File::scan() -- Padding found");
|
||||
}
|
||||
// Found the vorbis-comment
|
||||
if(blockType == 4) {
|
||||
else if(blockType == 4) {
|
||||
d->xiphCommentData = readBlock(length);
|
||||
// d->metadata.insert(VORBISCOMMENT, readBlock(length));
|
||||
d->hasXiphComment = true;
|
||||
|
||||
}
|
||||
|
||||
nextPageOffset += length + 4;
|
||||
if (nextPageOffset >= fileSize) {
|
||||
debug("FLAC::File::scan() -- FLAC stream corrupted");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
seek(nextPageOffset);
|
||||
}
|
||||
|
||||
|
||||
// End of metadata, now comes the datastream
|
||||
d->streamStart = nextPageOffset;
|
||||
d->streamLength = File::length() - d->streamStart;
|
||||
if (d->hasID3v1)
|
||||
d->streamLength -= 128;
|
||||
|
||||
d->scanned = true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user