mirror of
https://github.com/taglib/taglib.git
synced 2025-05-27 21:20:26 -04:00
Efficient lookup for an ID3v2 tag in MPEG files with garbage.
This looks for an ID3v2 tag until reaching the first valid MPEG frame in O(n) time.
This commit is contained in:
parent
d64c833359
commit
d2e0e55223
@ -488,28 +488,41 @@ long MPEG::File::findID3v2()
|
||||
const ByteVector headerID = ID3v2::Header::fileIdentifier();
|
||||
|
||||
seek(0);
|
||||
|
||||
const ByteVector data = readBlock(headerID.size());
|
||||
if(data.size() < headerID.size())
|
||||
return -1;
|
||||
|
||||
if(data == headerID)
|
||||
if(readBlock(headerID.size()) == headerID)
|
||||
return 0;
|
||||
|
||||
if(firstSyncByte(data[0]) && secondSynchByte(data[1]))
|
||||
Header firstHeader(this, 0, true);
|
||||
if(firstHeader.isValid())
|
||||
return -1;
|
||||
|
||||
// Look for the entire file, if neither an MEPG frame or ID3v2 tag was found
|
||||
// at the beginning of the file.
|
||||
// We don't care about the inefficiency of the code, since this is a seldom case.
|
||||
// Look for an ID3v2 tag until reaching the first valid MPEG frame.
|
||||
|
||||
const long tagOffset = find(headerID);
|
||||
if(tagOffset < 0)
|
||||
return -1;
|
||||
char frameSyncBytes[2] = {};
|
||||
char tagHeaderBytes[4] = {};
|
||||
long position = 0;
|
||||
|
||||
const long frameOffset = firstFrameOffset();
|
||||
if(frameOffset < tagOffset)
|
||||
return -1;
|
||||
while(true) {
|
||||
seek(position);
|
||||
const ByteVector buffer = readBlock(bufferSize());
|
||||
if(buffer.isEmpty())
|
||||
return -1;
|
||||
|
||||
return tagOffset;
|
||||
for(unsigned int i = 0; i < buffer.size(); ++i) {
|
||||
frameSyncBytes[0] = frameSyncBytes[1];
|
||||
frameSyncBytes[1] = buffer[i];
|
||||
if(firstSyncByte(frameSyncBytes[0]) && secondSynchByte(frameSyncBytes[1])) {
|
||||
Header header(this, position + i - 1, true);
|
||||
if(header.isValid())
|
||||
return -1;
|
||||
}
|
||||
|
||||
tagHeaderBytes[0] = tagHeaderBytes[1];
|
||||
tagHeaderBytes[1] = tagHeaderBytes[2];
|
||||
tagHeaderBytes[2] = buffer[i];
|
||||
if(headerID == tagHeaderBytes)
|
||||
return position + i - 2;
|
||||
}
|
||||
|
||||
position += bufferSize();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user