aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukáš Lalinský <lalinsky@gmail.com>2011-07-14 13:40:33 +0200
committerLukáš Lalinský <lalinsky@gmail.com>2011-07-14 13:40:33 +0200
commitb53c08c06786b0f92235a91f1c955242b5bdf7dc (patch)
tree54c5631076cbb3253912292248ac775cca006297
parent2fd10b5fd5ed2185d77a4773c8e97a0f5de25a73 (diff)
parent0ea8e44df79892ccdf27ce1d82c92dff3c678efa (diff)
Merge remote branch 'HessiJames/master'
-rw-r--r--NEWS1
-rw-r--r--taglib/mpeg/mpegfile.cpp101
-rw-r--r--taglib/mpeg/mpegfile.h6
3 files changed, 107 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index b157c457..48b01078 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ TagLib 1.8 (In Development)
* Support for writing ID3v2.3 tags.
* Added methods for checking if WMA and MP4 files are DRM-protected.
* Started using atomic int operations for reference counting.
+ * Find APE tags even if there's a Lyrics3v2 tag present (BUG:254223).
TagLib 1.7 (Mar 11, 2011)
=========================
diff --git a/taglib/mpeg/mpegfile.cpp b/taglib/mpeg/mpegfile.cpp
index a3bad823..985370c9 100644
--- a/taglib/mpeg/mpegfile.cpp
+++ b/taglib/mpeg/mpegfile.cpp
@@ -56,7 +56,9 @@ public:
ID3v1Location(-1),
hasID3v2(false),
hasID3v1(false),
+ hasLyrics3v2(false),
hasAPE(false),
+ lyrics3v2Size(0),
properties(0)
{
@@ -85,7 +87,9 @@ public:
bool hasID3v2;
bool hasID3v1;
+ bool hasLyrics3v2;
bool hasAPE;
+ long lyrics3v2Size;
Properties *properties;
};
@@ -198,6 +202,10 @@ bool MPEG::File::save(int tags, bool stripOthers, int id3v2Version)
if(ID3v1Tag())
d->ID3v1Location = findID3v1();
+ // Lyrics3v2 tag location has changed, update if it exists
+
+ findLyrics3v2();
+
// APE tag location has changed, update if it exists
if(APETag())
@@ -296,6 +304,10 @@ bool MPEG::File::strip(int tags, bool freeMemory)
if(ID3v1Tag())
d->ID3v1Location = findID3v1();
+ // Lyrics3v2 tag location has changed, update if it exists
+
+ findLyrics3v2();
+
// APE tag location has changed, update if it exists
if(APETag())
@@ -432,6 +444,10 @@ void MPEG::File::read(bool readProperties, Properties::ReadStyle propertiesStyle
d->tag.set(ID3v1Index, new ID3v1::Tag(this, d->ID3v1Location));
d->hasID3v1 = true;
}
+
+ // Look for a Lyrics3v2 tag
+
+ findLyrics3v2();
// Look for an APE tag
@@ -576,10 +592,41 @@ long MPEG::File::findID3v1()
return -1;
}
+void MPEG::File::findLyrics3v2()
+{
+ if(isValid()) {
+ long offset = -9;
+ if( d->hasID3v1 )
+ offset -= 128;
+ seek(offset, End);
+
+ if(readBlock(9) == "LYRICS200") {
+ d->hasLyrics3v2 = true;
+
+ offset -= 6;
+ seek(offset, End);
+
+ ByteVector sizeVector = readBlock(6);
+ d->lyrics3v2Size = 15 + readNumber(sizeVector);
+
+ return;
+ }
+ }
+
+ d->hasLyrics3v2 = false;
+ d->lyrics3v2Size = 0;
+}
+
void MPEG::File::findAPE()
{
if(isValid()) {
- seek(d->hasID3v1 ? -160 : -32, End);
+ long offset = -32;
+ if(d->hasID3v1)
+ offset -= 128;
+ if(d->hasLyrics3v2)
+ offset -= d->lyrics3v2Size;
+
+ seek(offset, End);
long p = tell();
@@ -597,6 +644,58 @@ void MPEG::File::findAPE()
d->APEFooterLocation = -1;
}
+long MPEG::File::readNumber(ByteVector vector)
+{
+ long number = 0;
+ int exp = 1;
+ int value = 0;
+ for(int i=vector.size(); i>0; i--) {
+ switch(vector.at(i-1)) {
+ case '1': {
+ value = 1;
+ break;
+ }
+ case '2': {
+ value = 2;
+ break;
+ }
+ case '3': {
+ value = 3;
+ break;
+ }
+ case '4': {
+ value = 4;
+ break;
+ }
+ case '5': {
+ value = 5;
+ break;
+ }
+ case '6': {
+ value = 6;
+ break;
+ }
+ case '7': {
+ value = 7;
+ break;
+ }
+ case '8': {
+ value = 8;
+ break;
+ }
+ case '9': {
+ value = 9;
+ break;
+ }
+ default:
+ value = 0;
+ }
+ number += value * exp;
+ exp *= 10;
+ }
+ return number;
+}
+
bool MPEG::File::secondSynchByte(char byte)
{
if(uchar(byte) == 0xff)
diff --git a/taglib/mpeg/mpegfile.h b/taglib/mpeg/mpegfile.h
index cff5469d..270cd7ae 100644
--- a/taglib/mpeg/mpegfile.h
+++ b/taglib/mpeg/mpegfile.h
@@ -287,9 +287,15 @@ namespace TagLib {
void read(bool readProperties, Properties::ReadStyle propertiesStyle);
long findID3v2();
long findID3v1();
+ void findLyrics3v2();
void findAPE();
/*!
+ * Extracts a number from a ByteVector
+ */
+ long readNumber(ByteVector vector);
+
+ /*!
* MPEG frames can be recognized by the bit pattern 11111111 111, so the
* first byte is easy to check for, however checking to see if the second byte
* starts with \e 111 is a bit more tricky, hence this member function.