mirror of
https://github.com/taglib/taglib.git
synced 2025-07-18 04:54:19 -04:00
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
This commit is contained in:
@ -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
|
||||
|
@ -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
|
||||
)
|
||||
|
||||
|
@ -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 )
|
||||
|
@ -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
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <id3v1tag.h>
|
||||
#include <xiphcomment.h>
|
||||
|
||||
#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<Picture *> 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::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();
|
||||
}
|
||||
|
||||
|
@ -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<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 &);
|
||||
|
197
taglib/flac/flacpicture.cpp
Normal file
197
taglib/flac/flacpicture.cpp
Normal file
@ -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 <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;
|
||||
}
|
||||
|
147
taglib/flac/flacpicture.h
Normal file
147
taglib/flac/flacpicture.h
Normal file
@ -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<Picture> PictureList;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
BIN
tests/data/silence-44-s.flac
Normal file
BIN
tests/data/silence-44-s.flac
Normal file
Binary file not shown.
@ -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<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);
|
||||
|
Reference in New Issue
Block a user