25 Commits

Author SHA1 Message Date
Lukáš Lalinský
f7f46b2320 Fix release date
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1112833 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-09 09:37:51 +00:00
Scott Wheeler
c823c21eb2 Forward declarations don't need exports.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1111035 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-04 17:33:01 +00:00
Lukáš Lalinský
aee204df54 Ok, actually change the API version
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1110990 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-04 15:31:23 +00:00
Lukáš Lalinský
7f860790ec There is actually one new function, so the API version needs to be different
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1110988 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-04 15:20:46 +00:00
Lukáš Lalinský
b1cac7175f Increment version number
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1110983 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-04 15:01:21 +00:00
Lukáš Lalinský
e76466097b Don't upgrade ID3v2.2 TDA frame when upgrading to TRCD
We already do this for TDAT. Using both parts, the year and the date,
would be better we the code currently doesn't have enough context to
do that.

BUG:228968


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1110552 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-03 16:58:03 +00:00
Lukáš Lalinský
6612abce72 Changelog for 1.6.2
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1110546 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-03 16:16:51 +00:00
Lukáš Lalinský
3943668603 Ignore trailing non-data atoms when parsing MP4 covr atoms
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1110209 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-02 12:14:32 +00:00
Lukáš Lalinský
2ef8fc5118 Save ASF attributes larger than 64k to the metadata library object
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1110205 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-02 11:53:28 +00:00
Scott Wheeler
4202ce3ec9 Update .pro file
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1100537 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-03-07 19:03:35 +00:00
Lukáš Lalinský
0d16255d09 Fix compilation fo the test runner on Windows
Patch by Stephen Hewitt


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1078612 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-01-22 13:30:05 +00:00
Lukáš Lalinský
d394317767 MP4 int pair atoms should have flags set to 0
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1078611 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-01-22 13:28:14 +00:00
Lukáš Lalinský
9e9077d1e0 Be more paranoid about checking MP4 files
To consider something a valid MP4 file, it must have a 'moov' atom. Otherwise
it's marked as invalid and we won't try to read/write tags.

CCBUG:216819


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1062426 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-12-14 18:42:40 +00:00
Urs Wolfer
b11d2e8b56 optimizegraphics: Losslessly optimized PNG and SVGZ files with "optipng -o5" and "advdef -z -4".
Reduced disk space: 10144KB (9MB)

git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1062098 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-12-13 19:51:03 +00:00
Lukáš Lalinský
74c3c282c4 Handle WM/TrackNumber with DWORD content
The default type for this attribute is String, but even MSDN suggests to
support also DWORD, because some applications write such files.

BUG:218526


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1062026 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-12-13 15:32:55 +00:00
Lukáš Lalinský
004551faec Fix tagreader_c.c to not try to access invalid pointers
BUG:218334


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1061671 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-12-12 16:44:34 +00:00
Scott Wheeler
5df7692aa1 pedantry++
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1057066 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-12-01 12:01:43 +00:00
Peter van Hardenberg
85df71ea2e When decoding syncsafe integers, assume non-syncsafe integers are written by buggy software and treat them as normal integers.
From Songbird bug 12964, original author Mike Smith (msmith@songbirdnest.com)

git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1056922 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-12-01 09:11:21 +00:00
Alexander Neundorf
1b6ab18080 this patch should make taglib build with the Sun Studio compiler (http://bugs.kde.org/show_bug.cgi?id=215225)
Alex




git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1054212 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-11-25 18:45:13 +00:00
Lukáš Lalinský
0f0f2f7288 Explicitly say that we are using TagLib::File (CCBUG:213544)
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1046111 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-11-07 15:05:25 +00:00
Lukáš Lalinský
4c70372fe4 Fixed a memory leak in FileRef's OGA format detection
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1044769 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-11-04 15:37:21 +00:00
Lukáš Lalinský
d81af82ec4 Add test_flac.cpp to Makefile.am
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1043989 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-11-02 19:54:10 +00:00
Lukáš Lalinský
44c08b8ca2 New utility class to make sure temporary files are always deleted
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1043988 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-11-02 19:53:15 +00:00
Lukáš Lalinský
c962d78a57 Always read tags from the first Vorbis Comment block in FLAC files
Prevously TagLib saved tags to the first block, but read them from the
last one. Having multiple VC blocks is a non-standard situation, but
this is the best we can do (libFLAC also uses the first block in the
case of multiple VC blocks). 

BUG:211089


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1043985 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-11-02 19:41:12 +00:00
Scott Wheeler
2039c725f4 Missing "not" in docs.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1042978 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-31 11:32:31 +00:00
41 changed files with 470 additions and 191 deletions

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.1\"" >> taglib.doxyfile; \
echo "PROJECT_NUMBER = \"Version 1.6.2\"" >> taglib.doxyfile; \
echo "INPUT = $(srcdir)" >> taglib.doxyfile; \
echo "OUTPUT_DIRECTORY = doc/api" >> taglib.doxyfile; \
echo "HTML_OUTPUT = html" >> taglib.doxyfile; \

16
NEWS
View File

@@ -1,3 +1,19 @@
TagLib 1.6.2 (Apr 9, 2010)
==========================
* Read Vorbis Comments from the first FLAC metadata block, if there are
multipe ones. (BUG:211089)
* Fixed a memory leak in FileRef's OGA format detection.
* Fixed compilation with the Sun Studio compiler. (BUG:215225)
* Handle WM/TrackNumber attributes with DWORD content in WMA files.
(BUG:218526)
* More strict check if something is a valid MP4 file. (BUG:216819)
* Correctly save MP4 int-pair atoms with flags set to 0.
* Fixed compilation of the test runner on Windows.
* Store ASF attributes larger than 64k in the metadata library object.
* Ignore trailing non-data atoms when parsing MP4 covr atoms.
* Don't upgrade ID3v2.2 frame TDA to TDRC. (BUG:228968)
TagLib 1.6.1 (Oct 31, 2009)
===========================

View File

@@ -37,8 +37,13 @@ IF(HAVE_CRUN_LIB)
# the only game in town, the three available STLs -- Cstd,
# stlport4 and stdcxx -- make this a mess. The KDE-Solaris
# team supports stdcxx (Apache RogueWave stdcxx 4.1.3).
#
TARGET_LINK_LIBRARIES(tag_c stdcxx Crun)
# According to http://bugs.kde.org/show_bug.cgi?id=215225 the library can have the following two names:
FIND_LIBRARY(ROGUEWAVE_STDCXX_LIBRARY NAMES stdcxx4 stdcxx)
IF(NOT ROGUEWAVE_STDCXX_LIBRARY)
MESSAGE(FATAL_ERROR "Did not find supported STL library (tried stdcxx4 and stdcxx)")
ENDIF(NOT ROGUEWAVE_STDCXX_LIBRARY)
TARGET_LINK_LIBRARIES(tag_c ${ROGUEWAVE_STDCXX_LIBRARY} Crun)
ENDIF(HAVE_CRUN_LIB)
SET_TARGET_PROPERTIES(tag_c PROPERTIES

View File

@@ -6,6 +6,6 @@ includedir=@includedir@
Name: TagLib C Bindings
Description: Audio meta-data library (C bindings)
Requires: taglib
Version: 1.6.1
Version: 1.6.2
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.1)
AM_INIT_AUTOMAKE(taglib,1.6.2)
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.1 ($title)</h1></td></tr>
<tr><td valign="top"><h1>TagLib 1.6.2 ($title)</h1></td></tr>
<tr>
<td valign="bottom">
<div id="links">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -51,23 +51,27 @@ int main(int argc, char *argv[])
tag = taglib_file_tag(file);
properties = taglib_file_audioproperties(file);
printf("-- TAG --\n");
printf("title - \"%s\"\n", taglib_tag_title(tag));
printf("artist - \"%s\"\n", taglib_tag_artist(tag));
printf("album - \"%s\"\n", taglib_tag_album(tag));
printf("year - \"%i\"\n", taglib_tag_year(tag));
printf("comment - \"%s\"\n", taglib_tag_comment(tag));
printf("track - \"%i\"\n", taglib_tag_track(tag));
printf("genre - \"%s\"\n", taglib_tag_genre(tag));
if(tag != NULL) {
printf("-- TAG --\n");
printf("title - \"%s\"\n", taglib_tag_title(tag));
printf("artist - \"%s\"\n", taglib_tag_artist(tag));
printf("album - \"%s\"\n", taglib_tag_album(tag));
printf("year - \"%i\"\n", taglib_tag_year(tag));
printf("comment - \"%s\"\n", taglib_tag_comment(tag));
printf("track - \"%i\"\n", taglib_tag_track(tag));
printf("genre - \"%s\"\n", taglib_tag_genre(tag));
}
seconds = taglib_audioproperties_length(properties) % 60;
minutes = (taglib_audioproperties_length(properties) - seconds) / 60;
if(properties != NULL) {
seconds = taglib_audioproperties_length(properties) % 60;
minutes = (taglib_audioproperties_length(properties) - seconds) / 60;
printf("-- AUDIO --\n");
printf("bitrate - %i\n", taglib_audioproperties_bitrate(properties));
printf("sample rate - %i\n", taglib_audioproperties_samplerate(properties));
printf("channels - %i\n", taglib_audioproperties_channels(properties));
printf("length - %i:%02i\n", minutes, seconds);
printf("-- AUDIO --\n");
printf("bitrate - %i\n", taglib_audioproperties_bitrate(properties));
printf("sample rate - %i\n", taglib_audioproperties_samplerate(properties));
printf("channels - %i\n", taglib_audioproperties_channels(properties));
printf("length - %i:%02i\n", minutes, seconds);
}
taglib_tag_free_strings();
taglib_file_free(file);

View File

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

View File

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

View File

@@ -46,8 +46,9 @@ taglib_includedir = $(includedir)/taglib
# 7:0:6 -- TagLib 1.6 RC1
# 7:1:6 -- TagLib 1.6
# 8:0:7 -- TagLib 1.6.1
# 9:0:8 -- TagLib 1.6.2
libtag_la_LDFLAGS = $(all_libraries) -no-undefined -version-info 8:0:7
libtag_la_LDFLAGS = $(all_libraries) -no-undefined -version-info 9:0:8
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

@@ -30,6 +30,7 @@
#ifdef WITH_ASF
#include <taglib.h>
#include <tdebug.h>
#include "asfattribute.h"
#include "asffile.h"
@@ -197,6 +198,10 @@ ASF::Attribute::parse(ASF::File &f, int kind)
name = f.readString(nameLength);
}
if(kind != 2 && size > 65535) {
debug("ASF::Attribute::parse() -- Value larger than 64kB");
}
switch(d->type) {
case WordType:
d->shortValue = f.readWORD();
@@ -232,6 +237,27 @@ ASF::Attribute::parse(ASF::File &f, int kind)
return name;
}
int
ASF::Attribute::dataSize() const
{
switch (d->type) {
case WordType:
return 2;
case BoolType:
return 4;
case DWordType:
return 4;
case QWordType:
return 5;
case UnicodeType:
return d->stringValue.size() * 2 + 2;
case BytesType:
case GuidType:
return d->byteVectorValue.size();
}
return 0;
}
ByteVector
ASF::Attribute::render(const String &name, int kind) const
{

View File

@@ -165,6 +165,9 @@ namespace TagLib
String parse(ASF::File &file, int kind = 0);
#endif
//! Returns the size of the stored data
int dataSize() const;
private:
friend class File;

View File

@@ -480,11 +480,12 @@ bool ASF::File::save()
bool inMetadataObject = false;
for(unsigned int j = 0; j < attributes.size(); j++) {
const Attribute &attribute = attributes[j];
if(!inExtendedContentDescriptionObject && attribute.language() == 0 && attribute.stream() == 0) {
bool largeValue = attribute.dataSize() > 65535;
if(!inExtendedContentDescriptionObject && !largeValue && attribute.language() == 0 && attribute.stream() == 0) {
d->extendedContentDescriptionObject->attributeData.append(attribute.render(name));
inExtendedContentDescriptionObject = true;
}
else if(!inMetadataObject && attribute.language() == 0 && attribute.stream() != 0) {
else if(!inMetadataObject && !largeValue && attribute.language() == 0 && attribute.stream() != 0) {
d->metadataObject->attributeData.append(attribute.render(name, 1));
inMetadataObject = true;
}

View File

@@ -105,8 +105,13 @@ ASF::Tag::year() const
unsigned int
ASF::Tag::track() const
{
if(d->attributeListMap.contains("WM/TrackNumber"))
return d->attributeListMap["WM/TrackNumber"][0].toString().toInt();
if(d->attributeListMap.contains("WM/TrackNumber")) {
const ASF::Attribute attr = d->attributeListMap["WM/TrackNumber"][0];
if(attr.type() == ASF::Attribute::DWordType)
return attr.toUInt();
else
return attr.toString().toInt();
}
if(d->attributeListMap.contains("WM/Track"))
return d->attributeListMap["WM/Track"][0].toUInt();
return 0;

View File

@@ -227,6 +227,7 @@ File *FileRef::create(FileName fileName, bool readAudioProperties,
File *file = new Ogg::FLAC::File(fileName, readAudioProperties, audioPropertiesStyle);
if (file->isValid())
return file;
delete file;
return new Ogg::Vorbis::File(fileName, readAudioProperties, audioPropertiesStyle);
}
if(ext == "FLAC")

View File

@@ -406,7 +406,6 @@ void FLAC::File::scan()
nextBlockOffset += length + 4;
// Search through the remaining metadata
while(!isLastBlock) {
header = readBlock(4);
@@ -416,8 +415,13 @@ void FLAC::File::scan()
// Found the vorbis-comment
if(blockType == VorbisComment) {
d->xiphCommentData = readBlock(length);
d->hasXiphComment = true;
if(!d->hasXiphComment) {
d->xiphCommentData = readBlock(length);
d->hasXiphComment = true;
}
else {
debug("FLAC::File::scan() -- multiple Vorbis Comment blocks found, using the first one");
}
}
nextBlockOffset += length + 4;

View File

@@ -113,6 +113,13 @@ MP4::File::read(bool readProperties, Properties::ReadStyle audioPropertiesStyle)
return;
}
// must have a moov atom, otherwise consider it invalid
MP4::Atom *moov = d->atoms->find("moov");
if(!moov) {
setValid(false);
return;
}
d->tag = new Tag(this, d->atoms);
if(readProperties) {
d->properties = new Properties(this, d->atoms, audioPropertiesStyle);

View File

@@ -42,12 +42,12 @@ class MP4::Tag::TagPrivate
public:
TagPrivate() : file(0), atoms(0) {}
~TagPrivate() {}
File *file;
TagLib::File *file;
Atoms *atoms;
ItemListMap items;
};
MP4::Tag::Tag(File *file, MP4::Atoms *atoms)
MP4::Tag::Tag(TagLib::File *file, MP4::Atoms *atoms)
{
d = new TagPrivate;
d->file = file;
@@ -209,7 +209,7 @@ MP4::Tag::parseCovr(MP4::Atom *atom, TagLib::File *file)
int flags = data.mid(pos + 8, 4).toUInt();
if(name != "data") {
debug("MP4: Unexpected atom \"" + name + "\", expecting \"data\"");
return;
break;
}
if(flags == MP4::CoverArt::PNG || flags == MP4::CoverArt::JPEG) {
value.append(MP4::CoverArt(MP4::CoverArt::Format(flags),
@@ -270,7 +270,7 @@ MP4::Tag::renderIntPair(const ByteVector &name, MP4::Item &item)
ByteVector::fromShort(item.toIntPair().first) +
ByteVector::fromShort(item.toIntPair().second) +
ByteVector(2, '\0'));
return renderData(name, 0x15, data);
return renderData(name, 0x00, data);
}
ByteVector
@@ -280,7 +280,7 @@ MP4::Tag::renderIntPairNoTrailing(const ByteVector &name, MP4::Item &item)
data.append(ByteVector(2, '\0') +
ByteVector::fromShort(item.toIntPair().first) +
ByteVector::fromShort(item.toIntPair().second));
return renderData(name, 0x15, data);
return renderData(name, 0x00, data);
}
ByteVector

View File

@@ -52,7 +52,7 @@ namespace TagLib {
*
* \warning It is advisable <b>not</b> to write non-ISO-8859-1 data to ID3v1
* tags. Please consider disabling the writing of ID3v1 tags in the case
* that the data is ISO-8859-1.
* that the data is not ISO-8859-1.
*
* \see ID3v1::Tag::setStringHandler()
*/

View File

@@ -282,7 +282,8 @@ bool FrameFactory::updateFrame(Frame::Header *header) const
frameID == "LNK" ||
frameID == "RVA" ||
frameID == "TIM" ||
frameID == "TSI")
frameID == "TSI" ||
frameID == "TDA")
{
debug("ID3v2.4 no longer supports the frame type " + String(frameID) +
". It will be discarded from the tag.");
@@ -310,7 +311,6 @@ bool FrameFactory::updateFrame(Frame::Header *header) const
convertFrame("TCM", "TCOM", header);
convertFrame("TCO", "TCON", header);
convertFrame("TCR", "TCOP", header);
convertFrame("TDA", "TDRC", header);
convertFrame("TDY", "TDLY", header);
convertFrame("TEN", "TENC", header);
convertFrame("TFT", "TFLT", header);

View File

@@ -35,7 +35,7 @@ namespace TagLib {
namespace ID3v2 {
class TAGLIB_EXPORT TextIdentificationFrame;
class TextIdentificationFrame;
//! A factory for creating ID3v2 frames during parsing

View File

@@ -33,10 +33,28 @@ using namespace ID3v2;
TagLib::uint SynchData::toUInt(const ByteVector &data)
{
uint sum = 0;
bool notSynchSafe = false;
int last = data.size() > 4 ? 3 : data.size() - 1;
for(int i = 0; i <= last; i++)
for(int i = 0; i <= last; i++) {
if(data[i] & 0x80) {
notSynchSafe = true;
break;
}
sum |= (data[i] & 0x7f) << ((last - i) * 7);
}
if(notSynchSafe) {
/*
* Invalid data; assume this was created by some buggy software that just
* put normal integers here rather than syncsafe ones, and try it that
* way.
*/
sum = 0;
for(int i = 0; i <= last; i++)
sum |= data[i] << ((last - i) * 8);
}
return sum;
}

View File

@@ -352,7 +352,7 @@ ByteVector ID3v2::Tag::render() const
// 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) {
if((*it)->header()->frameID().size() != 4) {
debug("A frame of unsupported or unknown type \'"
+ String((*it)->header()->frameID()) + "\' has been discarded");
continue;

View File

@@ -3,45 +3,54 @@
######################################################################
TEMPLATE = lib
CONFIG += lib_bundle
CONFIG += x86 ppc
CONFIG += lib_bundle staticlib
CONFIG += x86 x86_64 ppc
CONFIG -= qt
DEFINES += HAVE_ZLIB=1 NDEBUG
DEFINES += HAVE_ZLIB=1 NDEBUG WITH_ASF WITH_MP4
LIBS += -lz
TARGET = TagLib
VERSION = 1.6
VERSION = 1.6.2
DEPENDPATH += . \
ape \
flac \
mpc \
mp4 \
mpeg \
ogg \
ogg/speex \
toolkit \
trueaudio \
wavpack \
mpeg/id3v1 \
mpeg/id3v2 \
ogg/flac \
ogg/vorbis \
mpeg/id3v2/frames
ape \
asf \
flac \
mp4 \
mpc \
mpeg \
mpeg/id3v1 \
mpeg/id3v2 \
mpeg/id3v2/frames \
ogg \
ogg/flac \
ogg/speex \
ogg/vorbis \
riff \
riff/aiff \
riff/wav \
toolkit \
trueaudio \
wavpack
INCLUDEPATH += . \
toolkit \
mpeg \
ogg/vorbis \
ogg \
flac \
ogg/flac \
mpc \
mp4 \
wavpack \
ogg/speex \
trueaudio \
ape \
mpeg/id3v2 \
mpeg/id3v1 \
mpeg/id3v2/frames
ape \
asf \
flac \
mp4 \
mpc \
mpeg \
mpeg/id3v1 \
mpeg/id3v2 \
mpeg/id3v2/frames \
ogg \
ogg/flac \
ogg/speex \
ogg/vorbis \
riff \
riff/aiff \
riff/wav \
toolkit \
trueaudio \
wavpack
# Input
HEADERS += audioproperties.h \
@@ -108,31 +117,65 @@ HEADERS += audioproperties.h \
mpeg/id3v2/frames/urllinkframe.h \
toolkit/tlist.tcc \
toolkit/tmap.tcc
SOURCES += audioproperties.cpp \
fileref.cpp \
tag.cpp \
tagunion.cpp \
ape/apefooter.cpp \
SOURCES += ape/apefooter.cpp \
ape/apeitem.cpp \
ape/apetag.cpp \
asf/asfattribute.cpp \
asf/asffile.cpp \
asf/asfproperties.cpp \
asf/asftag.cpp \
audioproperties.cpp \
fileref.cpp \
flac/flacfile.cpp \
flac/flacproperties.cpp \
mp4/mp4atom.cpp \
mp4/mp4item.cpp \
mp4/mp4coverart.cpp \
mp4/mp4file.cpp \
mp4/mp4item.cpp \
mp4/mp4properties.cpp \
mp4/mp4tag.cpp \
mpc/mpcfile.cpp \
mpc/mpcproperties.cpp \
mpeg/id3v1/id3v1genres.cpp \
mpeg/id3v1/id3v1tag.cpp \
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 \
mpeg/id3v2/frames/unknownframe.cpp \
mpeg/id3v2/frames/unsynchronizedlyricsframe.cpp \
mpeg/id3v2/frames/urllinkframe.cpp \
mpeg/id3v2/id3v2extendedheader.cpp \
mpeg/id3v2/id3v2footer.cpp \
mpeg/id3v2/id3v2frame.cpp \
mpeg/id3v2/id3v2framefactory.cpp \
mpeg/id3v2/id3v2header.cpp \
mpeg/id3v2/id3v2synchdata.cpp \
mpeg/id3v2/id3v2tag.cpp \
mpeg/mpegfile.cpp \
mpeg/mpegheader.cpp \
mpeg/mpegproperties.cpp \
mpeg/xingheader.cpp \
ogg/flac/oggflacfile.cpp \
ogg/oggfile.cpp \
ogg/oggpage.cpp \
ogg/oggpageheader.cpp \
ogg/xiphcomment.cpp \
ogg/speex/speexfile.cpp \
ogg/speex/speexproperties.cpp \
ogg/vorbis/vorbisfile.cpp \
ogg/vorbis/vorbisproperties.cpp \
ogg/xiphcomment.cpp \
riff/aiff/aifffile.cpp \
riff/aiff/aiffproperties.cpp \
riff/rifffile.cpp \
riff/wav/wavfile.cpp \
riff/wav/wavproperties.cpp \
tag.cpp \
tagunion.cpp \
toolkit/tbytevector.cpp \
toolkit/tbytevectorlist.cpp \
toolkit/tdebug.cpp \
@@ -143,72 +186,42 @@ SOURCES += audioproperties.cpp \
trueaudio/trueaudiofile.cpp \
trueaudio/trueaudioproperties.cpp \
wavpack/wavpackfile.cpp \
wavpack/wavpackproperties.cpp \
mpeg/id3v1/id3v1genres.cpp \
mpeg/id3v1/id3v1tag.cpp \
mpeg/id3v2/id3v2extendedheader.cpp \
mpeg/id3v2/id3v2footer.cpp \
mpeg/id3v2/id3v2frame.cpp \
mpeg/id3v2/id3v2framefactory.cpp \
mpeg/id3v2/id3v2header.cpp \
mpeg/id3v2/id3v2synchdata.cpp \
mpeg/id3v2/id3v2tag.cpp \
ogg/flac/oggflacfile.cpp \
ogg/vorbis/vorbisfile.cpp \
ogg/vorbis/vorbisproperties.cpp \
mpeg/id3v2/frames/attachedpictureframe.cpp \
mpeg/id3v2/frames/commentsframe.cpp \
mpeg/id3v2/frames/generalencapsulatedobjectframe.cpp \
mpeg/id3v2/frames/popularimeterframe.cpp \
mpeg/id3v2/frames/relativevolumeframe.cpp \
mpeg/id3v2/frames/textidentificationframe.cpp \
mpeg/id3v2/frames/uniquefileidentifierframe.cpp \
mpeg/id3v2/frames/unknownframe.cpp \
mpeg/id3v2/frames/unsynchronizedlyricsframe.cpp \
mpeg/id3v2/frames/urllinkframe.cpp
wavpack/wavpackproperties.cpp
FRAMEWORK_HEADERS.version = Versions
FRAMEWORK_HEADERS.files = \
audioproperties.h \
fileref.h \
tag.h \
taglib_export.h \
FRAMEWORK_HEADERS.version = Versions
FRAMEWORK_HEADERS.files = \
ape/apefooter.h \
ape/apeitem.h \
ape/apetag.h \
asf/asfattribute.h \
asf/asffile.h \
asf/asfproperties.h \
asf/asftag.h \
audioproperties.h \
fileref.h \
flac/flacfile.h \
flac/flacproperties.h \
mp4/mp4atom.h \
mp4/mp4item.h \
mp4/mp4coverart.h \
mp4/mp4file.h \
mp4/mp4item.h \
mp4/mp4properties.h \
mp4/mp4tag.h \
mpc/mpcfile.h \
mpc/mpcproperties.h \
mpeg/mpegfile.h \
mpeg/mpegheader.h \
mpeg/mpegproperties.h \
mpeg/xingheader.h \
ogg/oggfile.h \
ogg/oggpage.h \
ogg/oggpageheader.h \
ogg/xiphcomment.h \
ogg/speex/speexfile.h \
ogg/speex/speexproperties.h \
toolkit/taglib.h \
toolkit/tbytevector.h \
toolkit/tbytevectorlist.h \
toolkit/tfile.h \
toolkit/tlist.h \
toolkit/tmap.h \
toolkit/tstring.h \
toolkit/tstringlist.h \
toolkit/unicode.h \
trueaudio/trueaudiofile.h \
trueaudio/trueaudioproperties.h \
wavpack/wavpackfile.h \
wavpack/wavpackproperties.h \
mpeg/id3v1/id3v1genres.h \
mpeg/id3v1/id3v1tag.h \
mpeg/id3v2/frames/attachedpictureframe.h \
mpeg/id3v2/frames/commentsframe.h \
mpeg/id3v2/frames/generalencapsulatedobjectframe.h \
mpeg/id3v2/frames/popularimeterframe.h \
mpeg/id3v2/frames/privateframe.h \
mpeg/id3v2/frames/relativevolumeframe.h \
mpeg/id3v2/frames/textidentificationframe.h \
mpeg/id3v2/frames/uniquefileidentifierframe.h \
mpeg/id3v2/frames/unknownframe.h \
mpeg/id3v2/frames/unsynchronizedlyricsframe.h \
mpeg/id3v2/frames/urllinkframe.h \
mpeg/id3v2/id3v2extendedheader.h \
mpeg/id3v2/id3v2footer.h \
mpeg/id3v2/id3v2frame.h \
@@ -216,19 +229,43 @@ SOURCES += audioproperties.cpp \
mpeg/id3v2/id3v2header.h \
mpeg/id3v2/id3v2synchdata.h \
mpeg/id3v2/id3v2tag.h \
mpeg/mpegfile.h \
mpeg/mpegheader.h \
mpeg/mpegproperties.h \
mpeg/xingheader.h \
ogg/flac/oggflacfile.h \
ogg/oggfile.h \
ogg/oggpage.h \
ogg/oggpageheader.h \
ogg/speex/speexfile.h \
ogg/speex/speexproperties.h \
ogg/vorbis/vorbisfile.h \
ogg/vorbis/vorbisproperties.h \
mpeg/id3v2/frames/attachedpictureframe.h \
mpeg/id3v2/frames/commentsframe.h \
mpeg/id3v2/frames/generalencapsulatedobjectframe.h \
mpeg/id3v2/frames/relativevolumeframe.h \
mpeg/id3v2/frames/textidentificationframe.h \
mpeg/id3v2/frames/uniquefileidentifierframe.h \
mpeg/id3v2/frames/unknownframe.h \
mpeg/id3v2/frames/unsynchronizedlyricsframe.h \
mpeg/id3v2/frames/urllinkframe.h \
ogg/xiphcomment.h \
riff/aiff/aifffile.h \
riff/aiff/aiffproperties.h \
riff/rifffile.h \
riff/wav/wavfile.h \
riff/wav/wavproperties.h \
tag.h \
taglib_export.h \
tagunion.h \
toolkit/taglib.h \
toolkit/tbytevector.h \
toolkit/tbytevectorlist.h \
toolkit/tdebug.h \
toolkit/tfile.h \
toolkit/tlist.h \
toolkit/tlist.tcc \
toolkit/tmap.tcc
toolkit/tmap.h \
toolkit/tmap.tcc \
toolkit/tstring.h \
toolkit/tstringlist.h \
toolkit/unicode.h \
trueaudio/trueaudiofile.h \
trueaudio/trueaudioproperties.h \
wavpack/wavpackfile.h \
wavpack/wavpackproperties.h
FRAMEWORK_HEADERS.path = Headers
QMAKE_BUNDLE_DATA += FRAMEWORK_HEADERS

View File

@@ -38,6 +38,8 @@
#define TAGLIB_EXPORT
#endif
#ifdef HAVE_CONFIG_H
#include "taglib_config.h"
#endif
#endif

View File

@@ -36,6 +36,7 @@ SET(test_runner_SRCS
test_riff.cpp
test_ogg.cpp
test_oggflac.cpp
test_flac.cpp
)
IF(WITH_MP4)
SET(test_runner_SRCS ${test_runner_SRCS}

View File

@@ -29,7 +29,8 @@ test_runner_SOURCES = \
test_riff.cpp \
test_aiff.cpp \
test_ogg.cpp \
test_oggflac.cpp
test_oggflac.cpp \
test_flac.cpp
if build_tests
TESTS = test_runner

BIN
tests/data/covr-junk.m4a Normal file

Binary file not shown.

BIN
tests/data/id3v22-tda.mp3 Normal file

Binary file not shown.

BIN
tests/data/multiple-vc.flac Normal file

Binary file not shown.

View File

@@ -19,12 +19,11 @@ public:
void testReading()
{
string filename = copyFile("empty", ".aiff");
ScopedFileCopy copy("empty", ".aiff");
string filename = copy.fileName();
RIFF::AIFF::File *f = new RIFF::AIFF::File(filename.c_str());
CPPUNIT_ASSERT_EQUAL(689, f->audioProperties()->bitrate());
deleteFile(filename);
}
};

View File

@@ -18,6 +18,8 @@ class TestASF : public CppUnit::TestFixture
CPPUNIT_TEST(testSaveMultipleValues);
CPPUNIT_TEST(testSaveStream);
CPPUNIT_TEST(testSaveLanguage);
CPPUNIT_TEST(testDWordTrackNumber);
CPPUNIT_TEST(testSaveLargeValue);
CPPUNIT_TEST_SUITE_END();
public:
@@ -39,7 +41,8 @@ public:
void testSaveMultipleValues()
{
string newname = copyFile("silence-1", ".wma");
ScopedFileCopy copy("silence-1", ".wma");
string newname = copy.fileName();
ASF::File *f = new ASF::File(newname.c_str());
ASF::AttributeList values;
@@ -52,13 +55,38 @@ public:
f = new ASF::File(newname.c_str());
CPPUNIT_ASSERT_EQUAL(2, (int)f->tag()->attributeListMap()["WM/AlbumTitle"].size());
delete f;
}
deleteFile(newname);
void testDWordTrackNumber()
{
ScopedFileCopy copy("silence-1", ".wma");
string newname = copy.fileName();
ASF::File *f = new ASF::File(newname.c_str());
CPPUNIT_ASSERT(!f->tag()->attributeListMap().contains("WM/TrackNumber"));
f->tag()->setAttribute("WM/TrackNumber", (unsigned int)(123));
f->save();
delete f;
f = new ASF::File(newname.c_str());
CPPUNIT_ASSERT(f->tag()->attributeListMap().contains("WM/TrackNumber"));
CPPUNIT_ASSERT_EQUAL(ASF::Attribute::DWordType, f->tag()->attributeListMap()["WM/TrackNumber"].front().type());
CPPUNIT_ASSERT_EQUAL(TagLib::uint(123), f->tag()->track());
f->tag()->setTrack(234);
f->save();
delete f;
f = new ASF::File(newname.c_str());
CPPUNIT_ASSERT(f->tag()->attributeListMap().contains("WM/TrackNumber"));
CPPUNIT_ASSERT_EQUAL(ASF::Attribute::UnicodeType, f->tag()->attributeListMap()["WM/TrackNumber"].front().type());
CPPUNIT_ASSERT_EQUAL(TagLib::uint(234), f->tag()->track());
delete f;
}
void testSaveStream()
{
string newname = copyFile("silence-1", ".wma");
ScopedFileCopy copy("silence-1", ".wma");
string newname = copy.fileName();
ASF::File *f = new ASF::File(newname.c_str());
ASF::AttributeList values;
@@ -72,13 +100,12 @@ public:
f = new ASF::File(newname.c_str());
CPPUNIT_ASSERT_EQUAL(43, f->tag()->attributeListMap()["WM/AlbumTitle"][0].stream());
delete f;
deleteFile(newname);
}
void testSaveLanguage()
{
string newname = copyFile("silence-1", ".wma");
ScopedFileCopy copy("silence-1", ".wma");
string newname = copy.fileName();
ASF::File *f = new ASF::File(newname.c_str());
ASF::AttributeList values;
@@ -94,8 +121,24 @@ public:
CPPUNIT_ASSERT_EQUAL(32, f->tag()->attributeListMap()["WM/AlbumTitle"][0].stream());
CPPUNIT_ASSERT_EQUAL(56, f->tag()->attributeListMap()["WM/AlbumTitle"][0].language());
delete f;
}
deleteFile(newname);
void testSaveLargeValue()
{
ScopedFileCopy copy("silence-1", ".wma");
string newname = copy.fileName();
ASF::File *f = new ASF::File(newname.c_str());
ASF::AttributeList values;
ASF::Attribute attr(ByteVector(70000, 'x'));
values.append(attr);
f->tag()->attributeListMap()["WM/Blob"] = values;
f->save();
delete f;
f = new ASF::File(newname.c_str());
CPPUNIT_ASSERT_EQUAL(ByteVector(70000, 'x'), f->tag()->attributeListMap()["WM/Blob"][0].toByteVector());
delete f;
}
};

View File

@@ -38,7 +38,8 @@ public:
void fileRefSave(const string &filename, const string &ext)
{
string newname = copyFile(filename, ext);
ScopedFileCopy copy(filename, ext);
string newname = copy.fileName();
FileRef *f = new FileRef(newname.c_str());
CPPUNIT_ASSERT(!f->isNull());
@@ -77,8 +78,6 @@ public:
CPPUNIT_ASSERT_EQUAL(f->tag()->track(), TagLib::uint(7));
CPPUNIT_ASSERT_EQUAL(f->tag()->year(), TagLib::uint(2080));
delete f;
deleteFile(newname);
}
void testMusepack()

39
tests/test_flac.cpp Normal file
View File

@@ -0,0 +1,39 @@
#include <cppunit/extensions/HelperMacros.h>
#include <string>
#include <stdio.h>
#include <tag.h>
#include <tstringlist.h>
#include <tbytevectorlist.h>
#include <flacfile.h>
#include "utils.h"
using namespace std;
using namespace TagLib;
class TestFLAC : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(TestFLAC);
CPPUNIT_TEST(testMultipleCommentBlocks);
CPPUNIT_TEST_SUITE_END();
public:
void testMultipleCommentBlocks()
{
ScopedFileCopy copy("multiple-vc", ".flac");
string newname = copy.fileName();
FLAC::File *f = new FLAC::File(newname.c_str());
CPPUNIT_ASSERT_EQUAL(String("Artist 1"), f->tag()->artist());
f->tag()->setArtist("The Artist");
f->save();
delete f;
f = new FLAC::File(newname.c_str());
CPPUNIT_ASSERT_EQUAL(String("The Artist"), f->tag()->artist());
delete f;
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestFLAC);

View File

@@ -59,6 +59,8 @@ class TestID3v2 : public CppUnit::TestFixture
CPPUNIT_TEST(testUpdateGenre23_1);
CPPUNIT_TEST(testUpdateGenre23_2);
CPPUNIT_TEST(testUpdateGenre24);
CPPUNIT_TEST(testUpdateDate22);
// CPPUNIT_TEST(testUpdateFullDate22); TODO TYE+TDA should be upgraded to TDRC together
CPPUNIT_TEST_SUITE_END();
public:
@@ -242,7 +244,8 @@ public:
void testPOPMFromFile()
{
string newname = copyFile("xing", ".mp3");
ScopedFileCopy copy("xing", ".mp3");
string newname = copy.fileName();
ID3v2::PopularimeterFrame *f = new ID3v2::PopularimeterFrame();
f->setEmail("email@example.com");
@@ -256,7 +259,6 @@ public:
MPEG::File bar(newname.c_str());
CPPUNIT_ASSERT_EQUAL(String("email@example.com"), dynamic_cast<ID3v2::PopularimeterFrame *>(bar.ID3v2Tag()->frameList("POPM").front())->email());
CPPUNIT_ASSERT_EQUAL(200, dynamic_cast<ID3v2::PopularimeterFrame *>(bar.ID3v2Tag()->frameList("POPM").front())->rating());
deleteFile(newname);
}
// http://bugs.kde.org/show_bug.cgi?id=150481
@@ -369,7 +371,8 @@ public:
void testSaveUTF16Comment()
{
String::Type defaultEncoding = ID3v2::FrameFactory::instance()->defaultTextEncoding();
string newname = copyFile("xing", ".mp3");
ScopedFileCopy copy("xing", ".mp3");
string newname = copy.fileName();
ID3v2::FrameFactory::instance()->setDefaultTextEncoding(String::UTF16);
MPEG::File foo(newname.c_str());
foo.strip();
@@ -377,7 +380,6 @@ public:
foo.save();
MPEG::File bar(newname.c_str());
CPPUNIT_ASSERT_EQUAL(String("Test comment!"), bar.tag()->comment());
deleteFile(newname);
ID3v2::FrameFactory::instance()->setDefaultTextEncoding(defaultEncoding);
}
@@ -439,6 +441,20 @@ public:
CPPUNIT_ASSERT_EQUAL(String("R&B Eurodisco"), tag.genre());
}
void testUpdateDate22()
{
MPEG::File f("data/id3v22-tda.mp3", false);
CPPUNIT_ASSERT(f.tag());
CPPUNIT_ASSERT_EQUAL(TagLib::uint(2010), f.tag()->year());
}
void testUpdateFullDate22()
{
MPEG::File f("data/id3v22-tda.mp3", false);
CPPUNIT_ASSERT(f.tag());
CPPUNIT_ASSERT_EQUAL(String("2010-04-03"), f.ID3v2Tag()->frameListMap()["TDRC"].front()->toString());
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestID3v2);

View File

@@ -16,12 +16,14 @@ class TestMP4 : public CppUnit::TestFixture
CPPUNIT_TEST_SUITE(TestMP4);
CPPUNIT_TEST(testProperties);
CPPUNIT_TEST(testFreeForm);
CPPUNIT_TEST(testCheckValid);
CPPUNIT_TEST(testUpdateStco);
CPPUNIT_TEST(testSaveExisingWhenIlstIsLast);
CPPUNIT_TEST(test64BitAtom);
CPPUNIT_TEST(testGnre);
CPPUNIT_TEST(testCovrRead);
CPPUNIT_TEST(testCovrWrite);
CPPUNIT_TEST(testCovrRead2);
CPPUNIT_TEST_SUITE_END();
public:
@@ -36,9 +38,18 @@ public:
CPPUNIT_ASSERT_EQUAL(16, ((MP4::Properties *)f.audioProperties())->bitsPerSample());
}
void testCheckValid()
{
MP4::File f("data/empty.aiff");
CPPUNIT_ASSERT(!f.isValid());
MP4::File f2("data/has-tags.m4a");
CPPUNIT_ASSERT(f2.isValid());
}
void testUpdateStco()
{
string filename = copyFile("no-tags", ".3g2");
ScopedFileCopy copy("no-tags", ".3g2");
string filename = copy.fileName();
MP4::File *f = new MP4::File(filename.c_str());
f->tag()->setArtist(ByteVector(3000, 'x'));
@@ -80,13 +91,12 @@ public:
}
delete f;
deleteFile(filename);
}
void testFreeForm()
{
string filename = copyFile("has-tags", ".m4a");
ScopedFileCopy copy("has-tags", ".m4a");
string filename = copy.fileName();
MP4::File *f = new MP4::File(filename.c_str());
CPPUNIT_ASSERT(f->tag()->itemListMap().contains("----:com.apple.iTunes:iTunNORM"));
@@ -99,13 +109,12 @@ public:
CPPUNIT_ASSERT_EQUAL(String("Bar"), f->tag()->itemListMap()["----:org.kde.TagLib:Foo"].toStringList()[0]);
f->save();
delete f;
deleteFile(filename);
}
void testSaveExisingWhenIlstIsLast()
{
string filename = copyFile("ilst-is-last", ".m4a");
ScopedFileCopy copy("ilst-is-last", ".m4a");
string filename = copy.fileName();
MP4::File *f = new MP4::File(filename.c_str());
CPPUNIT_ASSERT_EQUAL(String("82,164"), f->tag()->itemListMap()["----:com.apple.iTunes:replaygain_track_minmax"].toStringList()[0]);
@@ -118,13 +127,12 @@ public:
CPPUNIT_ASSERT_EQUAL(String("82,164"), f->tag()->itemListMap()["----:com.apple.iTunes:replaygain_track_minmax"].toStringList()[0]);
CPPUNIT_ASSERT_EQUAL(String("Pearl Jam"), f->tag()->artist());
CPPUNIT_ASSERT_EQUAL(String("foo"), f->tag()->comment());
deleteFile(filename);
}
void test64BitAtom()
{
string filename = copyFile("64bit", ".mp4");
ScopedFileCopy copy("64bit", ".mp4");
string filename = copy.fileName();
MP4::File *f = new MP4::File(filename.c_str());
CPPUNIT_ASSERT_EQUAL(true, f->tag()->itemListMap()["cpil"].toBool());
@@ -144,14 +152,13 @@ public:
moov = atoms->atoms[0];
// original size + 'pgap' size + padding
CPPUNIT_ASSERT_EQUAL(long(77 + 25 + 974), moov->length);
deleteFile(filename);
}
void testGnre()
{
MP4::File *f = new MP4::File("data/gnre.m4a");
CPPUNIT_ASSERT_EQUAL(TagLib::String("Ska"), f->tag()->genre());
delete f;
}
void testCovrRead()
@@ -164,11 +171,13 @@ public:
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());
delete f;
}
void testCovrWrite()
{
string filename = copyFile("has-tags", ".m4a");
ScopedFileCopy copy("has-tags", ".m4a");
string filename = copy.fileName();
MP4::File *f = new MP4::File(filename.c_str());
CPPUNIT_ASSERT(f->tag()->itemListMap().contains("covr"));
@@ -189,8 +198,19 @@ public:
CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::PNG, l[2].format());
CPPUNIT_ASSERT_EQUAL(TagLib::uint(3), l[2].data().size());
delete f;
}
deleteFile(filename);
void testCovrRead2()
{
MP4::File *f = new MP4::File("data/covr-junk.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());
delete f;
}
};

View File

@@ -23,7 +23,8 @@ public:
void testSimple()
{
string newname = copyFile("empty", ".ogg");
ScopedFileCopy copy("empty", ".ogg");
string newname = copy.fileName();
Vorbis::File *f = new Vorbis::File(newname.c_str());
f->tag()->setArtist("The Artist");
@@ -33,13 +34,12 @@ public:
f = new Vorbis::File(newname.c_str());
CPPUNIT_ASSERT_EQUAL(String("The Artist"), f->tag()->artist());
delete f;
deleteFile(newname);
}
void testSplitPackets()
{
string newname = copyFile("empty", ".ogg");
ScopedFileCopy copy("empty", ".ogg");
string newname = copy.fileName();
Vorbis::File *f = new Vorbis::File(newname.c_str());
f->tag()->addField("test", ByteVector(128 * 1024, 'x') + ByteVector(1, '\0'));
@@ -49,8 +49,6 @@ public:
f = new Vorbis::File(newname.c_str());
CPPUNIT_ASSERT_EQUAL(19, f->lastPageHeader()->pageSequenceNumber());
delete f;
deleteFile(newname);
}
};

View File

@@ -21,7 +21,8 @@ public:
void testFramingBit()
{
string newname = copyFile("empty_flac", ".oga");
ScopedFileCopy copy("empty_flac", ".oga");
string newname = copy.fileName();
Ogg::FLAC::File *f = new Ogg::FLAC::File(newname.c_str());
f->tag()->setArtist("The Artist");
@@ -36,7 +37,6 @@ public:
CPPUNIT_ASSERT_EQUAL(9134, size);
delete f;
//deleteFile(newname);
}
};

View File

@@ -35,7 +35,8 @@ public:
void testPadding()
{
string filename = copyFile("empty", ".aiff");
ScopedFileCopy copy("empty", ".aiff");
string filename = copy.fileName();
PublicRIFF *f = new PublicRIFF(filename.c_str());
CPPUNIT_ASSERT_EQUAL(ByteVector("TEST"), f->chunkName(2));
@@ -72,8 +73,6 @@ public:
CPPUNIT_ASSERT_EQUAL(ByteVector("TEST"), f->chunkName(2));
CPPUNIT_ASSERT_EQUAL(ByteVector("foo"), f->chunkData(2));
deleteFile(filename);
}
};

View File

@@ -1,8 +1,12 @@
#include <string>
#include <stdio.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#include <fcntl.h>
#include <sys/fcntl.h>
#endif
#include <stdio.h>
#include <string>
using namespace std;
@@ -10,6 +14,10 @@ inline string copyFile(const string &filename, const string &ext)
{
string newname = string(tempnam(NULL, NULL)) + ext;
string oldname = string("data/") + filename + ext;
#ifdef _WIN32
CopyFile(oldname.c_str(), newname.c_str(), FALSE);
SetFileAttributes(newname.c_str(), GetFileAttributes(newname.c_str()) & ~FILE_ATTRIBUTE_READONLY);
#else
char buffer[4096];
int bytes;
int inf = open(oldname.c_str(), O_RDONLY);
@@ -18,6 +26,7 @@ inline string copyFile(const string &filename, const string &ext)
write(outf, buffer, bytes);
close(outf);
close(inf);
#endif
return newname;
}
@@ -25,3 +34,28 @@ inline void deleteFile(const string &filename)
{
remove(filename.c_str());
}
class ScopedFileCopy
{
public:
ScopedFileCopy(const string &filename, const string &ext, bool deleteFile=true)
{
m_deleteFile = deleteFile;
m_filename = copyFile(filename, ext);
}
~ScopedFileCopy()
{
if(m_deleteFile)
deleteFile(m_filename);
}
string fileName()
{
return m_filename;
}
private:
bool m_deleteFile;
string m_filename;
};