From dcef0fbad200a6efc34989a25e58f96aaf49d223 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Luk=C3=A1=C5=A1=20Lalinsk=C3=BD?= Date: Sun, 25 Jul 2010 11:06:36 +0000 Subject: [PATCH] Read-only support for FLAC picture blocks CCBUG:218696 git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1154376 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- bindings/c/CMakeLists.txt | 1 + taglib/CMakeLists.txt | 2 + taglib/flac/CMakeLists.txt | 2 +- taglib/flac/Makefile.am | 5 +- taglib/flac/flacfile.cpp | 43 +++++++- taglib/flac/flacfile.h | 20 ++++ taglib/flac/flacpicture.cpp | 197 +++++++++++++++++++++++++++++++++++ taglib/flac/flacpicture.h | 147 ++++++++++++++++++++++++++ tests/data/silence-44-s.flac | Bin 0 -> 50904 bytes tests/test_flac.cpp | 21 ++++ 10 files changed, 434 insertions(+), 4 deletions(-) create mode 100644 taglib/flac/flacpicture.cpp create mode 100644 taglib/flac/flacpicture.h create mode 100644 tests/data/silence-44-s.flac diff --git a/bindings/c/CMakeLists.txt b/bindings/c/CMakeLists.txt index a12adeaf..79c7a6b9 100644 --- a/bindings/c/CMakeLists.txt +++ b/bindings/c/CMakeLists.txt @@ -9,6 +9,7 @@ INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib ${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 diff --git a/taglib/CMakeLists.txt b/taglib/CMakeLists.txt index 619e31d9..04ce64e2 100644 --- a/taglib/CMakeLists.txt +++ b/taglib/CMakeLists.txt @@ -12,6 +12,7 @@ INCLUDE_DIRECTORIES( ${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 @@ -92,6 +93,7 @@ ogg/vorbis/vorbisproperties.cpp SET(flacs_SRCS flac/flacfile.cpp +flac/flacpicture.cpp flac/flacproperties.cpp ) diff --git a/taglib/flac/CMakeLists.txt b/taglib/flac/CMakeLists.txt index 8c983151..62768a43 100644 --- a/taglib/flac/CMakeLists.txt +++ b/taglib/flac/CMakeLists.txt @@ -1 +1 @@ -INSTALL( FILES flacfile.h flacproperties.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib ) +INSTALL( FILES flacfile.h flacpicture.h flacproperties.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib ) diff --git a/taglib/flac/Makefile.am b/taglib/flac/Makefile.am index 2d33975e..eebc7247 100644 --- a/taglib/flac/Makefile.am +++ b/taglib/flac/Makefile.am @@ -4,12 +4,13 @@ INCLUDES = \ -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 diff --git a/taglib/flac/flacfile.cpp b/taglib/flac/flacfile.cpp index 7f3d9023..799e2fe4 100644 --- a/taglib/flac/flacfile.cpp +++ b/taglib/flac/flacfile.cpp @@ -34,6 +34,7 @@ #include #include +#include "flacpicture.h" #include "flacfile.h" using namespace TagLib; @@ -41,7 +42,15 @@ 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 }; } @@ -64,6 +73,9 @@ public: ~FilePrivate() { + for(uint i = 0; i < pictureList.size(); i++) { + delete pictureList[i]; + } delete properties; } @@ -78,6 +90,7 @@ public: Properties *properties; ByteVector streamInfoData; ByteVector xiphCommentData; + List pictureList; long flacStart; long streamStart; @@ -423,6 +436,16 @@ void FLAC::File::scan() 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; @@ -502,3 +525,21 @@ long FLAC::File::findPaddingBreak(long nextBlockOffset, long targetOffset, bool return 0; } + +List 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(); +} + diff --git a/taglib/flac/flacfile.h b/taglib/flac/flacfile.h index 015ecc8e..84b8680a 100644 --- a/taglib/flac/flacfile.h +++ b/taglib/flac/flacfile.h @@ -28,7 +28,9 @@ #include "taglib_export.h" #include "tfile.h" +#include "tlist.h" +#include "flacpicture.h" #include "flacproperties.h" namespace TagLib { @@ -182,6 +184,24 @@ namespace TagLib { */ long streamLength(); // BIC: remove + /*! + * Returns a list of pictures attached to the FLAC file. + */ + List 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 &); diff --git a/taglib/flac/flacpicture.cpp b/taglib/flac/flacpicture.cpp new file mode 100644 index 00000000..e7f6958c --- /dev/null +++ b/taglib/flac/flacpicture.cpp @@ -0,0 +1,197 @@ +/************************************************************************** + 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 +#endif + +#include +#include +#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; +} + diff --git a/taglib/flac/flacpicture.h b/taglib/flac/flacpicture.h new file mode 100644 index 00000000..a05f0666 --- /dev/null +++ b/taglib/flac/flacpicture.h @@ -0,0 +1,147 @@ +/************************************************************************** + 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 PictureList; + + } + +} + +#endif diff --git a/tests/data/silence-44-s.flac b/tests/data/silence-44-s.flac new file mode 100644 index 0000000000000000000000000000000000000000..24e15deb8c85ef82baf22a231901d646397dd8c4 GIT binary patch literal 50904 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 literal 0 HcmV?d00001 diff --git a/tests/test_flac.cpp b/tests/test_flac.cpp index 990299b2..d14a597b 100644 --- a/tests/test_flac.cpp +++ b/tests/test_flac.cpp @@ -15,6 +15,7 @@ class TestFLAC : public CppUnit::TestFixture CPPUNIT_TEST_SUITE(TestFLAC); CPPUNIT_TEST(testSignature); CPPUNIT_TEST(testMultipleCommentBlocks); + CPPUNIT_TEST(testPicture); CPPUNIT_TEST_SUITE_END(); public: @@ -41,6 +42,26 @@ 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 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); -- 2.40.0