diff --git a/taglib-1.5-1.6-ape.patch b/taglib-1.5-1.6-ape.patch new file mode 100644 index 0000000..4455ea4 --- /dev/null +++ b/taglib-1.5-1.6-ape.patch @@ -0,0 +1,32 @@ +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) { diff --git a/taglib-1.5-1.6-flac.patch b/taglib-1.5-1.6-flac.patch new file mode 100644 index 0000000..5b6fe5b --- /dev/null +++ b/taglib-1.5-1.6-flac.patch @@ -0,0 +1,133 @@ +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; + } diff --git a/taglib-1.5-1.6-mpeg-cmake.patch b/taglib-1.5-1.6-mpeg-cmake.patch new file mode 100644 index 0000000..957f3c2 --- /dev/null +++ b/taglib-1.5-1.6-mpeg-cmake.patch @@ -0,0 +1,12 @@ +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 diff --git a/taglib-1.5-1.6-mpeg.patch b/taglib-1.5-1.6-mpeg.patch new file mode 100644 index 0000000..aa4f1d9 --- /dev/null +++ b/taglib-1.5-1.6-mpeg.patch @@ -0,0 +1,887 @@ +diff -Nur taglib-1.5/taglib/mpeg/mpegheader.cpp taglib/taglib/mpeg/mpegheader.cpp +--- taglib-1.5/taglib/mpeg/mpegheader.cpp 2008-02-04 16:14:46.000000000 +0100 ++++ taglib/taglib/mpeg/mpegheader.cpp 2009-01-16 06:16:48.000000000 +0100 +@@ -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/taglib/mpeg/mpegproperties.cpp taglib/taglib/mpeg/mpegproperties.cpp +--- taglib-1.5/taglib/mpeg/mpegproperties.cpp 2008-02-04 16:14:46.000000000 +0100 ++++ taglib/taglib/mpeg/mpegproperties.cpp 2009-07-10 16:34:04.000000000 +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 +diff -Nur taglib-1.5/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp taglib/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp +--- taglib-1.5/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp 2008-02-04 16:14:46.000000000 +0100 ++++ taglib/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp 2009-07-11 16:27:17.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 (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/taglib/mpeg/id3v2/frames/attachedpictureframe.h taglib/taglib/mpeg/id3v2/frames/attachedpictureframe.h +--- taglib-1.5/taglib/mpeg/id3v2/frames/attachedpictureframe.h 2008-02-04 16:14:46.000000000 +0100 ++++ taglib/taglib/mpeg/id3v2/frames/attachedpictureframe.h 2009-07-11 16:27:17.000000000 +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/taglib/mpeg/id3v2/frames/CMakeLists.txt taglib/taglib/mpeg/id3v2/frames/CMakeLists.txt +--- taglib-1.5/taglib/mpeg/id3v2/frames/CMakeLists.txt 2008-01-31 22:48:39.000000000 +0100 ++++ taglib/taglib/mpeg/id3v2/frames/CMakeLists.txt 2008-06-26 17:06:20.000000000 +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/taglib/mpeg/id3v2/frames/generalencapsulatedobjectframe.h taglib/taglib/mpeg/id3v2/frames/generalencapsulatedobjectframe.h +--- taglib-1.5/taglib/mpeg/id3v2/frames/generalencapsulatedobjectframe.h 2008-02-04 16:14:46.000000000 +0100 ++++ taglib/taglib/mpeg/id3v2/frames/generalencapsulatedobjectframe.h 2008-06-19 22:44:39.000000000 +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/taglib/mpeg/id3v2/frames/Makefile.am taglib/taglib/mpeg/id3v2/frames/Makefile.am +--- taglib-1.5/taglib/mpeg/id3v2/frames/Makefile.am 2008-01-31 22:48:28.000000000 +0100 ++++ taglib/taglib/mpeg/id3v2/frames/Makefile.am 2008-06-26 17:06:20.000000000 +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/taglib/mpeg/id3v2/frames/popularimeterframe.cpp taglib/taglib/mpeg/id3v2/frames/popularimeterframe.cpp +--- taglib-1.5/taglib/mpeg/id3v2/frames/popularimeterframe.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ taglib/taglib/mpeg/id3v2/frames/popularimeterframe.cpp 2008-05-22 22:40:14.000000000 +0200 +@@ -0,0 +1,137 @@ ++/*************************************************************************** ++ copyright : (C) 2008 by Lukas Lalinsky ++ 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/ * ++ ***************************************************************************/ ++ ++#include ++ ++#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/taglib/mpeg/id3v2/frames/popularimeterframe.h taglib/taglib/mpeg/id3v2/frames/popularimeterframe.h +--- taglib-1.5/taglib/mpeg/id3v2/frames/popularimeterframe.h 1970-01-01 01:00:00.000000000 +0100 ++++ taglib/taglib/mpeg/id3v2/frames/popularimeterframe.h 2008-05-22 14:06:45.000000000 +0200 +@@ -0,0 +1,132 @@ ++/*************************************************************************** ++ copyright : (C) 2008 by Lukas Lalinsky ++ 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/ * ++ ***************************************************************************/ ++ ++#ifndef TAGLIB_POPULARIMETERFRAME_H ++#define TAGLIB_POPULARIMETERFRAME_H ++ ++#include ++#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/taglib/mpeg/id3v2/frames/privateframe.cpp taglib/taglib/mpeg/id3v2/frames/privateframe.cpp +--- taglib-1.5/taglib/mpeg/id3v2/frames/privateframe.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ taglib/taglib/mpeg/id3v2/frames/privateframe.cpp 2008-06-27 00:11:11.000000000 +0200 +@@ -0,0 +1,128 @@ ++/*************************************************************************** ++ copyright : (C) 2008 by Serkan Kalyoncu ++ copyright : (C) 2008 by Scott Wheeler ++ email : wheeler@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 ++#include ++#include ++ ++#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/taglib/mpeg/id3v2/frames/privateframe.h taglib/taglib/mpeg/id3v2/frames/privateframe.h +--- taglib-1.5/taglib/mpeg/id3v2/frames/privateframe.h 1970-01-01 01:00:00.000000000 +0100 ++++ taglib/taglib/mpeg/id3v2/frames/privateframe.h 2008-06-27 00:11:11.000000000 +0200 +@@ -0,0 +1,111 @@ ++/*************************************************************************** ++ copyright : (C) 2008 by Serkan Kalyoncu ++ copyright : (C) 2008 by Scott Wheeler ++ email : wheeler@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/taglib/mpeg/id3v2/id3v2footer.cpp taglib/taglib/mpeg/id3v2/id3v2footer.cpp +--- taglib-1.5/taglib/mpeg/id3v2/id3v2footer.cpp 2008-02-04 16:14:46.000000000 +0100 ++++ taglib/taglib/mpeg/id3v2/id3v2footer.cpp 2008-12-05 17:43:38.000000000 +0100 +@@ -45,7 +45,7 @@ + + } + +-const unsigned int Footer::size() ++TagLib::uint Footer::size() + { + return FooterPrivate::size; + } +diff -Nur taglib-1.5/taglib/mpeg/id3v2/id3v2footer.h taglib/taglib/mpeg/id3v2/id3v2footer.h +--- taglib-1.5/taglib/mpeg/id3v2/id3v2footer.h 2008-02-04 16:14:46.000000000 +0100 ++++ taglib/taglib/mpeg/id3v2/id3v2footer.h 2008-12-05 01:37:39.000000000 +0100 +@@ -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/taglib/mpeg/id3v2/id3v2framefactory.cpp taglib/taglib/mpeg/id3v2/id3v2framefactory.cpp +--- taglib-1.5/taglib/mpeg/id3v2/id3v2framefactory.cpp 2008-02-21 01:43:14.000000000 +0100 ++++ taglib/taglib/mpeg/id3v2/id3v2framefactory.cpp 2009-07-11 16:27:17.000000000 +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/taglib/mpeg/id3v2/id3v2tag.cpp taglib/taglib/mpeg/id3v2/id3v2tag.cpp +--- taglib-1.5/taglib/mpeg/id3v2/id3v2tag.cpp 2008-02-04 21:33:54.000000000 +0100 ++++ taglib/taglib/mpeg/id3v2/id3v2tag.cpp 2009-07-11 16:43:58.000000000 +0200 +@@ -125,7 +125,9 @@ + + for(FrameList::ConstIterator it = comments.begin(); it != comments.end(); ++it) + { +- if(static_cast(*it)->description().isEmpty()) ++ CommentsFrame *frame = dynamic_cast(*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 --git a/taglib-1.5-1.6-ogg.patch b/taglib-1.5-1.6-ogg.patch new file mode 100644 index 0000000..6b03959 --- /dev/null +++ b/taglib-1.5-1.6-ogg.patch @@ -0,0 +1,46 @@ +diff -Nur taglib-1.5/taglib/ogg/xiphcomment.cpp taglib/taglib/ogg/xiphcomment.cpp +--- taglib-1.5/taglib/ogg/xiphcomment.cpp 2008-02-04 16:14:46.000000000 +0100 ++++ taglib/taglib/ogg/xiphcomment.cpp 2009-07-11 15:17:06.000000000 +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 diff --git a/taglib-1.5-1.6-toolkit.patch b/taglib-1.5-1.6-toolkit.patch new file mode 100644 index 0000000..6262891 --- /dev/null +++ b/taglib-1.5-1.6-toolkit.patch @@ -0,0 +1,42 @@ +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 +-#include ++#include + + 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 --git a/taglib-1.5-kde#161721.patch b/taglib-1.5-kde#161721.patch deleted file mode 100644 index 461f2ad..0000000 --- a/taglib-1.5-kde#161721.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff -up taglib-1.5/taglib/mpeg/id3v2/id3v2tag.cpp.kde#161721 taglib-1.5/taglib/mpeg/id3v2/id3v2tag.cpp ---- taglib-1.5/taglib/mpeg/id3v2/id3v2tag.cpp.kde#161721 2008-02-04 14:33:54.000000000 -0600 -+++ taglib-1.5/taglib/mpeg/id3v2/id3v2tag.cpp 2008-10-06 15:52:08.000000000 -0500 -@@ -125,7 +125,9 @@ String ID3v2::Tag::comment() const - - for(FrameList::ConstIterator it = comments.begin(); it != comments.end(); ++it) - { -- if(static_cast(*it)->description().isEmpty()) -+ CommentsFrame *frame = dynamic_cast(*it); -+ -+ if(frame && frame->description().isEmpty()) - return (*it)->toString(); - } - diff --git a/taglib.spec b/taglib.spec index fdc9f0c..d3b9812 100644 --- a/taglib.spec +++ b/taglib.spec @@ -30,7 +30,12 @@ Patch2: taglib-1.5rc1-multilib.patch Patch3: taglib-1.5-tests.patch ## upstream patches -Patch100: taglib-1.5-kde#161721.patch +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 @@ -60,7 +65,12 @@ Files needed when building software with %{name}. %patch2 -p1 -b .multilib %patch3 -p1 -b .tests -%patch100 -p1 -b .kde#161721.patch +%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 @@ -117,6 +127,29 @@ rm -rf %{buildroot} * Sat Aug 22 2009 Michael Schwendt - 1.5-6 - Add %%check section and conditionally build with tests. - Update descriptions (and mention the additional file formats). +- Cherry-pick bug-fix patches from 1.6 development (also replaces the + old taglib-1.5-kde#161721.patch): + * Fixed crash when saving a Locator APEv2 tag. (BUG:169810) + * TagLib can now use FLAC padding block. (BUG:107659) + * Fixed overflow while calculating bitrate of FLAC files with a very + high bitrate. + * XiphComment::year() now falls back to YEAR if DATE doesn't exist + and XiphComment::year() falls back to TRACKNUM if TRACKNUMBER doesn't + exist. (BUG:144396) + * Fixed a bug in ByteVectorList::split(). + * Fixed a possible crash in the non-const version of String::operator[] + and in String::operator+=. (BUG:169389) + * ID3v2.2 frames are now not incorrectly saved. (BUG:176373) + * Support for ID3v2.2 PIC frames. (BUG:167786) + * Improved ID3v2.3 genre parsing. (BUG:188578) + * Better checking of corrupted ID3v2 APIC data. (BUG:168382) + * Bitrate calculating using the Xing header now uses floating point + numbers. (BUG:172556) + * Added support for PRIV ID3v2 frames. + * Empty ID3v2 genres are no longer treated as numeric ID3v1 genres. + * Added support for the POPM (rating/playcount) ID3v2 frame. + * Fixed crash on handling unsupported ID3v2 frames, e.g. on encrypted + frames. (BUG:161721) * Sun Jul 26 2009 Fedora Release Engineering - 1.5-5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild