rpms/taglib/F-10 taglib-1.5-1.6-ape.patch, NONE, 1.1 taglib-1.5-1.6-flac.patch, NONE, 1.1 taglib-1.5-1.6-mpeg-cmake.patch, NONE, 1.1 taglib-1.5-1.6-mpeg.patch, NONE, 1.1 taglib-1.5-1.6-ogg.patch, NONE, 1.1 taglib-1.5-1.6-toolkit.patch, NONE, 1.1 taglib-1.5-tests.patch, NONE, 1.1 .cvsignore, 1.12, 1.13 sources, 1.12, 1.13 taglib.spec, 1.32, 1.33 taglib-1.6-test_mp4.patch, 1.1, NONE

Michael Schwendt mschwendt at fedoraproject.org
Mon Sep 14 17:09:38 UTC 2009


Author: mschwendt

Update of /cvs/pkgs/rpms/taglib/F-10
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv14180/F-10

Modified Files:
	.cvsignore sources taglib.spec 
Added Files:
	taglib-1.5-1.6-ape.patch taglib-1.5-1.6-flac.patch 
	taglib-1.5-1.6-mpeg-cmake.patch taglib-1.5-1.6-mpeg.patch 
	taglib-1.5-1.6-ogg.patch taglib-1.5-1.6-toolkit.patch 
	taglib-1.5-tests.patch 
Removed Files:
	taglib-1.6-test_mp4.patch 
Log Message:
resurrect taglib 1.5 with bug-fixes from 1.6

taglib-1.5-1.6-ape.patch:
 apeitem.cpp |    9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

--- NEW FILE taglib-1.5-1.6-ape.patch ---
diff -Nur taglib-1.5/taglib/ape/apeitem.cpp taglib/taglib/ape/apeitem.cpp
--- taglib-1.5/taglib/ape/apeitem.cpp	2008-02-12 17:30:25.000000000 +0100
+++ taglib/taglib/ape/apeitem.cpp	2009-01-11 00:15:33.000000000 +0100
@@ -160,14 +160,14 @@
 bool APE::Item::isEmpty() const
 {
   switch(d->type) {
-    case 0:
-    case 1:
+    case Text:
+    case Binary:
       if(d->text.isEmpty())
         return true;
       if(d->text.size() == 1 && d->text.front().isEmpty())
         return true;
       return false;
-    case 2:
+    case Locator:
       return d->value.isEmpty();
     default:
       return false;
@@ -206,8 +206,9 @@
   if(isEmpty())
     return data;
 
-  if(d->type != Item::Binary) {
+  if(d->type == Text) {
     StringList::ConstIterator it = d->text.begin();
+
     value.append(it->data(String::UTF8));
     it++;
     for(; it != d->text.end(); ++it) {

taglib-1.5-1.6-flac.patch:
 flacfile.cpp       |   83 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 flacfile.h         |    1 
 flacproperties.cpp |    2 -
 3 files changed, 78 insertions(+), 8 deletions(-)

--- NEW FILE taglib-1.5-1.6-flac.patch ---
diff -Nur taglib-1.5/taglib/flac/flacfile.cpp taglib/taglib/flac/flacfile.cpp
--- taglib-1.5/taglib/flac/flacfile.cpp	2008-01-31 06:19:03.000000000 +0100
+++ taglib/taglib/flac/flacfile.cpp	2009-07-12 23:53:18.000000000 +0200
@@ -42,6 +42,7 @@
 {
   enum { XiphIndex = 0, ID3v2Index = 1, ID3v1Index = 2 };
   enum { StreamInfo = 0, Padding, Application, SeekTable, VorbisComment, CueSheet };
+  enum { MinPaddingLength = 4096 };
 }
 
 class FLAC::File::FilePrivate
@@ -167,9 +168,49 @@
       uint blockLength = header.mid(1, 3).toUInt();
 
       if(blockType == VorbisComment) {
-        data[0] = header[0];
-        insert(data, nextBlockOffset, blockLength + 4);
-        break;
+
+        long paddingBreak = 0;
+
+        if(!isLastBlock) {
+          paddingBreak = findPaddingBreak(nextBlockOffset + blockLength + 4,
+                                          nextBlockOffset + d->xiphCommentData.size() + 8,
+                                          &isLastBlock);
+        }
+
+        uint paddingLength = 0;
+
+         if(paddingBreak) {
+
+           // There is space for comment and padding blocks without rewriting the
+           // whole file.  Note: This cannot overflow.
+
+           paddingLength = paddingBreak - (nextBlockOffset + d->xiphCommentData.size() + 8);
+         }
+         else {
+
+           // Not enough space, so we will have to rewrite the whole file
+           // following this block
+
+           paddingLength = d->xiphCommentData.size();
+
+           if(paddingLength < MinPaddingLength)
+             paddingLength = MinPaddingLength;
+
+           paddingBreak = nextBlockOffset + blockLength + 4;
+         }
+
+         ByteVector padding = ByteVector::fromUInt(paddingLength);
+
+         padding[0] = 1;
+
+         if(isLastBlock)
+           padding[0] |= 0x80;
+
+         padding.resize(paddingLength + 4);
+         ByteVector pair(data);
+         pair.append(padding);
+         insert(pair, nextBlockOffset, paddingBreak - nextBlockOffset);
+         break;
       }
 
       nextBlockOffset += blockLength + 4;
@@ -373,11 +414,8 @@
     isLastBlock = (header[0] & 0x80) != 0;
     length = header.mid(1, 3).toUInt();
 
-    if(blockType == Padding) {
-      // debug("FLAC::File::scan() -- Padding found");
-    }
     // Found the vorbis-comment
-    else if(blockType == VorbisComment) {
+    if(blockType == VorbisComment) {
       d->xiphCommentData = readBlock(length);
       d->hasXiphComment = true;
     }
@@ -429,3 +467,34 @@
 
   return -1;
 }
+
+long FLAC::File::findPaddingBreak(long nextBlockOffset, long targetOffset, bool *isLast)
+{
+  // Starting from nextBlockOffset, step over padding blocks to find the
+  // address of a block which is after targetOffset. Return zero if
+  // a non-padding block occurs before that point.
+
+  while(true) {
+    seek(nextBlockOffset);
+
+    ByteVector header = readBlock(4);
+    char blockType = header[0] & 0x7f;
+    bool isLastBlock = header[0] & 0x80;
+    uint length = header.mid(1, 3).toUInt();
+
+    if(blockType != Padding)
+      break;
+
+    nextBlockOffset += 4 + length;
+
+    if(nextBlockOffset >= targetOffset) {
+      *isLast = isLastBlock;
+      return nextBlockOffset;
+    }
+
+    if(isLastBlock)
+      break;
+  }
+
+  return 0;
+}
diff -Nur taglib-1.5/taglib/flac/flacfile.h taglib/taglib/flac/flacfile.h
--- taglib-1.5/taglib/flac/flacfile.h	2008-01-31 05:07:29.000000000 +0100
+++ taglib/taglib/flac/flacfile.h	2009-07-12 23:53:18.000000000 +0200
@@ -191,6 +191,7 @@
       long findID3v2();
       long findID3v1();
       ByteVector xiphCommentData() const;
+      long findPaddingBreak(long nextPageOffset, long targetOffset, bool *isLast);
 
       class FilePrivate;
       FilePrivate *d;
diff -Nur taglib-1.5/taglib/flac/flacproperties.cpp taglib/taglib/flac/flacproperties.cpp
--- taglib-1.5/taglib/flac/flacproperties.cpp	2008-01-11 01:55:09.000000000 +0100
+++ taglib/taglib/flac/flacproperties.cpp	2008-04-08 14:15:20.000000000 +0200
@@ -146,5 +146,5 @@
 
   // Real bitrate:
 
-  d->bitrate = d->length > 0 ? ((d->streamLength * 8L) / d->length) / 1000 : 0;
+  d->bitrate = d->length > 0 ? ((d->streamLength * 8UL) / d->length) / 1000 : 0;
 }

taglib-1.5-1.6-mpeg-cmake.patch:
 CMakeLists.txt |    2 ++
 1 file changed, 2 insertions(+)

--- NEW FILE taglib-1.5-1.6-mpeg-cmake.patch ---
diff -Nur taglib-1.5-orig/taglib/CMakeLists.txt taglib-1.5/taglib/CMakeLists.txt
--- taglib-1.5-orig/taglib/CMakeLists.txt	2008-02-12 05:15:20.000000000 +0100
+++ taglib-1.5/taglib/CMakeLists.txt	2009-08-22 12:18:40.000000000 +0200
@@ -62,6 +62,8 @@
 mpeg/id3v2/frames/attachedpictureframe.cpp
 mpeg/id3v2/frames/commentsframe.cpp
 mpeg/id3v2/frames/generalencapsulatedobjectframe.cpp
+mpeg/id3v2/frames/popularimeterframe.cpp
+mpeg/id3v2/frames/privateframe.cpp
 mpeg/id3v2/frames/relativevolumeframe.cpp
 mpeg/id3v2/frames/textidentificationframe.cpp
 mpeg/id3v2/frames/uniquefileidentifierframe.cpp

taglib-1.5-1.6-mpeg.patch:
 id3v2/frames/CMakeLists.txt                   |    2 
 id3v2/frames/Makefile.am                      |    4 
 id3v2/frames/attachedpictureframe.cpp         |   56 ++++++++++
 id3v2/frames/attachedpictureframe.h           |   16 ++-
 id3v2/frames/generalencapsulatedobjectframe.h |    4 
 id3v2/frames/popularimeterframe.cpp           |  137 ++++++++++++++++++++++++++
 id3v2/frames/popularimeterframe.h             |  132 +++++++++++++++++++++++++
 id3v2/frames/privateframe.cpp                 |  128 ++++++++++++++++++++++++
 id3v2/frames/privateframe.h                   |  111 +++++++++++++++++++++
 id3v2/id3v2footer.cpp                         |    2 
 id3v2/id3v2footer.h                           |    2 
 id3v2/id3v2framefactory.cpp                   |   63 ++++++++---
 id3v2/id3v2tag.cpp                            |   12 ++
 mpegheader.cpp                                |    4 
 mpegproperties.cpp                            |    6 -
 15 files changed, 649 insertions(+), 30 deletions(-)

--- NEW FILE taglib-1.5-1.6-mpeg.patch ---
diff -Nur taglib-1.5-orig/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp taglib-1.5-1.6/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp
--- taglib-1.5-orig/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp	2008-02-04 16:14:46.000000000 +0100
+++ taglib-1.5-1.6/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp	2009-09-04 10:50:24.000000000 +0200
@@ -50,7 +50,7 @@
 
 AttachedPictureFrame::AttachedPictureFrame() : Frame("APIC")
 {
-    d = new AttachedPictureFramePrivate;
+  d = new AttachedPictureFramePrivate;
 }
 
 AttachedPictureFrame::AttachedPictureFrame(const ByteVector &data) : Frame(data)
@@ -136,6 +136,12 @@
   int pos = 1;
 
   d->mimeType = readStringField(data, String::Latin1, &pos);
+  /* Now we need at least two more bytes available */	
+  if (uint(pos) + 1 >= data.size()) {
+    debug("Truncated picture frame.");
+    return;
+  }
+
   d->type = (TagLib::ID3v2::AttachedPictureFrame::Type)data[pos++];
   d->description = readStringField(data, d->textEncoding, &pos);
 
@@ -168,3 +174,51 @@
   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);
+}
diff -Nur taglib-1.5-orig/taglib/mpeg/id3v2/frames/attachedpictureframe.h taglib-1.5-1.6/taglib/mpeg/id3v2/frames/attachedpictureframe.h
--- taglib-1.5-orig/taglib/mpeg/id3v2/frames/attachedpictureframe.h	2008-02-04 16:14:46.000000000 +0100
+++ taglib-1.5-1.6/taglib/mpeg/id3v2/frames/attachedpictureframe.h	2009-09-14 18:56:05.113767634 +0200
@@ -205,14 +205,24 @@
     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;
     };
   }
 }
diff -Nur taglib-1.5-orig/taglib/mpeg/id3v2/frames/CMakeLists.txt taglib-1.5-1.6/taglib/mpeg/id3v2/frames/CMakeLists.txt
--- taglib-1.5-orig/taglib/mpeg/id3v2/frames/CMakeLists.txt	2008-01-31 22:48:39.000000000 +0100
+++ taglib-1.5-1.6/taglib/mpeg/id3v2/frames/CMakeLists.txt	2009-09-14 18:56:05.119755592 +0200
@@ -2,6 +2,8 @@
 	attachedpictureframe.h
 	commentsframe.h
 	generalencapsulatedobjectframe.h
+	popularimeterframe.h
+	privateframe.h
 	relativevolumeframe.h
 	textidentificationframe.h
 	uniquefileidentifierframe.h
diff -Nur taglib-1.5-orig/taglib/mpeg/id3v2/frames/generalencapsulatedobjectframe.h taglib-1.5-1.6/taglib/mpeg/id3v2/frames/generalencapsulatedobjectframe.h
--- taglib-1.5-orig/taglib/mpeg/id3v2/frames/generalencapsulatedobjectframe.h	2008-02-04 16:14:46.000000000 +0100
+++ taglib-1.5-1.6/taglib/mpeg/id3v2/frames/generalencapsulatedobjectframe.h	2009-09-14 18:56:05.126760312 +0200
@@ -61,6 +61,10 @@
 
       /*!
        * Constructs a GeneralEncapsulatedObjectFrame frame based on \a data.
+       *
+       * \warning This is \em not data for the encapsulated object, for that use
+       * setObject().  This constructor is used when reading the frame from the
+       * disk.
        */
       explicit GeneralEncapsulatedObjectFrame(const ByteVector &data);
 
diff -Nur taglib-1.5-orig/taglib/mpeg/id3v2/frames/Makefile.am taglib-1.5-1.6/taglib/mpeg/id3v2/frames/Makefile.am
--- taglib-1.5-orig/taglib/mpeg/id3v2/frames/Makefile.am	2008-01-31 22:48:28.000000000 +0100
+++ taglib-1.5-1.6/taglib/mpeg/id3v2/frames/Makefile.am	2009-09-14 18:56:05.132766369 +0200
@@ -10,6 +10,8 @@
 	attachedpictureframe.cpp \
 	commentsframe.cpp \
 	generalencapsulatedobjectframe.cpp \
+	popularimeterframe.cpp \
+	privateframe.cpp \
 	relativevolumeframe.cpp \
 	textidentificationframe.cpp \
 	uniquefileidentifierframe.cpp \
@@ -21,6 +23,8 @@
 	attachedpictureframe.h \
 	commentsframe.h \
 	generalencapsulatedobjectframe.h \
+	popularimeterframe.h \
+	privateframe.h \
 	relativevolumeframe.h \
 	textidentificationframe.h \
 	uniquefileidentifierframe.h \
diff -Nur taglib-1.5-orig/taglib/mpeg/id3v2/frames/popularimeterframe.cpp taglib-1.5-1.6/taglib/mpeg/id3v2/frames/popularimeterframe.cpp
--- taglib-1.5-orig/taglib/mpeg/id3v2/frames/popularimeterframe.cpp	1970-01-01 01:00:00.000000000 +0100
+++ taglib-1.5-1.6/taglib/mpeg/id3v2/frames/popularimeterframe.cpp	2009-09-14 18:56:05.139766543 +0200
@@ -0,0 +1,137 @@
+/***************************************************************************
+    copyright            : (C) 2008 by Lukas Lalinsky
+    email                : lalinsky at 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/                                           *
+ ***************************************************************************/
+
+#include <tdebug.h>
+
+#include "popularimeterframe.h"
+
+using namespace TagLib;
+using namespace ID3v2;
+
+class PopularimeterFrame::PopularimeterFramePrivate
+{
+public:
+  PopularimeterFramePrivate() : rating(0), counter(0) {}
+  String email;
+  int rating;
+  TagLib::uint counter;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+PopularimeterFrame::PopularimeterFrame() : Frame("POPM")
+{
+  d = new PopularimeterFramePrivate;
+}
+
+PopularimeterFrame::PopularimeterFrame(const ByteVector &data) : Frame(data)
+{
+  d = new PopularimeterFramePrivate;
+  setData(data);
+}
+
+PopularimeterFrame::~PopularimeterFrame()
+{
+  delete d;
+}
+
+String PopularimeterFrame::toString() const
+{
+  return d->email + " rating=" + String::number(d->rating) + " counter=" + String::number(d->counter);
+}
+
+String PopularimeterFrame::email() const
+{
+  return d->email;
+}
+
+void PopularimeterFrame::setEmail(const String &s)
+{
+  d->email = s;
+}
+
+int PopularimeterFrame::rating() const
+{
+  return d->rating;
+}
+
+void PopularimeterFrame::setRating(int s)
+{
+  d->rating = s;
+}
+
+TagLib::uint PopularimeterFrame::counter() const
+{
+  return d->counter;
+}
+
+void PopularimeterFrame::setCounter(TagLib::uint s)
+{
+  d->counter = s;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// protected members
+////////////////////////////////////////////////////////////////////////////////
+
+void PopularimeterFrame::parseFields(const ByteVector &data)
+{
+  int pos = 0, size = int(data.size());
+
+  d->email = readStringField(data, String::Latin1, &pos);
+
+  d->rating = 0;
+  d->counter = 0;
+  if(pos < size) {
+    d->rating = (unsigned char)(data[pos++]);
+    if(pos < size) {
+      d->counter = data.mid(pos, 4).toUInt();
+    }
+  }
+}
+
+ByteVector PopularimeterFrame::renderFields() const
+{
+  ByteVector data;
+
+  data.append(d->email.data(String::Latin1));
+  data.append(textDelimiter(String::Latin1));
+  data.append(char(d->rating));
+  data.append(ByteVector::fromUInt(d->counter));
+
+  return data;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// private members
+////////////////////////////////////////////////////////////////////////////////
+
+PopularimeterFrame::PopularimeterFrame(const ByteVector &data, Header *h) : Frame(h)
+{
+  d = new PopularimeterFramePrivate;
+  parseFields(fieldData(data));
+}
diff -Nur taglib-1.5-orig/taglib/mpeg/id3v2/frames/popularimeterframe.h taglib-1.5-1.6/taglib/mpeg/id3v2/frames/popularimeterframe.h
--- taglib-1.5-orig/taglib/mpeg/id3v2/frames/popularimeterframe.h	1970-01-01 01:00:00.000000000 +0100
+++ taglib-1.5-1.6/taglib/mpeg/id3v2/frames/popularimeterframe.h	2009-09-14 18:56:05.140768942 +0200
@@ -0,0 +1,132 @@
+/***************************************************************************
+    copyright            : (C) 2008 by Lukas Lalinsky
+    email                : lalinsky at 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/                                           *
+ ***************************************************************************/
+
+#ifndef TAGLIB_POPULARIMETERFRAME_H
+#define TAGLIB_POPULARIMETERFRAME_H
+
+#include <id3v2frame.h>
+#include "taglib_export.h"
+
+namespace TagLib {
+
+  namespace ID3v2 {
+
+    //! An implementation of ID3v2 "popularimeter"
+
+    /*!
+     * This implements the ID3v2 popularimeter (POPM frame).  It concists of
+     * an email, a rating and an optional counter.
+     */
+
+    class TAGLIB_EXPORT PopularimeterFrame : public Frame
+    {
+      friend class FrameFactory;
+
+    public:
+      /*!
+       * Construct an empty popularimeter frame.
+       */
+      explicit PopularimeterFrame();
+
+      /*!
+       * Construct a popularimeter based on the data in \a data.
+       */
+      explicit PopularimeterFrame(const ByteVector &data);
+
+      /*!
+       * Destroys this PopularimeterFrame instance.
+       */
+      virtual ~PopularimeterFrame();
+
+      /*!
+       * Returns the text of this popularimeter.
+       *
+       * \see text()
+       */
+      virtual String toString() const;
+
+      /*!
+       * Returns the email.
+       *
+       * \see setEmail()
+       */
+      String email() const;
+
+      /*!
+       * Set the email.
+       *
+       * \see email()
+       */
+      void setEmail(const String &email);
+
+      /*!
+       * Returns the rating.
+       *
+       * \see setRating()
+       */
+      int rating() const;
+
+      /*!
+       * Set the rating.
+       *
+       * \see rating()
+       */
+      void setRating(int rating);
+
+      /*!
+       * Returns the counter.
+       *
+       * \see setCounter()
+       */
+      uint counter() const;
+
+      /*!
+       * Set the counter.
+       *
+       * \see counter()
+       */
+      void setCounter(uint counter);
+
+    protected:
+      // Reimplementations.
+
+      virtual void parseFields(const ByteVector &data);
+      virtual ByteVector renderFields() const;
+
+    private:
+      /*!
+       * The constructor used by the FrameFactory.
+       */
+      PopularimeterFrame(const ByteVector &data, Header *h);
+      PopularimeterFrame(const PopularimeterFrame &);
+      PopularimeterFrame &operator=(const PopularimeterFrame &);
+
+      class PopularimeterFramePrivate;
+      PopularimeterFramePrivate *d;
+    };
+
+  }
+}
+#endif
diff -Nur taglib-1.5-orig/taglib/mpeg/id3v2/frames/privateframe.cpp taglib-1.5-1.6/taglib/mpeg/id3v2/frames/privateframe.cpp
--- taglib-1.5-orig/taglib/mpeg/id3v2/frames/privateframe.cpp	1970-01-01 01:00:00.000000000 +0100
+++ taglib-1.5-1.6/taglib/mpeg/id3v2/frames/privateframe.cpp	2009-09-14 18:56:05.142767428 +0200
@@ -0,0 +1,128 @@
+/***************************************************************************
+    copyright            : (C) 2008 by Serkan Kalyoncu
+    copyright            : (C) 2008 by Scott Wheeler
+    email                : wheeler at kde.org
+***************************************************************************/
+
+/***************************************************************************
+ *   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/                                           *
+ ***************************************************************************/
+
+#include <tbytevectorlist.h>
+#include <id3v2tag.h>
+#include <tdebug.h>
+
+#include "privateframe.h"
+
+using namespace TagLib;
+using namespace ID3v2;
+
+
+class PrivateFrame::PrivateFramePrivate
+{
+public:
+  ByteVector data;
+  String owner;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+PrivateFrame::PrivateFrame() : Frame("PRIV")
+{
+  d = new PrivateFramePrivate;
+}
+
+PrivateFrame::PrivateFrame(const ByteVector &data) : Frame(data)
+{
+  d = new PrivateFramePrivate;
+  setData(data);
+}
+
+PrivateFrame::~PrivateFrame()
+{
+  delete d;
+}
+
+String PrivateFrame::toString() const
+{
+  return d->owner;
+}
+
+String PrivateFrame::owner() const
+{
+  return d->owner;
+}
+
+ByteVector PrivateFrame::data() const
+{
+  return d->data;
+}
+
+void PrivateFrame::setOwner(const String &s)
+{
+  d->owner = s;
+}
+
+void PrivateFrame::setData(const ByteVector & data)
+{
+  d->data = data;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// protected members
+////////////////////////////////////////////////////////////////////////////////
+
+void PrivateFrame::parseFields(const ByteVector &data)
+{
+  if(data.size() < 2) {
+    debug("A private frame must contain at least 2 bytes.");
+    return;
+  }
+
+  // Owner identifier is assumed to be Latin1
+  
+  const int byteAlign =  1;
+  const int endOfOwner = data.find(textDelimiter(String::Latin1), 0, byteAlign);
+
+  d->owner =  String(data.mid(0, endOfOwner));
+  d->data = data.mid(endOfOwner + 1);
+}
+
+ByteVector PrivateFrame::renderFields() const
+{
+  ByteVector v;
+
+  v.append(d->owner.data(String::Latin1));
+  v.append(textDelimiter(String::Latin1));
+  v.append(d->data);
+
+  return v;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// private members
+////////////////////////////////////////////////////////////////////////////////
+
+PrivateFrame::PrivateFrame(const ByteVector &data, Header *h) : Frame(h)
+{
+  d = new PrivateFramePrivate();
+  parseFields(fieldData(data));
+}
diff -Nur taglib-1.5-orig/taglib/mpeg/id3v2/frames/privateframe.h taglib-1.5-1.6/taglib/mpeg/id3v2/frames/privateframe.h
--- taglib-1.5-orig/taglib/mpeg/id3v2/frames/privateframe.h	1970-01-01 01:00:00.000000000 +0100
+++ taglib-1.5-1.6/taglib/mpeg/id3v2/frames/privateframe.h	2009-09-14 18:56:05.143769445 +0200
@@ -0,0 +1,111 @@
+/***************************************************************************
+    copyright            : (C) 2008 by Serkan Kalyoncu
+    copyright            : (C) 2008 by Scott Wheeler
+    email                : wheeler at kde.org
+***************************************************************************/
+
+/***************************************************************************
+ *   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/                                           *
+ ***************************************************************************/
+
+#ifndef TAGLIB_PRIVATEFRAME_H
+#define TAGLIB_PRIVATEFRAME_H
+
+#include "id3v2frame.h"
+#include "taglib_export.h"
+
+namespace TagLib {
+
+  namespace ID3v2 {
+
+    //! An implementation of ID3v2 privateframe
+
+    class TAGLIB_EXPORT PrivateFrame : public Frame
+    {
+      friend class FrameFactory;
+
+    public:
+      /*!
+       * Construct an empty private frame.
+       */
+      PrivateFrame();
+
+      /*!
+       * Construct a private frame based on the data in \a data.
+       *
+       * \note This is the constructor used when parsing the frame from a file.
+       */
+      explicit PrivateFrame(const ByteVector &data);
+
+      /*!
+       * Destroys this private frame instance.
+       */
+      virtual ~PrivateFrame();
+
+      /*!
+       * Returns the text of this private frame, currently just the owner.
+       *
+       * \see text()
+       */
+      virtual String toString() const;
+
+      /*!
+       * \return The owner of the private frame.
+       * \note This should contain an email address or link to a website.
+       */
+      String owner() const;
+
+      /*!
+       *
+       */
+      ByteVector data() const;
+
+      /*!
+       * Sets the owner of the frame to \a s.
+       * \note This should contain an email address or link to a website.
+       */
+      void setOwner(const String &s);
+
+      /*!
+       *
+       */
+      void setData(const ByteVector &v);
+
+    protected:
+      // Reimplementations.
+
+      virtual void parseFields(const ByteVector &data);
+      virtual ByteVector renderFields() const;
+
+    private:
+      /*!
+       * The constructor used by the FrameFactory.
+       */
+      PrivateFrame(const ByteVector &data, Header *h);
+
+      PrivateFrame(const PrivateFrame &);
+      PrivateFrame &operator=(const PrivateFrame &);
+
+      class PrivateFramePrivate;
+      PrivateFramePrivate *d;
+    };
+
+  }
+}
+#endif
diff -Nur taglib-1.5-orig/taglib/mpeg/id3v2/id3v2footer.cpp taglib-1.5-1.6/taglib/mpeg/id3v2/id3v2footer.cpp
--- taglib-1.5-orig/taglib/mpeg/id3v2/id3v2footer.cpp	2008-02-04 16:14:46.000000000 +0100
+++ taglib-1.5-1.6/taglib/mpeg/id3v2/id3v2footer.cpp	2009-09-14 18:56:05.144768996 +0200
@@ -45,7 +45,7 @@
 
 }
 
-const unsigned int Footer::size()
+TagLib::uint Footer::size()
 {
   return FooterPrivate::size;
 }
diff -Nur taglib-1.5-orig/taglib/mpeg/id3v2/id3v2footer.h taglib-1.5-1.6/taglib/mpeg/id3v2/id3v2footer.h
--- taglib-1.5-orig/taglib/mpeg/id3v2/id3v2footer.h	2008-02-04 16:14:46.000000000 +0100
+++ taglib-1.5-1.6/taglib/mpeg/id3v2/id3v2footer.h	2009-09-14 18:56:05.145768506 +0200
@@ -62,7 +62,7 @@
       /*!
        * Returns the size of the footer.  Presently this is always 10 bytes.
        */
-      static const unsigned int size();
+      static uint size();
 
       /*!
        * Renders the footer based on the data in \a header.
diff -Nur taglib-1.5-orig/taglib/mpeg/id3v2/id3v2framefactory.cpp taglib-1.5-1.6/taglib/mpeg/id3v2/id3v2framefactory.cpp
--- taglib-1.5-orig/taglib/mpeg/id3v2/id3v2framefactory.cpp	2008-02-21 01:43:14.000000000 +0100
+++ taglib-1.5-1.6/taglib/mpeg/id3v2/id3v2framefactory.cpp	2009-09-14 18:56:05.147769486 +0200
@@ -31,6 +31,7 @@
 
 #include "id3v2framefactory.h"
 #include "id3v2synchdata.h"
+#include "id3v1genres.h"
 
 #include "frames/attachedpictureframe.h"
 #include "frames/commentsframe.h"
@@ -41,6 +42,8 @@
 #include "frames/generalencapsulatedobjectframe.h"
 #include "frames/urllinkframe.h"
 #include "frames/unsynchronizedlyricsframe.h"
+#include "frames/popularimeterframe.h"
+#include "frames/privateframe.h"
 
 using namespace TagLib;
 using namespace ID3v2;
@@ -180,7 +183,15 @@
     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);
@@ -220,6 +231,16 @@
     return f;
   }
 
+  // Popularimeter (frames 4.17)
+
+  if(frameID == "POPM")
+    return new PopularimeterFrame(data, header);
+
+  // Private (frames 4.27)
+
+  if(frameID == "PRIV")
+    return new PrivateFrame(data, header);
+
   return new UnknownFrame(data, header);
 }
 
@@ -280,7 +301,6 @@
     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);
@@ -382,26 +402,31 @@
 
 void FrameFactory::updateGenre(TextIdentificationFrame *frame) const
 {
-  StringList fields;
-  String s = frame->toString();
+  StringList fields = frame->fieldList();
+  StringList newfields;
 
-  while(s.startsWith("(")) {
-
-    int closing = s.find(")");
-
-    if(closing < 0)
-      break;
-
-    fields.append(s.substr(1, closing - 1));
-
-    s = s.substr(closing + 1);
+  for(StringList::Iterator it = fields.begin(); it != fields.end(); ++it) {
+    String s = *it;
+    int end = s.find(")");
+
+    if(s.startsWith("(") && end > 0) {
+      // "(12)Genre"
+      String text = s.substr(end + 1);
+      int number = s.substr(1, end - 1).toInt();
+      if (number > 0 && number <= 255 && !(ID3v1::genre(number) == text))
+        newfields.append(s.substr(1, end - 1));
+      if (!text.isEmpty())
+        newfields.append(text);
+    }
+    else {
+      // "Genre" or "12"
+      newfields.append(s);
+    }
   }
 
-  if(!s.isEmpty())
-    fields.append(s);
-
-  if(fields.isEmpty())
+  if(newfields.isEmpty())
     fields.append(String::null);
 
-  frame->setText(fields);
+  frame->setText(newfields);
+
 }
diff -Nur taglib-1.5-orig/taglib/mpeg/id3v2/id3v2tag.cpp taglib-1.5-1.6/taglib/mpeg/id3v2/id3v2tag.cpp
--- taglib-1.5-orig/taglib/mpeg/id3v2/id3v2tag.cpp	2008-02-04 21:33:54.000000000 +0100
+++ taglib-1.5-1.6/taglib/mpeg/id3v2/id3v2tag.cpp	2009-09-14 18:56:05.149769670 +0200
@@ -125,7 +125,9 @@
 
   for(FrameList::ConstIterator it = comments.begin(); it != comments.end(); ++it)
   {
-    if(static_cast<CommentsFrame *>(*it)->description().isEmpty())
+    CommentsFrame *frame = dynamic_cast<CommentsFrame *>(*it);
+
+    if(frame && frame->description().isEmpty())
       return (*it)->toString();
   }
 
@@ -159,6 +161,9 @@
 
   for(StringList::Iterator it = fields.begin(); it != fields.end(); ++it) {
 
+    if((*it).isEmpty())
+      continue;
+
     bool isNumber = true;
 
     for(String::ConstIterator charIt = (*it).begin();
@@ -347,6 +352,11 @@
   // Loop through the frames rendering them and adding them to the tagData.
 
   for(FrameList::Iterator it = d->frameList.begin(); it != d->frameList.end(); it++) {
+    if ((*it)->header()->frameID().size() != 4) {
+      debug("A frame of unsupported or unknown type \'"
+          + String((*it)->header()->frameID()) + "\' has been discarded");
+      continue;
+    }
     if(!(*it)->header()->tagAlterPreservation())
       tagData.append((*it)->render());
   }
diff -Nur taglib-1.5-orig/taglib/mpeg/mpegheader.cpp taglib-1.5-1.6/taglib/mpeg/mpegheader.cpp
--- taglib-1.5-orig/taglib/mpeg/mpegheader.cpp	2008-02-04 16:14:46.000000000 +0100
+++ taglib-1.5-1.6/taglib/mpeg/mpegheader.cpp	2009-09-14 18:56:05.102768244 +0200
@@ -164,7 +164,7 @@
 void MPEG::Header::parse(const ByteVector &data)
 {
   if(data.size() < 4 || uchar(data[0]) != 0xff) {
-    debug("MPEG::Header::parse() -- First byte did not mactch MPEG synch.");
+    debug("MPEG::Header::parse() -- First byte did not match MPEG synch.");
     return;
   }
 
@@ -173,7 +173,7 @@
   // Check for the second byte's part of the MPEG synch
 
   if(!flags[23] || !flags[22] || !flags[21]) {
-    debug("MPEG::Header::parse() -- Second byte did not mactch MPEG synch.");
+    debug("MPEG::Header::parse() -- Second byte did not match MPEG synch.");
     return;
   }
 
diff -Nur taglib-1.5-orig/taglib/mpeg/mpegproperties.cpp taglib-1.5-1.6/taglib/mpeg/mpegproperties.cpp
--- taglib-1.5-orig/taglib/mpeg/mpegproperties.cpp	2008-02-04 16:14:46.000000000 +0100
+++ taglib-1.5-1.6/taglib/mpeg/mpegproperties.cpp	2009-09-14 18:56:05.104764564 +0200
@@ -218,8 +218,10 @@
       double timePerFrame =
         double(firstHeader.samplesPerFrame()) / firstHeader.sampleRate();
 
-      d->length = int(timePerFrame * d->xingHeader->totalFrames());
-      d->bitrate = d->length > 0 ? d->xingHeader->totalSize() * 8 / d->length / 1000 : 0;
+      double length = timePerFrame * d->xingHeader->totalFrames();
+
+      d->length = int(length);
+      d->bitrate = d->length > 0 ? d->xingHeader->totalSize() * 8 / length / 1000 : 0;
   }
   else {
     // Since there was no valid Xing header found, we hope that we're in a constant

taglib-1.5-1.6-ogg.patch:
 oggfile.cpp     |  101 ++++++++++++++++++++++++++++++++++++++++++++++++--
 oggpage.cpp     |  112 +++++++++++++++++++++++++++++++++++++++++++++++++-------
 oggpage.h       |    8 ++++
 xiphcomment.cpp |   18 ++++++---
 4 files changed, 214 insertions(+), 25 deletions(-)

--- NEW FILE taglib-1.5-1.6-ogg.patch ---
diff -Nur taglib-1.5-orig/taglib/ogg/oggfile.cpp taglib-1.5-1.6/taglib/ogg/oggfile.cpp
--- taglib-1.5-orig/taglib/ogg/oggfile.cpp	2008-02-04 16:14:46.000000000 +0100
+++ taglib-1.5-1.6/taglib/ogg/oggfile.cpp	2009-09-04 10:50:24.000000000 +0200
@@ -270,11 +270,28 @@
   return true;
 }
 
-void Ogg::File::writePageGroup(const List<int> &pageGroup)
+void Ogg::File::writePageGroup(const List<int> &thePageGroup)
 {
-  if(pageGroup.isEmpty())
+  if(thePageGroup.isEmpty())
     return;
 
+
+  // pages in the pageGroup and packets must be equivalent 
+  // (originalSize and size of packets would not work together), 
+  // therefore we sometimes have to add pages to the group
+  List<int> pageGroup(thePageGroup);
+  while (!d->pages[pageGroup.back()]->header()->lastPacketCompleted()) {
+    if (d->currentPage->header()->pageSequenceNumber() == pageGroup.back()) {
+      if (nextPage() == false) {
+        debug("broken ogg file");
+        return;
+      }
+      pageGroup.append(d->currentPage->header()->pageSequenceNumber());
+    } else {
+      pageGroup.append(pageGroup.back() + 1);
+    }
+  }
+
   ByteVectorList packets;
 
   // If the first page of the group isn't dirty, append its partial content here.
@@ -313,6 +330,52 @@
                                       d->streamSerialNumber, pageGroup.front(),
                                       continued, completed);
 
+  List<Page *> renumberedPages;
+
+  // Correct the page numbering of following pages
+
+  if (pages.back()->header()->pageSequenceNumber() != pageGroup.back()) {
+
+    // TODO: change the internal data structure so that we don't need to hold the 
+    // complete file in memory (is unavoidable at the moment)
+
+    // read the complete stream
+    while(!d->currentPage->header()->lastPageOfStream()) {
+      if(nextPage() == false) {
+        debug("broken ogg file");
+        break;
+      }
+    }
+
+    // create a gap for the new pages
+    int numberOfNewPages = pages.back()->header()->pageSequenceNumber() - pageGroup.back();
+    List<Page *>::Iterator pageIter = d->pages.begin();
+    for(int i = 0; i < pageGroup.back(); i++) {
+      if(pageIter != d->pages.end()) {
+        ++pageIter;
+      }
+      else {
+        debug("Ogg::File::writePageGroup() -- Page sequence is broken in original file.");
+        break;
+      }
+    }
+
+    ++pageIter;
+    for(; pageIter != d->pages.end(); ++pageIter) {
+      Ogg::Page *newPage =
+        (*pageIter)->getCopyWithNewPageSequenceNumber(
+            (*pageIter)->header()->pageSequenceNumber() + numberOfNewPages);
+
+      ByteVector data;
+      data.append(newPage->render());
+      insert(data, newPage->fileOffset(), data.size());
+
+      renumberedPages.append(newPage);
+    }
+  }
+
+  // insert the new data
+
   ByteVector data;
   for(List<Page *>::ConstIterator it = pages.begin(); it != pages.end(); ++it)
     data.append((*it)->render());
@@ -328,9 +391,37 @@
   // Update the page index to include the pages we just created and to delete the
   // old pages.
 
+  // First step: Pages that contain the comment data
+
   for(List<Page *>::ConstIterator it = pages.begin(); it != pages.end(); ++it) {
-    const int index = (*it)->header()->pageSequenceNumber();
-    delete d->pages[index];
-    d->pages[index] = *it;
+    const unsigned int index = (*it)->header()->pageSequenceNumber();
+    if(index < d->pages.size()) {
+      delete d->pages[index];
+      d->pages[index] = *it;
+    }
+    else if(index == d->pages.size()) {
+      d->pages.append(*it);
+    }
+    else {
+      // oops - there's a hole in the sequence
+      debug("Ogg::File::writePageGroup() -- Page sequence is broken.");
+    }
+  }
+
+  // Second step: the renumbered pages
+
+  for(List<Page *>::ConstIterator it = renumberedPages.begin(); it != renumberedPages.end(); ++it) {
+    const unsigned int index = (*it)->header()->pageSequenceNumber();
+    if(index < d->pages.size()) {
+      delete d->pages[index];
+      d->pages[index] = *it;
+    }
+    else if(index == d->pages.size()) {
+      d->pages.append(*it);
+    }
+    else {
+      // oops - there's a hole in the sequence
+      debug("Ogg::File::writePageGroup() -- Page sequence is broken.");
+    }
   }
 }
diff -Nur taglib-1.5-orig/taglib/ogg/oggpage.cpp taglib-1.5-1.6/taglib/ogg/oggpage.cpp
--- taglib-1.5-orig/taglib/ogg/oggpage.cpp	2008-02-04 16:14:46.000000000 +0100
+++ taglib-1.5-1.6/taglib/ogg/oggpage.cpp	2009-09-14 19:01:31.026763633 +0200
@@ -116,12 +116,14 @@
     flags = ContainsPacketFlags(flags | CompletePacket);
   }
 
-  // Or if the page is (a) the first page and it's complete or (b) the last page
-  // and it's complete or (c) a page in the middle.
-
-  else if((flags & BeginsWithPacket && !d->header.firstPacketContinued()) ||
-          (flags & EndsWithPacket && d->header.lastPacketCompleted()) ||
-          (!(flags & BeginsWithPacket) && !(flags & EndsWithPacket)))
+  // Or if there is more than one page and the page is 
+  // (a) the first page and it's complete or 
+  // (b) the last page and it's complete or 
+  // (c) a page in the middle.
+  else if(packetCount() > 1 &&
+          ((flags & BeginsWithPacket && !d->header.firstPacketContinued()) ||
+           (flags & EndsWithPacket && d->header.lastPacketCompleted()) ||
+           (!(flags & BeginsWithPacket) && !(flags & EndsWithPacket))))
   {
     flags = ContainsPacketFlags(flags | CompletePacket);
   }
@@ -208,20 +210,101 @@
   for(ByteVectorList::ConstIterator it = packets.begin(); it != packets.end(); ++it)
     totalSize += (*it).size();
 
-  if(strategy == Repaginate || totalSize + packets.size() > 255 * 256) {
-    debug("Ogg::Page::paginate() -- Sorry!  Repagination is not yet implemented.");
-    return l;
-  }
+  // Handle creation of multiple pages with appropriate pagination.
+  if(strategy == Repaginate || totalSize + packets.size() > 255 * 255) {
 
-  // TODO: Handle creation of multiple pages here with appropriate pagination.
+    // SPLITSIZE must be a multiple of 255 in order to get the lacing values right
+    // create pages of about 8KB each
+#define SPLITSIZE (32*255)
+
+    int pageIndex = 0;
+
+    for(ByteVectorList::ConstIterator it = packets.begin(); it != packets.end(); ++it) {
+      bool continued = false;
+
+      // mark very first packet?
+      if(firstPacketContinued && it==packets.begin()) {
+        continued = true;
+      }
+
+      // append to buf
+      ByteVector packetBuf;
+      packetBuf.append(*it);
+
+      while(packetBuf.size() > SPLITSIZE) {
+        // output a Page
+        ByteVector packetForOnePage;
+        packetForOnePage.resize(SPLITSIZE);
+        std::copy(packetBuf.begin(), packetBuf.begin() + SPLITSIZE, packetForOnePage.begin());
+
+        ByteVectorList packetList;
+        packetList.append(packetForOnePage);
+        Page *p = new Page(packetList, streamSerialNumber, firstPage+pageIndex, continued, false, false);
+        l.append(p);
+
+        pageIndex++;
+        continued = true;
+        packetBuf = packetBuf.mid(SPLITSIZE);
+      }
+
+      ByteVectorList::ConstIterator jt = it;
+      ++jt;
+      bool lastPacketInList = (jt == packets.end());
+
+      // output a page for the rest (we output one packet per page, so this one should be completed)
+      ByteVectorList packetList;
+      packetList.append(packetBuf);
+
+      bool isVeryLastPacket = false;
+      if(containsLastPacket) {
+        // mark the very last output page as last of stream
+        ByteVectorList::ConstIterator jt = it;
+        ++jt;
+        if(jt == packets.end()) {
+          isVeryLastPacket = true;
+        }
+      }
+
+      Page *p = new Page(packetList, streamSerialNumber, firstPage+pageIndex, continued,
+                         lastPacketInList ? lastPacketCompleted : true, 
+                         isVeryLastPacket);
+      pageIndex++;
 
-  Page *p = new Page(packets, streamSerialNumber, firstPage, firstPacketContinued,
-                     lastPacketCompleted, containsLastPacket);
-  l.append(p);
+      l.append(p);
+    }
+  }
+  else {
+    Page *p = new Page(packets, streamSerialNumber, firstPage, firstPacketContinued,
+                       lastPacketCompleted, containsLastPacket);
+    l.append(p);
+  }
 
   return l;
 }
 
+Ogg::Page* Ogg::Page::getCopyWithNewPageSequenceNumber(int sequenceNumber)
+{
+  Page *pResultPage = NULL;
+
+  // TODO: a copy constructor would be helpful
+
+  if(d->file == 0) {
+    pResultPage = new Page(
+        d->packets,
+        d->header.streamSerialNumber(),
+        sequenceNumber,
+        d->header.firstPacketContinued(),
+        d->header.lastPacketCompleted(),
+        d->header.lastPageOfStream());
+  }
+  else
+  {
+    pResultPage = new Page(d->file, d->fileOffset);
+    pResultPage->d->header.setPageSequenceNumber(sequenceNumber);
+  }
+  return pResultPage;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // protected members
 ////////////////////////////////////////////////////////////////////////////////
@@ -254,3 +337,4 @@
   d->packets = packets;
   d->header.setPacketSizes(packetSizes);
 }
+
diff -Nur taglib-1.5-orig/taglib/ogg/oggpage.h taglib-1.5-1.6/taglib/ogg/oggpage.h
--- taglib-1.5-orig/taglib/ogg/oggpage.h	2008-02-04 16:14:46.000000000 +0100
+++ taglib-1.5-1.6/taglib/ogg/oggpage.h	2009-09-14 19:01:31.031764764 +0200
@@ -70,6 +70,14 @@
        */
       const PageHeader *header() const;
 
+      /*! 
+       * Returns a copy of the page with \a sequenceNumber set as sequence number.
+       * 
+       * \see header()
+       * \see PageHeader::setPageSequenceNumber()
+       */
+      Page* getCopyWithNewPageSequenceNumber(int sequenceNumber);
+
       /*!
        * Returns the index of the first packet wholly or partially contained in
        * this page.
diff -Nur taglib-1.5-orig/taglib/ogg/xiphcomment.cpp taglib-1.5-1.6/taglib/ogg/xiphcomment.cpp
--- taglib-1.5-orig/taglib/ogg/xiphcomment.cpp	2008-02-04 16:14:46.000000000 +0100
+++ taglib-1.5-1.6/taglib/ogg/xiphcomment.cpp	2009-09-14 19:01:31.011763641 +0200
@@ -103,16 +103,20 @@
 
 TagLib::uint Ogg::XiphComment::year() const
 {
-  if(d->fieldListMap["DATE"].isEmpty())
-    return 0;
-  return d->fieldListMap["DATE"].front().toInt();
+  if(!d->fieldListMap["DATE"].isEmpty())
+    return d->fieldListMap["DATE"].front().toInt();
+  if(!d->fieldListMap["YEAR"].isEmpty())
+    return d->fieldListMap["YEAR"].front().toInt();
+  return 0;
 }
 
 TagLib::uint Ogg::XiphComment::track() const
 {
-  if(d->fieldListMap["TRACKNUMBER"].isEmpty())
-    return 0;
-  return d->fieldListMap["TRACKNUMBER"].front().toInt();
+  if(!d->fieldListMap["TRACKNUMBER"].isEmpty())
+    return d->fieldListMap["TRACKNUMBER"].front().toInt();
+  if(!d->fieldListMap["TRACKNUM"].isEmpty())
+    return d->fieldListMap["TRACKNUM"].front().toInt();
+  return 0;
 }
 
 void Ogg::XiphComment::setTitle(const String &s)
@@ -142,6 +146,7 @@
 
 void Ogg::XiphComment::setYear(uint i)
 {
+  removeField("YEAR");
   if(i == 0)
     removeField("DATE");
   else
@@ -150,6 +155,7 @@
 
 void Ogg::XiphComment::setTrack(uint i)
 {
+  removeField("TRACKNUM");
   if(i == 0)
     removeField("TRACKNUMBER");
   else

taglib-1.5-1.6-toolkit.patch:
 taglib-1.5/taglib/toolkit/tstring.cpp     |    6 +++++-
 taglib-1.5/taglib/toolkit/tstring.h       |    2 +-
 taglib/taglib/toolkit/tbytevector.cpp     |    4 ++--
 taglib/taglib/toolkit/tbytevector.h       |    2 +-
 taglib/taglib/toolkit/tbytevectorlist.cpp |    2 +-
 5 files changed, 10 insertions(+), 6 deletions(-)

--- NEW FILE taglib-1.5-1.6-toolkit.patch ---
diff -Nur taglib-1.5/taglib/toolkit/tbytevector.cpp taglib/taglib/toolkit/tbytevector.cpp
--- taglib-1.5/taglib/toolkit/tbytevector.cpp	2008-02-12 04:18:52.000000000 +0100
+++ taglib/taglib/toolkit/tbytevector.cpp	2008-12-04 13:37:36.000000000 +0100
@@ -147,12 +147,12 @@
   public:
     ByteVectorMirror(const ByteVector &source) : v(source) {}
 
-    const char operator[](int index) const
+    char operator[](int index) const
     {
       return v[v.size() - index - 1];
     }
 
-    const char at(int index) const
+    char at(int index) const
     {
       return v.at(v.size() - index - 1);
     }
diff -Nur taglib-1.5/taglib/toolkit/tbytevector.h taglib/taglib/toolkit/tbytevector.h
--- taglib-1.5/taglib/toolkit/tbytevector.h	2008-02-05 19:51:48.000000000 +0100
+++ taglib/taglib/toolkit/tbytevector.h	2009-07-02 22:54:32.000000000 +0200
@@ -30,7 +30,7 @@
 #include "taglib_export.h"
 
 #include <vector>
-#include <ostream>
+#include <iostream>
 
 namespace TagLib {
 
diff -Nur taglib-1.5/taglib/toolkit/tbytevectorlist.cpp taglib/taglib/toolkit/tbytevectorlist.cpp
--- taglib-1.5/taglib/toolkit/tbytevectorlist.cpp	2008-02-04 16:14:45.000000000 +0100
+++ taglib/taglib/toolkit/tbytevectorlist.cpp	2009-07-11 15:24:21.000000000 +0200
@@ -52,7 +52,7 @@
       offset != -1 && (max == 0 || max > int(l.size()) + 1);
       offset = v.find(pattern, offset + pattern.size(), byteAlign))
   {
-    if(offset - previousOffset > 1)
+    if(offset - previousOffset >= 1)
       l.append(v.mid(previousOffset, offset - previousOffset));
     else
       l.append(ByteVector::null);
diff -Nur taglib-1.5-orig/taglib/toolkit/tstring.cpp taglib-1.5/taglib/toolkit/tstring.cpp
--- taglib-1.5-orig/taglib/toolkit/tstring.cpp	2008-02-04 16:14:45.000000000 +0100
+++ taglib-1.5/taglib/toolkit/tstring.cpp	2009-09-04 12:07:00.506121756 +0200
@@ -35,7 +35,7 @@
 
   inline unsigned short byteSwap(unsigned short x)
   {
-    return ((x) >> 8) & 0xff | ((x) & 0xff) << 8;
+    return (((x) >> 8) & 0xff) | (((x) & 0xff) << 8);
   }
 
   inline unsigned short combine(unsigned char c1, unsigned char c2)
@@ -510,6 +510,8 @@
 
 TagLib::wchar &String::operator[](int i)
 {
+  detach();
+
   return d->data[i];
 }
 
@@ -558,6 +560,8 @@
 
 String &String::operator+=(char c)
 {
+  detach();
+
   d->data += uchar(c);
   return *this;
 }
diff -Nur taglib-1.5-orig/taglib/toolkit/tstring.h taglib-1.5/taglib/toolkit/tstring.h
--- taglib-1.5-orig/taglib/toolkit/tstring.h	2008-02-04 16:14:45.000000000 +0100
+++ taglib-1.5/taglib/toolkit/tstring.h	2009-09-04 12:07:03.465121011 +0200
@@ -31,7 +31,7 @@
 #include "tbytevector.h"
 
 #include <string>
-#include <ostream>
+#include <iostream>
 
 /*!
  * \relates TagLib::String

taglib-1.5-tests.patch:
 test_string.cpp |    1 +
 1 file changed, 1 insertion(+)

--- NEW FILE taglib-1.5-tests.patch ---
diff -Nur taglib-1.5-orig/tests/test_string.cpp taglib-1.5/tests/test_string.cpp
--- taglib-1.5-orig/tests/test_string.cpp	2008-01-26 11:57:06.000000000 +0100
+++ taglib-1.5/tests/test_string.cpp	2009-08-22 11:17:55.000000000 +0200
@@ -24,6 +24,7 @@
 
 #include <cppunit/extensions/HelperMacros.h>
 #include <tstring.h>
+#include <cstring>
 
 using namespace std;
 using namespace TagLib;


Index: .cvsignore
===================================================================
RCS file: /cvs/pkgs/rpms/taglib/F-10/.cvsignore,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -p -r1.12 -r1.13
--- .cvsignore	14 Sep 2009 08:02:18 -0000	1.12
+++ .cvsignore	14 Sep 2009 17:09:37 -0000	1.13
@@ -1 +1 @@
-taglib-1.6.tar.gz
+taglib-1.5.tar.gz


Index: sources
===================================================================
RCS file: /cvs/pkgs/rpms/taglib/F-10/sources,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -p -r1.12 -r1.13
--- sources	14 Sep 2009 08:02:18 -0000	1.12
+++ sources	14 Sep 2009 17:09:37 -0000	1.13
@@ -1 +1 @@
-5ecad0816e586a954bd676a86237d054  taglib-1.6.tar.gz
+7b557dde7425c6deb7bbedd65b4f2717  taglib-1.5.tar.gz


Index: taglib.spec
===================================================================
RCS file: /cvs/pkgs/rpms/taglib/F-10/taglib.spec,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -p -r1.32 -r1.33
--- taglib.spec	14 Sep 2009 13:13:25 -0000	1.32
+++ taglib.spec	14 Sep 2009 17:09:38 -0000	1.33
@@ -11,16 +11,14 @@
 %global apidocdir __api-doc_fedora
 
 Name:       taglib	
-Version:    1.6
-Release:    1%{?dist}
+Version:    1.5
+Release:    9%{?dist}
 Summary:    Audio Meta-Data Library
 
 Group: 	    System Environment/Libraries
 License:    LGPLv2
 URL:        http://developer.kde.org/~wheeler/taglib.html
-# the temporary url from the 1.6 announcement
-Source0:    http://ftp.musicbrainz.org/pub/musicbrainz/users/luks/taglib/taglib-1.6.tar.gz
-#Source0:    http://developer.kde.org/~wheeler/files/src/taglib-%{version}.tar.gz
+Source0:    http://developer.kde.org/~wheeler/files/src/taglib-%{version}.tar.gz
 #Source0:    taglib-%{svn}.tar.gz
 # The svn tarball is generated with the following script
 Source1:    taglib-svn.sh
@@ -32,7 +30,15 @@ Patch1:     taglib-1.5b1-multilib.patch 
 # try 2, kiss omit -L%_libdir
 Patch2:     taglib-1.5rc1-multilib.patch
 
-Patch3: taglib-1.6-test_mp4.patch
+Patch3: taglib-1.5-tests.patch
+
+## upstream patches
+Patch101: taglib-1.5-1.6-ape.patch
+Patch102: taglib-1.5-1.6-ogg.patch
+Patch103: taglib-1.5-1.6-flac.patch
+Patch104: taglib-1.5-1.6-toolkit.patch
+Patch105: taglib-1.5-1.6-mpeg.patch
+Patch106: taglib-1.5-1.6-mpeg-cmake.patch
 
 BuildRequires: cmake
 BuildRequires: pkgconfig
@@ -86,13 +92,19 @@ Files needed when building software with
 ## omit for now
 %patch2 -p1 -b .multilib
 
-%patch3 -p1 -b .test_mp4
+%patch3 -p1 -b .tests
+%patch101 -p1 -b .ape
+%patch102 -p1 -b .ogg
+%patch103 -p1 -b .flac
+%patch104 -p1 -b .toolkit
+%patch105 -p1 -b .mpeg
+%patch106 -p1 -b .mpeg-build
 
 
 %build
 mkdir -p %{_target_platform}
 pushd %{_target_platform}
-%{cmake} %{?buildtests} -DWITH_ASF=1 -DWITH_MP4=1 ..
+%{cmake} %{?buildtests} ..
 popd
 
 make %{?_smp_mflags} -C %{_target_platform}
@@ -159,13 +171,8 @@ rm -rf %{buildroot}
 
 
 %changelog
-* Mon Sep 14 2009 Michael Schwendt <mschwendt at fedoraproject.org> - 1.6-1
-- Add patch to fix MP4 test on ppc/ppc64.
-- Update to 1.6 final.
-
-* Sun Sep  6 2009 Michael Schwendt <mschwendt at fedoraproject.org> - 1.6-0.1.rc1
-- Update to 1.6rc1 (further bug-fixes and support for AIFF and WAV).
-- Build optional support for MP4 and ASF/WMA files.
+* Mon Sep 14 2009 Michael Schwendt <mschwendt at fedoraproject.org> - 1.5-9
+- Merge minor changes in id3v2/ogg from 1.6 final.
 
 * Fri Sep  4 2009 Michael Schwendt <mschwendt at fedoraproject.org> - 1.5-8
 - Merge another bug-fix from 1.6rc1 (this adds 3 symbols) and


--- taglib-1.6-test_mp4.patch DELETED ---




More information about the fedora-extras-commits mailing list