Support for ID3v2.2 PIC frames

Patch by Marc Halbruegge
BUG:167786


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@994836 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
This commit is contained in:
Lukáš Lalinský 2009-07-11 14:27:17 +00:00
parent 39e6891c92
commit 0f11c5ab0c
4 changed files with 94 additions and 9 deletions

View File

@ -50,7 +50,7 @@ public:
AttachedPictureFrame::AttachedPictureFrame() : Frame("APIC")
{
d = new AttachedPictureFramePrivate;
d = new AttachedPictureFramePrivate;
}
AttachedPictureFrame::AttachedPictureFrame(const ByteVector &data) : Frame(data)
@ -174,3 +174,51 @@ AttachedPictureFrame::AttachedPictureFrame(const ByteVector &data, Header *h) :
d = new AttachedPictureFramePrivate;
parseFields(fieldData(data));
}
////////////////////////////////////////////////////////////////////////////////
// support for ID3v2.2 PIC frames
////////////////////////////////////////////////////////////////////////////////
void AttachedPictureFrameV22::parseFields(const ByteVector &data)
{
if(data.size() < 5) {
debug("A picture frame must contain at least 5 bytes.");
return;
}
d->textEncoding = String::Type(data[0]);
int pos = 1;
String fixedString = String(data.mid(pos, 3), String::Latin1);
pos += 3;
// convert fixed string image type to mime string
if (fixedString.upper() == "JPG") {
d->mimeType = "image/jpeg";
} else if (fixedString.upper() == "PNG") {
d->mimeType = "image/png";
} else {
debug("probably unsupported image type");
d->mimeType = "image/" + fixedString;
}
d->type = (TagLib::ID3v2::AttachedPictureFrame::Type)data[pos++];
d->description = readStringField(data, d->textEncoding, &pos);
d->data = data.mid(pos);
}
AttachedPictureFrameV22::AttachedPictureFrameV22(const ByteVector &data, Header *h)
{
d = new AttachedPictureFramePrivate;
// set v2.2 header to make fieldData work correctly
setHeader(h, true);
parseFields(fieldData(data));
// now set the v2.4 header
Frame::Header *newHeader = new Frame::Header("APIC");
newHeader->setFrameSize(h->frameSize());
setHeader(newHeader, false);
}

View File

@ -205,14 +205,24 @@ namespace TagLib {
protected:
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
private:
AttachedPictureFrame(const ByteVector &data, Header *h);
AttachedPictureFrame(const AttachedPictureFrame &);
AttachedPictureFrame &operator=(const AttachedPictureFrame &);
class AttachedPictureFramePrivate;
AttachedPictureFramePrivate *d;
private:
AttachedPictureFrame(const AttachedPictureFrame &);
AttachedPictureFrame &operator=(const AttachedPictureFrame &);
AttachedPictureFrame(const ByteVector &data, Header *h);
};
//! support for ID3v2.2 PIC frames
class TAGLIB_EXPORT AttachedPictureFrameV22 : public AttachedPictureFrame
{
protected:
virtual void parseFields(const ByteVector &data);
private:
AttachedPictureFrameV22(const ByteVector &data, Header *h);
friend class FrameFactory;
};
}
}

View File

@ -183,7 +183,15 @@ Frame *FrameFactory::createFrame(const ByteVector &origData, Header *tagHeader)
return f;
}
// Relative Volume Adjustment (frames 4.11)
// ID3v2.2 Attached Picture
if(frameID == "PIC") {
AttachedPictureFrame *f = new AttachedPictureFrameV22(data, header);
d->setTextEncoding(f);
return f;
}
// Relative Volume Adjustment (frames 4.11)
if(frameID == "RVA2")
return new RelativeVolumeFrame(data, header);
@ -293,7 +301,6 @@ bool FrameFactory::updateFrame(Frame::Header *header) const
convertFrame("IPL", "TIPL", header);
convertFrame("MCI", "MCDI", header);
convertFrame("MLL", "MLLT", header);
convertFrame("PIC", "APIC", header);
convertFrame("POP", "POPM", header);
convertFrame("REV", "RVRB", header);
convertFrame("SLT", "SYLT", header);

View File

@ -38,6 +38,7 @@ class TestID3v2 : public CppUnit::TestFixture
CPPUNIT_TEST(testReadStringField);
CPPUNIT_TEST(testParseAPIC);
CPPUNIT_TEST(testParseAPIC_UTF16_BOM);
CPPUNIT_TEST(testParseAPICv22);
CPPUNIT_TEST(testParseGEOB);
CPPUNIT_TEST(testPOPMtoString);
CPPUNIT_TEST(testParsePOPM);
@ -132,6 +133,25 @@ public:
CPPUNIT_ASSERT_EQUAL(ByteVector("\xff\xd8\xff", 3), f.picture());
}
void testParseAPICv22()
{
ID3v2::FrameFactory *factory = ID3v2::FrameFactory::instance();
ByteVector data = ByteVector("PIC"
"\x00\x00\x08"
"\x00"
"JPG"
"\x01"
"d\x00"
"\x00", 18);
ID3v2::AttachedPictureFrame *frame =
static_cast<TagLib::ID3v2::AttachedPictureFrame*>(factory->createFrame(data, TagLib::uint(2)));
CPPUNIT_ASSERT(frame);
CPPUNIT_ASSERT_EQUAL(String("image/jpeg"), frame->mimeType());
CPPUNIT_ASSERT_EQUAL(ID3v2::AttachedPictureFrame::FileIcon, frame->type());
CPPUNIT_ASSERT_EQUAL(String("d"), frame->description());
}
// http://bugs.kde.org/show_bug.cgi?id=151078
void testParseGEOB()
{