${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mpc
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mp4
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mpeg/id3v2
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mpeg/id3v2/frames
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/wavpack
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg/speex
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/trueaudio
${CMAKE_CURRENT_SOURCE_DIR}/ogg/vorbis
${CMAKE_CURRENT_SOURCE_DIR}/ogg/speex
${CMAKE_CURRENT_SOURCE_DIR}/mpeg/id3v2
+ ${CMAKE_CURRENT_SOURCE_DIR}/mpeg/id3v2/frames
${CMAKE_CURRENT_SOURCE_DIR}/mpeg/id3v1
${CMAKE_CURRENT_SOURCE_DIR}/ape
${CMAKE_CURRENT_SOURCE_DIR}/wavpack
SET(flacs_SRCS
flac/flacfile.cpp
+flac/flacpicture.cpp
flac/flacproperties.cpp
)
-INSTALL( FILES flacfile.h flacproperties.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib )
+INSTALL( FILES flacfile.h flacpicture.h flacproperties.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib )
-I$(top_srcdir)/taglib/toolkit \
-I$(top_srcdir)/taglib/ogg \
-I$(top_srcdir)/taglib/mpeg/id3v2 \
+ -I$(top_srcdir)/taglib/mpeg/id3v2/frames \
-I$(top_srcdir)/taglib/mpeg/id3v1 \
$(all_includes)
noinst_LTLIBRARIES = libflac.la
-libflac_la_SOURCES = flacfile.cpp flacproperties.cpp
+libflac_la_SOURCES = flacfile.cpp flacpicture.cpp flacproperties.cpp
-taglib_include_HEADERS = flacfile.h flacproperties.h
+taglib_include_HEADERS = flacfile.h flacpicture.h flacproperties.h
taglib_includedir = $(includedir)/taglib
#include <id3v1tag.h>
#include <xiphcomment.h>
+#include "flacpicture.h"
#include "flacfile.h"
using namespace TagLib;
namespace
{
enum { XiphIndex = 0, ID3v2Index = 1, ID3v1Index = 2 };
- enum { StreamInfo = 0, Padding, Application, SeekTable, VorbisComment, CueSheet };
+ enum {
+ StreamInfo = 0,
+ Padding,
+ Application,
+ SeekTable,
+ VorbisComment,
+ CueSheet,
+ PictureBlock
+ };
enum { MinPaddingLength = 4096 };
}
~FilePrivate()
{
+ for(uint i = 0; i < pictureList.size(); i++) {
+ delete pictureList[i];
+ }
delete properties;
}
Properties *properties;
ByteVector streamInfoData;
ByteVector xiphCommentData;
+ List<Picture *> pictureList;
long flacStart;
long streamStart;
debug("FLAC::File::scan() -- multiple Vorbis Comment blocks found, using the first one");
}
}
+ else if(blockType == PictureBlock) {
+ ByteVector pictureData = readBlock(length);
+ FLAC::Picture *picture = new FLAC::Picture();
+ if(picture->parse(pictureData)) {
+ addPicture(picture);
+ }
+ else {
+ debug("FLAC::File::scan() -- invalid picture found");
+ }
+ }
nextBlockOffset += length + 4;
return 0;
}
+
+List<FLAC::Picture *> FLAC::File::pictureList()
+{
+ return d->pictureList;
+}
+
+void FLAC::File::addPicture(Picture *picture)
+{
+ d->pictureList.append(picture);
+}
+
+void FLAC::File::removePictures()
+{
+ for(uint i = 0; i < d->pictureList.size(); i++)
+ delete d->pictureList[i];
+ d->pictureList.clear();
+}
+
#include "taglib_export.h"
#include "tfile.h"
+#include "tlist.h"
+#include "flacpicture.h"
#include "flacproperties.h"
namespace TagLib {
*/
long streamLength(); // BIC: remove
+ /*!
+ * Returns a list of pictures attached to the FLAC file.
+ */
+ List<Picture *> pictureList();
+
+ /*!
+ * Remove all attached images.
+ */
+ void removePictures();
+
+ /*!
+ * Add a new picture to the file. The file takes ownership of the
+ * picture and will handle freeing its memory.
+ *
+ * \note The file will be saved only after calling save().
+ */
+ void addPicture(Picture *picture);
+
private:
File(const File &);
File &operator=(const File &);
--- /dev/null
+/**************************************************************************
+ copyright : (C) 2010 by Lukáš Lalinský
+ email : lalinsky@gmail.com
+ **************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <taglib.h>
+#include <tdebug.h>
+#include "flacpicture.h"
+
+using namespace TagLib;
+
+class FLAC::Picture::PicturePrivate
+{
+public:
+ PicturePrivate() :
+ type(ID3v2::AttachedPictureFrame::Other),
+ width(0),
+ height(0),
+ colorDepth(0),
+ numColors(0)
+ {}
+
+ Type type;
+ String mimeType;
+ String description;
+ int width;
+ int height;
+ int colorDepth;
+ int numColors;
+ ByteVector data;
+};
+
+FLAC::Picture::Picture()
+{
+ d = new PicturePrivate;
+}
+
+FLAC::Picture::Picture(const ByteVector &data)
+{
+ d = new PicturePrivate;
+ parse(data);
+}
+
+FLAC::Picture::~Picture()
+{
+ delete d;
+}
+
+bool FLAC::Picture::parse(const ByteVector &data)
+{
+ if(data.size() < 32) {
+ debug("A picture block must contain at least 5 bytes.");
+ return false;
+ }
+
+ int pos = 0;
+ d->type = TagLib::ID3v2::AttachedPictureFrame::Type(data.mid(pos, 4).toUInt());
+ pos += 4;
+ uint mimeTypeLength = data.mid(pos, 4).toUInt();
+ pos += 4;
+ if(pos + mimeTypeLength + 24 > data.size()) {
+ debug("Invalid picture block.");
+ return false;
+ }
+ d->mimeType = String(data.mid(pos, mimeTypeLength), String::UTF8);
+ pos += mimeTypeLength;
+ uint descriptionLength = data.mid(pos, 4).toUInt();
+ pos += 4;
+ if(pos + descriptionLength + 20 > data.size()) {
+ debug("Invalid picture block.");
+ return false;
+ }
+ d->description = String(data.mid(pos, descriptionLength), String::UTF8);
+ pos += descriptionLength;
+ d->width = data.mid(pos, 4).toUInt();
+ pos += 4;
+ d->height = data.mid(pos, 4).toUInt();
+ pos += 4;
+ d->colorDepth = data.mid(pos, 4).toUInt();
+ pos += 4;
+ d->numColors = data.mid(pos, 4).toUInt();
+ pos += 4;
+ uint dataLength = data.mid(pos, 4).toUInt();
+ pos += 4;
+ if(pos + dataLength > data.size()) {
+ debug("Invalid picture block.");
+ return false;
+ }
+ d->data = data.mid(pos, dataLength);
+
+ return true;
+}
+
+FLAC::Picture::Type FLAC::Picture::type() const
+{
+ return d->type;
+}
+
+void FLAC::Picture::setType(FLAC::Picture::Type type)
+{
+ d->type = type;
+}
+
+String FLAC::Picture::mimeType() const
+{
+ return d->mimeType;
+}
+
+void FLAC::Picture::setMimeType(const String &mimeType)
+{
+ d->mimeType = mimeType;
+}
+
+String FLAC::Picture::description() const
+{
+ return d->description;
+}
+
+void FLAC::Picture::setDescription(const String &description)
+{
+ d->description = description;
+}
+
+int FLAC::Picture::width() const
+{
+ return d->width;
+}
+
+void FLAC::Picture::setWidth(int width)
+{
+ d->width = width;
+}
+
+int FLAC::Picture::height() const
+{
+ return d->height;
+}
+
+void FLAC::Picture::setHeight(int height)
+{
+ d->height = height;
+}
+
+int FLAC::Picture::colorDepth() const
+{
+ return d->colorDepth;
+}
+
+void FLAC::Picture::setColorDepth(int colorDepth)
+{
+ d->colorDepth = colorDepth;
+}
+
+int FLAC::Picture::numColors() const
+{
+ return d->numColors;
+}
+
+void FLAC::Picture::setNumColors(int numColors)
+{
+ d->numColors = numColors;
+}
+
+ByteVector FLAC::Picture::data() const
+{
+ return d->data;
+}
+
+void FLAC::Picture::setData(const ByteVector &data)
+{
+ d->data = data;
+}
+
--- /dev/null
+/**************************************************************************
+ copyright : (C) 2010 by Lukáš Lalinský
+ email : lalinsky@gmail.com
+ **************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifndef TAGLIB_FLACPICTURE_H
+#define TAGLIB_FLACPICTURE_H
+
+#include "tlist.h"
+#include "tbytevector.h"
+#include "taglib_export.h"
+#include "attachedpictureframe.h"
+
+namespace TagLib {
+
+ namespace FLAC {
+
+ class TAGLIB_EXPORT Picture
+ {
+ public:
+ typedef ID3v2::AttachedPictureFrame::Type Type;
+
+ Picture();
+ Picture(const ByteVector &data);
+ ~Picture();
+
+ /*!
+ * Returns the type of the image.
+ */
+ Type type() const;
+
+ /*!
+ * Sets the type of the image.
+ */
+ void setType(Type type);
+
+ /*!
+ * Returns the mime type of the image. This should in most cases be
+ * "image/png" or "image/jpeg".
+ */
+ String mimeType() const;
+
+ /*!
+ * Sets the mime type of the image. This should in most cases be
+ * "image/png" or "image/jpeg".
+ */
+ void setMimeType(const String &m);
+
+ /*!
+ * Returns a text description of the image.
+ */
+
+ String description() const;
+
+ /*!
+ * Sets a textual description of the image to \a desc.
+ */
+
+ void setDescription(const String &desc);
+
+ /*!
+ * Returns the width of the image.
+ */
+ int width() const;
+
+ /*!
+ * Sets the width of the image.
+ */
+ void setWidth(int w);
+
+ /*!
+ * Returns the height of the image.
+ */
+ int height() const;
+
+ /*!
+ * Sets the height of the image.
+ */
+ void setHeight(int h);
+
+ /*!
+ * Returns the color depth (in bits-per-pixel) of the image.
+ */
+ int colorDepth() const;
+
+ /*!
+ * Sets the color depth (in bits-per-pixel) of the image.
+ */
+ void setColorDepth(int depth);
+
+ /*!
+ * Returns the number of colors used on the image..
+ */
+ int numColors() const;
+
+ /*!
+ * Sets the number of colors used on the image (for indexed images).
+ */
+ void setNumColors(int numColors);
+
+ /*!
+ * Returns the image data.
+ */
+ ByteVector data() const;
+
+ /*!
+ * Sets the image data.
+ */
+ void setData(const ByteVector &data);
+
+ bool parse(const ByteVector &rawData);
+
+ private:
+ Picture(const Picture &item);
+ Picture &operator=(const Picture &item);
+
+ class PicturePrivate;
+ PicturePrivate *d;
+ };
+
+ typedef List<Picture> PictureList;
+
+ }
+
+}
+
+#endif
CPPUNIT_TEST_SUITE(TestFLAC);
CPPUNIT_TEST(testSignature);
CPPUNIT_TEST(testMultipleCommentBlocks);
+ CPPUNIT_TEST(testPicture);
CPPUNIT_TEST_SUITE_END();
public:
delete f;
}
+ void testPicture()
+ {
+ ScopedFileCopy copy("silence-44-s", ".flac");
+ string newname = copy.fileName();
+
+ FLAC::File *f = new FLAC::File(newname.c_str());
+ List<FLAC::Picture *> lst = f->pictureList();
+ CPPUNIT_ASSERT_EQUAL(TagLib::uint(1), lst.size());
+
+ FLAC::Picture *pic = lst.front();
+ CPPUNIT_ASSERT_EQUAL(3, int(pic->type()));
+ CPPUNIT_ASSERT_EQUAL(1, pic->width());
+ CPPUNIT_ASSERT_EQUAL(1, pic->height());
+ CPPUNIT_ASSERT_EQUAL(24, pic->colorDepth());
+ CPPUNIT_ASSERT_EQUAL(0, pic->numColors());
+ CPPUNIT_ASSERT_EQUAL(String("image/png"), pic->mimeType());
+ CPPUNIT_ASSERT_EQUAL(String("A pixel."), pic->description());
+ CPPUNIT_ASSERT_EQUAL(TagLib::uint(150), pic->data().size());
+ }
+
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestFLAC);