diff --git a/taglib/ape/apetag.cpp b/taglib/ape/apetag.cpp index 2d628f92..1c38d2bd 100644 --- a/taglib/ape/apetag.cpp +++ b/taglib/ape/apetag.cpp @@ -31,7 +31,6 @@ #define WANT_CLASS_INSTANTIATION_OF_MAP (1) #endif -#include #include #include #include @@ -46,10 +45,10 @@ using namespace APE; class APE::Tag::TagPrivate { public: - TagPrivate() : file(0), tagOffset(-1), tagLength(0) {} + TagPrivate() : file(0), footerLocation(-1), tagLength(0) {} File *file; - long tagOffset; + long footerLocation; long tagLength; Footer footer; @@ -66,11 +65,11 @@ APE::Tag::Tag() : TagLib::Tag() d = new TagPrivate; } -APE::Tag::Tag(File *file, long tagOffset) : TagLib::Tag() +APE::Tag::Tag(File *file, long footerLocation) : TagLib::Tag() { d = new TagPrivate; d->file = file; - d->tagOffset = tagOffset; + d->footerLocation = footerLocation; read(); } @@ -217,14 +216,14 @@ void APE::Tag::read() { if(d->file && d->file->isValid()) { - d->file->seek(d->tagOffset); + d->file->seek(d->footerLocation); d->footer.setData(d->file->readBlock(Footer::size())); if(d->footer.tagSize() <= Footer::size() || d->footer.tagSize() > uint(d->file->length())) return; - d->file->seek(d->tagOffset + Footer::size() - d->footer.tagSize()); + d->file->seek(d->footerLocation + Footer::size() - d->footer.tagSize()); parse(d->file->readBlock(d->footer.tagSize() - Footer::size())); } } diff --git a/taglib/ape/apetag.h b/taglib/ape/apetag.h index 1da02ea1..03a3c917 100644 --- a/taglib/ape/apetag.h +++ b/taglib/ape/apetag.h @@ -66,7 +66,7 @@ namespace TagLib { * Create an APE tag and parse the data in \a file with APE footer at * \a tagOffset. */ - Tag(File *file, long tagOffset); + Tag(File *file, long footerLocation); /*! * Destroys this Tag instance. diff --git a/taglib/mpeg/mpegfile.cpp b/taglib/mpeg/mpegfile.cpp index f69fd20f..024d8110 100644 --- a/taglib/mpeg/mpegfile.cpp +++ b/taglib/mpeg/mpegfile.cpp @@ -51,6 +51,7 @@ public: ID3v2Location(-1), ID3v2OriginalSize(0), APELocation(-1), + APEFooterLocation(-1), APEOriginalSize(0), ID3v1Location(-1), hasID3v2(false), @@ -72,6 +73,7 @@ public: uint ID3v2OriginalSize; long APELocation; + long APEFooterLocation; uint APEOriginalSize; long ID3v1Location; @@ -184,7 +186,7 @@ bool MPEG::File::save(int tags, bool stripOthers) // APE tag location has changed, update if it exists if(APETag()) - d->APELocation = findAPE(); + findAPE(); } else if(stripOthers) success = strip(ID3v2, false) && success; @@ -213,7 +215,6 @@ bool MPEG::File::save(int tags, bool stripOthers) insert(APETag()->render(), d->APELocation, d->APEOriginalSize); else { if(d->hasID3v1) { - debug("inserting ape tag before id3v1 tag"); insert(APETag()->render(), d->ID3v1Location, 0); d->APEOriginalSize = APETag()->footer()->completeTagSize(); d->hasAPE = true; @@ -223,6 +224,9 @@ bool MPEG::File::save(int tags, bool stripOthers) else { seek(0, End); d->APELocation = tell(); + d->APEFooterLocation = d->APELocation + + d->tag.access(APEIndex, false)->footer()->completeTagSize() + - APE::Footer::size(); writeBlock(APETag()->render()); d->APEOriginalSize = APETag()->footer()->completeTagSize(); d->hasAPE = true; @@ -279,7 +283,7 @@ bool MPEG::File::strip(int tags, bool freeMemory) // APE tag location has changed, update if it exists if(APETag()) - d->APELocation = findAPE(); + findAPE(); } if((tags & ID3v1) && d->hasID3v1) { @@ -294,9 +298,10 @@ bool MPEG::File::strip(int tags, bool freeMemory) if((tags & APE) && d->hasAPE) { removeBlock(d->APELocation, d->APEOriginalSize); d->APELocation = -1; + d->APEFooterLocation = -1; d->hasAPE = false; if(d->hasID3v1) { - if (d->ID3v1Location > d->APELocation) + if(d->ID3v1Location > d->APELocation) d->ID3v1Location -= d->APEOriginalSize; } @@ -414,16 +419,12 @@ void MPEG::File::read(bool readProperties, Properties::ReadStyle propertiesStyle // Look for an APE tag - d->APELocation = findAPE(); + findAPE(); if(d->APELocation >= 0) { - d->tag.set(APEIndex, new APE::Tag(this, d->APELocation)); - + d->tag.set(APEIndex, new APE::Tag(this, d->APEFooterLocation)); d->APEOriginalSize = APETag()->footer()->completeTagSize(); - - d->APELocation = d->APELocation + APETag()->footer()->size() - d->APEOriginalSize; - d->hasAPE = true; } @@ -559,18 +560,25 @@ long MPEG::File::findID3v1() return -1; } -long MPEG::File::findAPE() +void MPEG::File::findAPE() { if(isValid()) { seek(d->hasID3v1 ? -160 : -32, End); + long p = tell(); if(readBlock(8) == APE::Tag::fileIdentifier()) { - debug("found ape at " + String::number(int(p))); - return p; + d->APEFooterLocation = p; + seek(d->APEFooterLocation); + APE::Footer footer(readBlock(APE::Footer::size())); + d->APELocation = d->APEFooterLocation - footer.completeTagSize() + + APE::Footer::size(); + return; } } - return -1; + + d->APELocation = -1; + d->APEFooterLocation = -1; } bool MPEG::File::secondSynchByte(char byte) diff --git a/taglib/mpeg/mpegfile.h b/taglib/mpeg/mpegfile.h index 8a578f00..b53c94c7 100644 --- a/taglib/mpeg/mpegfile.h +++ b/taglib/mpeg/mpegfile.h @@ -259,7 +259,7 @@ namespace TagLib { void read(bool readProperties, Properties::ReadStyle propertiesStyle); long findID3v2(); long findID3v1(); - long findAPE(); + void findAPE(); /*! * MPEG frames can be recognized by the bit pattern 11111111 111, so the