]> granicus.if.org Git - taglib/commitdiff
Support for ASF embedded pictures
authorLukáš Lalinský <lalinsky@gmail.com>
Sun, 16 Jan 2011 11:57:12 +0000 (11:57 +0000)
committerLukáš Lalinský <lalinsky@gmail.com>
Sun, 16 Jan 2011 11:57:12 +0000 (11:57 +0000)
Patch by Anton Sergunov <setosha@gmail.com>

CCMAIL: setosha@gmail.com

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

14 files changed:
taglib/CMakeLists.txt
taglib/asf/CMakeLists.txt
taglib/asf/Makefile.am
taglib/asf/asfattribute.cpp
taglib/asf/asfattribute.h
taglib/asf/asffile.cpp
taglib/asf/asffile.h
taglib/asf/asfpicture.cpp [new file with mode: 0644]
taglib/asf/asfpicture.h [new file with mode: 0644]
taglib/taglib.pro
taglib/toolkit/tbytevector.cpp
taglib/toolkit/tbytevector.h
tests/test_asf.cpp
tests/test_bytevector.cpp

index 70da391db232a8de707995d3f008a7a2263a306c..f050a5c409d1bd3f3316260be0abcf7c525ec964 100644 (file)
@@ -150,6 +150,7 @@ asf/asftag.cpp
 asf/asffile.cpp
 asf/asfproperties.cpp
 asf/asfattribute.cpp
+asf/asfpicture.cpp
 )
 ELSE(WITH_ASF)
 SET(asf_SRCS)
index 1cf3569ad48a47a0402f8658146bdcd43eac4229..2855beca9a340389f9c825af8baa049f81ccbe87 100644 (file)
@@ -1 +1 @@
-INSTALL( FILES  asffile.h asfproperties.h asftag.h asfattribute.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib)
+INSTALL( FILES  asffile.h asfproperties.h asftag.h asfattribute.h asfpicture.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib)
index b5f79959f729191dcabb73080b23e583f38b35ff..1ac457f5ab9ba637de1957e20d0e068c7a45a3ac 100644 (file)
@@ -6,7 +6,7 @@ INCLUDES = \
 
 noinst_LTLIBRARIES = libasf.la
 
-libasf_la_SOURCES = asfattribute.cpp asffile.cpp asfproperties.cpp asftag.cpp
+libasf_la_SOURCES = asfattribute.cpp asffile.cpp asfproperties.cpp asftag.cpp asfpicture.cpp
 
-taglib_include_HEADERS = asfattribute.h asffile.h asfproperties.h asftag.h
+taglib_include_HEADERS = asfattribute.h asffile.h asfproperties.h asftag.h asfpicture.h
 taglib_includedir = $(includedir)/taglib
index 3405f980b21d422b16153d8a4f7ff74cd6f33309..fd30456e9471c7c66009893248bf3dfff5d9a036 100644 (file)
@@ -40,11 +40,13 @@ class ASF::Attribute::AttributePrivate : public RefCounter
 {
 public:
   AttributePrivate()
-    : stream(0),
+    : pictureValue(ASF::Picture::fromInvalid()),
+      stream(0),
       language(0) {}
   AttributeTypes type;
   String stringValue;
   ByteVector byteVectorValue;
+  ASF::Picture pictureValue;
   union {
     unsigned int intValue;
     unsigned short shortValue;
@@ -101,6 +103,13 @@ ASF::Attribute::Attribute(const ByteVector &value)
   d->byteVectorValue = value;
 }
 
+ASF::Attribute::Attribute(const ASF::Picture &value)
+{
+  d = new AttributePrivate;
+  d->type = BytesType;
+  d->pictureValue = value;
+}
+
 ASF::Attribute::Attribute(unsigned int value)
 {
   d = new AttributePrivate;
@@ -144,6 +153,8 @@ ASF::Attribute::toString() const
 ByteVector
 ASF::Attribute::toByteVector() const
 {
+  if(d->pictureValue.isValid())
+    return d->pictureValue.render();
   return d->byteVectorValue;
 }
 
@@ -171,12 +182,18 @@ ASF::Attribute::toULongLong() const
   return d->longLongValue;
 }
 
+ASF::Picture
+ASF::Attribute::toPicture() const
+{
+  return d->pictureValue;
+}
+
 String
 ASF::Attribute::parse(ASF::File &f, int kind)
 {
-  int size, nameLength;
+  uint size, nameLength;
   String name;
-
+  d->pictureValue = Picture::fromInvalid();
   // extended content descriptor
   if(kind == 0) {
     nameLength = f.readWORD();
@@ -234,6 +251,13 @@ ASF::Attribute::parse(ASF::File &f, int kind)
     break;
   }
 
+  if(d->type == BytesType && name == "WM/Picture") {
+    d->pictureValue.parse(d->byteVectorValue);
+    if(d->pictureValue.isValid()) {
+      d->byteVectorValue.clear();
+    }
+  }
+
   return name;
 }
 
@@ -252,6 +276,8 @@ ASF::Attribute::dataSize() const
   case UnicodeType:
     return d->stringValue.size() * 2 + 2;
   case BytesType:
+    if(d->pictureValue.isValid())
+      return d->pictureValue.dataSize();
   case GuidType:
     return d->byteVectorValue.size();
   }
@@ -290,6 +316,10 @@ ASF::Attribute::render(const String &name, int kind) const
     break;
 
   case BytesType:
+    if(d->pictureValue.isValid()) {
+      data.append(d->pictureValue.render());
+      break;
+    }
   case GuidType:
     data.append(d->byteVectorValue);
     break;
index c30e4e4c0464e85d597c03c215d15fadd4cb3f6a..561869997446c02e74466f3cc803ca7b97ab94d2 100644 (file)
@@ -29,6 +29,7 @@
 #include "tstring.h"
 #include "tbytevector.h"
 #include "taglib_export.h"
+#include "asfpicture.h"
 
 namespace TagLib
 {
@@ -37,6 +38,7 @@ namespace TagLib
   {
 
     class File;
+    class Picture;
 
     class TAGLIB_EXPORT Attribute
     {
@@ -68,7 +70,20 @@ namespace TagLib
       /*!
        * Constructs an attribute with \a key and a BytesType \a value.
        */
-      Attribute(const ByteVector &value);
+      Attribute(const ByteVector &value);      
+
+      /*!
+       * Constructs an attribute with \a key and a Picture \a value.
+       *
+       * This attribute is compatible with the ID3 frame, APIC. The ID3 specification for the APIC frame stipulates that,
+       * while there may be any number of APIC frames associated with a file,
+       * only one may be of type 1 and only one may be of type 2.
+       *
+       * The specification also states that the description of the picture can be no longer than 64 characters, but can be empty.
+       * WM/Picture attributes added with TagLib::ASF are not automatically validated to conform to ID3 specifications.
+       * You must add code in your application to perform validations if you want to maintain complete compatibility with ID3.
+       */
+      Attribute(const Picture &value);
 
       /*!
        * Constructs an attribute with \a key and a DWordType \a value.
@@ -140,6 +155,11 @@ namespace TagLib
        */
       ByteVector toByteVector() const;
 
+      /*!
+       * Returns the Picture \a value.
+       */
+      Picture toPicture() const;
+
       /*!
        * Returns the language number, or 0 is no stream number was set.
        */
@@ -176,7 +196,6 @@ namespace TagLib
       class AttributePrivate;
       AttributePrivate *d;
     };
-
   }
 
 }
index 30433cd9bab9e2e613cca8b27ca8abae1c51d769..c0cab9501f53754c7348720b508614de16c21d89 100644 (file)
@@ -518,7 +518,7 @@ int ASF::File::readBYTE()
 int ASF::File::readWORD()
 {
   ByteVector v = readBlock(2);
-  return v.toShort(false);
+  return v.toUShort(false);
 }
 
 unsigned int ASF::File::readDWORD()
index ea148323b815c17282ba2175c08655d08463eecc..9242aa68df8a908b1699a60f515cd114f11a7eec 100644 (file)
@@ -97,6 +97,7 @@ namespace TagLib {
       void read(bool readProperties, Properties::ReadStyle propertiesStyle);
 
       friend class Attribute;
+      friend class Picture;
 
       class BaseObject;
       class UnknownObject;
diff --git a/taglib/asf/asfpicture.cpp b/taglib/asf/asfpicture.cpp
new file mode 100644 (file)
index 0000000..ecf658c
--- /dev/null
@@ -0,0 +1,185 @@
+/**************************************************************************
+    copyright            : (C) 2005-2007 by Lukáš Lalinský
+    email                : lalinsky@gmail.com
+ **************************************************************************/
+
+/***************************************************************************
+ *   This library is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU Lesser General Public License version   *
+ *   2.1 as published by the Free Software Foundation.                     *
+ *                                                                         *
+ *   This library is distributed in the hope that it will be useful, but   *
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
+ *   Lesser General Public License for more details.                       *
+ *                                                                         *
+ *   You should have received a copy of the GNU Lesser General Public      *
+ *   License along with this library; if not, write to the Free Software   *
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
+ *   USA                                                                   *
+ *                                                                         *
+ *   Alternatively, this file is available under the Mozilla Public        *
+ *   License Version 1.1.  You may obtain a copy of the License at         *
+ *   http://www.mozilla.org/MPL/                                           *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef WITH_ASF
+
+#include <taglib.h>
+#include <tdebug.h>
+#include "asfattribute.h"
+#include "asffile.h"
+#include "asfpicture.h"
+
+using namespace TagLib;
+
+class ASF::Picture::PicturePriavte : public RefCounter
+{
+public:
+  bool valid;
+  Type type;
+  String mimeType;
+  String description;
+  ByteVector picture;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Picture class members
+////////////////////////////////////////////////////////////////////////////////
+
+ASF::Picture::Picture()
+{
+  d = new PicturePriavte();
+  d->valid = true;
+}
+
+ASF::Picture::Picture(const Picture& other)
+  : d(other.d)
+{
+  d->ref();
+}
+
+ASF::Picture::~Picture()
+{
+  if(d->deref())
+    delete d;
+}
+
+bool ASF::Picture::isValid() const
+{
+  return d->valid;
+}
+
+String ASF::Picture::mimeType() const
+{
+  return d->mimeType;
+}
+
+void ASF::Picture::setMimeType(const String &value)
+{
+  d->mimeType = value;
+}
+
+ASF::Picture::Type ASF::Picture::type() const
+{
+  return d->type;
+}
+
+void ASF::Picture::setType(const ASF::Picture::Type& t)
+{
+  d->type = t;
+}
+
+String ASF::Picture::description() const
+{
+  return d->description;
+}
+
+void ASF::Picture::setDescription(const String &desc)
+{
+  d->description = desc;
+}
+
+ByteVector ASF::Picture::picture() const
+{
+  return d->picture;
+}
+
+void ASF::Picture::setPicture(const ByteVector &p)
+{
+  d->picture = p;
+}
+
+int ASF::Picture::dataSize() const
+{
+  return
+    9 + (d->mimeType.length() + d->description.length()) * 2 +
+    d->picture.size();
+}
+
+ASF::Picture& ASF::Picture::operator=(const ASF::Picture& other)
+{
+  if(other.d != d) {
+    if(d->deref())
+      delete d;
+    d = other.d;
+    d->ref();
+  }
+  return *this;
+}
+
+ByteVector ASF::Picture::render() const
+{
+  if(!isValid())
+    return ByteVector::null;
+  return
+    ByteVector((char)d->type) +
+    ByteVector::fromUInt(d->picture.size(), false) +
+    ASF::File::renderString(d->mimeType) +
+    ASF::File::renderString(d->description) +
+    d->picture;
+}
+
+void ASF::Picture::parse(const ByteVector& bytes)
+{
+  d->valid = false;
+  if(bytes.size() < 9)
+    return;
+  int pos = 0;
+  d->type = (Type)bytes[0]; ++pos;
+  uint dataLen = bytes.mid(pos, 4).toUInt(false); pos+=4;
+
+  const ByteVector nullStringTerminator(2, 0);
+
+  int endPos = bytes.find(nullStringTerminator, pos, 2);
+  if(endPos < 0)
+    return;
+  d->mimeType = String(bytes.mid(pos, endPos - pos), String::UTF16LE);
+  pos = endPos+2;
+
+  endPos = bytes.find(nullStringTerminator, pos, 2);
+  if(endPos < 0)
+    return;
+  d->description = String(bytes.mid(pos, endPos - pos), String::UTF16LE);
+  pos = endPos+2;
+
+  if(dataLen + pos != bytes.size())
+    return;
+
+  d->picture = bytes.mid(pos, dataLen);
+  d->valid = true;
+  return;
+}
+
+ASF::Picture ASF::Picture::fromInvalid()
+{
+  Picture ret;
+  ret.d->valid = false;
+  return ret;
+}
+
+#endif
diff --git a/taglib/asf/asfpicture.h b/taglib/asf/asfpicture.h
new file mode 100644 (file)
index 0000000..d042ac3
--- /dev/null
@@ -0,0 +1,192 @@
+#ifndef ASFPICTURE_H
+#define ASFPICTURE_H
+
+#include "tstring.h"
+#include "tbytevector.h"
+#include "taglib_export.h"
+#include "attachedpictureframe.h"
+
+namespace TagLib
+{
+  namespace ASF
+  {
+
+    //! An ASF attached picture interface implementation
+
+    /*!
+     * This is an implementation of ASF attached pictures interface.  Pictures may be
+     * included in attributes, one per WM/Picture attribute (but there may be multiple WM/Picture
+     * attribute in a single tag).  These pictures are usually in either JPEG or
+     * PNG format.
+     * \see Attribute::toPicture()
+     * \see Attribute::Attribute(const Picture& picture)
+     */
+    class TAGLIB_EXPORT Picture {
+    public:
+
+      /*!
+       * This describes the function or content of the picture.
+       */
+      enum Type {
+        //! A type not enumerated below
+        Other              = 0x00,
+        //! 32x32 PNG image that should be used as the file icon
+        FileIcon           = 0x01,
+        //! File icon of a different size or format
+        OtherFileIcon      = 0x02,
+        //! Front cover image of the album
+        FrontCover         = 0x03,
+        //! Back cover image of the album
+        BackCover          = 0x04,
+        //! Inside leaflet page of the album
+        LeafletPage        = 0x05,
+        //! Image from the album itself
+        Media              = 0x06,
+        //! Picture of the lead artist or soloist
+        LeadArtist         = 0x07,
+        //! Picture of the artist or performer
+        Artist             = 0x08,
+        //! Picture of the conductor
+        Conductor          = 0x09,
+        //! Picture of the band or orchestra
+        Band               = 0x0A,
+        //! Picture of the composer
+        Composer           = 0x0B,
+        //! Picture of the lyricist or text writer
+        Lyricist           = 0x0C,
+        //! Picture of the recording location or studio
+        RecordingLocation  = 0x0D,
+        //! Picture of the artists during recording
+        DuringRecording    = 0x0E,
+        //! Picture of the artists during performance
+        DuringPerformance  = 0x0F,
+        //! Picture from a movie or video related to the track
+        MovieScreenCapture = 0x10,
+        //! Picture of a large, coloured fish
+        ColouredFish       = 0x11,
+        //! Illustration related to the track
+        Illustration       = 0x12,
+        //! Logo of the band or performer
+        BandLogo           = 0x13,
+        //! Logo of the publisher (record company)
+        PublisherLogo      = 0x14
+      };
+
+      /*!
+       * Constructs an empty picture.
+       */
+      Picture();
+
+      /*!
+       * Construct an picture as a copy of \a other.
+       */
+      Picture(const Picture& other);
+
+      /*!
+       * Destroys the picture.
+       */
+      virtual ~Picture();
+
+      /*!
+       * Copies the contents of \a other into this picture.
+       */
+      Picture& operator=(const Picture& other);
+
+      /*!
+       * Returns true if Picture stores valid picture
+       */
+      bool isValid() const;
+
+      /*!
+       * Returns the mime type of the image. This should in most cases be
+       * "image/png" or "image/jpeg".
+       * \see setMimeType(const String &)
+       * \see picture()
+       * \see setPicture(const ByteArray&)
+       */
+      String mimeType() const;
+
+      /*!
+       * Sets the mime type of the image.  This should in most cases be
+       * "image/png" or "image/jpeg".
+       * \see setMimeType(const String &)
+       * \see picture()
+       * \see setPicture(const ByteArray&)
+       */
+      void setMimeType(const String &value);
+
+      /*!
+       * Returns the type of the image.
+       *
+       * \see Type
+       * \see setType()
+       */
+      Type type() const;
+
+      /*!
+       * Sets the type for the image.
+       *
+       * \see Type
+       * \see type()
+       */
+      void setType(const ASF::Picture::Type& t);
+
+      /*!
+       * Returns a text description of the image.
+       *
+       * \see setDescription()
+       */
+      String description() const;
+
+      /*!
+       * Sets a textual description of the image to \a desc.
+       *
+       * \see description()
+       */
+      void setDescription(const String &desc);
+
+      /*!
+       * Returns the image data as a ByteVector.
+       *
+       * \note ByteVector has a data() method that returns a const char * which
+       * should make it easy to export this data to external programs.
+       *
+       * \see setPicture()
+       * \see mimeType()
+       */
+      ByteVector picture() const;
+
+      /*!
+       * Sets the image data to \a p.  \a p should be of the type specified in
+       * this frame's mime-type specification.
+       *
+       * \see picture()
+       * \see mimeType()
+       * \see setMimeType()
+       */
+      void setPicture(const ByteVector &p);
+
+      /*!
+       * Returns picture as binary raw data \a value
+       */
+      ByteVector render() const;
+
+      /*!
+       * Returns picture as binary raw data \a value
+       */
+      int dataSize() const;
+
+#ifndef DO_NOT_DOCUMENT
+      /* THIS IS PRIVATE, DON'T TOUCH IT! */
+      void parse(const ByteVector& );
+      static Picture fromInvalid();
+      friend class Attribute;
+#endif
+      private:
+        struct PicturePriavte;
+        PicturePriavte *d;
+      };
+  }
+}
+
+#endif // ASFPICTURE_H
index 0c462954fafbd1d4e03949fdffb381f84dac3115..0124143f05f751a9aaf4b82cad12f1641d3e8534 100644 (file)
@@ -63,6 +63,7 @@ HEADERS += audioproperties.h \
            ape/apetag.h \
            flac/flacfile.h \
            flac/flacproperties.h \
+           flac/flacpicture.h \
            mpc/mpcfile.h \
            mpc/mpcproperties.h \
            mp4/mp4atom.h \
@@ -124,10 +125,12 @@ SOURCES += ape/apefooter.cpp \
            asf/asffile.cpp \
            asf/asfproperties.cpp \
            asf/asftag.cpp \
+           asf/asfpicture.cpp \
            audioproperties.cpp \
            fileref.cpp \
            flac/flacfile.cpp \
            flac/flacproperties.cpp \
+           flac/flacpicture.cpp \
            mp4/mp4atom.cpp \
            mp4/mp4coverart.cpp \
            mp4/mp4file.cpp \
@@ -197,6 +200,7 @@ FRAMEWORK_HEADERS.files = \
            asf/asffile.h \
            asf/asfproperties.h \
            asf/asftag.h \
+           asf/asfpicture.h \
            audioproperties.h \
            fileref.h \
            flac/flacfile.h \
index 7495b9f0fdff18315623454676906b4c7c4484c8..9fb77b123db616157f46426002c15232b31ec433 100644 (file)
@@ -565,6 +565,11 @@ short ByteVector::toShort(bool mostSignificantByteFirst) const
   return toNumber<unsigned short>(d->data, mostSignificantByteFirst);
 }
 
+unsigned short ByteVector::toUShort(bool mostSignificantByteFirst) const
+{
+  return toNumber<unsigned short>(d->data, mostSignificantByteFirst);
+}
+
 long long ByteVector::toLongLong(bool mostSignificantByteFirst) const
 {
   return toNumber<unsigned long long>(d->data, mostSignificantByteFirst);
index 0fdb878ed876ed9f5f009dd2e688ca630da95e78..b7fffddedce23c9354a824c4d9352558f38625c3 100644 (file)
@@ -266,6 +266,17 @@ namespace TagLib {
      */
     short toShort(bool mostSignificantByteFirst = true) const;
 
+    /*!
+     * Converts the first 2 bytes of the vector to a unsigned short.
+     *
+     * If \a mostSignificantByteFirst is true this will operate left to right
+     * evaluating the integer.  For example if \a mostSignificantByteFirst is
+     * true then $00 $01 == 0x0001 == 1, if false, $01 00 == 0x01000000 == 1.
+     *
+     * \see fromShort()
+     */
+    unsigned short toUShort(bool mostSignificantByteFirst = true) const;
+
     /*!
      * Converts the first 8 bytes of the vector to a (signed) long long.
      *
index 5094f0f07cdce789e3e9174c6ca8db4c1977e1b9..d93dcb479f6199a8afe6dcb6dd5a09fa6821b176 100644 (file)
@@ -20,6 +20,8 @@ class TestASF : public CppUnit::TestFixture
   CPPUNIT_TEST(testSaveLanguage);
   CPPUNIT_TEST(testDWordTrackNumber);
   CPPUNIT_TEST(testSaveLargeValue);
+  CPPUNIT_TEST(testSavePicture);
+  CPPUNIT_TEST(testSaveMultiplePictures);
   CPPUNIT_TEST_SUITE_END();
 
 public:
@@ -141,6 +143,78 @@ public:
     delete f;
   }
 
+  void testSavePicture()
+  {
+    ScopedFileCopy copy("silence-1", ".wma");
+    string newname = copy.fileName();
+
+    ASF::File *f = new ASF::File(newname.c_str());
+    ASF::AttributeList values;
+    ASF::Picture picture;
+    picture.setMimeType("image/jpeg");
+    picture.setType(ASF::Picture::FrontCover);
+    picture.setDescription("description");
+    picture.setPicture("data");
+    ASF::Attribute attr(picture);
+    values.append(attr);
+    f->tag()->attributeListMap()["WM/Picture"] = values;
+    f->save();
+    delete f;
+
+    f = new ASF::File(newname.c_str());
+    ASF::AttributeList values2 = f->tag()->attributeListMap()["WM/Picture"];
+    CPPUNIT_ASSERT_EQUAL(TagLib::uint(1), values2.size());
+    ASF::Attribute attr2 = values2.front(); 
+    ASF::Picture picture2 = attr2.toPicture();
+    CPPUNIT_ASSERT(picture2.isValid());
+    CPPUNIT_ASSERT_EQUAL(String("image/jpeg"), picture2.mimeType());
+    CPPUNIT_ASSERT_EQUAL(ASF::Picture::FrontCover, picture2.type());
+    CPPUNIT_ASSERT_EQUAL(String("description"), picture2.description());
+    CPPUNIT_ASSERT_EQUAL(ByteVector("data"), picture2.picture());
+    delete f;
+  }
+
+  void testSaveMultiplePictures()
+  {
+    ScopedFileCopy copy("silence-1", ".wma");
+    string newname = copy.fileName();
+
+    ASF::File *f = new ASF::File(newname.c_str());
+    ASF::AttributeList values;
+    ASF::Picture picture;
+    picture.setMimeType("image/jpeg");
+    picture.setType(ASF::Picture::FrontCover);
+    picture.setDescription("description");
+    picture.setPicture("data");
+    values.append(ASF::Attribute(picture));
+    ASF::Picture picture2;
+    picture2.setMimeType("image/png");
+    picture2.setType(ASF::Picture::BackCover);
+    picture2.setDescription("back cover");
+    picture2.setPicture("PNG data");
+    values.append(ASF::Attribute(picture2));
+    f->tag()->attributeListMap()["WM/Picture"] = values;
+    f->save();
+    delete f;
+
+    f = new ASF::File(newname.c_str());
+    ASF::AttributeList values2 = f->tag()->attributeListMap()["WM/Picture"];
+    CPPUNIT_ASSERT_EQUAL(TagLib::uint(2), values2.size());
+    ASF::Picture picture3 = values2[1].toPicture();
+    CPPUNIT_ASSERT(picture3.isValid());
+    CPPUNIT_ASSERT_EQUAL(String("image/jpeg"), picture3.mimeType());
+    CPPUNIT_ASSERT_EQUAL(ASF::Picture::FrontCover, picture3.type());
+    CPPUNIT_ASSERT_EQUAL(String("description"), picture3.description());
+    CPPUNIT_ASSERT_EQUAL(ByteVector("data"), picture3.picture());
+    ASF::Picture picture4 = values2[0].toPicture();
+    CPPUNIT_ASSERT(picture4.isValid());
+    CPPUNIT_ASSERT_EQUAL(String("image/png"), picture4.mimeType());
+    CPPUNIT_ASSERT_EQUAL(ASF::Picture::BackCover, picture4.type());
+    CPPUNIT_ASSERT_EQUAL(String("back cover"), picture4.description());
+    CPPUNIT_ASSERT_EQUAL(ByteVector("PNG data"), picture4.picture());
+    delete f;
+  }
+
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(TestASF);
index 6b4dae3cf8f63c8f4fae992e264a321267625ccd..2b1f981f005144d1bc26bbb5448806ca51f0a8c3 100644 (file)
@@ -38,6 +38,7 @@ class TestByteVector : public CppUnit::TestFixture
   CPPUNIT_TEST(testRfind1);
   CPPUNIT_TEST(testRfind2);
   CPPUNIT_TEST(testToHex);
+  CPPUNIT_TEST(testToUShort);
   CPPUNIT_TEST_SUITE_END();
 
 public:
@@ -181,6 +182,15 @@ public:
     CPPUNIT_ASSERT_EQUAL(ByteVector("f0e1d2c3b4a5968778695a4b3c2d1e0f"), v.toHex());
   }
 
+  void testToUShort()
+  {
+    CPPUNIT_ASSERT_EQUAL((unsigned short)0xFFFF, ByteVector("\xff\xff", 2).toUShort());
+    CPPUNIT_ASSERT_EQUAL((unsigned short)0x0001, ByteVector("\x00\x01", 2).toUShort());
+    CPPUNIT_ASSERT_EQUAL((unsigned short)0x0100, ByteVector("\x00\x01", 2).toUShort(false));
+    CPPUNIT_ASSERT_EQUAL((unsigned short)0xFF01, ByteVector("\xFF\x01", 2).toUShort());
+    CPPUNIT_ASSERT_EQUAL((unsigned short)0x01FF, ByteVector("\xFF\x01", 2).toUShort(false));
+  }
+
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(TestByteVector);