]> granicus.if.org Git - taglib/commitdiff
Fix the APE positioning code. This obviously never worked properly...
authorScott Wheeler <wheeler@kde.org>
Tue, 12 Feb 2008 23:45:42 +0000 (23:45 +0000)
committerScott Wheeler <wheeler@kde.org>
Tue, 12 Feb 2008 23:45:42 +0000 (23:45 +0000)
BUG:112904

git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@774316 283d02a7-25f6-0310-bc7c-ecb5cbfe19da

taglib/ape/apetag.cpp
taglib/ape/apetag.h
taglib/mpeg/mpegfile.cpp
taglib/mpeg/mpegfile.h

index 2d628f92cc94f207835812c2e2fb7b1aa9900acb..1c38d2bdd05a3e45762ad156053c84d1e1f0f6c9 100644 (file)
@@ -31,7 +31,6 @@
 #define WANT_CLASS_INSTANTIATION_OF_MAP (1)
 #endif
 
-#include <tdebug.h>
 #include <tfile.h>
 #include <tstring.h>
 #include <tmap.h>
@@ -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()));
   }
 }
index 1da02ea194bb67cb33929ad468e7d9198051e461..03a3c9177907c52a576af03592967dc3eee2a814 100644 (file)
@@ -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.
index f69fd20f1aa94d3be12c0fae8eb71e63461b5fba..024d8110059a6f020277758d2123738a5afc02d2 100644 (file)
@@ -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<APE::Tag>(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)
index 8a578f00d6a9ace1b060399d1590ba3c7f90e8bc..b53c94c7ce363a7ca1cd917e7acf40704a8e1e0f 100644 (file)
@@ -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