mirror of
https://github.com/taglib/taglib.git
synced 2026-06-07 06:50:32 -04:00
Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7f46b2320 | ||
|
|
c823c21eb2 | ||
|
|
aee204df54 | ||
|
|
7f860790ec | ||
|
|
b1cac7175f | ||
|
|
e76466097b | ||
|
|
6612abce72 | ||
|
|
3943668603 | ||
|
|
2ef8fc5118 | ||
|
|
4202ce3ec9 | ||
|
|
0d16255d09 | ||
|
|
d394317767 | ||
|
|
9e9077d1e0 | ||
|
|
b11d2e8b56 | ||
|
|
74c3c282c4 | ||
|
|
004551faec | ||
|
|
5df7692aa1 | ||
|
|
85df71ea2e | ||
|
|
1b6ab18080 | ||
|
|
0f0f2f7288 | ||
|
|
4c70372fe4 | ||
|
|
d81af82ec4 | ||
|
|
44c08b8ca2 | ||
|
|
c962d78a57 | ||
|
|
2039c725f4 | ||
|
|
dcf4c7458b | ||
|
|
de162a9734 | ||
|
|
d685cd6e47 | ||
|
|
f1abbf33f2 | ||
|
|
5a40a45cc5 | ||
|
|
76b6d4fc9e | ||
|
|
e8281e1b9f | ||
|
|
bffd4da8b6 | ||
|
|
fa1a23fe5c | ||
|
|
4e9b41f540 | ||
|
|
724a68c79c | ||
|
|
03c63a11a5 | ||
|
|
ea9dbfd7ae | ||
|
|
af65fefef7 | ||
|
|
752a21edc9 | ||
|
|
18c621cdc2 | ||
|
|
be2f9ad6e5 |
@@ -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}")
|
||||
|
||||
|
||||
@@ -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.2\"" >> taglib.doxyfile; \
|
||||
echo "INPUT = $(srcdir)" >> taglib.doxyfile; \
|
||||
echo "OUTPUT_DIRECTORY = doc/api" >> taglib.doxyfile; \
|
||||
echo "HTML_OUTPUT = html" >> taglib.doxyfile; \
|
||||
|
||||
34
NEWS
34
NEWS
@@ -1,5 +1,35 @@
|
||||
TagLib 1.6
|
||||
==========
|
||||
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)
|
||||
===========================
|
||||
|
||||
* 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:
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.2
|
||||
Libs: -L${libdir} -ltag_c
|
||||
Cflags: -I${includedir}/taglib
|
||||
|
||||
@@ -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.2)
|
||||
|
||||
dnl almost the same like KDE_SET_PEFIX but the path is /usr/local
|
||||
dnl
|
||||
|
||||
@@ -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.2 ($title)</h1></td></tr>
|
||||
<tr>
|
||||
<td valign="bottom">
|
||||
<div id="links">
|
||||
|
||||
BIN
doc/taglib.png
BIN
doc/taglib.png
Binary file not shown.
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 2.7 KiB |
@@ -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);
|
||||
|
||||
1
include/mp4coverart.h
Normal file
1
include/mp4coverart.h
Normal file
@@ -0,0 +1 @@
|
||||
#include "../taglib/mp4/mp4coverart.h"
|
||||
@@ -35,7 +35,7 @@ do
|
||||
flags="$flags -I$includedir/taglib"
|
||||
;;
|
||||
--version)
|
||||
echo 1.6
|
||||
echo 1.6.2
|
||||
;;
|
||||
--prefix)
|
||||
echo $prefix
|
||||
|
||||
@@ -35,7 +35,7 @@ do
|
||||
flags="$flags -I$includedir/taglib"
|
||||
;;
|
||||
--version)
|
||||
echo 1.6
|
||||
echo 1.6.2
|
||||
;;
|
||||
--prefix)
|
||||
echo $prefix
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -45,8 +45,10 @@ 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
|
||||
# 9:0:8 -- TagLib 1.6.2
|
||||
|
||||
libtag_la_LDFLAGS = $(all_libraries) -no-undefined -version-info 7:1:6
|
||||
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 \
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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,18 @@ 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;
|
||||
delete file;
|
||||
return new Ogg::Vorbis::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
}
|
||||
if(ext == "FLAC")
|
||||
return new FLAC::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "MPC")
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
89
taglib/mp4/mp4coverart.cpp
Normal file
89
taglib/mp4/mp4coverart.cpp
Normal 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
71
taglib/mp4/mp4coverart.h
Normal 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
|
||||
@@ -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,18 @@ MP4::File::read(bool readProperties, Properties::ReadStyle audioPropertiesStyle)
|
||||
return;
|
||||
|
||||
d->atoms = new Atoms(this);
|
||||
if (!checkValid(d->atoms->atoms)) {
|
||||
setValid(false);
|
||||
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);
|
||||
@@ -105,6 +129,9 @@ MP4::File::read(bool readProperties, Properties::ReadStyle audioPropertiesStyle)
|
||||
bool
|
||||
MP4::File::save()
|
||||
{
|
||||
if(!isValid())
|
||||
return false;
|
||||
|
||||
return d->tag->save();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -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\"");
|
||||
break;
|
||||
}
|
||||
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)
|
||||
{
|
||||
@@ -243,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
|
||||
@@ -253,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
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
*/
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#ifndef TAGLIB_COMMENTSFRAME_H
|
||||
#define TAGLIB_COMMENTSFRAME_H
|
||||
|
||||
#include <id3v2frame.h>
|
||||
#include "id3v2frame.h"
|
||||
#include "taglib_export.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#ifndef TAGLIB_POPULARIMETERFRAME_H
|
||||
#define TAGLIB_POPULARIMETERFRAME_H
|
||||
|
||||
#include <id3v2frame.h>
|
||||
#include "id3v2frame.h"
|
||||
#include "taglib_export.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#ifndef TAGLIB_UNIQUEFILEIDENTIFIERFRAME
|
||||
#define TAGLIB_UNIQUEFILEIDENTIFIERFRAME
|
||||
|
||||
#include <id3v2frame.h>
|
||||
#include "id3v2frame.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#ifndef TAGLIB_UNKNOWNFRAME_H
|
||||
#define TAGLIB_UNKNOWNFRAME_H
|
||||
|
||||
#include <id3v2frame.h>
|
||||
#include "id3v2frame.h"
|
||||
#include "taglib_export.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#ifndef TAGLIB_UNSYNCHRONIZEDLYRICSFRAME_H
|
||||
#define TAGLIB_UNSYNCHRONIZEDLYRICSFRAME_H
|
||||
|
||||
#include <id3v2frame.h>
|
||||
#include "id3v2frame.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#ifndef TAGLIB_URLLINKFRAME_H
|
||||
#define TAGLIB_URLLINKFRAME_H
|
||||
|
||||
#include <id3v2frame.h>
|
||||
#include "id3v2frame.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace TagLib {
|
||||
|
||||
namespace ID3v2 {
|
||||
|
||||
class TAGLIB_EXPORT TextIdentificationFrame;
|
||||
class TextIdentificationFrame;
|
||||
|
||||
//! A factory for creating ID3v2 frames during parsing
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#ifndef TAGLIB_SPEEXPROPERTIES_H
|
||||
#define TAGLIB_SPEEXPROPERTIES_H
|
||||
|
||||
#include <audioproperties.h>
|
||||
#include "audioproperties.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -32,10 +32,14 @@
|
||||
#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
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "taglib_config.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#ifndef TAGLIB_TRUEAUDIOFILE_H
|
||||
#define TAGLIB_TRUEAUDIOFILE_H
|
||||
|
||||
#include <tfile.h>
|
||||
#include "tfile.h"
|
||||
#include "trueaudioproperties.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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,15 @@ SET(test_runner_SRCS
|
||||
test_aiff.cpp
|
||||
test_riff.cpp
|
||||
test_ogg.cpp
|
||||
test_oggflac.cpp
|
||||
test_flac.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)
|
||||
|
||||
@@ -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,9 @@ test_runner_SOURCES = \
|
||||
test_xiphcomment.cpp \
|
||||
test_riff.cpp \
|
||||
test_aiff.cpp \
|
||||
test_ogg.cpp
|
||||
test_ogg.cpp \
|
||||
test_oggflac.cpp \
|
||||
test_flac.cpp
|
||||
|
||||
if build_tests
|
||||
TESTS = test_runner
|
||||
|
||||
BIN
tests/data/covr-junk.m4a
Normal file
BIN
tests/data/covr-junk.m4a
Normal file
Binary file not shown.
BIN
tests/data/empty_flac.oga
Normal file
BIN
tests/data/empty_flac.oga
Normal file
Binary file not shown.
BIN
tests/data/empty_vorbis.ogg
Normal file
BIN
tests/data/empty_vorbis.ogg
Normal file
Binary file not shown.
BIN
tests/data/gnre.m4a
Normal file
BIN
tests/data/gnre.m4a
Normal file
Binary file not shown.
BIN
tests/data/id3v22-tda.mp3
Normal file
BIN
tests/data/id3v22-tda.mp3
Normal file
Binary file not shown.
BIN
tests/data/multiple-vc.flac
Normal file
BIN
tests/data/multiple-vc.flac
Normal file
Binary file not shown.
@@ -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);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
@@ -34,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());
|
||||
@@ -73,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()
|
||||
@@ -131,6 +134,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);
|
||||
|
||||
39
tests/test_flac.cpp
Normal file
39
tests/test_flac.cpp
Normal 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);
|
||||
@@ -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);
|
||||
|
||||
@@ -16,9 +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:
|
||||
@@ -33,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'));
|
||||
@@ -77,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"));
|
||||
@@ -96,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]);
|
||||
@@ -115,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());
|
||||
@@ -130,7 +141,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());
|
||||
@@ -141,8 +152,65 @@ 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()
|
||||
{
|
||||
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());
|
||||
delete f;
|
||||
}
|
||||
|
||||
void testCovrWrite()
|
||||
{
|
||||
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"));
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
49
tests/test_mp4coverart.cpp
Normal file
49
tests/test_mp4coverart.cpp
Normal 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
37
tests/test_mp4item.cpp
Normal 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);
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
44
tests/test_oggflac.cpp
Normal file
44
tests/test_oggflac.cpp
Normal 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()
|
||||
{
|
||||
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");
|
||||
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;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(TestOggFLAC);
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user