17 Commits
v1.6 ... v1.6.1

Author SHA1 Message Date
Lukáš Lalinský
dcf4c7458b A few more version numbers. We really need a way to automate this :(
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1042960 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-31 09:57:13 +00:00
Lukáš Lalinský
de162a9734 Update version in API docs
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1042958 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-31 09:43:51 +00:00
Lukáš Lalinský
d685cd6e47 Bump version numbers
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1042955 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-31 09:23:58 +00:00
Lukáš Lalinský
f1abbf33f2 A little more complex checking for broken files
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1042948 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-31 08:59:40 +00:00
Lukáš Lalinský
5a40a45cc5 Make sure we are not trying to read a file where MP4 atom header != 8 bytes
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1042945 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-31 08:36:26 +00:00
Lukáš Lalinský
76b6d4fc9e Fixed ID3v1-style genre to string conversion in MP4 files
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1042312 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-29 15:53:20 +00:00
Lukáš Lalinský
e8281e1b9f Support for MP4 cover art
CCMAIL:martin.trashbox@gmail.com


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1039809 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-24 16:55:54 +00:00
Lukáš Lalinský
bffd4da8b6 Return NULL/false rather than crash when accessing file attributes in FileRef
BUG:209417


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1039724 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-24 12:45:58 +00:00
Lukáš Lalinský
fa1a23fe5c Changelog for 1.6.1
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1039711 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-24 12:22:10 +00:00
Lukáš Lalinský
4e9b41f540 Proper .oga file handling in FileRef
This fixes a problem introduced in r983337. OGA files are mostly likely going
to be Ogg::FLAC, if applications are following the Xiph recommendation. But
they can be using any Ogg codec, so we must check multiple formats (Sound Juicer
on Ubuntu used to produce .oga files for Ogg Vorbis, I believe it doesn't do that
anymore).


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1039708 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-24 12:17:08 +00:00
Lukáš Lalinský
724a68c79c Don't wrote the Vorbis framing bit to OggFLAC files
https://bugs.launchpad.net/maxosx/+bug/445970
http://www.hydrogenaudio.org/forums/index.php?showtopic=75263

CCMAIL:me@sbooth.org


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1039704 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-24 12:01:40 +00:00
Lukáš Lalinský
03c63a11a5 Set visibility("default") for GCC on exported symbols
This does nothing with the current configuration, but it's useful if you compile the library with -fvisibility=hidden

Patch by Modestas Vainius


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1039693 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-24 11:07:41 +00:00
Lukáš Lalinský
ea9dbfd7ae Add missing exports for a few public ID3v1 functions
Patch by Modestas Vainius


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1038114 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-20 16:45:10 +00:00
Lukáš Lalinský
af65fefef7 Fix typo in taglib_c.pc
Patch by Modestas Vainius to fix a bug reported in Debian - http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=524696


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1038111 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-20 16:41:59 +00:00
Jeff Mitchell
752a21edc9 Fix copy+paste typos
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1035209 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-14 14:44:15 +00:00
Lukáš Lalinský
18c621cdc2 Always use #include "XXX" in TagLib's code
Patch by Stephen F. Booth, thanks!


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1033289 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-09 21:03:59 +00:00
Lukáš Lalinský
be2f9ad6e5 This value should be bool, not int
Since bool and int have the same size on x86 architectures, this worked for
me, but since they have a different size on ppc64, it caused the test to
fail. See http://marc.info/?l=taglib-devel&m=125291701231305&w=2 for details.

We should store the type in MP4::Item and do some type checking to avoid
mistakes like this...


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1023246 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-09-14 10:25:34 +00:00
58 changed files with 573 additions and 71 deletions

View File

@@ -40,7 +40,7 @@ endif (WIN32)
SET(TAGLIB_LIB_MAJOR_VERSION "1")
SET(TAGLIB_LIB_MINOR_VERSION "6")
SET(TAGLIB_LIB_PATCH_VERSION "0")
SET(TAGLIB_LIB_PATCH_VERSION "1")
SET(TAGLIB_LIB_VERSION_STRING "${TAGLIB_LIB_MAJOR_VERSION}.${TAGLIB_LIB_MINOR_VERSION}.${TAGLIB_LIB_PATCH_VERSION}")

View File

@@ -38,7 +38,7 @@ apidox:
fi; \
cp $(top_srcdir)/admin/Doxyfile.global taglib.doxyfile; \
echo "PROJECT_NAME = TagLib" >> taglib.doxyfile; \
echo "PROJECT_NUMBER = \"Version 1.6\"" >> taglib.doxyfile; \
echo "PROJECT_NUMBER = \"Version 1.6.1\"" >> taglib.doxyfile; \
echo "INPUT = $(srcdir)" >> taglib.doxyfile; \
echo "OUTPUT_DIRECTORY = doc/api" >> taglib.doxyfile; \
echo "HTML_OUTPUT = html" >> taglib.doxyfile; \

18
NEWS
View File

@@ -1,5 +1,19 @@
TagLib 1.6
==========
TagLib 1.6.1 (Oct 31, 2009)
===========================
* Better detection of the audio codec of .oga files in FileRef.
* Fixed saving of Vorbis comments to Ogg FLAC files. TagLib tried to
include the Vorbis framing bit, which is only correct for Ogg Vorbis.
* Public symbols now have explicitly set visibility to "default" on GCC.
* Added missing exports for static ID3v1 functions.
* Fixed a typo in taglib_c.pc
* Fixed a failing test on ppc64.
* Support for binary 'covr' atom in MP4 files. TagLib 1.6 treated them
as text atoms, which corrupted them in some cases.
* Fixed ID3v1-style genre to string conversion in MP4 files.
TagLib 1.6 (Sep 13, 2009)
=========================
1.6:

View File

@@ -35,6 +35,8 @@ extern "C" {
#else
#define TAGLIB_C_EXPORT __declspec(dllimport)
#endif
#elif defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 1)
#define TAGLIB_C_EXPORT __attribute__ ((visibility("default")))
#else
#define TAGLIB_C_EXPORT
#endif

View File

@@ -9,4 +9,4 @@ Description: Audio meta-data library (C bindings)
Requires: taglib
Version: ${TAGLIB_LIB_MAJOR_VERSION}.${TAGLIB_LIB_MINOR_VERSION}.${TAGLIB_LIB_PATCH_VERSION}
Libs: -L${LIB_INSTALL_DIR} -ltag_c
Cflags: -I=${INCLUDE_INSTALL_DIR}/taglib
Cflags: -I${INCLUDE_INSTALL_DIR}/taglib

View File

@@ -6,6 +6,6 @@ includedir=@includedir@
Name: TagLib C Bindings
Description: Audio meta-data library (C bindings)
Requires: taglib
Version: 1.6
Version: 1.6.1
Libs: -L${libdir} -ltag_c
Cflags: -I${includedir}/taglib

View File

@@ -38,7 +38,7 @@ dnl Perform program name transformation
AC_ARG_PROGRAM
dnl Automake doc recommends to do this only here. (Janos)
AM_INIT_AUTOMAKE(taglib,1.6)
AM_INIT_AUTOMAKE(taglib,1.6.1)
dnl almost the same like KDE_SET_PEFIX but the path is /usr/local
dnl

View File

@@ -17,7 +17,7 @@
<td>
<div id="intro">
<table border="0" height="119" cellpadding="0" cellspacing="0" width="100%">
<tr><td valign="top"><h1>TagLib 1.6 ($title)</h1></td></tr>
<tr><td valign="top"><h1>TagLib 1.6.1 ($title)</h1></td></tr>
<tr>
<td valign="bottom">
<div id="links">

1
include/mp4coverart.h Normal file
View File

@@ -0,0 +1 @@
#include "../taglib/mp4/mp4coverart.h"

View File

@@ -35,7 +35,7 @@ do
flags="$flags -I$includedir/taglib"
;;
--version)
echo 1.6
echo 1.6.1
;;
--prefix)
echo $prefix

View File

@@ -35,7 +35,7 @@ do
flags="$flags -I$includedir/taglib"
;;
--version)
echo 1.6
echo 1.6.1
;;
--prefix)
echo $prefix

View File

@@ -111,6 +111,7 @@ mp4/mp4atom.cpp
mp4/mp4tag.cpp
mp4/mp4item.cpp
mp4/mp4properties.cpp
mp4/mp4coverart.cpp
)
ELSE(WITH_MP4)
SET(mp4_SRCS)
@@ -200,6 +201,7 @@ SET_TARGET_PROPERTIES(tag PROPERTIES
SOVERSION ${TAGLIB_LIB_MAJOR_VERSION}
INSTALL_NAME_DIR ${LIB_INSTALL_DIR}
DEFINE_SYMBOL MAKE_TAGLIB_LIB
LINK_INTERFACE_LIBRARIES ""
)
INSTALL(TARGETS tag
LIBRARY DESTINATION ${LIB_INSTALL_DIR}

View File

@@ -45,8 +45,9 @@ taglib_includedir = $(includedir)/taglib
# 6:0:5 -- TagLib 1.5
# 7:0:6 -- TagLib 1.6 RC1
# 7:1:6 -- TagLib 1.6
# 8:0:7 -- TagLib 1.6.1
libtag_la_LDFLAGS = $(all_libraries) -no-undefined -version-info 7:1:6
libtag_la_LDFLAGS = $(all_libraries) -no-undefined -version-info 8:0:7
libtag_la_LIBADD = ./mpeg/libmpeg.la ./ogg/libogg.la ./flac/libflac.la ./mpc/libmpc.la \
./ape/libape.la ./toolkit/libtoolkit.la ./wavpack/libwavpack.la \
./trueaudio/libtrueaudio.la ./riff/libriff.la \

View File

@@ -26,8 +26,8 @@
#ifndef TAGLIB_ASFATTRIBUTE_H
#define TAGLIB_ASFATTRIBUTE_H
#include <tstring.h>
#include <tbytevector.h>
#include "tstring.h"
#include "tbytevector.h"
#include "taglib_export.h"
namespace TagLib

View File

@@ -26,8 +26,8 @@
#ifndef TAGLIB_ASFFILE_H
#define TAGLIB_ASFFILE_H
#include <tag.h>
#include <tfile.h>
#include "tag.h"
#include "tfile.h"
#include "taglib_export.h"
#include "asfproperties.h"
#include "asftag.h"

View File

@@ -26,8 +26,8 @@
#ifndef TAGLIB_ASFPROPERTIES_H
#define TAGLIB_ASFPROPERTIES_H
#include <audioproperties.h>
#include <tstring.h>
#include "audioproperties.h"
#include "tstring.h"
#include "taglib_export.h"
namespace TagLib {

View File

@@ -26,9 +26,9 @@
#ifndef TAGLIB_ASFTAG_H
#define TAGLIB_ASFTAG_H
#include <tag.h>
#include <tlist.h>
#include <tmap.h>
#include "tag.h"
#include "tlist.h"
#include "tmap.h"
#include "taglib_export.h"
#include "asfattribute.h"

View File

@@ -29,6 +29,7 @@
#include <tfile.h>
#include <tstring.h>
#include <tdebug.h>
#include "fileref.h"
#include "asffile.h"
@@ -93,11 +94,19 @@ FileRef::~FileRef()
Tag *FileRef::tag() const
{
if(isNull()) {
debug("FileRef::tag() - Called without a valid file.");
return 0;
}
return d->file->tag();
}
AudioProperties *FileRef::audioProperties() const
{
if(isNull()) {
debug("FileRef::audioProperties() - Called without a valid file.");
return 0;
}
return d->file->audioProperties();
}
@@ -108,6 +117,10 @@ File *FileRef::file() const
bool FileRef::save()
{
if(isNull()) {
debug("FileRef::save() - Called without a valid file.");
return false;
}
return d->file->save();
}
@@ -205,12 +218,17 @@ File *FileRef::create(FileName fileName, bool readAudioProperties,
int pos = s.rfind(".");
if(pos != -1) {
String ext = s.substr(pos + 1).upper();
if(ext == "OGG" || ext == "OGA")
return new Ogg::Vorbis::File(fileName, readAudioProperties, audioPropertiesStyle);
if(ext == "MP3")
return new MPEG::File(fileName, readAudioProperties, audioPropertiesStyle);
if(ext == "OGA")
return new Ogg::FLAC::File(fileName, readAudioProperties, audioPropertiesStyle);
if(ext == "OGG")
return new Ogg::Vorbis::File(fileName, readAudioProperties, audioPropertiesStyle);
if(ext == "OGA") {
/* .oga can be any audio in the Ogg container. First try FLAC, then Vorbis. */
File *file = new Ogg::FLAC::File(fileName, readAudioProperties, audioPropertiesStyle);
if (file->isValid())
return file;
return new Ogg::Vorbis::File(fileName, readAudioProperties, audioPropertiesStyle);
}
if(ext == "FLAC")
return new FLAC::File(fileName, readAudioProperties, audioPropertiesStyle);
if(ext == "MPC")

View File

@@ -26,8 +26,8 @@
#ifndef TAGLIB_FILEREF_H
#define TAGLIB_FILEREF_H
#include <tfile.h>
#include <tstringlist.h>
#include "tfile.h"
#include "tstringlist.h"
#include "taglib_export.h"
#include "audioproperties.h"

View File

@@ -1 +1 @@
INSTALL( FILES mp4file.h mp4atom.h mp4tag.h mp4item.h mp4properties.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib)
INSTALL( FILES mp4file.h mp4atom.h mp4tag.h mp4item.h mp4properties.h mp4coverart.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib)

View File

@@ -7,7 +7,7 @@ INCLUDES = \
noinst_LTLIBRARIES = libmp4.la
libmp4_la_SOURCES = mp4atom.cpp mp4file.cpp mp4item.cpp mp4properties.cpp mp4tag.cpp
libmp4_la_SOURCES = mp4atom.cpp mp4file.cpp mp4item.cpp mp4properties.cpp mp4tag.cpp mp4coverart.cpp
taglib_include_HEADERS = mp4atom.h mp4file.h mp4item.h mp4properties.h mp4tag.h
taglib_include_HEADERS = mp4atom.h mp4file.h mp4item.h mp4properties.h mp4tag.h mp4coverart.h
taglib_includedir = $(includedir)/taglib

View File

@@ -44,6 +44,15 @@ MP4::Atom::Atom(File *file)
{
offset = file->tell();
ByteVector header = file->readBlock(8);
if (header.size() != 8) {
// The atom header must be 8 bytes long, otherwise there is either
// trailing garbage or the file is truncated
debug("MP4: Couldn't read 8 bytes of data for atom header");
length = 0;
file->seek(0, File::End);
return;
}
length = header.mid(0, 4).toUInt();
if (length == 1) {
@@ -74,7 +83,10 @@ MP4::Atom::Atom(File *file)
file->seek(4, File::Current);
}
while(file->tell() < offset + length) {
children.append(new MP4::Atom(file));
MP4::Atom *child = new MP4::Atom(file);
children.append(child);
if (child->length == 0)
return;
}
return;
}
@@ -141,7 +153,10 @@ MP4::Atoms::Atoms(File *file)
long end = file->tell();
file->seek(0);
while(file->tell() + 8 <= end) {
atoms.append(new MP4::Atom(file));
MP4::Atom *atom = new MP4::Atom(file);
atoms.append(atom);
if (atom->length == 0)
break;
}
}

View File

@@ -30,8 +30,8 @@
#ifndef TAGLIB_MP4ATOM_H
#define TAGLIB_MP4ATOM_H
#include <tfile.h>
#include <tlist.h>
#include "tfile.h"
#include "tlist.h"
namespace TagLib {

View File

@@ -0,0 +1,89 @@
/**************************************************************************
copyright : (C) 2009 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
#ifdef WITH_MP4
#include <taglib.h>
#include <tdebug.h>
#include "mp4coverart.h"
using namespace TagLib;
class MP4::CoverArt::CoverArtPrivate : public RefCounter
{
public:
CoverArtPrivate() : RefCounter(), format(MP4::CoverArt::JPEG) {}
Format format;
ByteVector data;
};
MP4::CoverArt::CoverArt(Format format, const ByteVector &data)
{
d = new CoverArtPrivate;
d->format = format;
d->data = data;
}
MP4::CoverArt::CoverArt(const CoverArt &item) : d(item.d)
{
d->ref();
}
MP4::CoverArt &
MP4::CoverArt::operator=(const CoverArt &item)
{
if(d->deref()) {
delete d;
}
d = item.d;
d->ref();
return *this;
}
MP4::CoverArt::~CoverArt()
{
if(d->deref()) {
delete d;
}
}
MP4::CoverArt::Format
MP4::CoverArt::format() const
{
return d->format;
}
ByteVector
MP4::CoverArt::data() const
{
return d->data;
}
#endif

71
taglib/mp4/mp4coverart.h Normal file
View File

@@ -0,0 +1,71 @@
/**************************************************************************
copyright : (C) 2009 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_MP4COVERART_H
#define TAGLIB_MP4COVERART_H
#include "tlist.h"
#include "tbytevector.h"
#include "taglib_export.h"
namespace TagLib {
namespace MP4 {
class TAGLIB_EXPORT CoverArt
{
public:
/*!
* This describes the image type.
*/
enum Format {
JPEG = 0x0D,
PNG = 0x0E
};
CoverArt(Format format, const ByteVector &data);
~CoverArt();
CoverArt(const CoverArt &item);
CoverArt &operator=(const CoverArt &item);
//! Format of the image
Format format() const;
//! The image data
ByteVector data() const;
private:
class CoverArtPrivate;
CoverArtPrivate *d;
};
typedef List<CoverArt> CoverArtList;
}
}
#endif

View File

@@ -89,6 +89,18 @@ MP4::File::audioProperties() const
return d->properties;
}
bool
MP4::File::checkValid(const MP4::AtomList &list)
{
for(uint i = 0; i < list.size(); i++) {
if(list[i]->length == 0)
return false;
if(!checkValid(list[i]->children))
return false;
}
return true;
}
void
MP4::File::read(bool readProperties, Properties::ReadStyle audioPropertiesStyle)
{
@@ -96,6 +108,11 @@ MP4::File::read(bool readProperties, Properties::ReadStyle audioPropertiesStyle)
return;
d->atoms = new Atoms(this);
if (!checkValid(d->atoms->atoms)) {
setValid(false);
return;
}
d->tag = new Tag(this, d->atoms);
if(readProperties) {
d->properties = new Properties(this, d->atoms, audioPropertiesStyle);
@@ -105,6 +122,9 @@ MP4::File::read(bool readProperties, Properties::ReadStyle audioPropertiesStyle)
bool
MP4::File::save()
{
if(!isValid())
return false;
return d->tag->save();
}

View File

@@ -26,8 +26,8 @@
#ifndef TAGLIB_MP4FILE_H
#define TAGLIB_MP4FILE_H
#include <tag.h>
#include <tfile.h>
#include "tag.h"
#include "tfile.h"
#include "taglib_export.h"
#include "mp4properties.h"
#include "mp4tag.h"
@@ -49,7 +49,7 @@ namespace TagLib {
{
public:
/*!
* Contructs an ASF file from \a file. If \a readProperties is true the
* Contructs a MP4 file from \a file. If \a readProperties is true the
* file's audio properties will also be read using \a propertiesStyle. If
* false, \a propertiesStyle is ignored.
*
@@ -69,7 +69,7 @@ namespace TagLib {
* MP4::Tag implements the tag interface, so this serves as the
* reimplementation of TagLib::File::tag().
*
* \note The Tag <b>is still</b> owned by the ASF::File and should not be
* \note The Tag <b>is still</b> owned by the MP4::File and should not be
* deleted by the user. It will be deleted when the file (object) is
* destroyed.
*/
@@ -90,6 +90,7 @@ namespace TagLib {
private:
void read(bool readProperties, Properties::ReadStyle audioPropertiesStyle);
bool checkValid(const MP4::AtomList &list);
class FilePrivate;
FilePrivate *d;

View File

@@ -47,6 +47,7 @@ public:
IntPair m_intPair;
};
StringList m_stringList;
MP4::CoverArtList m_coverArtList;
};
MP4::Item::Item()
@@ -103,6 +104,12 @@ MP4::Item::Item(const StringList &value)
d->m_stringList = value;
}
MP4::Item::Item(const MP4::CoverArtList &value)
{
d = new ItemPrivate;
d->m_coverArtList = value;
}
bool
MP4::Item::toBool() const
{
@@ -127,6 +134,12 @@ MP4::Item::toStringList() const
return d->m_stringList;
}
MP4::CoverArtList
MP4::Item::toCoverArtList() const
{
return d->m_coverArtList;
}
bool
MP4::Item::isValid() const
{

View File

@@ -26,7 +26,8 @@
#ifndef TAGLIB_MP4ITEM_H
#define TAGLIB_MP4ITEM_H
#include <tstringlist.h>
#include "tstringlist.h"
#include "mp4coverart.h"
#include "taglib_export.h"
namespace TagLib {
@@ -49,11 +50,13 @@ namespace TagLib {
Item(bool value);
Item(int first, int second);
Item(const StringList &value);
Item(const CoverArtList &value);
int toInt() const;
bool toBool() const;
IntPair toIntPair() const;
StringList toStringList() const;
CoverArtList toCoverArtList() const;
bool isValid() const;

View File

@@ -77,6 +77,9 @@ MP4::Tag::Tag(File *file, MP4::Atoms *atoms)
else if(atom->name == "gnre") {
parseGnre(atom, file);
}
else if(atom->name == "covr") {
parseCovr(atom, file);
}
else {
parseText(atom, file);
}
@@ -140,8 +143,8 @@ MP4::Tag::parseGnre(MP4::Atom *atom, TagLib::File *file)
ByteVectorList data = parseData(atom, file);
if(data.size()) {
int idx = (int)data[0].toShort();
if(!d->items.contains("\251gen")) {
d->items.insert("\251gen", StringList(ID3v1::genre(idx)));
if(!d->items.contains("\251gen") && idx > 0) {
d->items.insert("\251gen", StringList(ID3v1::genre(idx - 1)));
}
}
}
@@ -194,6 +197,30 @@ MP4::Tag::parseFreeForm(MP4::Atom *atom, TagLib::File *file)
}
}
void
MP4::Tag::parseCovr(MP4::Atom *atom, TagLib::File *file)
{
MP4::CoverArtList value;
ByteVector data = file->readBlock(atom->length - 8);
unsigned int pos = 0;
while(pos < data.size()) {
int length = data.mid(pos, 4).toUInt();
ByteVector name = data.mid(pos + 4, 4);
int flags = data.mid(pos + 8, 4).toUInt();
if(name != "data") {
debug("MP4: Unexpected atom \"" + name + "\", expecting \"data\"");
return;
}
if(flags == MP4::CoverArt::PNG || flags == MP4::CoverArt::JPEG) {
value.append(MP4::CoverArt(MP4::CoverArt::Format(flags),
data.mid(pos + 16, length - 16)));
}
pos += length;
}
if(value.size() > 0)
d->items.insert(atom->name, value);
}
ByteVector
MP4::Tag::padIlst(const ByteVector &data, int length)
{
@@ -267,6 +294,18 @@ MP4::Tag::renderText(const ByteVector &name, MP4::Item &item, int flags)
return renderData(name, flags, data);
}
ByteVector
MP4::Tag::renderCovr(const ByteVector &name, MP4::Item &item)
{
ByteVector data;
MP4::CoverArtList value = item.toCoverArtList();
for(unsigned int i = 0; i < value.size(); i++) {
data.append(renderAtom("data", ByteVector::fromUInt(value[i].format()) +
ByteVector(4, '\0') + value[i].data()));
}
return renderAtom(name, data);
}
ByteVector
MP4::Tag::renderFreeForm(const String &name, MP4::Item &item)
{
@@ -306,6 +345,9 @@ MP4::Tag::save()
else if(name == "tmpo") {
data.append(renderInt(name.data(String::Latin1), i->second));
}
else if(name == "covr") {
data.append(renderCovr(name.data(String::Latin1), i->second));
}
else if(name.size() == 4){
data.append(renderText(name.data(String::Latin1), i->second));
}

View File

@@ -26,11 +26,11 @@
#ifndef TAGLIB_MP4TAG_H
#define TAGLIB_MP4TAG_H
#include <tag.h>
#include <tbytevectorlist.h>
#include <tfile.h>
#include <tmap.h>
#include <tstringlist.h>
#include "tag.h"
#include "tbytevectorlist.h"
#include "tfile.h"
#include "tmap.h"
#include "tstringlist.h"
#include "taglib_export.h"
#include "mp4atom.h"
#include "mp4item.h"
@@ -74,6 +74,7 @@ namespace TagLib {
void parseGnre(Atom *atom, TagLib::File *file);
void parseIntPair(Atom *atom, TagLib::File *file);
void parseBool(Atom *atom, TagLib::File *file);
void parseCovr(Atom *atom, TagLib::File *file);
TagLib::ByteVector padIlst(const ByteVector &data, int length = -1);
TagLib::ByteVector renderAtom(const ByteVector &name, const TagLib::ByteVector &data);
@@ -84,6 +85,7 @@ namespace TagLib {
TagLib::ByteVector renderInt(const ByteVector &name, Item &item);
TagLib::ByteVector renderIntPair(const ByteVector &name, Item &item);
TagLib::ByteVector renderIntPairNoTrailing(const ByteVector &name, Item &item);
TagLib::ByteVector renderCovr(const ByteVector &name, Item &item);
void updateParents(AtomList &path, long delta, int ignore = 0);
void updateOffsets(long delta, long offset);

View File

@@ -45,21 +45,21 @@ namespace TagLib {
* A "reverse mapping" that goes from the canonical ID3v1 genre name to the
* respective genre number. genreMap()["Rock"] ==
*/
GenreMap genreMap();
GenreMap TAGLIB_EXPORT genreMap();
/*!
* Returns the name of the genre at \a index in the ID3v1 genre list. If
* \a index is out of range -- less than zero or greater than 146 -- a null
* string will be returned.
*/
String genre(int index);
String TAGLIB_EXPORT genre(int index);
/*!
* Returns the genre index for the (case sensitive) genre \a name. If the
* genre is not in the list 255 (which signifies an unknown genre in ID3v1)
* will be returned.
*/
int genreIndex(const String &name);
int TAGLIB_EXPORT genreIndex(const String &name);
}
}

View File

@@ -26,8 +26,8 @@
#ifndef TAGLIB_ATTACHEDPICTUREFRAME_H
#define TAGLIB_ATTACHEDPICTUREFRAME_H
#include <id3v2frame.h>
#include <id3v2header.h>
#include "id3v2frame.h"
#include "id3v2header.h"
#include "taglib_export.h"
namespace TagLib {

View File

@@ -26,7 +26,7 @@
#ifndef TAGLIB_COMMENTSFRAME_H
#define TAGLIB_COMMENTSFRAME_H
#include <id3v2frame.h>
#include "id3v2frame.h"
#include "taglib_export.h"
namespace TagLib {

View File

@@ -28,8 +28,8 @@
#ifndef TAGLIB_GENERALENCAPSULATEDOBJECT_H
#define TAGLIB_GENERALENCAPSULATEDOBJECT_H
#include <id3v2frame.h>
#include <id3v2header.h>
#include "id3v2frame.h"
#include "id3v2header.h"
#include "taglib_export.h"
namespace TagLib {

View File

@@ -26,7 +26,7 @@
#ifndef TAGLIB_POPULARIMETERFRAME_H
#define TAGLIB_POPULARIMETERFRAME_H
#include <id3v2frame.h>
#include "id3v2frame.h"
#include "taglib_export.h"
namespace TagLib {

View File

@@ -26,8 +26,8 @@
#ifndef TAGLIB_RELATIVEVOLUMEFRAME_H
#define TAGLIB_RELATIVEVOLUMEFRAME_H
#include <tlist.h>
#include <id3v2frame.h>
#include "tlist.h"
#include "id3v2frame.h"
#include "taglib_export.h"
namespace TagLib {

View File

@@ -26,10 +26,10 @@
#ifndef TAGLIB_TEXTIDENTIFICATIONFRAME_H
#define TAGLIB_TEXTIDENTIFICATIONFRAME_H
#include <tstringlist.h>
#include "tstringlist.h"
#include "taglib_export.h"
#include <id3v2frame.h>
#include "id3v2frame.h"
namespace TagLib {

View File

@@ -26,7 +26,7 @@
#ifndef TAGLIB_UNIQUEFILEIDENTIFIERFRAME
#define TAGLIB_UNIQUEFILEIDENTIFIERFRAME
#include <id3v2frame.h>
#include "id3v2frame.h"
namespace TagLib {

View File

@@ -26,7 +26,7 @@
#ifndef TAGLIB_UNKNOWNFRAME_H
#define TAGLIB_UNKNOWNFRAME_H
#include <id3v2frame.h>
#include "id3v2frame.h"
#include "taglib_export.h"
namespace TagLib {

View File

@@ -28,7 +28,7 @@
#ifndef TAGLIB_UNSYNCHRONIZEDLYRICSFRAME_H
#define TAGLIB_UNSYNCHRONIZEDLYRICSFRAME_H
#include <id3v2frame.h>
#include "id3v2frame.h"
namespace TagLib {

View File

@@ -28,7 +28,7 @@
#ifndef TAGLIB_URLLINKFRAME_H
#define TAGLIB_URLLINKFRAME_H
#include <id3v2frame.h>
#include "id3v2frame.h"
namespace TagLib {

View File

@@ -93,7 +93,7 @@ Properties *Ogg::FLAC::File::audioProperties() const
bool Ogg::FLAC::File::save()
{
d->xiphCommentData = d->comment->render();
d->xiphCommentData = d->comment->render(false);
// Create FLAC metadata-block:

View File

@@ -30,8 +30,8 @@
#ifndef TAGLIB_SPEEXFILE_H
#define TAGLIB_SPEEXFILE_H
#include <oggfile.h>
#include <xiphcomment.h>
#include "oggfile.h"
#include "xiphcomment.h"
#include "speexproperties.h"

View File

@@ -30,7 +30,7 @@
#ifndef TAGLIB_SPEEXPROPERTIES_H
#define TAGLIB_SPEEXPROPERTIES_H
#include <audioproperties.h>
#include "audioproperties.h"
namespace TagLib {

View File

@@ -32,6 +32,8 @@
#else
#define TAGLIB_EXPORT __declspec(dllimport)
#endif
#elif defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 1)
#define TAGLIB_EXPORT __attribute__ ((visibility("default")))
#else
#define TAGLIB_EXPORT
#endif

View File

@@ -30,7 +30,7 @@
#ifndef TAGLIB_TRUEAUDIOFILE_H
#define TAGLIB_TRUEAUDIOFILE_H
#include <tfile.h>
#include "tfile.h"
#include "trueaudioproperties.h"
namespace TagLib {

View File

@@ -30,7 +30,7 @@
#ifndef TAGLIB_WVFILE_H
#define TAGLIB_WVFILE_H
#include <tfile.h>
#include "tfile.h"
#include "taglib_export.h"
#include "wavpackproperties.h"

View File

@@ -14,6 +14,8 @@ INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/trueaudio
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ogg
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ogg/vorbis
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ogg/flac
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/flac
)
SET(test_runner_SRCS
@@ -33,9 +35,14 @@ SET(test_runner_SRCS
test_aiff.cpp
test_riff.cpp
test_ogg.cpp
test_oggflac.cpp
)
IF(WITH_MP4)
SET(test_runner_SRCS ${test_runner_SRCS} test_mp4.cpp)
SET(test_runner_SRCS ${test_runner_SRCS}
test_mp4.cpp
test_mp4item.cpp
test_mp4coverart.cpp
)
ENDIF(WITH_MP4)
IF(WITH_ASF)

View File

@@ -7,6 +7,8 @@ INCLUDES = \
-I$(top_srcdir)/taglib/mpeg/id3v2 \
-I$(top_srcdir)/taglib/ogg \
-I$(top_srcdir)/taglib/ogg/vorbis \
-I$(top_srcdir)/taglib/ogg/flac \
-I$(top_srcdir)/taglib/flac \
-I$(top_srcdir)/taglib/riff \
-I$(top_srcdir)/taglib/riff/aiff \
-I$(top_srcdir)/taglib/mpeg/id3v2/frames
@@ -26,7 +28,8 @@ test_runner_SOURCES = \
test_xiphcomment.cpp \
test_riff.cpp \
test_aiff.cpp \
test_ogg.cpp
test_ogg.cpp \
test_oggflac.cpp
if build_tests
TESTS = test_runner

BIN
tests/data/empty_flac.oga Normal file

Binary file not shown.

BIN
tests/data/empty_vorbis.ogg Normal file

Binary file not shown.

BIN
tests/data/gnre.m4a Normal file

Binary file not shown.

View File

@@ -3,6 +3,8 @@
#include <stdio.h>
#include <tag.h>
#include <fileref.h>
#include <oggflacfile.h>
#include <vorbisfile.h>
#include "utils.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -22,6 +24,8 @@ class TestFileRef : public CppUnit::TestFixture
CPPUNIT_TEST(testSpeex);
CPPUNIT_TEST(testFLAC);
CPPUNIT_TEST(testMP3);
CPPUNIT_TEST(testOGA_FLAC);
CPPUNIT_TEST(testOGA_Vorbis);
#ifdef TAGLIB_WITH_MP4
CPPUNIT_TEST(testMP4_1);
CPPUNIT_TEST(testMP4_2);
@@ -131,6 +135,20 @@ public:
}
#endif
void testOGA_FLAC()
{
FileRef *f = new FileRef("data/empty_flac.oga");
CPPUNIT_ASSERT(dynamic_cast<Ogg::Vorbis::File *>(f->file()) == NULL);
CPPUNIT_ASSERT(dynamic_cast<Ogg::FLAC::File *>(f->file()) != NULL);
}
void testOGA_Vorbis()
{
FileRef *f = new FileRef("data/empty_vorbis.oga");
CPPUNIT_ASSERT(dynamic_cast<Ogg::Vorbis::File *>(f->file()) != NULL);
CPPUNIT_ASSERT(dynamic_cast<Ogg::FLAC::File *>(f->file()) == NULL);
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestFileRef);

View File

@@ -19,6 +19,9 @@ class TestMP4 : public CppUnit::TestFixture
CPPUNIT_TEST(testUpdateStco);
CPPUNIT_TEST(testSaveExisingWhenIlstIsLast);
CPPUNIT_TEST(test64BitAtom);
CPPUNIT_TEST(testGnre);
CPPUNIT_TEST(testCovrRead);
CPPUNIT_TEST(testCovrWrite);
CPPUNIT_TEST_SUITE_END();
public:
@@ -130,7 +133,7 @@ public:
MP4::Atom *moov = atoms->atoms[0];
CPPUNIT_ASSERT_EQUAL(long(77), moov->length);
f->tag()->itemListMap()["pgap"] = 1;
f->tag()->itemListMap()["pgap"] = true;
f->save();
f = new MP4::File(filename.c_str());
@@ -145,6 +148,51 @@ public:
deleteFile(filename);
}
void testGnre()
{
MP4::File *f = new MP4::File("data/gnre.m4a");
CPPUNIT_ASSERT_EQUAL(TagLib::String("Ska"), f->tag()->genre());
}
void testCovrRead()
{
MP4::File *f = new MP4::File("data/has-tags.m4a");
CPPUNIT_ASSERT(f->tag()->itemListMap().contains("covr"));
MP4::CoverArtList l = f->tag()->itemListMap()["covr"].toCoverArtList();
CPPUNIT_ASSERT_EQUAL(TagLib::uint(2), l.size());
CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::PNG, l[0].format());
CPPUNIT_ASSERT_EQUAL(TagLib::uint(79), l[0].data().size());
CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::JPEG, l[1].format());
CPPUNIT_ASSERT_EQUAL(TagLib::uint(287), l[1].data().size());
}
void testCovrWrite()
{
string filename = copyFile("has-tags", ".m4a");
MP4::File *f = new MP4::File(filename.c_str());
CPPUNIT_ASSERT(f->tag()->itemListMap().contains("covr"));
MP4::CoverArtList l = f->tag()->itemListMap()["covr"].toCoverArtList();
l.append(MP4::CoverArt(MP4::CoverArt::PNG, "foo"));
f->tag()->itemListMap()["covr"] = l;
f->save();
delete f;
f = new MP4::File(filename.c_str());
CPPUNIT_ASSERT(f->tag()->itemListMap().contains("covr"));
l = f->tag()->itemListMap()["covr"].toCoverArtList();
CPPUNIT_ASSERT_EQUAL(TagLib::uint(3), l.size());
CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::PNG, l[0].format());
CPPUNIT_ASSERT_EQUAL(TagLib::uint(79), l[0].data().size());
CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::JPEG, l[1].format());
CPPUNIT_ASSERT_EQUAL(TagLib::uint(287), l[1].data().size());
CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::PNG, l[2].format());
CPPUNIT_ASSERT_EQUAL(TagLib::uint(3), l[2].data().size());
delete f;
deleteFile(filename);
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestMP4);

View File

@@ -0,0 +1,49 @@
#include <cppunit/extensions/HelperMacros.h>
#include <string>
#include <stdio.h>
#include <tag.h>
#include <mp4coverart.h>
#include "utils.h"
using namespace std;
using namespace TagLib;
class TestMP4CoverArt : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(TestMP4CoverArt);
CPPUNIT_TEST(testSimple);
CPPUNIT_TEST(testList);
CPPUNIT_TEST_SUITE_END();
public:
void testSimple()
{
MP4::CoverArt c(MP4::CoverArt::PNG, "foo");
CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::PNG, c.format());
CPPUNIT_ASSERT_EQUAL(ByteVector("foo"), c.data());
MP4::CoverArt c2(c);
CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::PNG, c2.format());
CPPUNIT_ASSERT_EQUAL(ByteVector("foo"), c2.data());
MP4::CoverArt c3 = c;
CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::PNG, c3.format());
CPPUNIT_ASSERT_EQUAL(ByteVector("foo"), c3.data());
}
void testList()
{
MP4::CoverArtList l;
l.append(MP4::CoverArt(MP4::CoverArt::PNG, "foo"));
l.append(MP4::CoverArt(MP4::CoverArt::JPEG, "bar"));
CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::PNG, l[0].format());
CPPUNIT_ASSERT_EQUAL(ByteVector("foo"), l[0].data());
CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::JPEG, l[1].format());
CPPUNIT_ASSERT_EQUAL(ByteVector("bar"), l[1].data());
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestMP4CoverArt);

37
tests/test_mp4item.cpp Normal file
View File

@@ -0,0 +1,37 @@
#include <cppunit/extensions/HelperMacros.h>
#include <string>
#include <stdio.h>
#include <tag.h>
#include <mp4coverart.h>
#include <mp4item.h>
#include "utils.h"
using namespace std;
using namespace TagLib;
class TestMP4Item : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(TestMP4Item);
CPPUNIT_TEST(testCoverArtList);
CPPUNIT_TEST_SUITE_END();
public:
void testCoverArtList()
{
MP4::CoverArtList l;
l.append(MP4::CoverArt(MP4::CoverArt::PNG, "foo"));
l.append(MP4::CoverArt(MP4::CoverArt::JPEG, "bar"));
MP4::Item i(l);
MP4::CoverArtList l2 = i.toCoverArtList();
CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::PNG, l[0].format());
CPPUNIT_ASSERT_EQUAL(ByteVector("foo"), l[0].data());
CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::JPEG, l[1].format());
CPPUNIT_ASSERT_EQUAL(ByteVector("bar"), l[1].data());
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestMP4Item);

44
tests/test_oggflac.cpp Normal file
View File

@@ -0,0 +1,44 @@
#include <cppunit/extensions/HelperMacros.h>
#include <string>
#include <stdio.h>
#include <tag.h>
#include <tstringlist.h>
#include <tbytevectorlist.h>
#include <oggfile.h>
#include <oggflacfile.h>
#include "utils.h"
using namespace std;
using namespace TagLib;
class TestOggFLAC : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(TestOggFLAC);
CPPUNIT_TEST(testFramingBit);
CPPUNIT_TEST_SUITE_END();
public:
void testFramingBit()
{
string newname = copyFile("empty_flac", ".oga");
Ogg::FLAC::File *f = new Ogg::FLAC::File(newname.c_str());
f->tag()->setArtist("The Artist");
f->save();
delete f;
f = new Ogg::FLAC::File(newname.c_str());
CPPUNIT_ASSERT_EQUAL(String("The Artist"), f->tag()->artist());
f->seek(0, File::End);
int size = f->tell();
CPPUNIT_ASSERT_EQUAL(9134, size);
delete f;
//deleteFile(newname);
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestOggFLAC);