mirror of
https://github.com/taglib/taglib.git
synced 2025-05-27 21:20:26 -04:00
Decode unsynchronized ID3v2 frames efficiently.
It makes a great difference when decoding huge unsynchronized ID3v2 frames.
This commit is contained in:
parent
dadfe79799
commit
a9acca5d81
1
NEWS
1
NEWS
@ -3,6 +3,7 @@ TagLib 1.11 (Jan 30, 2016)
|
||||
|
||||
* Better handling of PCM WAV files with a 'fact' chunk.
|
||||
* Better handling of corrupted APE tags.
|
||||
* Efficient decoding of unsynchronized ID3v2 frames.
|
||||
* Fixed text encoding when saving certain frames in ID3v2.3 tags.
|
||||
* Several smaller bug fixes and performance improvements.
|
||||
|
||||
|
@ -74,11 +74,29 @@ ByteVector SynchData::fromUInt(unsigned int value)
|
||||
|
||||
ByteVector SynchData::decode(const ByteVector &data)
|
||||
{
|
||||
// We have this optimized method instead of using ByteVector::replace(),
|
||||
// since it makes a great difference when decoding huge unsynchronized frames.
|
||||
|
||||
if(data.size() < 2)
|
||||
return data;
|
||||
|
||||
ByteVector result = data;
|
||||
|
||||
ByteVector pattern(2, char(0));
|
||||
pattern[0] = '\xFF';
|
||||
pattern[1] = '\x00';
|
||||
char *begin = result.data();
|
||||
char *end = begin + result.size();
|
||||
|
||||
return result.replace(pattern, '\xFF');
|
||||
char *dst = begin;
|
||||
const char *src = begin;
|
||||
|
||||
do {
|
||||
*dst++ = *src++;
|
||||
|
||||
if(*(src - 1) == '\xff' && *src == '\x00')
|
||||
src++;
|
||||
|
||||
} while (src < end);
|
||||
|
||||
result.resize(static_cast<unsigned int>(dst - begin));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ class TestID3v2SynchData : public CppUnit::TestFixture
|
||||
CPPUNIT_TEST(testToUIntBrokenAndTooLarge);
|
||||
CPPUNIT_TEST(testDecode1);
|
||||
CPPUNIT_TEST(testDecode2);
|
||||
CPPUNIT_TEST(testDecode3);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
@ -104,6 +105,14 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("\xff\x44", 2), a);
|
||||
}
|
||||
|
||||
void testDecode3()
|
||||
{
|
||||
ByteVector a("\xff\xff\x00", 3);
|
||||
a = ID3v2::SynchData::decode(a);
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned int)2, a.size());
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("\xff\xff", 2), a);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(TestID3v2SynchData);
|
||||
|
Loading…
Reference in New Issue
Block a user