]> granicus.if.org Git - taglib/commitdiff
Support for ID3v2.2 PIC frames
authorLukáš Lalinský <lalinsky@gmail.com>
Sat, 11 Jul 2009 14:27:17 +0000 (14:27 +0000)
committerLukáš Lalinský <lalinsky@gmail.com>
Sat, 11 Jul 2009 14:27:17 +0000 (14:27 +0000)
Patch by Marc Halbruegge
BUG:167786

git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@994836 283d02a7-25f6-0310-bc7c-ecb5cbfe19da

taglib/mpeg/id3v2/frames/attachedpictureframe.cpp
taglib/mpeg/id3v2/frames/attachedpictureframe.h
taglib/mpeg/id3v2/id3v2framefactory.cpp
tests/test_id3v2.cpp

index 3ad71557c8dcc3990950f15caf435fffb949a265..ee8f3e0b1225bd9a558bfcac9c19b0d00556011d 100644 (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);
+}
index bd95ed22d281b83310408b8924c50d26f4f91e09..90b597b85ecb8ace923e7c3afa1c1c052ab96d33 100644 (file)
@@ -205,14 +205,24 @@ namespace TagLib {
     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;
     };
   }
 }
index 18da4c3eb759a40af476ada7b89ab8ed4fa2a3b9..e412cb30c9ada811522284b32792a32dbaf0bf45 100644 (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);
index 74701781cc2cd04d3fbe9fead0f7fee98d0ba64c..5aeaa8611a5820c9067138e3150b6d4500f1d239 100644 (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()
   {