AttachedPictureFrame::AttachedPictureFrame() : Frame("APIC")
{
- d = new AttachedPictureFramePrivate;
+ d = new AttachedPictureFramePrivate;
}
AttachedPictureFrame::AttachedPictureFrame(const ByteVector &data) : Frame(data)
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);
+}
protected:
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
+ class AttachedPictureFramePrivate;
+ AttachedPictureFramePrivate *d;
private:
- AttachedPictureFrame(const ByteVector &data, Header *h);
AttachedPictureFrame(const AttachedPictureFrame &);
AttachedPictureFrame &operator=(const AttachedPictureFrame &);
+ AttachedPictureFrame(const ByteVector &data, Header *h);
- class AttachedPictureFramePrivate;
- AttachedPictureFramePrivate *d;
+ };
+
+ //! 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;
};
}
}
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);
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);
CPPUNIT_TEST(testReadStringField);
CPPUNIT_TEST(testParseAPIC);
CPPUNIT_TEST(testParseAPIC_UTF16_BOM);
+ CPPUNIT_TEST(testParseAPICv22);
CPPUNIT_TEST(testParseGEOB);
CPPUNIT_TEST(testPOPMtoString);
CPPUNIT_TEST(testParsePOPM);
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()
{