42 Commits
v1.6 ... v1.6.2

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


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


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


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

CCMAIL:me@sbooth.org


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

Patch by Modestas Vainius


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


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


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


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

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


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

View File

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

View File

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

34
NEWS
View File

@@ -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:

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

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

View File

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

View File

@@ -6,6 +6,6 @@ includedir=@includedir@
Name: TagLib C Bindings
Description: Audio meta-data library (C bindings)
Requires: taglib
Version: 1.6
Version: 1.6.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)
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 ($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);

1
include/mp4coverart.h Normal file
View File

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

View File

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

View File

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

View File

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

View File

@@ -45,8 +45,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 \

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

@@ -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;

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

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

View File

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

View File

@@ -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

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

View File

@@ -29,6 +29,7 @@
#include <tfile.h>
#include <tstring.h>
#include <tdebug.h>
#include "fileref.h"
#include "asffile.h"
@@ -93,11 +94,19 @@ FileRef::~FileRef()
Tag *FileRef::tag() const
{
if(isNull()) {
debug("FileRef::tag() - Called without a valid file.");
return 0;
}
return d->file->tag();
}
AudioProperties *FileRef::audioProperties() const
{
if(isNull()) {
debug("FileRef::audioProperties() - Called without a valid file.");
return 0;
}
return d->file->audioProperties();
}
@@ -108,6 +117,10 @@ File *FileRef::file() const
bool FileRef::save()
{
if(isNull()) {
debug("FileRef::save() - Called without a valid file.");
return false;
}
return d->file->save();
}
@@ -205,12 +218,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")

View File

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

View File

@@ -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

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,89 @@
/**************************************************************************
copyright : (C) 2009 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef WITH_MP4
#include <taglib.h>
#include <tdebug.h>
#include "mp4coverart.h"
using namespace TagLib;
class MP4::CoverArt::CoverArtPrivate : public RefCounter
{
public:
CoverArtPrivate() : RefCounter(), format(MP4::CoverArt::JPEG) {}
Format format;
ByteVector data;
};
MP4::CoverArt::CoverArt(Format format, const ByteVector &data)
{
d = new CoverArtPrivate;
d->format = format;
d->data = data;
}
MP4::CoverArt::CoverArt(const CoverArt &item) : d(item.d)
{
d->ref();
}
MP4::CoverArt &
MP4::CoverArt::operator=(const CoverArt &item)
{
if(d->deref()) {
delete d;
}
d = item.d;
d->ref();
return *this;
}
MP4::CoverArt::~CoverArt()
{
if(d->deref()) {
delete d;
}
}
MP4::CoverArt::Format
MP4::CoverArt::format() const
{
return d->format;
}
ByteVector
MP4::CoverArt::data() const
{
return d->data;
}
#endif

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

@@ -0,0 +1,71 @@
/**************************************************************************
copyright : (C) 2009 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifndef TAGLIB_MP4COVERART_H
#define TAGLIB_MP4COVERART_H
#include "tlist.h"
#include "tbytevector.h"
#include "taglib_export.h"
namespace TagLib {
namespace MP4 {
class TAGLIB_EXPORT CoverArt
{
public:
/*!
* This describes the image type.
*/
enum Format {
JPEG = 0x0D,
PNG = 0x0E
};
CoverArt(Format format, const ByteVector &data);
~CoverArt();
CoverArt(const CoverArt &item);
CoverArt &operator=(const CoverArt &item);
//! Format of the image
Format format() const;
//! The image data
ByteVector data() const;
private:
class CoverArtPrivate;
CoverArtPrivate *d;
};
typedef List<CoverArt> CoverArtList;
}
}
#endif

View File

@@ -89,6 +89,18 @@ MP4::File::audioProperties() const
return d->properties;
}
bool
MP4::File::checkValid(const MP4::AtomList &list)
{
for(uint i = 0; i < list.size(); i++) {
if(list[i]->length == 0)
return false;
if(!checkValid(list[i]->children))
return false;
}
return true;
}
void
MP4::File::read(bool readProperties, Properties::ReadStyle audioPropertiesStyle)
{
@@ -96,6 +108,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();
}

View File

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

View File

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

View File

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

View File

@@ -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));
}

View File

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

View File

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

View File

@@ -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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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

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

View File

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

View File

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

View File

@@ -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

@@ -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

View File

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

View File

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

View File

@@ -14,6 +14,8 @@ INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/trueaudio
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ogg
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ogg/vorbis
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ogg/flac
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/flac
)
SET(test_runner_SRCS
@@ -33,9 +35,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)

View File

@@ -7,6 +7,8 @@ INCLUDES = \
-I$(top_srcdir)/taglib/mpeg/id3v2 \
-I$(top_srcdir)/taglib/ogg \
-I$(top_srcdir)/taglib/ogg/vorbis \
-I$(top_srcdir)/taglib/ogg/flac \
-I$(top_srcdir)/taglib/flac \
-I$(top_srcdir)/taglib/riff \
-I$(top_srcdir)/taglib/riff/aiff \
-I$(top_srcdir)/taglib/mpeg/id3v2/frames
@@ -26,7 +28,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

Binary file not shown.

BIN
tests/data/empty_flac.oga Normal file

Binary file not shown.

BIN
tests/data/empty_vorbis.ogg Normal file

Binary file not shown.

BIN
tests/data/gnre.m4a Normal file

Binary file not shown.

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

@@ -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
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,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;
}
};

View File

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

37
tests/test_mp4item.cpp Normal file
View File

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

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);
}
};

44
tests/test_oggflac.cpp Normal file
View File

@@ -0,0 +1,44 @@
#include <cppunit/extensions/HelperMacros.h>
#include <string>
#include <stdio.h>
#include <tag.h>
#include <tstringlist.h>
#include <tbytevectorlist.h>
#include <oggfile.h>
#include <oggflacfile.h>
#include "utils.h"
using namespace std;
using namespace TagLib;
class TestOggFLAC : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(TestOggFLAC);
CPPUNIT_TEST(testFramingBit);
CPPUNIT_TEST_SUITE_END();
public:
void testFramingBit()
{
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);

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;
};