Add a hack to read ID2v2.4 frames with v2.3-like sizes, written by iTunes.

The code is inside a '#ifndef NO_ITUNES_HACKS' block, so I hope it's ok to add it.


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@743534 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
This commit is contained in:
Lukáš Lalinský 2007-12-01 09:15:23 +00:00
parent fed2c020fe
commit c4a21adb8e
3 changed files with 27 additions and 3 deletions

View File

@ -54,6 +54,19 @@ public:
Frame::Header *header;
};
bool isValidFrameID(const ByteVector &frameID)
{
if(frameID.size() != 4) {
return false;
}
for(ByteVector::ConstIterator it = frameID.begin(); it != frameID.end(); it++) {
if( (*it < 'A' || *it > 'Z') && (*it < '1' || *it > '9') ) {
return false;
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
// static methods
////////////////////////////////////////////////////////////////////////////////
@ -394,6 +407,17 @@ void Frame::Header::setData(const ByteVector &data, uint version)
// the frame header (structure 4)
d->frameSize = SynchData::toUInt(data.mid(4, 4));
#ifndef NO_ITUNES_HACKS
// iTunes writes v2.4 tags with v2.3-like frame sizes
if(d->frameSize > 127) {
if(!isValidFrameID(data.mid(d->frameSize + 10, 4))) {
unsigned int uintSize = data.mid(4, 4).toUInt();
if(isValidFrameID(data.mid(uintSize + 10, 4))) {
d->frameSize = uintSize;
}
}
}
#endif
{ // read the first byte of flags
std::bitset<8> flags(data[8]);

BIN
tests/data/005411.id3 Normal file

Binary file not shown.

View File

@ -39,7 +39,7 @@ class TestID3v2 : public CppUnit::TestFixture
CPPUNIT_TEST(testParseUniqueFileIdentifierFrame);
CPPUNIT_TEST(testParseEmptyUniqueFileIdentifierFrame);
CPPUNIT_TEST(testBrokenFrame1);
//CPPUNIT_TEST(testItunes24FrameSize);
CPPUNIT_TEST(testItunes24FrameSize);
CPPUNIT_TEST(testParseUrlLinkFrame);
CPPUNIT_TEST(testRenderUrlLinkFrame);
CPPUNIT_TEST(testParseUserUrlLinkFrame);
@ -221,13 +221,13 @@ public:
f.render());
}
/*void testItunes24FrameSize()
void testItunes24FrameSize()
{
MPEG::File f("data/005411.id3", false);
CPPUNIT_ASSERT(f.tag());
CPPUNIT_ASSERT(f.ID3v2Tag()->frameListMap().contains("TIT2"));
CPPUNIT_ASSERT_EQUAL(String("Sunshine Superman"), f.ID3v2Tag()->frameListMap()["TIT2"].front()->toString());
}*/
}
};