summaryrefslogtreecommitdiffstats
path: root/src/metadata
diff options
context:
space:
mode:
Diffstat (limited to 'src/metadata')
-rw-r--r--src/metadata/Makefile.am37
-rw-r--r--src/metadata/aac/Makefile.am12
-rw-r--r--src/metadata/aac/aacfiletyperesolver.cpp38
-rw-r--r--src/metadata/aac/aacfiletyperesolver.h36
-rwxr-xr-xsrc/metadata/ape/Makefile.am6
-rwxr-xr-xsrc/metadata/ape/taglib_monkeysaudiofiletyperesolver.cpp21
-rwxr-xr-xsrc/metadata/ape/taglib_monkeysaudiofiletyperesolver.h19
-rw-r--r--src/metadata/asf/Makefile.am20
-rw-r--r--src/metadata/asf/asfattribute.cpp304
-rw-r--r--src/metadata/asf/asfattribute.h176
-rw-r--r--src/metadata/asf/asffile.cpp547
-rw-r--r--src/metadata/asf/asffile.h114
-rw-r--r--src/metadata/asf/asfproperties.cpp95
-rw-r--r--src/metadata/asf/asfproperties.h69
-rw-r--r--src/metadata/asf/asftag.cpp202
-rw-r--r--src/metadata/asf/asftag.h181
-rw-r--r--src/metadata/asf/taglib_asffiletyperesolver.cpp47
-rw-r--r--src/metadata/asf/taglib_asffiletyperesolver.h42
-rw-r--r--src/metadata/audible/Makefile.am17
-rw-r--r--src/metadata/audible/audibleproperties.cpp86
-rw-r--r--src/metadata/audible/audibleproperties.h85
-rw-r--r--src/metadata/audible/audibletag.cpp163
-rw-r--r--src/metadata/audible/audibletag.h185
-rw-r--r--src/metadata/audible/taglib_audiblefile.cpp121
-rw-r--r--src/metadata/audible/taglib_audiblefile.h93
-rw-r--r--src/metadata/audible/taglib_audiblefiletyperesolver.cpp44
-rw-r--r--src/metadata/audible/taglib_audiblefiletyperesolver.h36
-rw-r--r--src/metadata/m4a/Makefile.am84
-rw-r--r--src/metadata/m4a/boxfactory.cpp150
-rw-r--r--src/metadata/m4a/boxfactory.h45
-rw-r--r--src/metadata/m4a/itunesalbbox.cpp89
-rw-r--r--src/metadata/m4a/itunesalbbox.h50
-rw-r--r--src/metadata/m4a/itunesartbox.cpp89
-rw-r--r--src/metadata/m4a/itunesartbox.h50
-rw-r--r--src/metadata/m4a/itunescmtbox.cpp89
-rw-r--r--src/metadata/m4a/itunescmtbox.h50
-rw-r--r--src/metadata/m4a/itunescvrbox.cpp89
-rw-r--r--src/metadata/m4a/itunescvrbox.h50
-rw-r--r--src/metadata/m4a/itunesdatabox.cpp63
-rw-r--r--src/metadata/m4a/itunesdatabox.h53
-rw-r--r--src/metadata/m4a/itunesdaybox.cpp89
-rw-r--r--src/metadata/m4a/itunesdaybox.h50
-rw-r--r--src/metadata/m4a/itunesdiskbox.cpp93
-rw-r--r--src/metadata/m4a/itunesdiskbox.h50
-rw-r--r--src/metadata/m4a/itunesgenbox.cpp89
-rw-r--r--src/metadata/m4a/itunesgenbox.h50
-rw-r--r--src/metadata/m4a/itunesgrpbox.cpp89
-rw-r--r--src/metadata/m4a/itunesgrpbox.h50
-rw-r--r--src/metadata/m4a/itunesnambox.cpp89
-rw-r--r--src/metadata/m4a/itunesnambox.h50
-rw-r--r--src/metadata/m4a/itunestmpobox.cpp93
-rw-r--r--src/metadata/m4a/itunestmpobox.h50
-rw-r--r--src/metadata/m4a/itunestrknbox.cpp93
-rw-r--r--src/metadata/m4a/itunestrknbox.h50
-rw-r--r--src/metadata/m4a/ituneswrtbox.cpp89
-rw-r--r--src/metadata/m4a/ituneswrtbox.h50
-rw-r--r--src/metadata/m4a/mp4audioproperties.cpp75
-rw-r--r--src/metadata/m4a/mp4audioproperties.h73
-rw-r--r--src/metadata/m4a/mp4audiosampleentry.cpp146
-rw-r--r--src/metadata/m4a/mp4audiosampleentry.h57
-rw-r--r--src/metadata/m4a/mp4file.cpp377
-rw-r--r--src/metadata/m4a/mp4file.h169
-rw-r--r--src/metadata/m4a/mp4fourcc.cpp84
-rw-r--r--src/metadata/m4a/mp4fourcc.h63
-rw-r--r--src/metadata/m4a/mp4hdlrbox.cpp75
-rw-r--r--src/metadata/m4a/mp4hdlrbox.h53
-rw-r--r--src/metadata/m4a/mp4ilstbox.cpp97
-rw-r--r--src/metadata/m4a/mp4ilstbox.h49
-rw-r--r--src/metadata/m4a/mp4isobox.cpp76
-rw-r--r--src/metadata/m4a/mp4isobox.h67
-rw-r--r--src/metadata/m4a/mp4isofullbox.cpp67
-rw-r--r--src/metadata/m4a/mp4isofullbox.h57
-rw-r--r--src/metadata/m4a/mp4itunestag.cpp197
-rw-r--r--src/metadata/m4a/mp4itunestag.h95
-rw-r--r--src/metadata/m4a/mp4mdiabox.cpp111
-rw-r--r--src/metadata/m4a/mp4mdiabox.h49
-rw-r--r--src/metadata/m4a/mp4metabox.cpp86
-rw-r--r--src/metadata/m4a/mp4metabox.h49
-rw-r--r--src/metadata/m4a/mp4minfbox.cpp104
-rw-r--r--src/metadata/m4a/mp4minfbox.h51
-rw-r--r--src/metadata/m4a/mp4moovbox.cpp86
-rw-r--r--src/metadata/m4a/mp4moovbox.h49
-rw-r--r--src/metadata/m4a/mp4mvhdbox.cpp140
-rw-r--r--src/metadata/m4a/mp4mvhdbox.h65
-rw-r--r--src/metadata/m4a/mp4propsproxy.cpp89
-rw-r--r--src/metadata/m4a/mp4propsproxy.h65
-rw-r--r--src/metadata/m4a/mp4sampleentry.cpp59
-rw-r--r--src/metadata/m4a/mp4sampleentry.h54
-rw-r--r--src/metadata/m4a/mp4skipbox.cpp50
-rw-r--r--src/metadata/m4a/mp4skipbox.h50
-rw-r--r--src/metadata/m4a/mp4stblbox.cpp105
-rw-r--r--src/metadata/m4a/mp4stblbox.h51
-rw-r--r--src/metadata/m4a/mp4stsdbox.cpp91
-rw-r--r--src/metadata/m4a/mp4stsdbox.h51
-rw-r--r--src/metadata/m4a/mp4tagsproxy.cpp168
-rw-r--r--src/metadata/m4a/mp4tagsproxy.h99
-rw-r--r--src/metadata/m4a/mp4trakbox.cpp86
-rw-r--r--src/metadata/m4a/mp4trakbox.h49
-rw-r--r--src/metadata/m4a/mp4udtabox.cpp95
-rw-r--r--src/metadata/m4a/mp4udtabox.h49
-rw-r--r--src/metadata/m4a/taglib_mp4filetyperesolver.cpp42
-rw-r--r--src/metadata/m4a/taglib_mp4filetyperesolver.h36
-rw-r--r--src/metadata/mp4/Makefile.am18
-rwxr-xr-xsrc/metadata/optimfrog/Makefile.am6
-rwxr-xr-xsrc/metadata/optimfrog/taglib_optimfrogfiletyperesolver.cpp21
-rwxr-xr-xsrc/metadata/optimfrog/taglib_optimfrogfiletyperesolver.h19
-rw-r--r--src/metadata/rmff/Makefile.am15
-rw-r--r--src/metadata/rmff/rmff.cpp998
-rw-r--r--src/metadata/rmff/rmff.h348
-rw-r--r--src/metadata/rmff/taglib_realmediafile.cpp213
-rw-r--r--src/metadata/rmff/taglib_realmediafile.h133
-rw-r--r--src/metadata/rmff/taglib_realmediafiletyperesolver.cpp53
-rw-r--r--src/metadata/rmff/taglib_realmediafiletyperesolver.h39
-rw-r--r--src/metadata/speex/Makefile.am16
-rw-r--r--src/metadata/speex/speexfile.cpp111
-rw-r--r--src/metadata/speex/speexfile.h93
-rw-r--r--src/metadata/speex/speexproperties.cpp171
-rw-r--r--src/metadata/speex/speexproperties.h83
-rw-r--r--src/metadata/speex/taglib_speexfiletyperesolver.cpp44
-rw-r--r--src/metadata/speex/taglib_speexfiletyperesolver.h36
-rwxr-xr-xsrc/metadata/tagengine.cpp419
-rwxr-xr-xsrc/metadata/tagengine.h79
-rwxr-xr-xsrc/metadata/tplugins.cpp151
-rwxr-xr-xsrc/metadata/tplugins.h27
-rw-r--r--src/metadata/trueaudio/Makefile.am16
-rw-r--r--src/metadata/trueaudio/combinedtag.h171
-rw-r--r--src/metadata/trueaudio/taglib_trueaudiofiletyperesolver.cpp44
-rw-r--r--src/metadata/trueaudio/taglib_trueaudiofiletyperesolver.h36
-rw-r--r--src/metadata/trueaudio/ttafile.cpp307
-rw-r--r--src/metadata/trueaudio/ttafile.h178
-rw-r--r--src/metadata/trueaudio/ttaproperties.cpp134
-rw-r--r--src/metadata/trueaudio/ttaproperties.h86
-rw-r--r--src/metadata/wav/Makefile.am15
-rw-r--r--src/metadata/wav/wavfile.cpp115
-rw-r--r--src/metadata/wav/wavfile.h92
-rw-r--r--src/metadata/wav/wavfiletyperesolver.cpp44
-rw-r--r--src/metadata/wav/wavfiletyperesolver.h36
-rw-r--r--src/metadata/wav/wavproperties.cpp108
-rw-r--r--src/metadata/wav/wavproperties.h85
-rw-r--r--src/metadata/wavpack/Makefile.am16
-rw-r--r--src/metadata/wavpack/combinedtag.h171
-rw-r--r--src/metadata/wavpack/taglib_wavpackfiletyperesolver.cpp44
-rw-r--r--src/metadata/wavpack/taglib_wavpackfiletyperesolver.h36
-rw-r--r--src/metadata/wavpack/wvfile.cpp311
-rw-r--r--src/metadata/wavpack/wvfile.h160
-rw-r--r--src/metadata/wavpack/wvproperties.cpp141
-rw-r--r--src/metadata/wavpack/wvproperties.h86
147 files changed, 14352 insertions, 0 deletions
diff --git a/src/metadata/Makefile.am b/src/metadata/Makefile.am
new file mode 100644
index 0000000..8e7209f
--- /dev/null
+++ b/src/metadata/Makefile.am
@@ -0,0 +1,37 @@
+if with_mp4v2
+MP4_SUBDIR = mp4
+MP4_LDADD = mp4/libtagmp4.la
+else
+MP4_SUBDIR = m4a
+MP4_LDADD = m4a/libtagm4a.la
+endif
+
+SUBDIRS = speex wavpack trueaudio asf audible rmff $(MP4_SUBDIR) aac wav ape optimfrog
+
+
+INCLUDES = $(all_includes) $(taglib_includes)
+METASOURCES = AUTO
+libmetadata_la_LDFLAGS = $(all_libraries)
+noinst_LTLIBRARIES = libmetadata.la
+
+libmetadata_la_SOURCES = \
+ tplugins.cpp \
+ tagengine.cpp
+
+noinst_HEADERS = \
+ tplugins.h \
+ tagengine.h
+
+libmetadata_la_LIBADD = \
+ speex/libtagspeex.la \
+ trueaudio/libtagtrueaudio.la \
+ wavpack/libtagwavpack.la \
+ asf/libtagasf.la \
+ wav/libtagwav.la \
+ rmff/libtagrealmedia.la \
+ $(MP4_LDADD) \
+ $(taglib_libs) \
+ aac/libtagaac.la \
+ audible/libtagaudible.la \
+ ape/libtagmonkeysaudio.la \
+ optimfrog/libtagoptimfrog.la
diff --git a/src/metadata/aac/Makefile.am b/src/metadata/aac/Makefile.am
new file mode 100644
index 0000000..b6b0f43
--- /dev/null
+++ b/src/metadata/aac/Makefile.am
@@ -0,0 +1,12 @@
+SUBDIRS =
+METASOURCES = AUTO
+INCLUDES = $(all_includes) $(taglib_includes)
+
+libtagaac_la_LDFLAGS = $(all_libraries)
+noinst_LTLIBRARIES = libtagaac.la
+
+libtagaac_la_SOURCES = \
+ aacfiletyperesolver.cpp
+
+noinst_HEADERS = \
+ aacfiletyperesolver.h
diff --git a/src/metadata/aac/aacfiletyperesolver.cpp b/src/metadata/aac/aacfiletyperesolver.cpp
new file mode 100644
index 0000000..fcc2a86
--- /dev/null
+++ b/src/metadata/aac/aacfiletyperesolver.cpp
@@ -0,0 +1,38 @@
+/***************************************************************************
+ copyright : (C) 2006 by Martin Aumueller
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "aacfiletyperesolver.h"
+#include <taglib/mpegfile.h>
+
+#include <string.h>
+
+TagLib::File *AACFileTypeResolver::createFile(const char *fileName,
+ bool readProperties,
+ TagLib::AudioProperties::ReadStyle propertiesStyle) const
+{
+ const char *ext = strrchr(fileName, '.');
+ if(ext && !strcasecmp(ext, ".aac"))
+ {
+ return new TagLib::MPEG::File(fileName, readProperties, propertiesStyle);
+ }
+
+ return 0;
+}
diff --git a/src/metadata/aac/aacfiletyperesolver.h b/src/metadata/aac/aacfiletyperesolver.h
new file mode 100644
index 0000000..6c33b71
--- /dev/null
+++ b/src/metadata/aac/aacfiletyperesolver.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ copyright : (C) 2006 by Martin Aumueller
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef TAGLIB_AACFILETYPERESOLVER_H
+#define TAGLIB_AACFILETYPERESOLVER_H
+
+#include <taglib/tfile.h>
+#include <taglib/fileref.h>
+
+
+class AACFileTypeResolver : public TagLib::FileRef::FileTypeResolver
+{
+ TagLib::File *createFile(const char *fileName,
+ bool readAudioProperties,
+ TagLib::AudioProperties::ReadStyle audioPropertiesStyle) const;
+};
+
+#endif
diff --git a/src/metadata/ape/Makefile.am b/src/metadata/ape/Makefile.am
new file mode 100755
index 0000000..156cf91
--- /dev/null
+++ b/src/metadata/ape/Makefile.am
@@ -0,0 +1,6 @@
+INCLUDES = $(all_includes) $(taglib_includes)
+METASOURCES = AUTO
+libtagmonkeysaudio_la_LDFLAGS = $(all_libraries)
+noinst_LTLIBRARIES = libtagmonkeysaudio.la
+noinst_HEADERS = taglib_monkeysaudiofiletyperesolver.h
+libtagmonkeysaudio_la_SOURCES = taglib_monkeysaudiofiletyperesolver.cpp
diff --git a/src/metadata/ape/taglib_monkeysaudiofiletyperesolver.cpp b/src/metadata/ape/taglib_monkeysaudiofiletyperesolver.cpp
new file mode 100755
index 0000000..fea0344
--- /dev/null
+++ b/src/metadata/ape/taglib_monkeysaudiofiletyperesolver.cpp
@@ -0,0 +1,21 @@
+// (c) 2006 Martin Aumueller <[email protected]>
+// modified 2006 Daniel Faust <[email protected]>
+// See COPYING file for licensing information
+
+#include "taglib_monkeysaudiofiletyperesolver.h"
+#include <taglib/mpcfile.h>
+
+#include <string.h>
+
+TagLib::File *MonkeysAudioFileTypeResolver::createFile(const char *fileName,
+ bool readProperties,
+ TagLib::AudioProperties::ReadStyle propertiesStyle) const
+{
+ const char *ext = strrchr(fileName, '.');
+ if(ext && (!strcasecmp(ext, ".ape") || !strcasecmp(ext, ".mac")))
+ {
+ return new TagLib::MPC::File(fileName, readProperties, propertiesStyle);
+ }
+
+ return 0;
+}
diff --git a/src/metadata/ape/taglib_monkeysaudiofiletyperesolver.h b/src/metadata/ape/taglib_monkeysaudiofiletyperesolver.h
new file mode 100755
index 0000000..4af4a7b
--- /dev/null
+++ b/src/metadata/ape/taglib_monkeysaudiofiletyperesolver.h
@@ -0,0 +1,19 @@
+// (c) 2006 Martin Aumueller <[email protected]>
+// modified 2006 Daniel Faust <[email protected]>
+// See COPYING file for licensing information
+
+#ifndef TAGLIB_MONKEYSAUDIOFILETYPERESOLVER_H
+#define TAGLIB_MONKEYSAUDIOFILETYPERESOLVER_H
+
+#include <taglib/tfile.h>
+#include <taglib/fileref.h>
+
+
+class MonkeysAudioFileTypeResolver : public TagLib::FileRef::FileTypeResolver
+{
+ TagLib::File *createFile(const char *fileName,
+ bool readAudioProperties,
+ TagLib::AudioProperties::ReadStyle audioPropertiesStyle) const;
+};
+
+#endif
diff --git a/src/metadata/asf/Makefile.am b/src/metadata/asf/Makefile.am
new file mode 100644
index 0000000..63fa0e1
--- /dev/null
+++ b/src/metadata/asf/Makefile.am
@@ -0,0 +1,20 @@
+SUBDIRS =
+
+INCLUDES = $(all_includes) $(taglib_includes)
+METASOURCES = AUTO
+libtagasf_la_LDFLAGS = $(all_libraries)
+noinst_LTLIBRARIES = libtagasf.la
+
+libtagasf_la_SOURCES = \
+ asfattribute.cpp \
+ asfproperties.cpp \
+ asftag.cpp \
+ asffile.cpp \
+ taglib_asffiletyperesolver.cpp
+
+noinst_HEADERS = \
+ asfattribute.h \
+ asfproperties.h \
+ asftag.h \
+ asffile.h \
+ taglib_asffiletyperesolver.h
diff --git a/src/metadata/asf/asfattribute.cpp b/src/metadata/asf/asfattribute.cpp
new file mode 100644
index 0000000..bfe81c5
--- /dev/null
+++ b/src/metadata/asf/asfattribute.cpp
@@ -0,0 +1,304 @@
+/**************************************************************************
+ copyright : (C) 2005-2007 by Lukáš Lalinský
+ **************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 *
+ * USA *
+ ***************************************************************************/
+
+#include <taglib.h>
+#include "asfattribute.h"
+#include "asffile.h"
+
+using namespace TagLib;
+
+class ASF::Attribute::AttributePrivate : public RefCounter
+{
+public:
+ AttributePrivate()
+ : stream(0),
+ language(0) {}
+ AttributeTypes type;
+ String stringValue;
+ ByteVector byteVectorValue;
+ union {
+ unsigned int intValue;
+ unsigned short shortValue;
+ unsigned long long longLongValue;
+ bool boolValue;
+ };
+ int stream;
+ int language;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+ASF::Attribute::Attribute()
+{
+ d = new AttributePrivate;
+ d->type = UnicodeType;
+}
+
+ASF::Attribute::Attribute(const ASF::Attribute &other)
+ : d(other.d)
+{
+ d->ref();
+}
+
+ASF::Attribute &
+ASF::Attribute::operator=(const ASF::Attribute &other)
+{
+ if(d->deref())
+ delete d;
+ d = other.d;
+ d->ref();
+ return *this;
+}
+
+ASF::Attribute::~Attribute()
+{
+ if(d->deref())
+ delete d;
+}
+
+ASF::Attribute::Attribute(const String &value)
+{
+ d = new AttributePrivate;
+ d->type = UnicodeType;
+ d->stringValue = value;
+}
+
+ASF::Attribute::Attribute(const ByteVector &value)
+{
+ d = new AttributePrivate;
+ d->type = BytesType;
+ d->byteVectorValue = value;
+}
+
+ASF::Attribute::Attribute(unsigned int value)
+{
+ d = new AttributePrivate;
+ d->type = DWordType;
+ d->intValue = value;
+}
+
+ASF::Attribute::Attribute(unsigned long long value)
+{
+ d = new AttributePrivate;
+ d->type = QWordType;
+ d->longLongValue = value;
+}
+
+ASF::Attribute::Attribute(unsigned short value)
+{
+ d = new AttributePrivate;
+ d->type = WordType;
+ d->shortValue = value;
+}
+
+ASF::Attribute::Attribute(bool value)
+{
+ d = new AttributePrivate;
+ d->type = BoolType;
+ d->boolValue = value;
+}
+
+ASF::Attribute::AttributeTypes
+ASF::Attribute::type() const
+{
+ return d->type;
+}
+
+String
+ASF::Attribute::toString() const
+{
+ return d->stringValue;
+}
+
+ByteVector
+ASF::Attribute::toByteVector() const
+{
+ return d->byteVectorValue;
+}
+
+unsigned short
+ASF::Attribute::toBool() const
+{
+ return d->shortValue;
+}
+
+unsigned short
+ASF::Attribute::toUShort() const
+{
+ return d->shortValue;
+}
+
+unsigned int
+ASF::Attribute::toUInt() const
+{
+ return d->intValue;
+}
+
+unsigned long long
+ASF::Attribute::toULongLong() const
+{
+ return d->longLongValue;
+}
+
+String
+ASF::Attribute::parse(ASF::File &f, int kind)
+{
+ int size, nameLength;
+ String name;
+
+ // extended content descriptor
+ if(kind == 0) {
+ nameLength = f.readWORD();
+ name = f.readString(nameLength);
+ d->type = ASF::Attribute::AttributeTypes(f.readWORD());
+ size = f.readWORD();
+ }
+ // metadata & metadata library
+ else {
+ int temp = f.readWORD();
+ // metadata library
+ if(kind == 2) {
+ d->language = temp;
+ }
+ d->stream = f.readWORD();
+ nameLength = f.readWORD();
+ d->type = ASF::Attribute::AttributeTypes(f.readWORD());
+ size = f.readDWORD();
+ name = f.readString(nameLength);
+ }
+
+ switch(d->type) {
+ case WordType:
+ d->shortValue = f.readWORD();
+ break;
+
+ case BoolType:
+ if(kind == 0) {
+ d->boolValue = f.readDWORD() == 1;
+ }
+ else {
+ d->boolValue = f.readWORD() == 1;
+ }
+ break;
+
+ case DWordType:
+ d->intValue = f.readDWORD();
+ break;
+
+ case QWordType:
+ d->longLongValue = f.readQWORD();
+ break;
+
+ case UnicodeType:
+ d->stringValue = f.readString(size);
+ break;
+
+ case BytesType:
+ case GuidType:
+ d->byteVectorValue = f.readBlock(size);
+ break;
+ }
+
+ return name;
+}
+
+ByteVector
+ASF::Attribute::render(const String &name, int kind) const
+{
+ ByteVector data;
+
+ switch (d->type) {
+ case WordType:
+ data.append(ByteVector::fromShort(d->shortValue, false));
+ break;
+
+ case BoolType:
+ if(kind == 0) {
+ data.append(ByteVector::fromUInt(d->boolValue ? 1 : 0, false));
+ }
+ else {
+ data.append(ByteVector::fromShort(d->boolValue ? 1 : 0, false));
+ }
+ break;
+
+ case DWordType:
+ data.append(ByteVector::fromUInt(d->intValue, false));
+ break;
+
+ case QWordType:
+ data.append(ByteVector::fromLongLong(d->longLongValue, false));
+ break;
+
+ case UnicodeType:
+ data.append(File::renderString(d->stringValue));
+ break;
+
+ case BytesType:
+ case GuidType:
+ data.append(d->byteVectorValue);
+ break;
+ }
+
+ if(kind == 0) {
+ data = File::renderString(name, true) +
+ ByteVector::fromShort((int)d->type, false) +
+ ByteVector::fromShort(data.size(), false) +
+ data;
+ }
+ else {
+ ByteVector nameData = File::renderString(name);
+ data = ByteVector::fromShort(kind == 2 ? d->language : 0, false) +
+ ByteVector::fromShort(d->stream, false) +
+ ByteVector::fromShort(nameData.size(), false) +
+ ByteVector::fromShort((int)d->type, false) +
+ ByteVector::fromUInt(data.size(), false) +
+ nameData +
+ data;
+ }
+
+ return data;
+}
+
+int
+ASF::Attribute::language() const
+{
+ return d->language;
+}
+
+void
+ASF::Attribute::setLanguage(int value)
+{
+ d->language = value;
+}
+
+int
+ASF::Attribute::stream() const
+{
+ return d->stream;
+}
+
+void
+ASF::Attribute::setStream(int value)
+{
+ d->stream = value;
+}
diff --git a/src/metadata/asf/asfattribute.h b/src/metadata/asf/asfattribute.h
new file mode 100644
index 0000000..9a8e3c9
--- /dev/null
+++ b/src/metadata/asf/asfattribute.h
@@ -0,0 +1,176 @@
+/**************************************************************************
+ copyright : (C) 2005-2007 by Lukáš Lalinský
+ **************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 *
+ * USA *
+ ***************************************************************************/
+
+#ifndef TAGLIB_ASFATTRIBUTE_H
+#define TAGLIB_ASFATTRIBUTE_H
+
+#include <tstring.h>
+#include <tbytevector.h>
+
+namespace TagLib
+{
+
+ namespace ASF
+ {
+
+ class File;
+
+ class Attribute
+ {
+ public:
+
+ /*!
+ * Enum of types an Attribute can have.
+ */
+ enum AttributeTypes {
+ UnicodeType = 0,
+ BytesType = 1,
+ BoolType = 2,
+ DWordType = 3,
+ QWordType = 4,
+ WordType = 5,
+ GuidType = 6
+ };
+
+ /*!
+ * Constructs an empty attribute.
+ */
+ Attribute();
+
+ /*!
+ * Constructs an attribute with \a key and a UnicodeType \a value.
+ */
+ Attribute(const String &value);
+
+ /*!
+ * Constructs an attribute with \a key and a BytesType \a value.
+ */
+ Attribute(const ByteVector &value);
+
+ /*!
+ * Constructs an attribute with \a key and a DWordType \a value.
+ */
+ Attribute(unsigned int value);
+
+ /*!
+ * Constructs an attribute with \a key and a QWordType \a value.
+ */
+ Attribute(unsigned long long value);
+
+ /*!
+ * Constructs an attribute with \a key and a WordType \a value.
+ */
+ Attribute(unsigned short value);
+
+ /*!
+ * Constructs an attribute with \a key and a BoolType \a value.
+ */
+ Attribute(bool value);
+
+ /*!
+ * Construct an attribute as a copy of \a other.
+ */
+ Attribute(const Attribute &item);
+
+ /*!
+ * Copies the contents of \a other into this item.
+ */
+ ASF::Attribute &operator=(const Attribute &other);
+
+ /*!
+ * Destroys the attribute.
+ */
+ virtual ~Attribute();
+
+ /*!
+ * Returns type of the value.
+ */
+ AttributeTypes type() const;
+
+ /*!
+ * Returns the BoolType \a value.
+ */
+ unsigned short toBool() const;
+
+ /*!
+ * Returns the WordType \a value.
+ */
+ unsigned short toUShort() const;
+
+ /*!
+ * Returns the DWordType \a value.
+ */
+ unsigned int toUInt() const;
+
+ /*!
+ * Returns the QWordType \a value.
+ */
+ unsigned long long toULongLong() const;
+
+ /*!
+ * Returns the UnicodeType \a value.
+ */
+ String toString() const;
+
+ /*!
+ * Returns the BytesType \a value.
+ */
+ ByteVector toByteVector() const;
+
+ /*!
+ * Returns the language number, or 0 is no stream number was set.
+ */
+ int language() const;
+
+ /*!
+ * Sets the language number.
+ */
+ void setLanguage(int value);
+
+ /*!
+ * Returns the stream number, or 0 is no stream number was set.
+ */
+ int stream() const;
+
+ /*!
+ * Sets the stream number.
+ */
+ void setStream(int value);
+
+#ifndef DO_NOT_DOCUMENT
+ /* THIS IS PRIVATE, DON'T TOUCH IT! */
+ String parse(ASF::File &file, int kind = 0);
+#endif
+
+ private:
+ friend class File;
+
+ ByteVector render(const String &name, int kind = 0) const;
+
+ class AttributePrivate;
+ AttributePrivate *d;
+ };
+
+ }
+
+}
+
+#endif
diff --git a/src/metadata/asf/asffile.cpp b/src/metadata/asf/asffile.cpp
new file mode 100644
index 0000000..55a12cc
--- /dev/null
+++ b/src/metadata/asf/asffile.cpp
@@ -0,0 +1,547 @@
+/**************************************************************************
+ copyright : (C) 2005-2007 by Lukáš Lalinský
+ **************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 *
+ * USA *
+ ***************************************************************************/
+
+#include <tbytevectorlist.h>
+#include <tstring.h>
+#include "asffile.h"
+#include "asftag.h"
+#include "asfproperties.h"
+
+using namespace TagLib;
+
+class ASF::File::FilePrivate
+{
+public:
+ FilePrivate():
+ size(0),
+ tag(0),
+ properties(0),
+ contentDescriptionObject(0),
+ extendedContentDescriptionObject(0),
+ headerExtensionObject(0),
+ metadataObject(0),
+ metadataLibraryObject(0) {}
+ unsigned long long size;
+ ASF::Tag *tag;
+ ASF::Properties *properties;
+ List<ASF::File::BaseObject *> objects;
+ ASF::File::ContentDescriptionObject *contentDescriptionObject;
+ ASF::File::ExtendedContentDescriptionObject *extendedContentDescriptionObject;
+ ASF::File::HeaderExtensionObject *headerExtensionObject;
+ ASF::File::MetadataObject *metadataObject;
+ ASF::File::MetadataLibraryObject *metadataLibraryObject;
+};
+
+static ByteVector headerGuid("\x30\x26\xB2\x75\x8E\x66\xCF\x11\xA6\xD9\x00\xAA\x00\x62\xCE\x6C", 16);
+static ByteVector filePropertiesGuid("\xA1\xDC\xAB\x8C\x47\xA9\xCF\x11\x8E\xE4\x00\xC0\x0C\x20\x53\x65", 16);
+static ByteVector streamPropertiesGuid("\x91\x07\xDC\xB7\xB7\xA9\xCF\x11\x8E\xE6\x00\xC0\x0C\x20\x53\x65", 16);
+static ByteVector contentDescriptionGuid("\x33\x26\xB2\x75\x8E\x66\xCF\x11\xA6\xD9\x00\xAA\x00\x62\xCE\x6C", 16);
+static ByteVector extendedContentDescriptionGuid("\x40\xA4\xD0\xD2\x07\xE3\xD2\x11\x97\xF0\x00\xA0\xC9\x5E\xA8\x50", 16);
+static ByteVector headerExtensionGuid("\xb5\x03\xbf_.\xa9\xcf\x11\x8e\xe3\x00\xc0\x0c Se", 16);
+static ByteVector metadataGuid("\xEA\xCB\xF8\xC5\xAF[wH\204g\xAA\214D\xFAL\xCA", 16);
+static ByteVector metadataLibraryGuid("\224\034#D\230\224\321I\241A\x1d\x13NEpT", 16);
+
+class ASF::File::BaseObject
+{
+public:
+ ByteVector data;
+ virtual ~BaseObject() {}
+ virtual ByteVector guid() = 0;
+ virtual void parse(ASF::File *file, unsigned int size);
+ virtual ByteVector render(ASF::File *file);
+};
+
+class ASF::File::UnknownObject : public ASF::File::BaseObject
+{
+ ByteVector myGuid;
+public:
+ UnknownObject(const ByteVector &guid);
+ ByteVector guid();
+};
+
+class ASF::File::FilePropertiesObject : public ASF::File::BaseObject
+{
+public:
+ ByteVector guid();
+ void parse(ASF::File *file, uint size);
+};
+
+class ASF::File::StreamPropertiesObject : public ASF::File::BaseObject
+{
+public:
+ ByteVector guid();
+ void parse(ASF::File *file, uint size);
+};
+
+class ASF::File::ContentDescriptionObject : public ASF::File::BaseObject
+{
+public:
+ ByteVector guid();
+ void parse(ASF::File *file, uint size);
+ ByteVector render(ASF::File *file);
+};
+
+class ASF::File::ExtendedContentDescriptionObject : public ASF::File::BaseObject
+{
+public:
+ ByteVectorList attributeData;
+ ByteVector guid();
+ void parse(ASF::File *file, uint size);
+ ByteVector render(ASF::File *file);
+};
+
+class ASF::File::MetadataObject : public ASF::File::BaseObject
+{
+public:
+ ByteVectorList attributeData;
+ ByteVector guid();
+ void parse(ASF::File *file, uint size);
+ ByteVector render(ASF::File *file);
+};
+
+class ASF::File::MetadataLibraryObject : public ASF::File::BaseObject
+{
+public:
+ ByteVectorList attributeData;
+ ByteVector guid();
+ void parse(ASF::File *file, uint size);
+ ByteVector render(ASF::File *file);
+};
+
+class ASF::File::HeaderExtensionObject : public ASF::File::BaseObject
+{
+public:
+ List<ASF::File::BaseObject *> objects;
+ ByteVector guid();
+ void parse(ASF::File *file, uint size);
+ ByteVector render(ASF::File *file);
+};
+
+void
+ASF::File::BaseObject::parse(ASF::File *file, unsigned int size)
+{
+ data = file->readBlock(size - 24);
+}
+
+ByteVector
+ASF::File::BaseObject::render(ASF::File * /*file*/)
+{
+ return guid() + ByteVector::fromLongLong(data.size() + 24, false) + data;
+}
+
+ASF::File::UnknownObject::UnknownObject(const ByteVector &guid) : myGuid(guid)
+{
+}
+
+ByteVector
+ASF::File::UnknownObject::guid()
+{
+ return myGuid;
+}
+
+ByteVector
+ASF::File::FilePropertiesObject::guid()
+{
+ return filePropertiesGuid;
+}
+
+void
+ASF::File::FilePropertiesObject::parse(ASF::File *file, uint size)
+{
+ BaseObject::parse(file, size);
+ file->d->properties->setLength((int)(data.mid(40, 8).toLongLong(false) / 10000000L - data.mid(56, 8).toLongLong(false) / 1000L));
+}
+
+ByteVector
+ASF::File::StreamPropertiesObject::guid()
+{
+ return streamPropertiesGuid;
+}
+
+void
+ASF::File::StreamPropertiesObject::parse(ASF::File *file, uint size)
+{
+ BaseObject::parse(file, size);
+ file->d->properties->setChannels(data.mid(56, 2).toShort(false));
+ file->d->properties->setSampleRate(data.mid(58, 4).toUInt(false));
+ file->d->properties->setBitrate(data.mid(62, 4).toUInt(false) * 8 / 1000);
+}
+
+ByteVector
+ASF::File::ContentDescriptionObject::guid()
+{
+ return contentDescriptionGuid;
+}
+
+void
+ASF::File::ContentDescriptionObject::parse(ASF::File *file, uint /*size*/)
+{
+ file->d->contentDescriptionObject = this;
+ int titleLength = file->readWORD();
+ int artistLength = file->readWORD();
+ int copyrightLength = file->readWORD();
+ int commentLength = file->readWORD();
+ int ratingLength = file->readWORD();
+ file->d->tag->setTitle(file->readString(titleLength));
+ file->d->tag->setArtist(file->readString(artistLength));
+ file->d->tag->setCopyright(file->readString(copyrightLength));
+ file->d->tag->setComment(file->readString(commentLength));
+ file->d->tag->setRating(file->readString(ratingLength));
+}
+
+ByteVector
+ASF::File::ContentDescriptionObject::render(ASF::File *file)
+{
+ ByteVector v1 = file->renderString(file->d->tag->title());
+ ByteVector v2 = file->renderString(file->d->tag->artist());
+ ByteVector v3 = file->renderString(file->d->tag->copyright());
+ ByteVector v4 = file->renderString(file->d->tag->comment());
+ ByteVector v5 = file->renderString(file->d->tag->rating());
+ data.clear();
+ data.append(ByteVector::fromShort(v1.size(), false));
+ data.append(ByteVector::fromShort(v2.size(), false));
+ data.append(ByteVector::fromShort(v3.size(), false));
+ data.append(ByteVector::fromShort(v4.size(), false));
+ data.append(ByteVector::fromShort(v5.size(), false));
+ data.append(v1);
+ data.append(v2);
+ data.append(v3);
+ data.append(v4);
+ data.append(v5);
+ return BaseObject::render(file);
+}
+
+ByteVector
+ASF::File::ExtendedContentDescriptionObject::guid()
+{
+ return extendedContentDescriptionGuid;
+}
+
+void
+ASF::File::ExtendedContentDescriptionObject::parse(ASF::File *file, uint /*size*/)
+{
+ file->d->extendedContentDescriptionObject = this;
+ int count = file->readWORD();
+ while(count--) {
+ ASF::Attribute attribute;
+ String name = attribute.parse(*file);
+ file->d->tag->addAttribute(name, attribute);
+ }
+}
+
+ByteVector
+ASF::File::ExtendedContentDescriptionObject::render(ASF::File *file)
+{
+ data.clear();
+ data.append(ByteVector::fromShort(attributeData.size(), false));
+ data.append(attributeData.toByteVector(ByteVector::null));
+ return BaseObject::render(file);
+}
+
+ByteVector
+ASF::File::MetadataObject::guid()
+{
+ return metadataGuid;
+}
+
+void
+ASF::File::MetadataObject::parse(ASF::File *file, uint /*size*/)
+{
+ file->d->metadataObject = this;
+ int count = file->readWORD();
+ while(count--) {
+ ASF::Attribute attribute;
+ String name = attribute.parse(*file, 1);
+ file->d->tag->addAttribute(name, attribute);
+ }
+}
+
+ByteVector
+ASF::File::MetadataObject::render(ASF::File *file)
+{
+ data.clear();
+ data.append(ByteVector::fromShort(attributeData.size(), false));
+ data.append(attributeData.toByteVector(ByteVector::null));
+ return BaseObject::render(file);
+}
+
+ByteVector
+ASF::File::MetadataLibraryObject::guid()
+{
+ return metadataLibraryGuid;
+}
+
+void
+ASF::File::MetadataLibraryObject::parse(ASF::File *file, uint /*size*/)
+{
+ file->d->metadataLibraryObject = this;
+ int count = file->readWORD();
+ while(count--) {
+ ASF::Attribute attribute;
+ String name = attribute.parse(*file, 2);
+ file->d->tag->addAttribute(name, attribute);
+ }
+}
+
+ByteVector
+ASF::File::MetadataLibraryObject::render(ASF::File *file)
+{
+ data.clear();
+ data.append(ByteVector::fromShort(attributeData.size(), false));
+ data.append(attributeData.toByteVector(ByteVector::null));
+ return BaseObject::render(file);
+}
+
+ByteVector
+ASF::File::HeaderExtensionObject::guid()
+{
+ return headerExtensionGuid;
+}
+
+void
+ASF::File::HeaderExtensionObject::parse(ASF::File *file, uint /*size*/)
+{
+ file->d->headerExtensionObject = this;
+ file->seek(18, File::Current);
+ long long dataSize = file->readDWORD();
+ long long dataPos = 0;
+ while(dataPos < dataSize) {
+ ByteVector guid = file->readBlock(16);
+ long long size = file->readQWORD();
+ BaseObject *obj;
+ if(guid == metadataGuid) {
+ obj = new MetadataObject();
+ }
+ else if(guid == metadataLibraryGuid) {
+ obj = new MetadataLibraryObject();
+ }
+ else {
+ obj = new UnknownObject(guid);
+ }
+ obj->parse(file, size);
+ objects.append(obj);
+ dataPos += size;
+ }
+}
+
+ByteVector
+ASF::File::HeaderExtensionObject::render(ASF::File *file)
+{
+ data.clear();
+ for(unsigned int i = 0; i < objects.size(); i++) {
+ data.append(objects[i]->render(file));
+ }
+ data = ByteVector("\x11\xD2\xD3\xAB\xBA\xA9\xcf\x11\x8E\xE6\x00\xC0\x0C\x20\x53\x65\x06\x00", 18) + ByteVector::fromUInt(data.size(), false) + data;
+ return BaseObject::render(file);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+ASF::File::File(const char *file, bool readProperties, Properties::ReadStyle propertiesStyle)
+ : TagLib::File(file)
+{
+ d = new FilePrivate;
+ read(readProperties, propertiesStyle);
+}
+
+ASF::File::~File()
+{
+ for(unsigned int i = 0; i < d->objects.size(); i++) {
+ delete d->objects[i];
+ }
+ if(d->tag) {
+ delete d->tag;
+ }
+ if(d->properties) {
+ delete d->properties;
+ }
+ delete d;
+}
+
+ASF::Tag *ASF::File::tag() const
+{
+ return d->tag;
+}
+
+ASF::Properties *ASF::File::audioProperties() const
+{
+ return d->properties;
+}
+
+void ASF::File::read(bool /*readProperties*/, Properties::ReadStyle /*propertiesStyle*/)
+{
+ if(!isValid())
+ return;
+
+ ByteVector guid = readBlock(16);
+ if(guid != headerGuid) {
+ return;
+ }
+
+ d->tag = new ASF::Tag();
+ d->properties = new ASF::Properties();
+
+ d->size = readQWORD();
+ int numObjects = readDWORD();
+ seek(2, Current);
+
+ for(int i = 0; i < numObjects; i++) {
+ ByteVector guid = readBlock(16);
+ long size = (long)readQWORD();
+ BaseObject *obj;
+ if(guid == filePropertiesGuid) {
+ obj = new FilePropertiesObject();
+ }
+ else if(guid == streamPropertiesGuid) {
+ obj = new StreamPropertiesObject();
+ }
+ else if(guid == contentDescriptionGuid) {
+ obj = new ContentDescriptionObject();
+ }
+ else if(guid == extendedContentDescriptionGuid) {
+ obj = new ExtendedContentDescriptionObject();
+ }
+ else if(guid == headerExtensionGuid) {
+ obj = new HeaderExtensionObject();
+ }
+ else {
+ obj = new UnknownObject(guid);
+ }
+ obj->parse(this, size);
+ d->objects.append(obj);
+ }
+}
+
+bool ASF::File::save()
+{
+ if(readOnly()) {
+ return false;
+ }
+
+ if(!d->contentDescriptionObject) {
+ d->contentDescriptionObject = new ContentDescriptionObject();
+ d->objects.append(d->contentDescriptionObject);
+ }
+ if(!d->extendedContentDescriptionObject) {
+ d->extendedContentDescriptionObject = new ExtendedContentDescriptionObject();
+ d->objects.append(d->extendedContentDescriptionObject);
+ }
+ if(!d->headerExtensionObject) {
+ d->headerExtensionObject = new HeaderExtensionObject();
+ d->objects.append(d->headerExtensionObject);
+ }
+ if(!d->metadataObject) {
+ d->metadataObject = new MetadataObject();
+ d->headerExtensionObject->objects.append(d->metadataObject);
+ }
+ if(!d->metadataLibraryObject) {
+ d->metadataLibraryObject = new MetadataLibraryObject();
+ d->headerExtensionObject->objects.append(d->metadataLibraryObject);
+ }
+
+ ASF::AttributeListMap::ConstIterator it = d->tag->attributeListMap().begin();
+ for(; it != d->tag->attributeListMap().end(); it++) {
+ const String &name = it->first;
+ const AttributeList &attributes = it->second;
+ bool inExtendedContentDescriptionObject = false;
+ 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) {
+ d->extendedContentDescriptionObject->attributeData.append(attribute.render(name));
+ inExtendedContentDescriptionObject = true;
+ }
+ else if(!inMetadataObject && attribute.language() == 0 && attribute.stream() != 0) {
+ d->metadataObject->attributeData.append(attribute.render(name, 1));
+ inMetadataObject = true;
+ }
+ else {
+ d->metadataLibraryObject->attributeData.append(attribute.render(name, 2));
+ }
+ }
+ }
+
+ ByteVector data;
+ for(unsigned int i = 0; i < d->objects.size(); i++) {
+ data.append(d->objects[i]->render(this));
+ }
+ data = headerGuid + ByteVector::fromLongLong(data.size() + 30, false) + ByteVector::fromUInt(d->objects.size(), false) + ByteVector("\x01\x02", 2) + data;
+ insert(data, 0, d->size);
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// protected members
+////////////////////////////////////////////////////////////////////////////////
+
+int ASF::File::readBYTE()
+{
+ ByteVector v = readBlock(1);
+ return v[0];
+}
+
+int ASF::File::readWORD()
+{
+ ByteVector v = readBlock(2);
+ return v.toShort(false);
+}
+
+unsigned int ASF::File::readDWORD()
+{
+ ByteVector v = readBlock(4);
+ return v.toUInt(false);
+}
+
+long long ASF::File::readQWORD()
+{
+ ByteVector v = readBlock(8);
+ return v.toLongLong(false);
+}
+
+String
+ASF::File::readString(int length)
+{
+ ByteVector data = readBlock(length);
+ unsigned int size = data.size();
+ while (size >= 2) {
+ if(data[size - 1] != '\0' || data[size - 2] != '\0') {
+ break;
+ }
+ size -= 2;
+ }
+ if(size != data.size()) {
+ data.resize(size);
+ }
+ return String(data, String::UTF16LE);
+}
+
+ByteVector
+ASF::File::renderString(const String &str, bool includeLength)
+{
+ ByteVector data = str.data(String::UTF16LE) + ByteVector::fromShort(0, false);
+ if(includeLength) {
+ data = ByteVector::fromShort(data.size(), false) + data;
+ }
+ return data;
+}
diff --git a/src/metadata/asf/asffile.h b/src/metadata/asf/asffile.h
new file mode 100644
index 0000000..db97331
--- /dev/null
+++ b/src/metadata/asf/asffile.h
@@ -0,0 +1,114 @@
+/**************************************************************************
+ copyright : (C) 2005-2007 by Lukáš Lalinský
+ **************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 *
+ * USA *
+ ***************************************************************************/
+
+#ifndef TAGLIB_ASFFILE_H
+#define TAGLIB_ASFFILE_H
+
+#include <tag.h>
+#include <tfile.h>
+#include "asfproperties.h"
+#include "asftag.h"
+
+namespace TagLib {
+
+ //! An implementation of ASF (WMA) metadata
+ namespace ASF {
+
+ /*!
+ * This implements and provides an interface for ASF files to the
+ * TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing
+ * the abstract TagLib::File API as well as providing some additional
+ * information specific to ASF files.
+ */
+ class File : public TagLib::File
+ {
+ public:
+
+ /*!
+ * Contructs an ASF 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.
+ *
+ * \note In the current implementation, both \a readProperties and
+ * \a propertiesStyle are ignored.
+ */
+ File(const char *file, bool readProperties = true, Properties::ReadStyle propertiesStyle = Properties::Average);
+
+ /*!
+ * Destroys this instance of the File.
+ */
+ virtual ~File();
+
+ /*!
+ * Returns a pointer to the ASF tag of the file.
+ *
+ * ASF::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
+ * deleted by the user. It will be deleted when the file (object) is
+ * destroyed.
+ */
+ virtual Tag *tag() const;
+
+ /*!
+ * Returns the ASF audio properties for this file.
+ */
+ virtual Properties *audioProperties() const;
+
+ /*!
+ * Save the file.
+ *
+ * This returns true if the save was successful.
+ */
+ virtual bool save();
+
+ private:
+
+ int readBYTE();
+ int readWORD();
+ unsigned int readDWORD();
+ long long readQWORD();
+ static ByteVector renderString(const String &str, bool includeLength = false);
+ String readString(int len);
+ void read(bool readProperties, Properties::ReadStyle propertiesStyle);
+
+ friend class Attribute;
+
+ class BaseObject;
+ class UnknownObject;
+ class FilePropertiesObject;
+ class StreamPropertiesObject;
+ class ContentDescriptionObject;
+ class ExtendedContentDescriptionObject;
+ class HeaderExtensionObject;
+ class MetadataObject;
+ class MetadataLibraryObject;
+
+ class FilePrivate;
+ FilePrivate *d;
+ };
+
+ }
+
+}
+
+#endif
diff --git a/src/metadata/asf/asfproperties.cpp b/src/metadata/asf/asfproperties.cpp
new file mode 100644
index 0000000..ca1d983
--- /dev/null
+++ b/src/metadata/asf/asfproperties.cpp
@@ -0,0 +1,95 @@
+/**************************************************************************
+ copyright : (C) 2005-2007 by Lukáš Lalinský
+ **************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 *
+ * USA *
+ ***************************************************************************/
+
+#include <tstring.h>
+#include "asfproperties.h"
+
+using namespace TagLib;
+
+class ASF::Properties::PropertiesPrivate
+{
+public:
+ PropertiesPrivate(): length(0), bitrate(0), sampleRate(0), channels(0) {}
+ int length;
+ int bitrate;
+ int sampleRate;
+ int channels;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+ASF::Properties::Properties() : AudioProperties(AudioProperties::Average)
+{
+ d = new PropertiesPrivate;
+}
+
+ASF::Properties::~Properties()
+{
+ if(d)
+ delete d;
+}
+
+int ASF::Properties::length() const
+{
+ return d->length;
+}
+
+int ASF::Properties::bitrate() const
+{
+ return d->bitrate;
+}
+
+int ASF::Properties::sampleRate() const
+{
+ return d->sampleRate;
+}
+
+int ASF::Properties::channels() const
+{
+ return d->channels;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// private members
+////////////////////////////////////////////////////////////////////////////////
+
+void ASF::Properties::setLength(int length)
+{
+ d->length = length;
+}
+
+void ASF::Properties::setBitrate(int length)
+{
+ d->bitrate = length;
+}
+
+void ASF::Properties::setSampleRate(int length)
+{
+ d->sampleRate = length;
+}
+
+void ASF::Properties::setChannels(int length)
+{
+ d->channels = length;
+}
+
diff --git a/src/metadata/asf/asfproperties.h b/src/metadata/asf/asfproperties.h
new file mode 100644
index 0000000..150db8a
--- /dev/null
+++ b/src/metadata/asf/asfproperties.h
@@ -0,0 +1,69 @@
+/**************************************************************************
+ copyright : (C) 2005-2007 by Lukáš Lalinský
+ **************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 *
+ * USA *
+ ***************************************************************************/
+
+#ifndef TAGLIB_ASFPROPERTIES_H
+#define TAGLIB_ASFPROPERTIES_H
+
+#include <audioproperties.h>
+#include <tstring.h>
+
+namespace TagLib {
+
+ namespace ASF {
+
+ //! An implementation of ASF audio properties
+ class Properties : public AudioProperties
+ {
+ public:
+
+ /*!
+ * Create an instance of ASF::Properties.
+ */
+ Properties();
+
+ /*!
+ * Destroys this ASF::Properties instance.
+ */
+ virtual ~Properties();
+
+ // Reimplementations.
+ virtual int length() const;
+ virtual int bitrate() const;
+ virtual int sampleRate() const;
+ virtual int channels() const;
+
+#ifndef DO_NOT_DOCUMENT
+ void setLength(int value);
+ void setBitrate(int value);
+ void setSampleRate(int value);
+ void setChannels(int value);
+#endif
+
+ private:
+ class PropertiesPrivate;
+ PropertiesPrivate *d;
+ };
+
+ }
+
+}
+
+#endif
diff --git a/src/metadata/asf/asftag.cpp b/src/metadata/asf/asftag.cpp
new file mode 100644
index 0000000..300887e
--- /dev/null
+++ b/src/metadata/asf/asftag.cpp
@@ -0,0 +1,202 @@
+/**************************************************************************
+ copyright : (C) 2005-2007 by Lukáš Lalinský
+ **************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 *
+ * USA *
+ ***************************************************************************/
+
+#include "asftag.h"
+
+using namespace TagLib;
+
+class ASF::Tag::TagPrivate
+{
+public:
+ String title;
+ String artist;
+ String copyright;
+ String comment;
+ String rating;
+ AttributeListMap attributeListMap;
+};
+
+ASF::Tag::Tag()
+: TagLib::Tag()
+{
+ d = new TagPrivate;
+}
+
+ASF::Tag::~Tag()
+{
+ if(d)
+ delete d;
+}
+
+String
+ASF::Tag::title() const
+{
+ return d->title;
+}
+
+String
+ASF::Tag::artist() const
+{
+ return d->artist;
+}
+
+String
+ASF::Tag::album() const
+{
+ if(d->attributeListMap.contains("WM/AlbumTitle"))
+ return d->attributeListMap["WM/AlbumTitle"][0].toString();
+ return String::null;
+}
+
+String
+ASF::Tag::copyright() const
+{
+ return d->copyright;
+}
+
+String
+ASF::Tag::comment() const
+{
+ return d->comment;
+}
+
+String
+ASF::Tag::rating() const
+{
+ return d->rating;
+}
+
+unsigned int
+ASF::Tag::year() const
+{
+ if(d->attributeListMap.contains("WM/Year"))
+ return d->attributeListMap["WM/Year"][0].toString().toInt();
+ return 0;
+}
+
+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/Track"))
+ return d->attributeListMap["WM/Track"][0].toUInt();
+ return 0;
+}
+
+String
+ASF::Tag::genre() const
+{
+ if(d->attributeListMap.contains("WM/Genre"))
+ return d->attributeListMap["WM/Genre"][0].toString();
+ return String::null;
+}
+
+void
+ASF::Tag::setTitle(const String &value)
+{
+ d->title = value;
+}
+
+void
+ASF::Tag::setArtist(const String &value)
+{
+ d->artist = value;
+}
+
+void
+ASF::Tag::setCopyright(const String &value)
+{
+ d->copyright = value;
+}
+
+void
+ASF::Tag::setComment(const String &value)
+{
+ d->comment = value;
+}
+
+void
+ASF::Tag::setRating(const String &value)
+{
+ d->rating = value;
+}
+
+void
+ASF::Tag::setAlbum(const String &value)
+{
+ setAttribute("WM/AlbumTitle", value);
+}
+
+void
+ASF::Tag::setGenre(const String &value)
+{
+ setAttribute("WM/Genre", value);
+}
+
+void
+ASF::Tag::setYear(uint value)
+{
+ setAttribute("WM/Year", String::number(value));
+}
+
+void
+ASF::Tag::setTrack(uint value)
+{
+ setAttribute("WM/TrackNumber", String::number(value));
+}
+
+ASF::AttributeListMap&
+ASF::Tag::attributeListMap()
+{
+ return d->attributeListMap;
+}
+
+void ASF::Tag::removeItem(const String &key)
+{
+ AttributeListMap::Iterator it = d->attributeListMap.find(key);
+ if(it != d->attributeListMap.end())
+ d->attributeListMap.erase(it);
+}
+
+void ASF::Tag::setAttribute(const String &name, const Attribute &attribute)
+{
+ AttributeList value;
+ value.append(attribute);
+ d->attributeListMap.insert(name, value);
+}
+
+void ASF::Tag::addAttribute(const String &name, const Attribute &attribute)
+{
+ if(d->attributeListMap.contains(name)) {
+ d->attributeListMap[name].append(attribute);
+ }
+ else {
+ setAttribute(name, attribute);
+ }
+}
+
+bool ASF::Tag::isEmpty() const {
+ return TagLib::Tag::isEmpty() &&
+ copyright().isEmpty() &&
+ rating().isEmpty() &&
+ d->attributeListMap.isEmpty();
+}
diff --git a/src/metadata/asf/asftag.h b/src/metadata/asf/asftag.h
new file mode 100644
index 0000000..f282dee
--- /dev/null
+++ b/src/metadata/asf/asftag.h
@@ -0,0 +1,181 @@
+/**************************************************************************
+ copyright : (C) 2005-2007 by Lukáš Lalinský
+ **************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 *
+ * USA *
+ ***************************************************************************/
+
+#ifndef TAGLIB_ASFTAG_H
+#define TAGLIB_ASFTAG_H
+
+#include <tag.h>
+#include <tlist.h>
+#include <tmap.h>
+#include "asfattribute.h"
+
+namespace TagLib {
+
+ namespace ASF {
+
+ typedef List<Attribute> AttributeList;
+ typedef Map<String, AttributeList> AttributeListMap;
+
+ class Tag : public TagLib::Tag {
+
+ friend class File;
+
+ public:
+
+ Tag();
+
+ virtual ~Tag();
+
+ /*!
+ * Returns the track name.
+ */
+ virtual String title() const;
+
+ /*!
+ * Returns the artist name.
+ */
+ virtual String artist() const;
+
+ /*!
+ * Returns the album name; if no album name is present in the tag
+ * String::null will be returned.
+ */
+ virtual String album() const;
+
+ /*!
+ * Returns the track comment.
+ */
+ virtual String comment() const;
+
+ /*!
+ * Returns the genre name; if no genre is present in the tag String::null
+ * will be returned.
+ */
+ virtual String genre() const;
+
+ /*!
+ * Returns the rating.
+ */
+ virtual String rating() const;
+
+ /*!
+ * Returns the genre name; if no genre is present in the tag String::null
+ * will be returned.
+ */
+ virtual String copyright() const;
+
+ /*!
+ * Returns the year; if there is no year set, this will return 0.
+ */
+ virtual uint year() const;
+
+ /*!
+ * Returns the track number; if there is no track number set, this will
+ * return 0.
+ */
+ virtual uint track() const;
+
+ /*!
+ * Sets the title to \a s.
+ */
+ virtual void setTitle(const String &s);
+
+ /*!
+ * Sets the artist to \a s.
+ */
+ virtual void setArtist(const String &s);
+
+ /*!
+ * Sets the album to \a s. If \a s is String::null then this value will be
+ * cleared.
+ */
+ virtual void setAlbum(const String &s);
+
+ /*!
+ * Sets the comment to \a s.
+ */
+ virtual void setComment(const String &s);
+
+ /*!
+ * Sets the rating to \a s.
+ */
+ virtual void setRating(const String &s);
+
+ /*!
+ * Sets the copyright to \a s.
+ */
+ virtual void setCopyright(const String &s);
+
+ /*!
+ * Sets the genre to \a s.
+ */
+ virtual void setGenre(const String &s);
+
+ /*!
+ * Sets the year to \a i. If \a s is 0 then this value will be cleared.
+ */
+ virtual void setYear(uint i);
+
+ /*!
+ * Sets the track to \a i. If \a s is 0 then this value will be cleared.
+ */
+ virtual void setTrack(uint i);
+
+ /*!
+ * Returns true if the tag does not contain any data. This should be
+ * reimplemented in subclasses that provide more than the basic tagging
+ * abilities in this class.
+ */
+ virtual bool isEmpty() const;
+
+ /*!
+ * Returns a reference to the item list map. This is an AttributeListMap of
+ * all of the items in the tag.
+ *
+ * This is the most powerfull structure for accessing the items of the tag.
+ */
+ AttributeListMap &attributeListMap();
+
+ /*!
+ * Removes the \a key attribute from the tag
+ */
+ void removeItem(const String &name);
+
+ /*!
+ * Sets the \a key attribute to the value of \a attribute. If an attribute
+ * with the \a key is already present, it will be replaced.
+ */
+ void setAttribute(const String &name, const Attribute &attribute);
+
+ /*!
+ * Sets the \a key attribute to the value of \a attribute. If an attribute
+ * with the \a key is already present, it will be added to the list.
+ */
+ void addAttribute(const String &name, const Attribute &attribute);
+
+ private:
+
+ class TagPrivate;
+ TagPrivate *d;
+ };
+ }
+}
+#endif
diff --git a/src/metadata/asf/taglib_asffiletyperesolver.cpp b/src/metadata/asf/taglib_asffiletyperesolver.cpp
new file mode 100644
index 0000000..f9ed059
--- /dev/null
+++ b/src/metadata/asf/taglib_asffiletyperesolver.cpp
@@ -0,0 +1,47 @@
+/***************************************************************************
+ copyright : (C) 2005 by Martin Aumueller
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// (c) 2005 Martin Aumueller <[email protected]>
+// See COPYING file for licensing information
+
+#include "taglib_asffiletyperesolver.h"
+#include "asffile.h"
+
+#include <string.h>
+
+TagLib::File *ASFFileTypeResolver::createFile(const char *fileName,
+ bool readProperties,
+ TagLib::AudioProperties::ReadStyle propertiesStyle) const
+{
+ const char *ext = strrchr(fileName, '.');
+ if(ext && (!strcasecmp(ext, ".wma") || !strcasecmp(ext, ".asf")))
+ {
+ TagLib::ASF::File *f = new TagLib::ASF::File(fileName, readProperties, propertiesStyle);
+ if(f->isValid())
+ return f;
+ else
+ {
+ delete f;
+ }
+ }
+
+ return 0;
+}
diff --git a/src/metadata/asf/taglib_asffiletyperesolver.h b/src/metadata/asf/taglib_asffiletyperesolver.h
new file mode 100644
index 0000000..ab524b4
--- /dev/null
+++ b/src/metadata/asf/taglib_asffiletyperesolver.h
@@ -0,0 +1,42 @@
+/***************************************************************************
+ copyright : (C) 2005 by Martin Aumueller
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// (c) 2005 Martin Aumueller <[email protected]>
+// See COPYING file for licensing information
+
+#ifndef TAGLIB_ASFFILETYPERESOLVER_H
+#define TAGLIB_ASFFILETYPERESOLVER_H
+
+#include <taglib/tfile.h>
+#include <taglib/fileref.h>
+
+
+class ASFFileTypeResolver : public TagLib::FileRef::FileTypeResolver
+{
+ TagLib::File *createFile(const char *fileName,
+ bool readAudioProperties,
+ TagLib::AudioProperties::ReadStyle audioPropertiesStyle) const;
+
+public:
+ virtual ~ASFFileTypeResolver() {}
+};
+
+#endif
diff --git a/src/metadata/audible/Makefile.am b/src/metadata/audible/Makefile.am
new file mode 100644
index 0000000..dcade34
--- /dev/null
+++ b/src/metadata/audible/Makefile.am
@@ -0,0 +1,17 @@
+SUBDIRS =
+
+INCLUDES = $(all_includes) $(taglib_includes)
+METASOURCES = AUTO
+libtagaudible_la_LDFLAGS = $(all_libraries)
+noinst_LTLIBRARIES = libtagaudible.la
+
+libtagaudible_la_SOURCES = audibleproperties.cpp \
+ audibletag.cpp \
+ taglib_audiblefile.cpp \
+ taglib_audiblefiletyperesolver.cpp
+
+noinst_HEADERS = audibleproperties.h \
+ audibletag.h \
+ taglib_audiblefile.h \
+ taglib_audiblefiletyperesolver.h
+
diff --git a/src/metadata/audible/audibleproperties.cpp b/src/metadata/audible/audibleproperties.cpp
new file mode 100644
index 0000000..4f39322
--- /dev/null
+++ b/src/metadata/audible/audibleproperties.cpp
@@ -0,0 +1,86 @@
+/***************************************************************************
+ copyright : (C) 2005 by Martin Aumueller
+
+ copyright : (C) 2005 by Andy Leadbetter
+ (original mp4 implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <stdio.h>
+
+#include "audibleproperties.h"
+
+#include <taglib/tstring.h>
+
+#include "taglib_audiblefile.h"
+
+#include <netinet/in.h> // ntohl
+
+using namespace TagLib;
+
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+Audible::Properties::Properties(Properties::ReadStyle style) : AudioProperties(style)
+{
+ m_length = 0;
+ m_bitrate = 0;
+ m_sampleRate = 0;
+ m_channels = 0;
+}
+
+Audible::Properties::~Properties()
+{
+}
+
+int Audible::Properties::length() const
+{
+ return m_length;
+}
+
+int Audible::Properties::bitrate() const
+{
+ return m_bitrate;
+}
+
+int Audible::Properties::sampleRate() const
+{
+ return m_sampleRate;
+}
+
+int Audible::Properties::channels() const
+{
+ return m_channels;
+}
+
+#define LENGTH_OFF 61
+
+void Audible::Properties::readAudibleProperties( FILE *fp, int off )
+{
+ fseek(fp, off+LENGTH_OFF, SEEK_SET );
+ fread(&m_length, sizeof(m_length), 1, fp);
+ m_length = ntohl(m_length);
+ //fprintf(stderr, "len (sec): %d\n", m_length);
+ m_bitrate = 0;
+ m_sampleRate = 0;
+ m_channels = 1;
+}
diff --git a/src/metadata/audible/audibleproperties.h b/src/metadata/audible/audibleproperties.h
new file mode 100644
index 0000000..948fc30
--- /dev/null
+++ b/src/metadata/audible/audibleproperties.h
@@ -0,0 +1,85 @@
+/***************************************************************************
+ copyright : (C) 2005 by Martin Aumueller
+
+ copyright : (C) 2005 by Andy Leadbetter
+ (original mp4 implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef TAGLIB_AUDIBLEPROPERTIES_H
+#define TAGLIB_AUDIBLEPROPERTIES_H
+
+#include <config.h>
+
+#include <taglib/audioproperties.h>
+#include <taglib/tstring.h>
+
+namespace TagLib {
+
+ namespace Audible {
+
+ class File;
+
+ /*!
+ * This reads the data from a Audible stream to support the
+ * AudioProperties API.
+ */
+
+ class Properties : public AudioProperties
+ {
+ public:
+ /*!
+ * Initialize this structure
+ */
+ Properties(Properties::ReadStyle style);
+
+ /*!
+ * Destroys this Audible Properties instance.
+ */
+ virtual ~Properties();
+
+ // Reimplementations.
+
+ virtual int length() const;
+ virtual int bitrate() const;
+ virtual int sampleRate() const;
+ virtual int channels() const;
+
+ void readAudibleProperties(FILE *file, int off);
+
+
+ private:
+ void readAudioTrackProperties(FILE *file);
+ friend class Audible::File;
+
+ int m_length;
+ int m_bitrate;
+ int m_sampleRate;
+ int m_channels;
+
+ Properties(const Properties &);
+ Properties &operator=(const Properties &);
+
+ void read();
+ };
+ }
+}
+
+#endif
diff --git a/src/metadata/audible/audibletag.cpp b/src/metadata/audible/audibletag.cpp
new file mode 100644
index 0000000..0fe786f
--- /dev/null
+++ b/src/metadata/audible/audibletag.cpp
@@ -0,0 +1,163 @@
+/***************************************************************************
+ copyright : (C) 2005 by Martin Aumueller
+
+ copyright : (C) 2005 by Andy Leadbetter
+ (original mp4 implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <stdio.h>
+
+#include "audibletag.h"
+
+#include <taglib/tag.h>
+
+#include <netinet/in.h> // ntohl
+#include <stdlib.h>
+#include <string.h>
+
+using namespace TagLib;
+
+Audible::Tag::Tag() : TagLib::Tag::Tag() {
+ m_title = String::null;
+ m_artist = String::null;
+ m_album = String::null;
+ m_comment = String::null;
+ m_genre = String::null;
+ m_year = 0;
+ m_track = 0;
+ m_userID = 0;
+ m_tagsEndOffset = -1;
+}
+
+Audible::Tag::~Tag() {
+}
+
+bool Audible::Tag::isEmpty() const {
+ return m_title == String::null &&
+ m_artist == String::null &&
+ m_album == String::null &&
+ m_comment == String::null &&
+ m_genre == String::null &&
+ m_year == 0 &&
+ m_track == 0 &&
+ m_userID == 0;
+}
+
+void Audible::Tag::duplicate(const Tag *source, Tag *target, bool overwrite) {
+ // No nonstandard information stored yet
+ Tag::duplicate(source, target, overwrite);
+}
+
+#define OFF_PRODUCT_ID 197
+#define OFF_TAGS 189
+
+void Audible::Tag::readTags( FILE *fp )
+{
+ char buf[1023];
+ fseek(fp, OFF_PRODUCT_ID, SEEK_SET);
+ fread(buf, strlen("product_id"), 1, fp);
+ if(memcmp(buf, "product_id", strlen("product_id")))
+ {
+ buf[20]='\0';
+ fprintf(stderr, "no valid Audible aa file: %s\n", buf);
+ return;
+ }
+
+ // Now parse tag.
+
+ fseek(fp, OFF_TAGS, SEEK_SET);
+ char *name, *value;
+
+ m_tagsEndOffset = OFF_TAGS;
+
+ bool lasttag = false;
+ while(!lasttag)
+ {
+ lasttag = !readTag(fp, &name, &value);
+ if(!strcmp(name, "title"))
+ {
+ m_title = String(value, String::Latin1);
+ }
+ else if(!strcmp(name, "author"))
+ {
+ m_artist = String(value, String::Latin1);
+ }
+ else if(!strcmp(name, "long_description"))
+ {
+ m_comment = String(value, String::Latin1);
+ }
+ else if(!strcmp(name, "description"))
+ {
+ if( m_comment.isNull() )
+ m_comment = String(value, String::Latin1);
+ }
+ else if(!strcmp(name, "pubdate"))
+ {
+ m_year = 0;
+ char *p = strrchr(value, '-');
+ if(p)
+ m_year = strtol(p+1, NULL, 10);
+ }
+ else if(!strcmp(name, "user_id"))
+ {
+ m_userID = strtol(value, NULL, 10);
+ }
+
+ delete[] name;
+ delete[] value;
+ }
+
+ m_album = String("", String::Latin1);
+ m_track = 0;
+ m_genre = String("Audiobook", String::Latin1);
+}
+
+bool Audible::Tag::readTag( FILE *fp, char **name, char **value)
+{
+ uint32_t nlen;
+ fread(&nlen, sizeof(nlen), 1, fp);
+ nlen = ntohl(nlen);
+ //fprintf(stderr, "tagname len=%x\n", (unsigned)nlen);
+ *name = new char[nlen+1];
+ (*name)[nlen] = '\0';
+
+ uint32_t vlen;
+ fread(&vlen, sizeof(vlen), 1, fp);
+ vlen = ntohl(vlen);
+ //fprintf(stderr, "tag len=%x\n", (unsigned)vlen);
+ *value = new char[vlen+1];
+ (*value)[vlen] = '\0';
+
+ fread(*name, nlen, 1, fp);
+ fread(*value, vlen, 1, fp);
+ char lasttag;
+ fread(&lasttag, 1, 1, fp);
+ //fprintf(stderr, "%s: \"%s\"\n", *name, *value);
+
+ m_tagsEndOffset += 2 * 4 + nlen + vlen + 1;
+
+ return !lasttag;
+}
+
+int Audible::Tag::getTagsEndOffset()
+{
+ return m_tagsEndOffset;
+}
diff --git a/src/metadata/audible/audibletag.h b/src/metadata/audible/audibletag.h
new file mode 100644
index 0000000..f03966f
--- /dev/null
+++ b/src/metadata/audible/audibletag.h
@@ -0,0 +1,185 @@
+/***************************************************************************
+ copyright : (C) 2005 by Martin Aumueller
+
+ copyright : (C) 2005 by Andy Leadbetter
+ (original mp4 implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef TAGLIB_AUDIBLETAG_H
+#define TAGLIB_AUDIBLETAG_H
+
+#include <config.h>
+
+#include <taglib/tag.h>
+#include "taglib_audiblefile.h"
+
+namespace TagLib {
+
+ namespace Audible {
+ /*!
+ * This implements the generic TagLib::Tag API
+ */
+ class Tag : public TagLib::Tag
+ {
+ public:
+ Tag();
+
+ /*!
+ * read tags from the aa file.
+ */
+ void readTags( FILE *file );
+
+ /*!
+ * Destroys this AudibleTag instance.
+ */
+ virtual ~Tag();
+
+ /*!
+ * Returns the track name; if no track name is present in the tag
+ * String::null will be returned.
+ */
+ virtual String title() const { return m_title; }
+
+ /*!
+ * Returns the artist name; if no artist name is present in the tag
+ * String::null will be returned.
+ */
+ virtual String artist() const { return m_artist; }
+
+ /*!
+ * Returns the album name; if no album name is present in the tag
+ * String::null will be returned.
+ */
+ virtual String album() const { return m_album; }
+
+ /*!
+ * Returns the track comment; if no comment is present in the tag
+ * String::null will be returned.
+ */
+ virtual String comment() const { return m_comment; }
+
+ /*!
+ * Returns the genre name; if no genre is present in the tag String::null
+ * will be returned.
+ */
+ virtual String genre() const { return m_genre; }
+
+ /*!
+ * Returns the year; if there is no year set, this will return 0.
+ */
+ virtual uint year() const { return m_year; }
+
+ /*!
+ * Returns the track number; if there is no track number set, this will
+ * return 0.
+ */
+ virtual uint track() const { return m_track; }
+
+ /*!
+ * Returns the user id for this file.
+ */
+ virtual uint userID() const { return m_userID; }
+
+ /*!
+ * Sets the title to \a s. If \a s is String::null then this value will be
+ * cleared.
+ */
+ virtual void setTitle(const String &s) { m_title = s; }
+
+ /*!
+ * Sets the artist to \a s. If \a s is String::null then this value will be
+ * cleared.
+ */
+ virtual void setArtist(const String &s) { m_artist = s; }
+
+ /*!
+ * Sets the album to \a s. If \a s is String::null then this value will be
+ * cleared.
+ */
+ virtual void setAlbum(const String &s) { m_album = s; }
+
+ /*!
+ * Sets the album to \a s. If \a s is String::null then this value will be
+ * cleared.
+ */
+ virtual void setComment(const String &s) { m_comment = s; }
+
+ /*!
+ * Sets the genre to \a s. If \a s is String::null then this value will be
+ * cleared. For tag formats that use a fixed set of genres, the appropriate
+ * value will be selected based on a string comparison. A list of available
+ * genres for those formats should be available in that type's
+ * implementation.
+ */
+ virtual void setGenre(const String &s) { m_genre = s; }
+
+ /*!
+ * Sets the year to \a i. If \a s is 0 then this value will be cleared.
+ */
+ virtual void setYear(uint i) { m_year = i; }
+
+ /*!
+ * Sets the track to \a i. If \a s is 0 then this value will be cleared.
+ */
+ virtual void setTrack(uint i) { m_track = i; }
+
+ /*!
+ * Returns true if the tag does not contain any data. This should be
+ * reimplemented in subclasses that provide more than the basic tagging
+ * abilities in this class.
+ */
+ virtual bool isEmpty() const;
+
+ /*!
+ * Copies the generic data from one tag to another.
+ *
+ * \note This will not affect any of the lower level details of the tag. For
+ * instance if any of the tag type specific data (maybe a URL for a band) is
+ * set, this will not modify or copy that. This just copies using the API
+ * in this class.
+ *
+ * If \a overwrite is true then the values will be unconditionally copied.
+ * If false only empty values will be overwritten.
+ */
+ static void duplicate(const Tag *source, Tag *target, bool overwrite = true);
+
+ virtual void setUserID(uint id) { m_userID = id; }
+
+ int getTagsEndOffset();
+
+
+
+ protected:
+ String m_title;
+ String m_artist;
+ String m_album;
+ String m_comment;
+ String m_genre;
+ uint m_year;
+ uint m_track;
+ uint m_userID;
+ bool readTag( FILE *fp, char **name, char **value);
+ int m_tagsEndOffset;
+ };
+ }
+}
+
+#endif
diff --git a/src/metadata/audible/taglib_audiblefile.cpp b/src/metadata/audible/taglib_audiblefile.cpp
new file mode 100644
index 0000000..47f5182
--- /dev/null
+++ b/src/metadata/audible/taglib_audiblefile.cpp
@@ -0,0 +1,121 @@
+/***************************************************************************
+ copyright : (C) 2005 by Martin Aumueller
+
+ copyright : (C) 2005 by Andy Leadbetter
+ (original mp4 implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <stdio.h>
+
+#include "taglib_audiblefile.h"
+
+#include "audibletag.h"
+#include <taglib/tfile.h>
+#include <taglib/audioproperties.h>
+
+namespace TagLib {
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+Audible::File::File(const char *file,
+ bool readProperties,
+ Properties::ReadStyle propertiesStyle,
+ FILE *fp)
+ : TagLib::File(file)
+ , audibletag( NULL )
+ , properties( NULL )
+{
+
+ // debug ("Audible::File: create new file object.");
+ //debug ( file );
+
+ /**
+ * Create the Audible file.
+ */
+
+ if(fp)
+ audiblefile = fp;
+ else
+ audiblefile = fopen(file, "rb");
+
+ if( isOpen() )
+ {
+ read(readProperties, propertiesStyle );
+ }
+}
+
+Audible::File::~File()
+{
+ if(audiblefile)
+ fclose(audiblefile);
+ delete audibletag;
+ delete properties;
+}
+
+TagLib::Tag *Audible::File::tag() const
+{
+ return audibletag;
+}
+
+TagLib::Audible::Tag *Audible::File::getAudibleTag() const
+{
+ return audibletag;
+}
+
+Audible::Properties *Audible::File::audioProperties() const
+{
+ return properties;
+}
+
+bool Audible::File::save()
+{
+ return false;
+}
+
+bool Audible::File::isOpen()
+{
+ return audiblefile != NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// private members
+////////////////////////////////////////////////////////////////////////////////
+
+void Audible::File::read(bool readProperties, Properties::ReadStyle propertiesStyle)
+{
+ properties = new Audible::Properties(propertiesStyle);
+ audibletag = new Audible::Tag();
+
+ if (audiblefile != NULL) {
+ audibletag->readTags( audiblefile );
+ int off = audibletag->getTagsEndOffset();
+ //fprintf(stderr, "off=%d\n", off);
+
+ if(readProperties)
+ {
+ // Parse bitrate etc.
+ properties->readAudibleProperties( audiblefile, off );
+ }
+ }
+}
+
+}
diff --git a/src/metadata/audible/taglib_audiblefile.h b/src/metadata/audible/taglib_audiblefile.h
new file mode 100644
index 0000000..c1860ae
--- /dev/null
+++ b/src/metadata/audible/taglib_audiblefile.h
@@ -0,0 +1,93 @@
+/***************************************************************************
+ copyright : (C) 2005 by Martin Aumueller
+
+ copyright : (C) 2005 by Andy Leadbetter
+ (original mp4 implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef TAGLIB_AUDIBLEFILE_H
+#define TAGLIB_AUDIBLEFILE_H
+
+#include <taglib/tfile.h>
+#include "audibleproperties.h"
+#include "audibletag.h"
+
+namespace TagLib {
+
+ namespace Audible {
+
+ class Tag;
+
+ class File : public TagLib::File
+ {
+ public:
+ /*!
+ * Contructs a Audible 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.
+ */
+ File(const char *file, bool readProperties = true,
+ Properties::ReadStyle propertiesStyle = Properties::Average,
+ FILE *fp=NULL);
+
+ /*!
+ * Destroys this instance of the File.
+ */
+ virtual ~File();
+
+
+ virtual TagLib::Tag *tag() const;
+
+ /*!
+ * Returns the Audible::Properties for this file. If no audio properties
+ * were read then this will return a null pointer.
+ */
+ virtual Audible::Properties *audioProperties() const;
+
+ /*!
+ * Save the file.
+ * This is the same as calling save(AllTags);
+ *
+ * \note As of now, saving Audible tags is not supported.
+ */
+ virtual bool save();
+
+ void read(bool readProperties, Properties::ReadStyle propertiesStyle);
+
+ Audible::Tag *getAudibleTag() const;
+
+ bool isAudibleFile() const;
+
+ protected:
+ File(const File &);
+ File &operator=(const File &);
+ bool isOpen();
+
+
+ Audible::Tag *audibletag;
+ Audible::Properties *properties;
+
+ FILE *audiblefile;
+ };
+ }
+}
+
+#endif
diff --git a/src/metadata/audible/taglib_audiblefiletyperesolver.cpp b/src/metadata/audible/taglib_audiblefiletyperesolver.cpp
new file mode 100644
index 0000000..152b17c
--- /dev/null
+++ b/src/metadata/audible/taglib_audiblefiletyperesolver.cpp
@@ -0,0 +1,44 @@
+/***************************************************************************
+ copyright : (C) 2005 by Martin Aumueller
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <stdio.h>
+
+#include "taglib_audiblefiletyperesolver.h"
+#include "taglib_audiblefile.h"
+
+#include <string.h>
+
+TagLib::File *AudibleFileTypeResolver::createFile(const char *fileName,
+ bool readProperties,
+ TagLib::AudioProperties::ReadStyle propertiesStyle) const
+{
+ const char *ext = strrchr(fileName, '.');
+ if(ext && !strcasecmp(ext, ".aa"))
+ {
+ FILE *fp = fopen(fileName, "rb");
+ if(!fp)
+ return 0;
+
+ return new TagLib::Audible::File(fileName, readProperties, propertiesStyle, fp);
+ }
+
+ return 0;
+}
diff --git a/src/metadata/audible/taglib_audiblefiletyperesolver.h b/src/metadata/audible/taglib_audiblefiletyperesolver.h
new file mode 100644
index 0000000..6f1e705
--- /dev/null
+++ b/src/metadata/audible/taglib_audiblefiletyperesolver.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ copyright : (C) 2005 by Martin Aumueller
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef TAGLIB_AUDIBLEFILETYPERESOLVER_H
+#define TAGLIB_AUDIBLEFILETYPERESOLVER_H
+
+#include <taglib/tfile.h>
+#include <taglib/fileref.h>
+
+
+class AudibleFileTypeResolver : public TagLib::FileRef::FileTypeResolver
+{
+ TagLib::File *createFile(const char *fileName,
+ bool readAudioProperties,
+ TagLib::AudioProperties::ReadStyle audioPropertiesStyle) const;
+};
+
+#endif
diff --git a/src/metadata/m4a/Makefile.am b/src/metadata/m4a/Makefile.am
new file mode 100644
index 0000000..34d9af4
--- /dev/null
+++ b/src/metadata/m4a/Makefile.am
@@ -0,0 +1,84 @@
+SUBDIRS =
+METASOURCES = AUTO
+INCLUDES = $(all_includes) $(taglib_includes)
+
+libtagm4a_la_LDFLAGS = $(all_libraries)
+noinst_LTLIBRARIES = libtagm4a.la
+
+libtagm4a_la_SOURCES = \
+ taglib_mp4filetyperesolver.cpp \
+ mp4file.cpp \
+ mp4itunestag.cpp \
+ mp4isobox.cpp \
+ mp4isofullbox.cpp \
+ mp4skipbox.cpp \
+ mp4moovbox.cpp \
+ mp4mvhdbox.cpp \
+ mp4ilstbox.cpp \
+ boxfactory.cpp \
+ mp4fourcc.cpp \
+ mp4udtabox.cpp \
+ mp4metabox.cpp \
+ mp4tagsproxy.cpp \
+ mp4mdiabox.cpp \
+ mp4minfbox.cpp \
+ mp4audioproperties.cpp \
+ mp4hdlrbox.cpp \
+ mp4stblbox.cpp \
+ mp4audiosampleentry.cpp \
+ mp4stsdbox.cpp \
+ mp4sampleentry.cpp \
+ mp4trakbox.cpp \
+ mp4propsproxy.cpp \
+ itunesnambox.cpp \
+ itunesartbox.cpp \
+ itunesalbbox.cpp \
+ itunescvrbox.cpp \
+ itunesgenbox.cpp \
+ itunestrknbox.cpp \
+ itunesdaybox.cpp \
+ itunescmtbox.cpp \
+ itunesgrpbox.cpp \
+ ituneswrtbox.cpp \
+ itunesdiskbox.cpp \
+ itunestmpobox.cpp \
+ itunesdatabox.cpp
+
+noinst_HEADERS = \
+ taglib_mp4filetyperesolver.h \
+ mp4file.h \
+ mp4itunestag.h \
+ mp4isobox.h \
+ mp4isofullbox.h \
+ mp4skipbox.h \
+ mp4moovbox.h \
+ mp4mvhdbox.h \
+ mp4ilstbox.h \
+ boxfactory.h \
+ mp4fourcc.h \
+ mp4udtabox.h \
+ mp4metabox.h \
+ mp4tagsproxy.h \
+ mp4audioproperties.h \
+ mp4hdlrbox.h \
+ mp4propsproxy.h \
+ mp4mdiabox.h \
+ mp4stsdbox.h \
+ mp4trakbox.h \
+ mp4stblbox.h \
+ mp4audiosampleentry.h \
+ mp4minfbox.h \
+ mp4sampleentry.h \
+ itunesnambox.h \
+ itunesartbox.h \
+ itunesalbbox.h \
+ itunesgenbox.h \
+ itunestrknbox.h \
+ itunesdaybox.h \
+ itunescmtbox.h \
+ itunescvrbox.h \
+ itunesgrpbox.h \
+ ituneswrtbox.h \
+ itunesdiskbox.h \
+ itunestmpobox.h \
+ itunesdatabox.h
diff --git a/src/metadata/m4a/boxfactory.cpp b/src/metadata/m4a/boxfactory.cpp
new file mode 100644
index 0000000..0fc8eb4
--- /dev/null
+++ b/src/metadata/m4a/boxfactory.cpp
@@ -0,0 +1,150 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <iostream>
+#include "tstring.h"
+#include "boxfactory.h"
+#include "mp4skipbox.h"
+#include "mp4moovbox.h"
+#include "mp4mvhdbox.h"
+#include "mp4trakbox.h"
+#include "mp4mdiabox.h"
+#include "mp4minfbox.h"
+#include "mp4stblbox.h"
+#include "mp4stsdbox.h"
+#include "mp4hdlrbox.h"
+#include "mp4udtabox.h"
+#include "mp4metabox.h"
+#include "mp4ilstbox.h"
+#include "itunesnambox.h"
+#include "itunesartbox.h"
+#include "itunesalbbox.h"
+#include "itunesgenbox.h"
+#include "itunesdaybox.h"
+#include "itunestrknbox.h"
+#include "itunescmtbox.h"
+#include "itunesgrpbox.h"
+#include "ituneswrtbox.h"
+#include "itunesdiskbox.h"
+#include "itunestmpobox.h"
+#include "itunescvrbox.h"
+#include "itunesdatabox.h"
+
+using namespace TagLib;
+
+MP4::BoxFactory::BoxFactory()
+{
+}
+
+MP4::BoxFactory::~BoxFactory()
+{
+}
+
+//! factory function
+MP4::Mp4IsoBox* MP4::BoxFactory::createInstance( TagLib::File* anyfile, MP4::Fourcc fourcc, uint size, long offset ) const
+{
+ MP4::File * file = dynamic_cast<MP4::File *>(anyfile);
+ if(!file)
+ return 0;
+
+ //std::cout << "creating box for: " << fourcc.toString() << std::endl;
+
+ switch( fourcc )
+ {
+ case 0x6d6f6f76: // 'moov'
+ return new MP4::Mp4MoovBox( file, fourcc, size, offset );
+ break;
+ case 0x6d766864: // 'mvhd'
+ return new MP4::Mp4MvhdBox( file, fourcc, size, offset );
+ break;
+ case 0x7472616b: // 'trak'
+ return new MP4::Mp4TrakBox( file, fourcc, size, offset );
+ break;
+ case 0x6d646961: // 'mdia'
+ return new MP4::Mp4MdiaBox( file, fourcc, size, offset );
+ break;
+ case 0x6d696e66: // 'minf'
+ return new MP4::Mp4MinfBox( file, fourcc, size, offset );
+ break;
+ case 0x7374626c: // 'stbl'
+ return new MP4::Mp4StblBox( file, fourcc, size, offset );
+ break;
+ case 0x73747364: // 'stsd'
+ return new MP4::Mp4StsdBox( file, fourcc, size, offset );
+ break;
+ case 0x68646c72: // 'hdlr'
+ return new MP4::Mp4HdlrBox( file, fourcc, size, offset );
+ break;
+ case 0x75647461: // 'udta'
+ return new MP4::Mp4UdtaBox( file, fourcc, size, offset );
+ break;
+ case 0x6d657461: // 'meta'
+ return new MP4::Mp4MetaBox( file, fourcc, size, offset );
+ break;
+ case 0x696c7374: // 'ilst'
+ return new MP4::Mp4IlstBox( file, fourcc, size, offset );
+ break;
+ case 0xa96e616d: // '_nam'
+ return new MP4::ITunesNamBox( file, fourcc, size, offset );
+ break;
+ case 0xa9415254: // '_ART'
+ return new MP4::ITunesArtBox( file, fourcc, size, offset );
+ break;
+ case 0xa9616c62: // '_alb'
+ return new MP4::ITunesAlbBox( file, fourcc, size, offset );
+ break;
+ case 0xa967656e: // '_gen'
+ return new MP4::ITunesGenBox( file, fourcc, size, offset );
+ break;
+ case 0x676e7265: // 'gnre'
+ return new MP4::ITunesGenBox( file, fourcc, size, offset );
+ break;
+ case 0xa9646179: // '_day'
+ return new MP4::ITunesDayBox( file, fourcc, size, offset );
+ break;
+ case 0x74726b6e: // 'trkn'
+ return new MP4::ITunesTrknBox( file, fourcc, size, offset );
+ break;
+ case 0xa9636d74: // '_cmt'
+ return new MP4::ITunesCmtBox( file, fourcc, size, offset );
+ break;
+ case 0xa9677270: // '_grp'
+ return new MP4::ITunesGrpBox( file, fourcc, size, offset );
+ break;
+ case 0xa9777274: // '_wrt'
+ return new MP4::ITunesWrtBox( file, fourcc, size, offset );
+ break;
+ case 0x6469736b: // 'disk'
+ return new MP4::ITunesDiskBox( file, fourcc, size, offset );
+ break;
+ case 0x746d706f: // 'tmpo'
+ return new MP4::ITunesTmpoBox( file, fourcc, size, offset );
+ break;
+ case 0x636f7672: // 'covr'
+ return new MP4::ITunesCvrBox( file, fourcc, size, offset );
+ break;
+ case 0x64616461: // 'data'
+ return new MP4::ITunesDataBox( file, fourcc, size, offset );
+ break;
+ default:
+ return new MP4::Mp4SkipBox( file, fourcc, size, offset );
+ }
+}
diff --git a/src/metadata/m4a/boxfactory.h b/src/metadata/m4a/boxfactory.h
new file mode 100644
index 0000000..7edcd6c
--- /dev/null
+++ b/src/metadata/m4a/boxfactory.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef BOXFACTORY_H
+#define BOXFACTORY_H
+
+#include "taglib.h"
+#include "mp4isobox.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class BoxFactory
+ {
+ public:
+ BoxFactory();
+ ~BoxFactory();
+
+ //! factory function
+ Mp4IsoBox* createInstance( TagLib::File* anyfile, MP4::Fourcc fourcc, uint size, long offset ) const;
+ }; // class BoxFactory
+
+ } // namepace MP4
+} // namepace TagLib
+
+#endif // BOXFACTORY_H
diff --git a/src/metadata/m4a/itunesalbbox.cpp b/src/metadata/m4a/itunesalbbox.cpp
new file mode 100644
index 0000000..5832fa0
--- /dev/null
+++ b/src/metadata/m4a/itunesalbbox.cpp
@@ -0,0 +1,89 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <iostream>
+#include "itunesalbbox.h"
+#include "itunesdatabox.h"
+#include "mp4isobox.h"
+#include "mp4file.h"
+#include "tfile.h"
+#include "mp4tagsproxy.h"
+
+using namespace TagLib;
+
+class MP4::ITunesAlbBox::ITunesAlbBoxPrivate
+{
+public:
+ ITunesDataBox* dataBox;
+};
+
+MP4::ITunesAlbBox::ITunesAlbBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
+ :Mp4IsoBox(file, fourcc, size, offset)
+{
+ d = new MP4::ITunesAlbBox::ITunesAlbBoxPrivate();
+ d->dataBox = 0;
+}
+
+MP4::ITunesAlbBox::~ITunesAlbBox()
+{
+ if( d->dataBox != 0 )
+ delete d->dataBox;
+ delete d;
+}
+
+//! parse the content of the box
+void MP4::ITunesAlbBox::parse()
+{
+ TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
+
+ // parse data box
+ TagLib::uint size;
+ MP4::Fourcc fourcc;
+
+ if(mp4file->readSizeAndType( size, fourcc ) == true)
+ {
+ // check for type - must be 'data'
+ if( fourcc != MP4::Fourcc("data") )
+ {
+ std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
+ // jump over data tag
+ mp4file->seek( size-8, TagLib::File::Current );
+ return;
+ }
+ d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
+ d->dataBox->parsebox();
+ }
+ else
+ {
+ // reading unsuccessful - serious error!
+ std::cerr << "Error in parsing ITunesAlbBox - serious Error in taglib!" << std::endl;
+ return;
+ }
+ // register data box
+ mp4file->tagProxy()->registerBox( Mp4TagsProxy::album, d->dataBox );
+
+#if 0
+ // get data pointer - just for debugging...
+ TagLib::String dataString( d->dataBox->data() );
+ std::cout << "Content of album box: " << dataString << std::endl;
+#endif
+}
+
diff --git a/src/metadata/m4a/itunesalbbox.h b/src/metadata/m4a/itunesalbbox.h
new file mode 100644
index 0000000..f2462c2
--- /dev/null
+++ b/src/metadata/m4a/itunesalbbox.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef ITUNESALBBOX_H
+#define ITUNESALBBOX_H
+
+#include "mp4isobox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class ITunesAlbBox: public Mp4IsoBox
+ {
+ public:
+ ITunesAlbBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
+ ~ITunesAlbBox();
+
+ private:
+ //! parse the content of the box
+ virtual void parse();
+
+ protected:
+ class ITunesAlbBoxPrivate;
+ ITunesAlbBoxPrivate* d;
+ }; // class ITunesAlbBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // ITUNESALBBOX_H
diff --git a/src/metadata/m4a/itunesartbox.cpp b/src/metadata/m4a/itunesartbox.cpp
new file mode 100644
index 0000000..19e717d
--- /dev/null
+++ b/src/metadata/m4a/itunesartbox.cpp
@@ -0,0 +1,89 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <iostream>
+#include "itunesartbox.h"
+#include "itunesdatabox.h"
+#include "mp4isobox.h"
+#include "mp4file.h"
+#include "tfile.h"
+#include "mp4tagsproxy.h"
+
+using namespace TagLib;
+
+class MP4::ITunesArtBox::ITunesArtBoxPrivate
+{
+public:
+ ITunesDataBox* dataBox;
+};
+
+MP4::ITunesArtBox::ITunesArtBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
+ :Mp4IsoBox(file, fourcc, size, offset)
+{
+ d = new MP4::ITunesArtBox::ITunesArtBoxPrivate();
+ d->dataBox = 0;
+}
+
+MP4::ITunesArtBox::~ITunesArtBox()
+{
+ if( d->dataBox != 0 )
+ delete d->dataBox;
+ delete d;
+}
+
+//! parse the content of the box
+void MP4::ITunesArtBox::parse()
+{
+ TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
+
+ // parse data box
+ TagLib::uint size;
+ MP4::Fourcc fourcc;
+
+ if(mp4file->readSizeAndType( size, fourcc ) == true)
+ {
+ // check for type - must be 'data'
+ if( fourcc != MP4::Fourcc("data") )
+ {
+ std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
+ // jump over data tag
+ mp4file->seek( size-8, TagLib::File::Current );
+ return;
+ }
+ d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
+ d->dataBox->parsebox();
+ }
+ else
+ {
+ // reading unsuccessful - serious error!
+ std::cerr << "Error in parsing ITunesArtBox - serious Error in taglib!" << std::endl;
+ return;
+ }
+ // register data box
+ mp4file->tagProxy()->registerBox( Mp4TagsProxy::artist, d->dataBox );
+
+#if 0
+ // get data pointer - just for debugging...
+ TagLib::String dataString( d->dataBox->data() );
+ std::cout << "Content of artist box: " << dataString << std::endl;
+#endif
+}
+
diff --git a/src/metadata/m4a/itunesartbox.h b/src/metadata/m4a/itunesartbox.h
new file mode 100644
index 0000000..5d197aa
--- /dev/null
+++ b/src/metadata/m4a/itunesartbox.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef ITUNESARTBOX_H
+#define ITUNESARTBOX_H
+
+#include "mp4isobox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class ITunesArtBox: public Mp4IsoBox
+ {
+ public:
+ ITunesArtBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
+ ~ITunesArtBox();
+
+ private:
+ //! parse the content of the box
+ virtual void parse();
+
+ protected:
+ class ITunesArtBoxPrivate;
+ ITunesArtBoxPrivate* d;
+ }; // class ITunesArtBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // ITUNESARTBOX_H
diff --git a/src/metadata/m4a/itunescmtbox.cpp b/src/metadata/m4a/itunescmtbox.cpp
new file mode 100644
index 0000000..c79f0f7
--- /dev/null
+++ b/src/metadata/m4a/itunescmtbox.cpp
@@ -0,0 +1,89 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <iostream>
+#include "itunescmtbox.h"
+#include "itunesdatabox.h"
+#include "mp4isobox.h"
+#include "mp4file.h"
+#include "tfile.h"
+#include "mp4tagsproxy.h"
+
+using namespace TagLib;
+
+class MP4::ITunesCmtBox::ITunesCmtBoxPrivate
+{
+public:
+ ITunesDataBox* dataBox;
+};
+
+MP4::ITunesCmtBox::ITunesCmtBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
+ :Mp4IsoBox(file, fourcc, size, offset)
+{
+ d = new MP4::ITunesCmtBox::ITunesCmtBoxPrivate();
+ d->dataBox = 0;
+}
+
+MP4::ITunesCmtBox::~ITunesCmtBox()
+{
+ if( d->dataBox != 0 )
+ delete d->dataBox;
+ delete d;
+}
+
+//! parse the content of the box
+void MP4::ITunesCmtBox::parse()
+{
+ TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
+
+ // parse data box
+ TagLib::uint size;
+ MP4::Fourcc fourcc;
+
+ if(mp4file->readSizeAndType( size, fourcc ) == true)
+ {
+ // check for type - must be 'data'
+ if( fourcc != MP4::Fourcc("data") )
+ {
+ std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
+ // jump over data tag
+ mp4file->seek( size-8, TagLib::File::Current );
+ return;
+ }
+ d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
+ d->dataBox->parsebox();
+ }
+ else
+ {
+ // reading unsuccessful - serious error!
+ std::cerr << "Error in parsing ITunesCmtBox - serious Error in taglib!" << std::endl;
+ return;
+ }
+ // register data box
+ mp4file->tagProxy()->registerBox( Mp4TagsProxy::comment, d->dataBox );
+
+#if 0
+ // get data pointer - just for debugging...
+ TagLib::String dataString( d->dataBox->data() );
+ std::cout << "Content of title box: " << dataString << std::endl;
+#endif
+}
+
diff --git a/src/metadata/m4a/itunescmtbox.h b/src/metadata/m4a/itunescmtbox.h
new file mode 100644
index 0000000..83ad65d
--- /dev/null
+++ b/src/metadata/m4a/itunescmtbox.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef ITUNESCMTBOX_H
+#define ITUNESCMTBOX_H
+
+#include "mp4isobox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class ITunesCmtBox: public Mp4IsoBox
+ {
+ public:
+ ITunesCmtBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
+ ~ITunesCmtBox();
+
+ private:
+ //! parse the content of the box
+ virtual void parse();
+
+ protected:
+ class ITunesCmtBoxPrivate;
+ ITunesCmtBoxPrivate* d;
+ }; // class ITunesCmtBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // ITUNESCMTBOX_H
diff --git a/src/metadata/m4a/itunescvrbox.cpp b/src/metadata/m4a/itunescvrbox.cpp
new file mode 100644
index 0000000..4a7b3db
--- /dev/null
+++ b/src/metadata/m4a/itunescvrbox.cpp
@@ -0,0 +1,89 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <iostream>
+#include "itunescvrbox.h"
+#include "itunesdatabox.h"
+#include "mp4isobox.h"
+#include "mp4file.h"
+#include "tfile.h"
+#include "mp4tagsproxy.h"
+
+using namespace TagLib;
+
+class MP4::ITunesCvrBox::ITunesCvrBoxPrivate
+{
+public:
+ ITunesDataBox* dataBox;
+};
+
+MP4::ITunesCvrBox::ITunesCvrBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
+ :Mp4IsoBox(file, fourcc, size, offset)
+{
+ d = new MP4::ITunesCvrBox::ITunesCvrBoxPrivate();
+ d->dataBox = 0;
+}
+
+MP4::ITunesCvrBox::~ITunesCvrBox()
+{
+ if( d->dataBox != 0 )
+ delete d->dataBox;
+ delete d;
+}
+
+//! parse the content of the box
+void MP4::ITunesCvrBox::parse()
+{
+ TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
+
+ // parse data box
+ TagLib::uint size;
+ MP4::Fourcc fourcc;
+
+ if(mp4file->readSizeAndType( size, fourcc ) == true)
+ {
+ // check for type - must be 'data'
+ if( fourcc != MP4::Fourcc("data") )
+ {
+ std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
+ // jump over data tag
+ mp4file->seek( size-8, TagLib::File::Current );
+ return;
+ }
+ d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
+ d->dataBox->parsebox();
+ }
+ else
+ {
+ // reading unsuccessful - serious error!
+ std::cerr << "Error in parsing ITunesCvrBox - serious Error in taglib!" << std::endl;
+ return;
+ }
+ // register data box
+ mp4file->tagProxy()->registerBox( Mp4TagsProxy::cover, d->dataBox );
+
+#if 0
+ // get data pointer - just for debugging...
+ TagLib::String dataString( d->dataBox->data() );
+ std::cout << "Content of album box: " << dataString << std::endl;
+#endif
+}
+
diff --git a/src/metadata/m4a/itunescvrbox.h b/src/metadata/m4a/itunescvrbox.h
new file mode 100644
index 0000000..a2693c2
--- /dev/null
+++ b/src/metadata/m4a/itunescvrbox.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef ITUNESCVRBOX_H
+#define ITUNESCVRBOX_H
+
+#include "mp4isobox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class ITunesCvrBox: public Mp4IsoBox
+ {
+ public:
+ ITunesCvrBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
+ ~ITunesCvrBox();
+
+ private:
+ //! parse the content of the box
+ virtual void parse();
+
+ protected:
+ class ITunesCvrBoxPrivate;
+ ITunesCvrBoxPrivate* d;
+ }; // class ITunesCvrBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // ITUNESCVRBOX_H
diff --git a/src/metadata/m4a/itunesdatabox.cpp b/src/metadata/m4a/itunesdatabox.cpp
new file mode 100644
index 0000000..7565a42
--- /dev/null
+++ b/src/metadata/m4a/itunesdatabox.cpp
@@ -0,0 +1,63 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <iostream>
+#include "itunesdatabox.h"
+#include "tbytevector.h"
+#include "mp4isobox.h"
+#include "tfile.h"
+
+using namespace TagLib;
+
+class MP4::ITunesDataBox::ITunesDataBoxPrivate
+{
+public:
+ ByteVector data;
+};
+
+MP4::ITunesDataBox::ITunesDataBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
+ :Mp4IsoFullBox(file, fourcc, size, offset)
+{
+ d = new MP4::ITunesDataBox::ITunesDataBoxPrivate();
+}
+
+MP4::ITunesDataBox::~ITunesDataBox()
+{
+ delete d;
+}
+
+ByteVector MP4::ITunesDataBox::data() const
+{
+ return d->data;
+}
+
+//! parse the content of the box
+void MP4::ITunesDataBox::parse()
+{
+ // skip first 4 byte - don't know what they are supposed to be for - simply 4 zeros
+ file()->seek( 4, TagLib::File::Current );
+ // read contents - remaining size is box_size-12-4 (12:fullbox header, 4:starting zeros of data box)
+#if 0
+ std::cout << " reading data box with data length: " << size()-16 << std::endl;
+#endif
+ d->data = file()->readBlock( size()-12-4 );
+}
+
diff --git a/src/metadata/m4a/itunesdatabox.h b/src/metadata/m4a/itunesdatabox.h
new file mode 100644
index 0000000..d0c802c
--- /dev/null
+++ b/src/metadata/m4a/itunesdatabox.h
@@ -0,0 +1,53 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef ITUNESDATABOX_H
+#define ITUNESDATABOX_H
+
+#include "mp4isofullbox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class ITunesDataBox: public Mp4IsoFullBox
+ {
+ public:
+ ITunesDataBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
+ ~ITunesDataBox();
+
+ //! get the internal data, which can be txt or binary data as well
+ ByteVector data() const;
+
+ private:
+ //! parse the content of the box
+ virtual void parse();
+
+ protected:
+ class ITunesDataBoxPrivate;
+ ITunesDataBoxPrivate* d;
+ }; // class ITunesDataBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // ITUNESDATABOX_H
diff --git a/src/metadata/m4a/itunesdaybox.cpp b/src/metadata/m4a/itunesdaybox.cpp
new file mode 100644
index 0000000..16568d7
--- /dev/null
+++ b/src/metadata/m4a/itunesdaybox.cpp
@@ -0,0 +1,89 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <iostream>
+#include "itunesdaybox.h"
+#include "itunesdatabox.h"
+#include "mp4isobox.h"
+#include "mp4file.h"
+#include "tfile.h"
+#include "mp4tagsproxy.h"
+
+using namespace TagLib;
+
+class MP4::ITunesDayBox::ITunesDayBoxPrivate
+{
+public:
+ ITunesDataBox* dataBox;
+};
+
+MP4::ITunesDayBox::ITunesDayBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
+ :Mp4IsoBox(file, fourcc, size, offset)
+{
+ d = new MP4::ITunesDayBox::ITunesDayBoxPrivate();
+ d->dataBox = 0;
+}
+
+MP4::ITunesDayBox::~ITunesDayBox()
+{
+ if( d->dataBox != 0 )
+ delete d->dataBox;
+ delete d;
+}
+
+//! parse the content of the box
+void MP4::ITunesDayBox::parse()
+{
+ TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
+
+ // parse data box
+ TagLib::uint size;
+ MP4::Fourcc fourcc;
+
+ if(mp4file->readSizeAndType( size, fourcc ) == true)
+ {
+ // check for type - must be 'data'
+ if( fourcc != MP4::Fourcc("data") )
+ {
+ std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
+ // jump over data tag
+ mp4file->seek( size-8, TagLib::File::Current );
+ return;
+ }
+ d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
+ d->dataBox->parsebox();
+ }
+ else
+ {
+ // reading unsuccessful - serious error!
+ std::cerr << "Error in parsing ITunesDayBox - serious Error in taglib!" << std::endl;
+ return;
+ }
+ // register data box
+ mp4file->tagProxy()->registerBox( Mp4TagsProxy::year, d->dataBox );
+
+#if 0
+ // get data pointer - just for debugging...
+ TagLib::String dataString( d->dataBox->data() );
+ std::cout << "Content of day box: " << dataString.substr(0,4) << std::endl;
+#endif
+}
+
diff --git a/src/metadata/m4a/itunesdaybox.h b/src/metadata/m4a/itunesdaybox.h
new file mode 100644
index 0000000..7291363
--- /dev/null
+++ b/src/metadata/m4a/itunesdaybox.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef ITUNESDAYBOX_H
+#define ITUNESDAYBOX_H
+
+#include "mp4isobox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class ITunesDayBox: public Mp4IsoBox
+ {
+ public:
+ ITunesDayBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
+ ~ITunesDayBox();
+
+ private:
+ //! parse the content of the box
+ virtual void parse();
+
+ protected:
+ class ITunesDayBoxPrivate;
+ ITunesDayBoxPrivate* d;
+ }; // class ITunesDayBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // ITUNESDAYBOX_H
diff --git a/src/metadata/m4a/itunesdiskbox.cpp b/src/metadata/m4a/itunesdiskbox.cpp
new file mode 100644
index 0000000..93c47f2
--- /dev/null
+++ b/src/metadata/m4a/itunesdiskbox.cpp
@@ -0,0 +1,93 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <iostream>
+#include "itunesdiskbox.h"
+#include "itunesdatabox.h"
+#include "mp4isobox.h"
+#include "mp4file.h"
+#include "tfile.h"
+#include "mp4tagsproxy.h"
+
+using namespace TagLib;
+
+class MP4::ITunesDiskBox::ITunesDiskBoxPrivate
+{
+public:
+ ITunesDataBox* dataBox;
+};
+
+MP4::ITunesDiskBox::ITunesDiskBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
+ :Mp4IsoBox(file, fourcc, size, offset)
+{
+ d = new MP4::ITunesDiskBox::ITunesDiskBoxPrivate();
+ d->dataBox = 0;
+}
+
+MP4::ITunesDiskBox::~ITunesDiskBox()
+{
+ if( d->dataBox != 0 )
+ delete d->dataBox;
+ delete d;
+}
+
+//! parse the content of the box
+void MP4::ITunesDiskBox::parse()
+{
+ TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
+
+ // parse data box
+ TagLib::uint size;
+ MP4::Fourcc fourcc;
+
+ if(mp4file->readSizeAndType( size, fourcc ) == true)
+ {
+ // check for type - must be 'data'
+ if( fourcc != MP4::Fourcc("data") )
+ {
+ std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
+ // jump over data tag
+ mp4file->seek( size-8, TagLib::File::Current );
+ return;
+ }
+ d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
+ d->dataBox->parsebox();
+ }
+ else
+ {
+ // reading unsuccessful - serious error!
+ std::cerr << "Error in parsing ITunesDiskBox - serious Error in taglib!" << std::endl;
+ return;
+ }
+ // register data box
+ mp4file->tagProxy()->registerBox( Mp4TagsProxy::disk, d->dataBox );
+
+#if 0
+ // get data pointer - just for debugging...
+ TagLib::ByteVector trknData = d->dataBox->data();
+ TagLib::String trknumber = TagLib::String::number( static_cast<int>( static_cast<unsigned char>(trknData[0]) << 24 |
+ static_cast<unsigned char>(trknData[1]) << 16 |
+ static_cast<unsigned char>(trknData[2]) << 8 |
+ static_cast<unsigned char>(trknData[3]) ) );
+ std::cout << "Content of tracknumber box: " << trknumber << std::endl;
+#endif
+}
+
diff --git a/src/metadata/m4a/itunesdiskbox.h b/src/metadata/m4a/itunesdiskbox.h
new file mode 100644
index 0000000..bad73da
--- /dev/null
+++ b/src/metadata/m4a/itunesdiskbox.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef ITUNESDISKBOX_H
+#define ITUNESDISKBOX_H
+
+#include "mp4isobox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class ITunesDiskBox: public Mp4IsoBox
+ {
+ public:
+ ITunesDiskBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
+ ~ITunesDiskBox();
+
+ private:
+ //! parse the content of the box
+ virtual void parse();
+
+ protected:
+ class ITunesDiskBoxPrivate;
+ ITunesDiskBoxPrivate* d;
+ }; // class ITunesDiskBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // ITUNESDISKBOX_H
diff --git a/src/metadata/m4a/itunesgenbox.cpp b/src/metadata/m4a/itunesgenbox.cpp
new file mode 100644
index 0000000..08708bc
--- /dev/null
+++ b/src/metadata/m4a/itunesgenbox.cpp
@@ -0,0 +1,89 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <iostream>
+#include "itunesgenbox.h"
+#include "itunesdatabox.h"
+#include "mp4isobox.h"
+#include "mp4file.h"
+#include "tfile.h"
+#include "mp4tagsproxy.h"
+
+using namespace TagLib;
+
+class MP4::ITunesGenBox::ITunesGenBoxPrivate
+{
+public:
+ ITunesDataBox* dataBox;
+};
+
+MP4::ITunesGenBox::ITunesGenBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
+ :Mp4IsoBox(file, fourcc, size, offset)
+{
+ d = new MP4::ITunesGenBox::ITunesGenBoxPrivate();
+ d->dataBox = 0;
+}
+
+MP4::ITunesGenBox::~ITunesGenBox()
+{
+ if( d->dataBox != 0 )
+ delete d->dataBox;
+ delete d;
+}
+
+//! parse the content of the box
+void MP4::ITunesGenBox::parse()
+{
+ TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
+
+ // parse data box
+ TagLib::uint size;
+ MP4::Fourcc fourcc;
+
+ if(mp4file->readSizeAndType( size, fourcc ) == true)
+ {
+ // check for type - must be 'data'
+ if( fourcc != MP4::Fourcc("data") )
+ {
+ std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
+ // jump over data tag
+ mp4file->seek( size-8, TagLib::File::Current );
+ return;
+ }
+ d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
+ d->dataBox->parsebox();
+ }
+ else
+ {
+ // reading unsuccessful - serious error!
+ std::cerr << "Error in parsing ITunesGenBox - serious Error in taglib!" << std::endl;
+ return;
+ }
+ // register data box
+ mp4file->tagProxy()->registerBox( Mp4TagsProxy::genre, d->dataBox );
+
+#if 0
+ // get data pointer - just for debugging...
+ TagLib::String dataString( d->dataBox->data() );
+ std::cout << "Content of genre box: " << dataString << std::endl;
+#endif
+}
+
diff --git a/src/metadata/m4a/itunesgenbox.h b/src/metadata/m4a/itunesgenbox.h
new file mode 100644
index 0000000..deb7fe3
--- /dev/null
+++ b/src/metadata/m4a/itunesgenbox.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef ITUNESGENBOX_H
+#define ITUNESGENBOX_H
+
+#include "mp4isobox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class ITunesGenBox: public Mp4IsoBox
+ {
+ public:
+ ITunesGenBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
+ ~ITunesGenBox();
+
+ private:
+ //! parse the content of the box
+ virtual void parse();
+
+ protected:
+ class ITunesGenBoxPrivate;
+ ITunesGenBoxPrivate* d;
+ }; // class ITunesGenBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // ITUNESGENBOX_H
diff --git a/src/metadata/m4a/itunesgrpbox.cpp b/src/metadata/m4a/itunesgrpbox.cpp
new file mode 100644
index 0000000..061b6bd
--- /dev/null
+++ b/src/metadata/m4a/itunesgrpbox.cpp
@@ -0,0 +1,89 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <iostream>
+#include "itunesgrpbox.h"
+#include "itunesdatabox.h"
+#include "mp4isobox.h"
+#include "mp4file.h"
+#include "tfile.h"
+#include "mp4tagsproxy.h"
+
+using namespace TagLib;
+
+class MP4::ITunesGrpBox::ITunesGrpBoxPrivate
+{
+public:
+ ITunesDataBox* dataBox;
+};
+
+MP4::ITunesGrpBox::ITunesGrpBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
+ :Mp4IsoBox(file, fourcc, size, offset)
+{
+ d = new MP4::ITunesGrpBox::ITunesGrpBoxPrivate();
+ d->dataBox = 0;
+}
+
+MP4::ITunesGrpBox::~ITunesGrpBox()
+{
+ if( d->dataBox != 0 )
+ delete d->dataBox;
+ delete d;
+}
+
+//! parse the content of the box
+void MP4::ITunesGrpBox::parse()
+{
+ TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
+
+ // parse data box
+ TagLib::uint size;
+ MP4::Fourcc fourcc;
+
+ if(mp4file->readSizeAndType( size, fourcc ) == true)
+ {
+ // check for type - must be 'data'
+ if( fourcc != MP4::Fourcc("data") )
+ {
+ std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
+ // jump over data tag
+ mp4file->seek( size-8, TagLib::File::Current );
+ return;
+ }
+ d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
+ d->dataBox->parsebox();
+ }
+ else
+ {
+ // reading unsuccessful - serious error!
+ std::cerr << "Error in parsing ITunesGrpBox - serious Error in taglib!" << std::endl;
+ return;
+ }
+ // register data box
+ mp4file->tagProxy()->registerBox( Mp4TagsProxy::grouping, d->dataBox );
+
+#if 0
+ // get data pointer - just for debugging...
+ TagLib::String dataString( d->dataBox->data() );
+ std::cout << "Content of title box: " << dataString << std::endl;
+#endif
+}
+
diff --git a/src/metadata/m4a/itunesgrpbox.h b/src/metadata/m4a/itunesgrpbox.h
new file mode 100644
index 0000000..62922f0
--- /dev/null
+++ b/src/metadata/m4a/itunesgrpbox.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef ITUNESGRPBOX_H
+#define ITUNESGRPBOX_H
+
+#include "mp4isobox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class ITunesGrpBox: public Mp4IsoBox
+ {
+ public:
+ ITunesGrpBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
+ ~ITunesGrpBox();
+
+ private:
+ //! parse the content of the box
+ virtual void parse();
+
+ protected:
+ class ITunesGrpBoxPrivate;
+ ITunesGrpBoxPrivate* d;
+ }; // class ITunesGrpBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // ITUNESGRPBOX_H
diff --git a/src/metadata/m4a/itunesnambox.cpp b/src/metadata/m4a/itunesnambox.cpp
new file mode 100644
index 0000000..6cc954b
--- /dev/null
+++ b/src/metadata/m4a/itunesnambox.cpp
@@ -0,0 +1,89 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <iostream>
+#include "itunesnambox.h"
+#include "itunesdatabox.h"
+#include "mp4isobox.h"
+#include "mp4file.h"
+#include "tfile.h"
+#include "mp4tagsproxy.h"
+
+using namespace TagLib;
+
+class MP4::ITunesNamBox::ITunesNamBoxPrivate
+{
+public:
+ ITunesDataBox* dataBox;
+};
+
+MP4::ITunesNamBox::ITunesNamBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
+ :Mp4IsoBox(file, fourcc, size, offset)
+{
+ d = new MP4::ITunesNamBox::ITunesNamBoxPrivate();
+ d->dataBox = 0;
+}
+
+MP4::ITunesNamBox::~ITunesNamBox()
+{
+ if( d->dataBox != 0 )
+ delete d->dataBox;
+ delete d;
+}
+
+//! parse the content of the box
+void MP4::ITunesNamBox::parse()
+{
+ TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
+
+ // parse data box
+ TagLib::uint size;
+ MP4::Fourcc fourcc;
+
+ if(mp4file->readSizeAndType( size, fourcc ) == true)
+ {
+ // check for type - must be 'data'
+ if( fourcc != MP4::Fourcc("data") )
+ {
+ std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
+ // jump over data tag
+ mp4file->seek( size-8, TagLib::File::Current );
+ return;
+ }
+ d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
+ d->dataBox->parsebox();
+ }
+ else
+ {
+ // reading unsuccessful - serious error!
+ std::cerr << "Error in parsing ITunesNamBox - serious Error in taglib!" << std::endl;
+ return;
+ }
+ // register data box
+ mp4file->tagProxy()->registerBox( Mp4TagsProxy::title, d->dataBox );
+
+#if 0
+ // get data pointer - just for debugging...
+ TagLib::String dataString( d->dataBox->data() );
+ std::cout << "Content of title box: " << dataString << std::endl;
+#endif
+}
+
diff --git a/src/metadata/m4a/itunesnambox.h b/src/metadata/m4a/itunesnambox.h
new file mode 100644
index 0000000..434fd84
--- /dev/null
+++ b/src/metadata/m4a/itunesnambox.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef ITUNESNAMBOX_H
+#define ITUNESNAMBOX_H
+
+#include "mp4isobox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class ITunesNamBox: public Mp4IsoBox
+ {
+ public:
+ ITunesNamBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
+ ~ITunesNamBox();
+
+ private:
+ //! parse the content of the box
+ virtual void parse();
+
+ protected:
+ class ITunesNamBoxPrivate;
+ ITunesNamBoxPrivate* d;
+ }; // class ITunesNamBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // ITUNESNAMBOX_H
diff --git a/src/metadata/m4a/itunestmpobox.cpp b/src/metadata/m4a/itunestmpobox.cpp
new file mode 100644
index 0000000..3d0ad2d
--- /dev/null
+++ b/src/metadata/m4a/itunestmpobox.cpp
@@ -0,0 +1,93 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <iostream>
+#include "itunestmpobox.h"
+#include "itunesdatabox.h"
+#include "mp4isobox.h"
+#include "mp4file.h"
+#include "tfile.h"
+#include "mp4tagsproxy.h"
+
+using namespace TagLib;
+
+class MP4::ITunesTmpoBox::ITunesTmpoBoxPrivate
+{
+public:
+ ITunesDataBox* dataBox;
+};
+
+MP4::ITunesTmpoBox::ITunesTmpoBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
+ :Mp4IsoBox(file, fourcc, size, offset)
+{
+ d = new MP4::ITunesTmpoBox::ITunesTmpoBoxPrivate();
+ d->dataBox = 0;
+}
+
+MP4::ITunesTmpoBox::~ITunesTmpoBox()
+{
+ if( d->dataBox != 0 )
+ delete d->dataBox;
+ delete d;
+}
+
+//! parse the content of the box
+void MP4::ITunesTmpoBox::parse()
+{
+ TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
+
+ // parse data box
+ TagLib::uint size;
+ MP4::Fourcc fourcc;
+
+ if(mp4file->readSizeAndType( size, fourcc ) == true)
+ {
+ // check for type - must be 'data'
+ if( fourcc != MP4::Fourcc("data") )
+ {
+ std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
+ // jump over data tag
+ mp4file->seek( size-8, TagLib::File::Current );
+ return;
+ }
+ d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
+ d->dataBox->parsebox();
+ }
+ else
+ {
+ // reading unsuccessful - serious error!
+ std::cerr << "Error in parsing ITunesTmpoBox - serious Error in taglib!" << std::endl;
+ return;
+ }
+ // register data box
+ mp4file->tagProxy()->registerBox( Mp4TagsProxy::bpm, d->dataBox );
+
+#if 0
+ // get data pointer - just for debugging...
+ TagLib::ByteVector trknData = d->dataBox->data();
+ TagLib::String trknumber = TagLib::String::number( static_cast<int>( static_cast<unsigned char>(trknData[0]) << 24 |
+ static_cast<unsigned char>(trknData[1]) << 16 |
+ static_cast<unsigned char>(trknData[2]) << 8 |
+ static_cast<unsigned char>(trknData[3]) ) );
+ std::cout << "Content of tracknumber box: " << trknumber << std::endl;
+#endif
+}
+
diff --git a/src/metadata/m4a/itunestmpobox.h b/src/metadata/m4a/itunestmpobox.h
new file mode 100644
index 0000000..981f938
--- /dev/null
+++ b/src/metadata/m4a/itunestmpobox.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef ITUNESTMPOBOX_H
+#define ITUNESTMPOBOX_H
+
+#include "mp4isobox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class ITunesTmpoBox: public Mp4IsoBox
+ {
+ public:
+ ITunesTmpoBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
+ ~ITunesTmpoBox();
+
+ private:
+ //! parse the content of the box
+ virtual void parse();
+
+ protected:
+ class ITunesTmpoBoxPrivate;
+ ITunesTmpoBoxPrivate* d;
+ }; // class ITunesTmpoBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // ITUNESTMPOBOX_H
diff --git a/src/metadata/m4a/itunestrknbox.cpp b/src/metadata/m4a/itunestrknbox.cpp
new file mode 100644
index 0000000..f8d36cb
--- /dev/null
+++ b/src/metadata/m4a/itunestrknbox.cpp
@@ -0,0 +1,93 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <iostream>
+#include "itunestrknbox.h"
+#include "itunesdatabox.h"
+#include "mp4isobox.h"
+#include "mp4file.h"
+#include "tfile.h"
+#include "mp4tagsproxy.h"
+
+using namespace TagLib;
+
+class MP4::ITunesTrknBox::ITunesTrknBoxPrivate
+{
+public:
+ ITunesDataBox* dataBox;
+};
+
+MP4::ITunesTrknBox::ITunesTrknBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
+ :Mp4IsoBox(file, fourcc, size, offset)
+{
+ d = new MP4::ITunesTrknBox::ITunesTrknBoxPrivate();
+ d->dataBox = 0;
+}
+
+MP4::ITunesTrknBox::~ITunesTrknBox()
+{
+ if( d->dataBox != 0 )
+ delete d->dataBox;
+ delete d;
+}
+
+//! parse the content of the box
+void MP4::ITunesTrknBox::parse()
+{
+ TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
+
+ // parse data box
+ TagLib::uint size;
+ MP4::Fourcc fourcc;
+
+ if(mp4file->readSizeAndType( size, fourcc ) == true)
+ {
+ // check for type - must be 'data'
+ if( fourcc != MP4::Fourcc("data") )
+ {
+ std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
+ // jump over data tag
+ mp4file->seek( size-8, TagLib::File::Current );
+ return;
+ }
+ d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
+ d->dataBox->parsebox();
+ }
+ else
+ {
+ // reading unsuccessful - serious error!
+ std::cerr << "Error in parsing ITunesTrknBox - serious Error in taglib!" << std::endl;
+ return;
+ }
+ // register data box
+ mp4file->tagProxy()->registerBox( Mp4TagsProxy::trackno, d->dataBox );
+
+#if 0
+ // get data pointer - just for debugging...
+ TagLib::ByteVector trknData = d->dataBox->data();
+ TagLib::String trknumber = TagLib::String::number( static_cast<int>( static_cast<unsigned char>(trknData[0]) << 24 |
+ static_cast<unsigned char>(trknData[1]) << 16 |
+ static_cast<unsigned char>(trknData[2]) << 8 |
+ static_cast<unsigned char>(trknData[3]) ) );
+ std::cout << "Content of tracknumber box: " << trknumber << std::endl;
+#endif
+}
+
diff --git a/src/metadata/m4a/itunestrknbox.h b/src/metadata/m4a/itunestrknbox.h
new file mode 100644
index 0000000..f603e1f
--- /dev/null
+++ b/src/metadata/m4a/itunestrknbox.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef ITUNESTRKNBOX_H
+#define ITUNESTRKNBOX_H
+
+#include "mp4isobox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class ITunesTrknBox: public Mp4IsoBox
+ {
+ public:
+ ITunesTrknBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
+ ~ITunesTrknBox();
+
+ private:
+ //! parse the content of the box
+ virtual void parse();
+
+ protected:
+ class ITunesTrknBoxPrivate;
+ ITunesTrknBoxPrivate* d;
+ }; // class ITunesTrknBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // ITUNESTRKNBOX_H
diff --git a/src/metadata/m4a/ituneswrtbox.cpp b/src/metadata/m4a/ituneswrtbox.cpp
new file mode 100644
index 0000000..ecf3c43
--- /dev/null
+++ b/src/metadata/m4a/ituneswrtbox.cpp
@@ -0,0 +1,89 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <iostream>
+#include "ituneswrtbox.h"
+#include "itunesdatabox.h"
+#include "mp4isobox.h"
+#include "mp4file.h"
+#include "tfile.h"
+#include "mp4tagsproxy.h"
+
+using namespace TagLib;
+
+class MP4::ITunesWrtBox::ITunesWrtBoxPrivate
+{
+public:
+ ITunesDataBox* dataBox;
+};
+
+MP4::ITunesWrtBox::ITunesWrtBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
+ :Mp4IsoBox(file, fourcc, size, offset)
+{
+ d = new MP4::ITunesWrtBox::ITunesWrtBoxPrivate();
+ d->dataBox = 0;
+}
+
+MP4::ITunesWrtBox::~ITunesWrtBox()
+{
+ if( d->dataBox != 0 )
+ delete d->dataBox;
+ delete d;
+}
+
+//! parse the content of the box
+void MP4::ITunesWrtBox::parse()
+{
+ TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
+
+ // parse data box
+ TagLib::uint size;
+ MP4::Fourcc fourcc;
+
+ if(mp4file->readSizeAndType( size, fourcc ) == true)
+ {
+ // check for type - must be 'data'
+ if( fourcc != MP4::Fourcc("data") )
+ {
+ std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
+ // jump over data tag
+ mp4file->seek( size-8, TagLib::File::Current );
+ return;
+ }
+ d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
+ d->dataBox->parsebox();
+ }
+ else
+ {
+ // reading unsuccessful - serious error!
+ std::cerr << "Error in parsing ITunesWrtBox - serious Error in taglib!" << std::endl;
+ return;
+ }
+ // register data box
+ mp4file->tagProxy()->registerBox( Mp4TagsProxy::composer, d->dataBox );
+
+#if 0
+ // get data pointer - just for debugging...
+ TagLib::String dataString( d->dataBox->data() );
+ std::cout << "Content of title box: " << dataString << std::endl;
+#endif
+}
+
diff --git a/src/metadata/m4a/ituneswrtbox.h b/src/metadata/m4a/ituneswrtbox.h
new file mode 100644
index 0000000..740d94c
--- /dev/null
+++ b/src/metadata/m4a/ituneswrtbox.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef ITUNESWRTBOX_H
+#define ITUNESWRTBOX_H
+
+#include "mp4isobox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class ITunesWrtBox: public Mp4IsoBox
+ {
+ public:
+ ITunesWrtBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
+ ~ITunesWrtBox();
+
+ private:
+ //! parse the content of the box
+ virtual void parse();
+
+ protected:
+ class ITunesWrtBoxPrivate;
+ ITunesWrtBoxPrivate* d;
+ }; // class ITunesWrtBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // ITUNESWRTBOX_H
diff --git a/src/metadata/m4a/mp4audioproperties.cpp b/src/metadata/m4a/mp4audioproperties.cpp
new file mode 100644
index 0000000..77afab1
--- /dev/null
+++ b/src/metadata/m4a/mp4audioproperties.cpp
@@ -0,0 +1,75 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "mp4audioproperties.h"
+#include "mp4propsproxy.h"
+
+using namespace TagLib;
+
+class MP4::AudioProperties::AudioPropertiesPrivate
+{
+public:
+ MP4::Mp4PropsProxy* propsproxy;
+}; // AudioPropertiesPrivate
+
+MP4::AudioProperties::AudioProperties():TagLib::AudioProperties(TagLib::AudioProperties::Average)
+{
+ d = new MP4::AudioProperties::AudioPropertiesPrivate();
+}
+
+MP4::AudioProperties::~AudioProperties()
+{
+ delete d;
+}
+
+void MP4::AudioProperties::setProxy( Mp4PropsProxy* proxy )
+{
+ d->propsproxy = proxy;
+}
+
+int MP4::AudioProperties::length() const
+{
+ if( d->propsproxy == 0 )
+ return 0;
+ return d->propsproxy->seconds();
+}
+
+int MP4::AudioProperties::bitrate() const
+{
+ if( d->propsproxy == 0 )
+ return 0;
+ return d->propsproxy->bitRate()/1000;
+}
+
+int MP4::AudioProperties::sampleRate() const
+{
+ if( d->propsproxy == 0 )
+ return 0;
+ return d->propsproxy->sampleRate();
+}
+
+int MP4::AudioProperties::channels() const
+{
+ if( d->propsproxy == 0 )
+ return 0;
+ return d->propsproxy->channels();
+}
+
diff --git a/src/metadata/m4a/mp4audioproperties.h b/src/metadata/m4a/mp4audioproperties.h
new file mode 100644
index 0000000..4e61790
--- /dev/null
+++ b/src/metadata/m4a/mp4audioproperties.h
@@ -0,0 +1,73 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef MP4AUDIOPROPERTIES_H
+#define MP4AUDIOPROPERTIES_H MP4AUDIOPROPERTIES_H
+
+#include "audioproperties.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class Mp4PropsProxy;
+
+ class AudioProperties : public TagLib::AudioProperties
+ {
+ public:
+ //! constructor
+ AudioProperties();
+ //! destructor
+ ~AudioProperties();
+
+ //! function to set the proxy
+ void setProxy( Mp4PropsProxy* proxy );
+
+ /*!
+ * Returns the length of the file in seconds.
+ */
+ int length() const;
+
+ /*!
+ * Returns the most appropriate bit rate for the file in kb/s. For constant
+ * bitrate formats this is simply the bitrate of the file. For variable
+ * bitrate formats this is either the average or nominal bitrate.
+ */
+ int bitrate() const;
+
+ /*!
+ * Returns the sample rate in Hz.
+ */
+ int sampleRate() const;
+
+ /*!
+ * Returns the number of audio channels.
+ */
+ int channels() const;
+
+ private:
+ class AudioPropertiesPrivate;
+ AudioPropertiesPrivate* d;
+ };
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // MP4AUDIOPROPERTIES_H
diff --git a/src/metadata/m4a/mp4audiosampleentry.cpp b/src/metadata/m4a/mp4audiosampleentry.cpp
new file mode 100644
index 0000000..fb87547
--- /dev/null
+++ b/src/metadata/m4a/mp4audiosampleentry.cpp
@@ -0,0 +1,146 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <iostream>
+#include "mp4audiosampleentry.h"
+#include "mp4isobox.h"
+#include "mp4file.h"
+#include "mp4propsproxy.h"
+
+using namespace TagLib;
+
+class MP4::Mp4AudioSampleEntry::Mp4AudioSampleEntryPrivate
+{
+public:
+ TagLib::uint channelcount;
+ TagLib::uint samplerate;
+ TagLib::uint bitrate;
+};
+
+MP4::Mp4AudioSampleEntry::Mp4AudioSampleEntry( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
+ :Mp4SampleEntry(file, fourcc, size, offset)
+{
+ d = new MP4::Mp4AudioSampleEntry::Mp4AudioSampleEntryPrivate();
+}
+
+MP4::Mp4AudioSampleEntry::~Mp4AudioSampleEntry()
+{
+ delete d;
+}
+
+TagLib::uint MP4::Mp4AudioSampleEntry::channels() const
+{
+ return d->channelcount;
+}
+
+TagLib::uint MP4::Mp4AudioSampleEntry::samplerate() const
+{
+ return d->samplerate;
+}
+
+TagLib::uint MP4::Mp4AudioSampleEntry::bitrate() const
+{
+ return d->bitrate;
+}
+
+void MP4::Mp4AudioSampleEntry::parseEntry()
+{
+ TagLib::MP4::File* mp4file = dynamic_cast<TagLib::MP4::File*>(file());
+ if(!mp4file)
+ return;
+
+ // read 8 reserved bytes
+ mp4file->seek( 8, TagLib::File::Current );
+ // read channelcount
+ if(!mp4file->readShort( d->channelcount ))
+ return;
+ // seek over samplesize, pre_defined and reserved
+ mp4file->seek( 6, TagLib::File::Current );
+ // read samplerate
+ if(!mp4file->readInt( d->samplerate ))
+ return;
+
+ // register box at proxy
+ mp4file->propProxy()->registerAudioSampleEntry( this );
+
+
+ //std::cout << "fourcc of audio sample entry: " << fourcc().toString() << std::endl;
+ // check for both mp4a (plain files) and drms (encrypted files)
+ if( (fourcc() == MP4::Fourcc("mp4a")) ||
+ (fourcc() == MP4::Fourcc("drms")) )
+ {
+ TagLib::MP4::Fourcc fourcc;
+ TagLib::uint esds_size;
+
+ if (!mp4file->readSizeAndType( esds_size, fourcc ))
+ return;
+
+ // read esds' main parts
+ if( size()-48 > 0 )
+ ByteVector flags_version = mp4file->readBlock(4);
+ else
+ return;
+
+ ByteVector EsDescrTag = mp4file->readBlock(1);
+ // first 4 bytes contain full box specifics (version & flags)
+ // upcoming byte must be ESDescrTag (0x03)
+ if( EsDescrTag[0] == 0x03 )
+ {
+ TagLib::uint descr_len = mp4file->readSystemsLen();
+ TagLib::uint EsId;
+ if( !mp4file->readShort( EsId ) )
+ return;
+ ByteVector priority = mp4file->readBlock(1);
+ if( descr_len < 20 )
+ return;
+ }
+ else
+ {
+ TagLib::uint EsId;
+ if( !mp4file->readShort( EsId ) )
+ return;
+ }
+ // read decoder configuration tag (0x04)
+ ByteVector DecCfgTag = mp4file->readBlock(1);
+ if( DecCfgTag[0] != 0x04 )
+ return;
+ // read decoder configuration length
+ // TagLib::uint deccfg_len = mp4file->readSystemsLen();
+ // read object type Id
+ ByteVector objId = mp4file->readBlock(1);
+ // read stream type id
+ ByteVector strId = mp4file->readBlock(1);
+ // read buffer Size DB
+ ByteVector bufferSizeDB = mp4file->readBlock(3);
+ // read max bitrate
+ TagLib::uint max_bitrate;
+ if( !mp4file->readInt( max_bitrate ) )
+ return;
+ // read average bitrate
+ if( !mp4file->readInt( d->bitrate ) )
+ return;
+ // skip the rest
+ mp4file->seek( offset()+size()-8, File::Beginning );
+ }
+ else
+ mp4file->seek( size()-36, File::Current );
+}
+
diff --git a/src/metadata/m4a/mp4audiosampleentry.h b/src/metadata/m4a/mp4audiosampleentry.h
new file mode 100644
index 0000000..c39c5e3
--- /dev/null
+++ b/src/metadata/m4a/mp4audiosampleentry.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef MP4AUDIOSAMPLEENTRY_H
+#define MP4AUDIOSAMPLEENTRY_H
+
+#include "mp4sampleentry.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class Mp4AudioSampleEntry: public Mp4SampleEntry
+ {
+ public:
+ Mp4AudioSampleEntry( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
+ ~Mp4AudioSampleEntry();
+
+ //! function to get the number of channels
+ TagLib::uint channels() const;
+ //! function to get the sample rate
+ TagLib::uint samplerate() const;
+ //! function to get the average bitrate of the audio stream
+ TagLib::uint bitrate() const;
+
+ private:
+ //! parse the content of the box
+ void parseEntry();
+
+ protected:
+ class Mp4AudioSampleEntryPrivate;
+ Mp4AudioSampleEntryPrivate* d;
+ }; // class Mp4AudioSampleEntry
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // MP4AUDIOSAMPLEENTRY_H
diff --git a/src/metadata/m4a/mp4file.cpp b/src/metadata/m4a/mp4file.cpp
new file mode 100644
index 0000000..7d37d59
--- /dev/null
+++ b/src/metadata/m4a/mp4file.cpp
@@ -0,0 +1,377 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <tbytevector.h>
+#include <tstring.h>
+#include "tlist.h"
+
+#include "mp4itunestag.h"
+#include "mp4file.h"
+#include "boxfactory.h"
+#include "mp4tagsproxy.h"
+#include "mp4propsproxy.h"
+#include "mp4audioproperties.h"
+#include "itunesdatabox.h"
+
+using namespace TagLib;
+
+class MP4::File::FilePrivate
+{
+public:
+ //! list for all boxes of the mp4 file
+ TagLib::List<MP4::Mp4IsoBox*> boxes;
+ //! the box factory - will create all boxes by tag and size
+ MP4::BoxFactory boxfactory;
+ //! proxy for the tags is filled after parsing
+ MP4::Mp4TagsProxy tagsProxy;
+ //! proxy for audio properties
+ MP4::Mp4PropsProxy propsProxy;
+ //! the tag returned by tag() function
+ MP4::Tag mp4tag;
+ //! container for the audio properties returned by properties() function
+ MP4::AudioProperties mp4audioproperties;
+ //! is set to valid after successfully parsing
+ bool isValid;
+};
+
+//! function to fill the tags with converted proxy data, which has been parsed out of the file previously
+static void fillTagFromProxy( MP4::Mp4TagsProxy& proxy, MP4::Tag& mp4tag );
+
+MP4::File::File(const char *file, bool , AudioProperties::ReadStyle )
+ :TagLib::File( file )
+{
+ // create member container
+ d = new MP4::File::FilePrivate();
+
+
+ d->isValid = false;
+ TagLib::uint size;
+ MP4::Fourcc fourcc;
+
+ while( readSizeAndType( size, fourcc ) == true )
+ {
+ // create the appropriate subclass and parse it
+ MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( this, fourcc, size, tell() );
+ curbox->parsebox();
+ d->boxes.append( curbox );
+ }
+
+ for( TagLib::List<MP4::Mp4IsoBox*>::Iterator iter = d->boxes.begin();
+ iter != d->boxes.end();
+ iter++ )
+ {
+ if( (*iter)->fourcc() == MP4::Fourcc("moov") )
+ {
+ d->isValid = true;
+ break;
+ }
+ }
+
+ //if( d->isValid )
+ //debug( "file is valid" );
+ //else
+ //debug( "file is NOT valid" );
+
+ // fill tags from proxy data
+ fillTagFromProxy( d->tagsProxy, d->mp4tag );
+}
+
+MP4::File::~File()
+{
+ TagLib::List<Mp4IsoBox*>::Iterator delIter;
+ for( delIter = d->boxes.begin();
+ delIter != d->boxes.end();
+ delIter++ )
+ {
+ delete *delIter;
+ }
+ delete d;
+}
+
+Tag *MP4::File::tag() const
+{
+ return &d->mp4tag;
+}
+
+AudioProperties * MP4::File::audioProperties() const
+{
+ d->mp4audioproperties.setProxy( &d->propsProxy );
+ return &d->mp4audioproperties;
+}
+
+bool MP4::File::save()
+{
+ return false;
+}
+
+void MP4::File::remove()
+{
+}
+
+TagLib::uint MP4::File::readSystemsLen()
+{
+ TagLib::uint length = 0;
+ TagLib::uint nbytes = 0;
+ ByteVector input;
+ TagLib::uchar tmp_input;
+
+ do
+ {
+ input = readBlock(1);
+ tmp_input = static_cast<TagLib::uchar>(input[0]);
+ nbytes++;
+ length = (length<<7) | (tmp_input&0x7F);
+ } while( (tmp_input&0x80) && (nbytes<4) );
+
+ return length;
+}
+
+bool MP4::File::readSizeAndType( TagLib::uint& size, MP4::Fourcc& fourcc )
+{
+ // read the two blocks from file
+ ByteVector readsize = readBlock(4);
+ ByteVector readtype = readBlock(4);
+
+ if( (readsize.size() != 4) || (readtype.size() != 4) )
+ return false;
+
+ // set size
+ size = static_cast<unsigned char>(readsize[0]) << 24 |
+ static_cast<unsigned char>(readsize[1]) << 16 |
+ static_cast<unsigned char>(readsize[2]) << 8 |
+ static_cast<unsigned char>(readsize[3]);
+
+ // type and size seem to be part of the stored size
+ if( size < 8 )
+ return false;
+
+ // set fourcc
+ fourcc = readtype.data();
+
+ return true;
+}
+
+bool MP4::File::readInt( TagLib::uint& toRead )
+{
+ ByteVector readbuffer = readBlock(4);
+ if( readbuffer.size() != 4 )
+ return false;
+
+ toRead = static_cast<unsigned char>(readbuffer[0]) << 24 |
+ static_cast<unsigned char>(readbuffer[1]) << 16 |
+ static_cast<unsigned char>(readbuffer[2]) << 8 |
+ static_cast<unsigned char>(readbuffer[3]);
+ return true;
+}
+
+bool MP4::File::readShort( TagLib::uint& toRead )
+{
+ ByteVector readbuffer = readBlock(2);
+ if( readbuffer.size() != 2 )
+ return false;
+
+ toRead = static_cast<unsigned char>(readbuffer[0]) << 8 |
+ static_cast<unsigned char>(readbuffer[1]);
+ return true;
+}
+
+bool MP4::File::readLongLong( TagLib::ulonglong& toRead )
+{
+ ByteVector readbuffer = readBlock(8);
+ if( readbuffer.size() != 8 )
+ return false;
+
+ toRead = static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[0])) << 56 |
+ static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[1])) << 48 |
+ static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[2])) << 40 |
+ static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[3])) << 32 |
+ static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[4])) << 24 |
+ static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[5])) << 16 |
+ static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[6])) << 8 |
+ static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[7]));
+ return true;
+}
+
+bool MP4::File::readFourcc( TagLib::MP4::Fourcc& fourcc )
+{
+ ByteVector readtype = readBlock(4);
+
+ if( readtype.size() != 4)
+ return false;
+
+ // set fourcc
+ fourcc = readtype.data();
+
+ return true;
+}
+
+MP4::Mp4TagsProxy* MP4::File::tagProxy() const
+{
+ return &d->tagsProxy;
+}
+
+MP4::Mp4PropsProxy* MP4::File::propProxy() const
+{
+ return &d->propsProxy;
+}
+
+void fillTagFromProxy( MP4::Mp4TagsProxy& proxy, MP4::Tag& mp4tag )
+{
+ // tmp buffer for each tag
+ MP4::ITunesDataBox* databox;
+
+ databox = proxy.titleData();
+ if( databox != 0 )
+ {
+ // convert data to string
+ TagLib::String datastring( databox->data(), String::UTF8 );
+ // check if string was set
+ if( !datastring.isEmpty() )
+ mp4tag.setTitle( datastring );
+ }
+
+ databox = proxy.artistData();
+ if( databox != 0 )
+ {
+ // convert data to string
+ TagLib::String datastring( databox->data(), String::UTF8 );
+ // check if string was set
+ if( !datastring.isEmpty() )
+ mp4tag.setArtist( datastring );
+ }
+
+ databox = proxy.albumData();
+ if( databox != 0 )
+ {
+ // convert data to string
+ TagLib::String datastring( databox->data(), String::UTF8 );
+ // check if string was set
+ if( !datastring.isEmpty() )
+ mp4tag.setAlbum( datastring );
+ }
+
+ databox = proxy.genreData();
+ if( databox != 0 )
+ {
+ // convert data to string
+ TagLib::String datastring( databox->data(), String::UTF8 );
+ // check if string was set
+ if( !datastring.isEmpty() )
+ mp4tag.setGenre( datastring );
+ }
+
+ databox = proxy.yearData();
+ if( databox != 0 )
+ {
+ // convert data to string
+ TagLib::String datastring( databox->data(), String::UTF8 );
+ // check if string was set
+ if( !datastring.isEmpty() )
+ mp4tag.setYear( datastring.toInt() );
+ }
+
+ databox = proxy.trknData();
+ if( databox != 0 )
+ {
+ // convert data to uint
+ TagLib::ByteVector datavec = databox->data();
+ if( datavec.size() >= 4 )
+ {
+ TagLib::uint trackno = static_cast<TagLib::uint>( static_cast<unsigned char>(datavec[0]) << 24 |
+ static_cast<unsigned char>(datavec[1]) << 16 |
+ static_cast<unsigned char>(datavec[2]) << 8 |
+ static_cast<unsigned char>(datavec[3]) );
+ mp4tag.setTrack( trackno );
+ }
+ else
+ mp4tag.setTrack( 0 );
+ }
+
+ databox = proxy.commentData();
+ if( databox != 0 )
+ {
+ // convert data to string
+ TagLib::String datastring( databox->data(), String::UTF8 );
+ // check if string was set
+ if( !datastring.isEmpty() )
+ mp4tag.setComment( datastring );
+ }
+
+ databox = proxy.groupingData();
+ if( databox != 0 )
+ {
+ // convert data to string
+ TagLib::String datastring( databox->data(), String::UTF8 );
+ // check if string was set
+ if( !datastring.isEmpty() )
+ mp4tag.setGrouping( datastring );
+ }
+
+ databox = proxy.composerData();
+ if( databox != 0 )
+ {
+ // convert data to string
+ TagLib::String datastring( databox->data(), String::UTF8 );
+ // check if string was set
+ if( !datastring.isEmpty() )
+ mp4tag.setComposer( datastring );
+ }
+
+ databox = proxy.diskData();
+ if( databox != 0 )
+ {
+ // convert data to uint
+ TagLib::ByteVector datavec = databox->data();
+ if( datavec.size() >= 4 )
+ {
+ TagLib::uint discno = static_cast<TagLib::uint>( static_cast<unsigned char>(datavec[0]) << 24 |
+ static_cast<unsigned char>(datavec[1]) << 16 |
+ static_cast<unsigned char>(datavec[2]) << 8 |
+ static_cast<unsigned char>(datavec[3]) );
+ mp4tag.setDisk( discno );
+ }
+ else
+ mp4tag.setDisk( 0 );
+ }
+
+ databox = proxy.bpmData();
+ if( databox != 0 )
+ {
+ // convert data to uint
+ TagLib::ByteVector datavec = databox->data();
+
+ if( datavec.size() >= 2 )
+ {
+ TagLib::uint bpm = static_cast<TagLib::uint>( static_cast<unsigned char>(datavec[0]) << 8 |
+ static_cast<unsigned char>(datavec[1]) );
+ mp4tag.setBpm( bpm );
+ }
+ else
+ mp4tag.setBpm( 0 );
+ }
+
+ databox = proxy.coverData();
+ if( databox != 0 )
+ {
+ // get byte vector
+ mp4tag.setCover( databox->data() );
+ }
+}
diff --git a/src/metadata/m4a/mp4file.h b/src/metadata/m4a/mp4file.h
new file mode 100644
index 0000000..9e40dbc
--- /dev/null
+++ b/src/metadata/m4a/mp4file.h
@@ -0,0 +1,169 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+/***************************************************************************
+ copyright : (C) 2002, 2003 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 *
+ * USA *
+ ***************************************************************************/
+
+#ifndef TAGLIB_MP4FILE_H
+#define TAGLIB_MP4FILE_H
+
+#include <tfile.h>
+#include <audioproperties.h>
+
+#include "mp4fourcc.h"
+
+namespace TagLib {
+
+ typedef unsigned long long ulonglong;
+
+ class Tag;
+
+ namespace MP4
+ {
+ class Mp4TagsProxy;
+ class Mp4PropsProxy;
+
+ //! An implementation of TagLib::File with mp4 itunes specific methods
+
+ /*!
+ * This implements and provides an interface for mp4 itunes files to the
+ * TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing
+ * the abstract TagLib::File API as well as providing some additional
+ * information specific to mp4 itunes files. (TODO)
+ */
+
+ class File : public TagLib::File
+ {
+ public:
+ /*!
+ * Contructs an mp4 itunes 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.
+ */
+ File(const char *file, bool readProperties = true,
+ AudioProperties::ReadStyle propertiesStyle = AudioProperties::Average);
+
+ /*!
+ * Destroys this instance of the File.
+ */
+ virtual ~File();
+
+ /*!
+ * Returns the Tag for this file. This will be an APE tag, an ID3v1 tag
+ * or a combination of the two.
+ */
+ virtual TagLib::Tag *tag() const;
+
+ /*!
+ * Returns the mp4 itunes::Properties for this file. If no audio properties
+ * were read then this will return a null pointer.
+ */
+ virtual AudioProperties *audioProperties() const;
+
+ /*!
+ * Saves the file.
+ */
+ virtual bool save();
+
+ /*!
+ * This will remove all tags.
+ *
+ * \note This will also invalidate pointers to the tags
+ * as their memory will be freed.
+ * \note In order to make the removal permanent save() still needs to be called
+ */
+ void remove();
+
+ /*!
+ * Helper function for parsing the MP4 file - reads the size and type of the next box.
+ * Returns true if read succeeded - not at EOF
+ */
+ bool readSizeAndType( TagLib::uint& size, MP4::Fourcc& fourcc );
+
+ /*!
+ * Helper function to read the length of an descriptor in systems manner
+ */
+ TagLib::uint readSystemsLen();
+
+ /*!
+ * Helper function for reading an unsigned int out of the file (big endian method)
+ */
+ bool readInt( TagLib::uint& toRead );
+
+ /*!
+ * Helper function for reading an unsigned short out of the file (big endian method)
+ */
+ bool readShort( TagLib::uint& toRead );
+
+ /*!
+ * Helper function for reading an unsigned long long (64bit) out of the file (big endian method)
+ */
+ bool readLongLong( TagLib::ulonglong& toRead );
+
+ /*!
+ * Helper function to read a fourcc code
+ */
+ bool readFourcc( TagLib::MP4::Fourcc& fourcc );
+
+ /*!
+ * Function to get the tags proxy for registration of the tags boxes.
+ * The proxy provides direct access to the data boxes of the certain tags - normally
+ * covered by several levels of subboxes
+ */
+ Mp4TagsProxy* tagProxy() const;
+
+ /*!
+ * Function to get the properties proxy for registration of the properties boxes.
+ * The proxy provides direct access to the needed boxes describing audio properties.
+ */
+ Mp4PropsProxy* propProxy() const;
+
+ private:
+ File(const File &);
+ File &operator=(const File &);
+
+ class FilePrivate;
+ FilePrivate *d;
+ };
+
+ } // namespace MP4
+
+} // namespace TagLib
+
+#endif // TAGLIB_MP4FILE_H
diff --git a/src/metadata/m4a/mp4fourcc.cpp b/src/metadata/m4a/mp4fourcc.cpp
new file mode 100644
index 0000000..dac0f99
--- /dev/null
+++ b/src/metadata/m4a/mp4fourcc.cpp
@@ -0,0 +1,84 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "mp4fourcc.h"
+
+using namespace TagLib;
+
+MP4::Fourcc::Fourcc()
+{
+ m_fourcc = 0U;
+}
+
+MP4::Fourcc::Fourcc( TagLib::String fourcc )
+{
+ m_fourcc = 0U;
+
+ if( fourcc.size() >= 4 )
+ m_fourcc = static_cast<unsigned char>(fourcc[0]) << 24 |
+ static_cast<unsigned char>(fourcc[1]) << 16 |
+ static_cast<unsigned char>(fourcc[2]) << 8 |
+ static_cast<unsigned char>(fourcc[3]);
+}
+
+MP4::Fourcc::~Fourcc()
+{}
+
+TagLib::String MP4::Fourcc::toString() const
+{
+ TagLib::String fourcc;
+ fourcc.append(static_cast<char>(m_fourcc >> 24 & 0xFF));
+ fourcc.append(static_cast<char>(m_fourcc >> 16 & 0xFF));
+ fourcc.append(static_cast<char>(m_fourcc >> 8 & 0xFF));
+ fourcc.append(static_cast<char>(m_fourcc & 0xFF));
+
+ return fourcc;
+}
+
+MP4::Fourcc::operator unsigned int() const
+{
+ return m_fourcc;
+}
+
+bool MP4::Fourcc::operator == (unsigned int fourccB ) const
+{
+ return (m_fourcc==fourccB);
+}
+
+bool MP4::Fourcc::operator != (unsigned int fourccB ) const
+{
+ return (m_fourcc!=fourccB);
+}
+
+MP4::Fourcc& MP4::Fourcc::operator = (unsigned int fourcc )
+{
+ m_fourcc = fourcc;
+ return *this;
+}
+
+MP4::Fourcc& MP4::Fourcc::operator = (char fourcc[4])
+{
+ m_fourcc = static_cast<unsigned char>(fourcc[0]) << 24 |
+ static_cast<unsigned char>(fourcc[1]) << 16 |
+ static_cast<unsigned char>(fourcc[2]) << 8 |
+ static_cast<unsigned char>(fourcc[3]);
+ return *this;
+}
diff --git a/src/metadata/m4a/mp4fourcc.h b/src/metadata/m4a/mp4fourcc.h
new file mode 100644
index 0000000..90e498a
--- /dev/null
+++ b/src/metadata/m4a/mp4fourcc.h
@@ -0,0 +1,63 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef MP4FOURCC_H
+#define MP4FOURCC_H
+
+#include "tstring.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ /*! union for easy fourcc / type handling */
+ class Fourcc
+ {
+ public:
+ //! std constructor
+ Fourcc();
+ //! string constructor
+ Fourcc(TagLib::String fourcc);
+
+ //! destructor
+ ~Fourcc();
+
+ //! function to get a string version of the fourcc
+ TagLib::String toString() const;
+ //! cast operator to unsigned int
+ operator unsigned int() const;
+ //! comparison operator
+ bool operator == (unsigned int fourccB ) const;
+ //! comparison operator
+ bool operator != (unsigned int fourccB ) const;
+ //! assigment operator for unsigned int
+ Fourcc& operator = (unsigned int fourcc );
+ //! assigment operator for character string
+ Fourcc& operator = (char fourcc[4]);
+
+ private:
+ uint m_fourcc; /*!< integer code of the fourcc */
+ };
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // MP4FOURCC_H
diff --git a/src/metadata/m4a/mp4hdlrbox.cpp b/src/metadata/m4a/mp4hdlrbox.cpp
new file mode 100644
index 0000000..a3ec5f7
--- /dev/null
+++ b/src/metadata/m4a/mp4hdlrbox.cpp
@@ -0,0 +1,75 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <deque>
+#include <iostream>
+#include "mp4hdlrbox.h"
+#include "boxfactory.h"
+#include "mp4file.h"
+
+using namespace TagLib;
+
+class MP4::Mp4HdlrBox::Mp4HdlrBoxPrivate
+{
+public:
+ TagLib::uint pre_defined;
+ MP4::Fourcc handler_type;
+ TagLib::String hdlr_string;
+}; // class Mp4HdlrBoxPrivate
+
+MP4::Mp4HdlrBox::Mp4HdlrBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
+ : Mp4IsoFullBox( file, fourcc, size, offset )
+{
+ d = new MP4::Mp4HdlrBox::Mp4HdlrBoxPrivate();
+}
+
+MP4::Mp4HdlrBox::~Mp4HdlrBox()
+{
+ delete d;
+}
+
+MP4::Fourcc MP4::Mp4HdlrBox::hdlr_type() const
+{
+ return d->handler_type;
+}
+
+TagLib::String MP4::Mp4HdlrBox::hdlr_string() const
+{
+ return d->hdlr_string;
+}
+
+void MP4::Mp4HdlrBox::parse()
+{
+ TagLib::uint totalread = 12+20;
+
+ TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
+ if( mp4file->readInt( d->pre_defined ) == false )
+ return;
+ if( mp4file->readFourcc( d->handler_type ) == false )
+ return;
+
+ // read reserved into trash
+ mp4file->seek( 3*4, TagLib::File::Current );
+
+ // check if there are bytes remaining - used for hdlr string
+ if( size() - totalread != 0 )
+ d->hdlr_string = mp4file->readBlock( size()-totalread );
+}
diff --git a/src/metadata/m4a/mp4hdlrbox.h b/src/metadata/m4a/mp4hdlrbox.h
new file mode 100644
index 0000000..0a6bf54
--- /dev/null
+++ b/src/metadata/m4a/mp4hdlrbox.h
@@ -0,0 +1,53 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef MP4HDLRBOX_H
+#define MP4HDLRBOX_H
+
+#include "mp4isofullbox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class Mp4HdlrBox: public Mp4IsoFullBox
+ {
+ public:
+ Mp4HdlrBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
+ ~Mp4HdlrBox();
+
+ //! parse hdlr contents
+ void parse();
+ //! get the handler type
+ MP4::Fourcc hdlr_type() const;
+ //! get the hdlr string
+ TagLib::String hdlr_string() const;
+
+ private:
+ class Mp4HdlrBoxPrivate;
+ Mp4HdlrBoxPrivate* d;
+ }; // Mp4HdlrBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // MP4HDLRBOX_H
diff --git a/src/metadata/m4a/mp4ilstbox.cpp b/src/metadata/m4a/mp4ilstbox.cpp
new file mode 100644
index 0000000..1d5ae9a
--- /dev/null
+++ b/src/metadata/m4a/mp4ilstbox.cpp
@@ -0,0 +1,97 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "tlist.h"
+#include <iostream>
+#include "mp4ilstbox.h"
+#include "boxfactory.h"
+#include "mp4file.h"
+
+using namespace TagLib;
+
+class MP4::Mp4IlstBox::Mp4IlstBoxPrivate
+{
+public:
+ //! container for all boxes in ilst box
+ TagLib::List<Mp4IsoBox*> ilstBoxes;
+ //! a box factory for creating the appropriate boxes
+ MP4::BoxFactory boxfactory;
+}; // class Mp4IlstBoxPrivate
+
+MP4::Mp4IlstBox::Mp4IlstBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
+ : Mp4IsoBox( file, fourcc, size, offset )
+{
+ d = new MP4::Mp4IlstBox::Mp4IlstBoxPrivate();
+}
+
+MP4::Mp4IlstBox::~Mp4IlstBox()
+{
+ TagLib::List<Mp4IsoBox*>::Iterator delIter;
+ for( delIter = d->ilstBoxes.begin();
+ delIter != d->ilstBoxes.end();
+ delIter++ )
+ {
+ delete *delIter;
+ }
+ delete d;
+}
+
+void MP4::Mp4IlstBox::parse()
+{
+#if 0
+ std::cout << " parsing ilst box" << std::endl;
+#endif
+
+ TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
+
+ TagLib::uint totalsize = 8;
+ // parse all contained boxes
+ TagLib::uint size;
+ MP4::Fourcc fourcc;
+
+#if 0
+ std::cout << " ";
+#endif
+ while( (mp4file->readSizeAndType( size, fourcc ) == true) )
+ {
+ totalsize += size;
+
+ // check for errors
+ if( totalsize > MP4::Mp4IsoBox::size() )
+ {
+ std::cerr << "Error in mp4 file " << mp4file->name() << " ilst box contains bad box with name: " << fourcc.toString() << std::endl;
+ return;
+ }
+
+ // create the appropriate subclass and parse it
+ MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( mp4file, fourcc, size, mp4file->tell() );
+ curbox->parsebox();
+ d->ilstBoxes.append( curbox );
+
+ // check for end of ilst box
+ if( totalsize == MP4::Mp4IsoBox::size() )
+ break;
+
+#if 0
+ std::cout << " ";
+#endif
+ }
+}
diff --git a/src/metadata/m4a/mp4ilstbox.h b/src/metadata/m4a/mp4ilstbox.h
new file mode 100644
index 0000000..9e7ad1c
--- /dev/null
+++ b/src/metadata/m4a/mp4ilstbox.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef MP4ILSTBOX_H
+#define MP4ILSTBOX_H
+
+#include "mp4isobox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class Mp4IlstBox: public Mp4IsoBox
+ {
+ public:
+ Mp4IlstBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
+ ~Mp4IlstBox();
+
+ //! parse ilst contents
+ void parse();
+
+ private:
+ class Mp4IlstBoxPrivate;
+ Mp4IlstBoxPrivate* d;
+ }; // Mp4IlstBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // MP4ILSTBOX_H
diff --git a/src/metadata/m4a/mp4isobox.cpp b/src/metadata/m4a/mp4isobox.cpp
new file mode 100644
index 0000000..7f08924
--- /dev/null
+++ b/src/metadata/m4a/mp4isobox.cpp
@@ -0,0 +1,76 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "mp4isobox.h"
+#include "tfile.h"
+
+using namespace TagLib;
+
+class MP4::Mp4IsoBox::Mp4IsoBoxPrivate
+{
+public:
+ MP4::Fourcc fourcc;
+ TagLib::uint size;
+ long offset;
+ TagLib::File* file;
+};
+
+MP4::Mp4IsoBox::Mp4IsoBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
+{
+ d = new MP4::Mp4IsoBox::Mp4IsoBoxPrivate();
+ d->file = file;
+ d->fourcc = fourcc;
+ d->size = size;
+ d->offset = offset;
+}
+
+MP4::Mp4IsoBox::~Mp4IsoBox()
+{
+ delete d;
+}
+
+void MP4::Mp4IsoBox::parsebox()
+{
+ // seek to offset
+ file()->seek( offset(), File::Beginning );
+ // simply call parse method of sub class
+ parse();
+}
+
+MP4::Fourcc MP4::Mp4IsoBox::fourcc() const
+{
+ return d->fourcc;
+}
+
+TagLib::uint MP4::Mp4IsoBox::size() const
+{
+ return d->size;
+}
+
+long MP4::Mp4IsoBox::offset() const
+{
+ return d->offset;
+}
+
+TagLib::File* MP4::Mp4IsoBox::file() const
+{
+ return d->file;
+}
diff --git a/src/metadata/m4a/mp4isobox.h b/src/metadata/m4a/mp4isobox.h
new file mode 100644
index 0000000..4d4edc9
--- /dev/null
+++ b/src/metadata/m4a/mp4isobox.h
@@ -0,0 +1,67 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef MP4ISOBOX_H
+#define MP4ISOBOX_H
+
+#include "taglib.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ class File;
+
+ namespace MP4
+ {
+ class Mp4IsoBox
+ {
+ public:
+ //! constructor for base class
+ Mp4IsoBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
+ //! destructor - simply freeing private ptr
+ virtual ~Mp4IsoBox();
+
+ //! function to get the fourcc code
+ MP4::Fourcc fourcc() const;
+ //! function to get the size of tha atom/box
+ uint size() const;
+ //! function to get the offset of the atom in the mp4 file
+ long offset() const;
+
+ //! parse wrapper to get common interface for both box and fullbox
+ virtual void parsebox();
+ //! pure virtual function for all subclasses to implement
+ virtual void parse() = 0;
+
+ protected:
+ //! function to get the file pointer
+ TagLib::File* file() const;
+
+ protected:
+ class Mp4IsoBoxPrivate;
+ Mp4IsoBoxPrivate* d;
+ };
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // MP4ISOBOX_H
+
diff --git a/src/metadata/m4a/mp4isofullbox.cpp b/src/metadata/m4a/mp4isofullbox.cpp
new file mode 100644
index 0000000..f938ad4
--- /dev/null
+++ b/src/metadata/m4a/mp4isofullbox.cpp
@@ -0,0 +1,67 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "mp4isofullbox.h"
+#include "tfile.h"
+
+using namespace TagLib;
+
+class MP4::Mp4IsoFullBox::Mp4IsoFullBoxPrivate
+{
+public:
+ uchar version;
+ uint flags;
+}; // Mp4IsoFullBoxPrivate
+
+
+MP4::Mp4IsoFullBox::Mp4IsoFullBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
+: Mp4IsoBox( file, fourcc, size, offset )
+{
+ d = new MP4::Mp4IsoFullBox::Mp4IsoFullBoxPrivate();
+}
+
+MP4::Mp4IsoFullBox::~Mp4IsoFullBox()
+{
+ delete d;
+}
+
+void MP4::Mp4IsoFullBox::parsebox()
+{
+ // seek to offset
+ Mp4IsoBox::file()->seek(Mp4IsoBox::offset(), File::Beginning );
+ // parse version and flags
+ ByteVector version_flags = Mp4IsoBox::file()->readBlock(4);
+ d->version = version_flags[0];
+ d->flags = version_flags[1] << 16 || version_flags[2] << 8 || version_flags[3];
+ // call parse method of subclass
+ parse();
+}
+
+TagLib::uchar MP4::Mp4IsoFullBox::version()
+{
+ return d->version;
+}
+
+TagLib::uint MP4::Mp4IsoFullBox::flags()
+{
+ return d->flags;
+}
+
diff --git a/src/metadata/m4a/mp4isofullbox.h b/src/metadata/m4a/mp4isofullbox.h
new file mode 100644
index 0000000..bc01b61
--- /dev/null
+++ b/src/metadata/m4a/mp4isofullbox.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef MP4ISOFULLBOX_H
+#define MP4ISOFULLBOX_H
+
+#include "mp4isobox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class Mp4IsoFullBox : public Mp4IsoBox
+ {
+ public:
+ //! constructor for full box
+ Mp4IsoFullBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
+ //! destructor for mp4 iso full box
+ virtual ~Mp4IsoFullBox();
+
+ //! function to get the version of box
+ uchar version();
+ //! function to get the flag map
+ uint flags();
+
+ //! parse wrapper to get common interface for both box and fullbox
+ virtual void parsebox();
+
+ protected:
+ class Mp4IsoFullBoxPrivate;
+ Mp4IsoFullBoxPrivate* d;
+ };
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // MP4ISOFULLBOX_H
+
diff --git a/src/metadata/m4a/mp4itunestag.cpp b/src/metadata/m4a/mp4itunestag.cpp
new file mode 100644
index 0000000..aabd644
--- /dev/null
+++ b/src/metadata/m4a/mp4itunestag.cpp
@@ -0,0 +1,197 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "mp4itunestag.h"
+
+using namespace TagLib;
+
+class MP4::Tag::TagPrivate
+{
+public:
+ MP4::File* mp4file;
+ TagLib::String title;
+ TagLib::String artist;
+ TagLib::String album;
+ TagLib::String genre;
+ TagLib::uint year;
+ TagLib::uint track;
+ TagLib::String comment;
+ TagLib::String grouping;
+ TagLib::String composer;
+ TagLib::uint disk;
+ TagLib::uint bpm;
+ bool isEmpty;
+ TagLib::ByteVector cover;
+};
+
+
+MP4::Tag::Tag( )
+{
+ d = new TagPrivate();
+ d->year = 0;
+ d->track = 0;
+ d->disk = 0;
+ d->bpm = 0;
+ d->isEmpty = true;
+}
+
+MP4::Tag::~Tag()
+{
+ delete d;
+}
+
+String MP4::Tag::title() const
+{
+ return d->title;
+}
+
+String MP4::Tag::artist() const
+{
+ return d->artist;
+}
+
+String MP4::Tag::album() const
+{
+ return d->album;
+}
+
+String MP4::Tag::comment() const
+{
+ return d->comment;
+}
+
+String MP4::Tag::genre() const
+{
+ return d->genre;
+}
+
+TagLib::uint MP4::Tag::year() const
+{
+ return d->year;
+}
+
+TagLib::uint MP4::Tag::track() const
+{
+ return d->track;
+}
+
+String MP4::Tag::grouping() const
+{
+ return d->grouping;
+}
+
+String MP4::Tag::composer() const
+{
+ return d->composer;
+}
+
+TagLib::uint MP4::Tag::disk() const
+{
+ return d->disk;
+}
+
+TagLib::uint MP4::Tag::bpm() const
+{
+ return d->bpm;
+}
+
+TagLib::ByteVector MP4::Tag::cover() const
+{
+ return d->cover;
+}
+
+void MP4::Tag::setTitle(const String &s)
+{
+ d->title = s;
+ d->isEmpty = false;
+}
+
+void MP4::Tag::setArtist(const String &s)
+{
+ d->artist = s;
+ d->isEmpty = false;
+}
+
+void MP4::Tag::setAlbum(const String &s)
+{
+ d->album = s;
+ d->isEmpty = false;
+}
+
+void MP4::Tag::setComment(const String &s)
+{
+ d->comment = s;
+ d->isEmpty = false;
+}
+
+void MP4::Tag::setGenre(const String &s)
+{
+ d->genre = s;
+ d->isEmpty = false;
+}
+
+void MP4::Tag::setYear(const TagLib::uint i)
+{
+ d->year = i;
+ d->isEmpty = false;
+}
+
+void MP4::Tag::setTrack(const TagLib::uint i)
+{
+ d->track = i;
+ d->isEmpty = false;
+}
+
+void MP4::Tag::setGrouping(const String &s)
+{
+ d->grouping = s;
+ d->isEmpty = false;
+}
+
+void MP4::Tag::setComposer(const String &s)
+{
+ d->composer = s;
+ d->isEmpty = false;
+}
+
+void MP4::Tag::setDisk(const TagLib::uint i)
+{
+ d->disk = i;
+ d->isEmpty = false;
+}
+
+void MP4::Tag::setBpm(const TagLib::uint i)
+{
+ d->bpm = i;
+ d->isEmpty = false;
+}
+
+void MP4::Tag::setCover(const TagLib::ByteVector& c)
+{
+ d->cover = c;
+ d->isEmpty = false;
+}
+
+bool MP4::Tag::isEmpty() const
+{
+ return d->isEmpty;
+}
+
diff --git a/src/metadata/m4a/mp4itunestag.h b/src/metadata/m4a/mp4itunestag.h
new file mode 100644
index 0000000..9e572a7
--- /dev/null
+++ b/src/metadata/m4a/mp4itunestag.h
@@ -0,0 +1,95 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef MP4ITUNESTAG_H
+#define MP4ITUNESTAG_H
+
+#include "taglib.h"
+#include "tstring.h"
+#include "tag.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class File;
+
+ class Tag : public TagLib::Tag
+ {
+ public:
+ /*!
+ * Constructs an empty MP4 iTunes tag.
+ */
+ Tag( );
+
+ /*!
+ * Destroys this Tag instance.
+ */
+ virtual ~Tag();
+
+ // Reimplementations.
+
+ virtual String title() const;
+ virtual String artist() const;
+ virtual String album() const;
+ virtual String comment() const;
+ virtual String genre() const;
+ virtual uint year() const;
+ virtual uint track() const;
+
+ virtual void setTitle(const String &s);
+ virtual void setArtist(const String &s);
+ virtual void setAlbum(const String &s);
+ virtual void setComment(const String &s);
+ virtual void setGenre(const String &s);
+ virtual void setYear(const uint i);
+ virtual void setTrack(const uint i);
+
+ // MP4 specific fields
+
+ String grouping() const;
+ String composer() const;
+ uint disk() const;
+ uint bpm() const;
+ ByteVector cover() const;
+ int compilation() const { return -1; }
+
+ void setGrouping(const String &s);
+ void setComposer(const String &s);
+ void setDisk(const uint i);
+ void setBpm(const uint i);
+ void setCover( const ByteVector& cover );
+ void setCompilation( bool /*isCompilation*/ ) {}
+
+ virtual bool isEmpty() const;
+
+ private:
+ Tag(const Tag &);
+ Tag &operator=(const Tag &);
+
+ class TagPrivate;
+ TagPrivate *d;
+ };
+ } // namespace MP4
+
+} // namespace TagLib
+
+#endif // MP4ITUNESTAG_H
diff --git a/src/metadata/m4a/mp4mdiabox.cpp b/src/metadata/m4a/mp4mdiabox.cpp
new file mode 100644
index 0000000..c3b30ad
--- /dev/null
+++ b/src/metadata/m4a/mp4mdiabox.cpp
@@ -0,0 +1,111 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "tlist.h"
+#include <iostream>
+#include "mp4mdiabox.h"
+#include "mp4hdlrbox.h"
+#include "mp4minfbox.h"
+#include "boxfactory.h"
+#include "mp4file.h"
+
+using namespace TagLib;
+
+class MP4::Mp4MdiaBox::Mp4MdiaBoxPrivate
+{
+public:
+ //! container for all boxes in mdia box
+ TagLib::List<Mp4IsoBox*> mdiaBoxes;
+ //! a box factory for creating the appropriate boxes
+ MP4::BoxFactory boxfactory;
+}; // class Mp4MdiaBoxPrivate
+
+MP4::Mp4MdiaBox::Mp4MdiaBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
+ : Mp4IsoBox( file, fourcc, size, offset )
+{
+ d = new MP4::Mp4MdiaBox::Mp4MdiaBoxPrivate();
+}
+
+MP4::Mp4MdiaBox::~Mp4MdiaBox()
+{
+ TagLib::List<Mp4IsoBox*>::Iterator delIter;
+ for( delIter = d->mdiaBoxes.begin();
+ delIter != d->mdiaBoxes.end();
+ delIter++ )
+ {
+ delete *delIter;
+ }
+ delete d;
+}
+
+void MP4::Mp4MdiaBox::parse()
+{
+ TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
+
+ TagLib::uint totalsize = 8;
+ // parse all contained boxes
+ TagLib::uint size;
+ MP4::Fourcc fourcc;
+
+ // stores the current handler type
+ TagLib::MP4::Fourcc hdlrtype;
+
+ while( (mp4file->readSizeAndType( size, fourcc ) == true) )
+ {
+ totalsize += size;
+
+ // check for errors
+ if( totalsize > MP4::Mp4IsoBox::size() )
+ {
+ std::cerr << "Error in mp4 file " << mp4file->name() << " mdia box contains bad box with name: " << fourcc.toString() << std::endl;
+ return;
+ }
+
+ // create the appropriate subclass and parse it
+ MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( mp4file, fourcc, size, mp4file->tell() );
+ if( static_cast<TagLib::uint>( fourcc ) == 0x6d696e66 /*"minf"*/ )
+ {
+ // cast to minf
+ Mp4MinfBox* minfbox = dynamic_cast<Mp4MinfBox*>( curbox );
+ if(!minfbox)
+ return;
+ // set handler type
+ minfbox->setHandlerType( hdlrtype );
+ }
+
+ curbox->parsebox();
+ d->mdiaBoxes.append( curbox );
+
+ if(static_cast<TagLib::uint>( fourcc ) == 0x68646c72 /*"hdlr"*/ )
+ {
+ // cast to hdlr box
+ Mp4HdlrBox* hdlrbox = dynamic_cast<Mp4HdlrBox*>( curbox );
+ if(!hdlrbox)
+ return;
+ // get handler type
+ hdlrtype = hdlrbox->hdlr_type();
+ }
+ // check for end of mdia box
+ if( totalsize == MP4::Mp4IsoBox::size() )
+ break;
+
+ }
+}
diff --git a/src/metadata/m4a/mp4mdiabox.h b/src/metadata/m4a/mp4mdiabox.h
new file mode 100644
index 0000000..16503bd
--- /dev/null
+++ b/src/metadata/m4a/mp4mdiabox.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef MP4MDIABOX_H
+#define MP4MDIABOX_H
+
+#include "mp4isobox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class Mp4MdiaBox: public Mp4IsoBox
+ {
+ public:
+ Mp4MdiaBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
+ ~Mp4MdiaBox();
+
+ //! parse mdia contents
+ void parse();
+
+ private:
+ class Mp4MdiaBoxPrivate;
+ Mp4MdiaBoxPrivate* d;
+ }; // Mp4MdiaBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // MP4MDIABOX_H
diff --git a/src/metadata/m4a/mp4metabox.cpp b/src/metadata/m4a/mp4metabox.cpp
new file mode 100644
index 0000000..30eebf2
--- /dev/null
+++ b/src/metadata/m4a/mp4metabox.cpp
@@ -0,0 +1,86 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <tlist.h>
+#include <iostream>
+#include "mp4metabox.h"
+#include "boxfactory.h"
+#include "mp4file.h"
+
+using namespace TagLib;
+
+class MP4::Mp4MetaBox::Mp4MetaBoxPrivate
+{
+public:
+ //! container for all boxes in meta box
+ TagLib::List<Mp4IsoBox*> metaBoxes;
+ //! a box factory for creating the appropriate boxes
+ MP4::BoxFactory boxfactory;
+}; // class Mp4MetaBoxPrivate
+
+MP4::Mp4MetaBox::Mp4MetaBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
+ : Mp4IsoFullBox( file, fourcc, size, offset )
+{
+ d = new MP4::Mp4MetaBox::Mp4MetaBoxPrivate();
+}
+
+MP4::Mp4MetaBox::~Mp4MetaBox()
+{
+ TagLib::List<Mp4IsoBox*>::Iterator delIter;
+ for( delIter = d->metaBoxes.begin();
+ delIter != d->metaBoxes.end();
+ delIter++ )
+ {
+ delete *delIter;
+ }
+ delete d;
+}
+
+void MP4::Mp4MetaBox::parse()
+{
+ TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
+
+ TagLib::uint totalsize = 12; // initial size of box
+ // parse all contained boxes
+ TagLib::uint size;
+ MP4::Fourcc fourcc;
+
+ while( (mp4file->readSizeAndType( size, fourcc ) == true) )
+ {
+ totalsize += size;
+
+ // check for errors
+ if( totalsize > MP4::Mp4IsoBox::size() )
+ {
+ std::cerr << "Error in mp4 file " << mp4file->name() << " meta box contains bad box with name: " << fourcc.toString() << std::endl;
+ return;
+ }
+
+ // create the appropriate subclass and parse it
+ MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( mp4file, fourcc, size, mp4file->tell() );
+ curbox->parsebox();
+ d->metaBoxes.append( curbox );
+
+ // check for end of meta box
+ if( totalsize == MP4::Mp4IsoBox::size() )
+ break;
+ }
+}
diff --git a/src/metadata/m4a/mp4metabox.h b/src/metadata/m4a/mp4metabox.h
new file mode 100644
index 0000000..58d9667
--- /dev/null
+++ b/src/metadata/m4a/mp4metabox.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef MP4METABOX_H
+#define MP4METABOX_H
+
+#include "mp4isofullbox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class Mp4MetaBox: public Mp4IsoFullBox
+ {
+ public:
+ Mp4MetaBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
+ ~Mp4MetaBox();
+
+ //! parse meta contents
+ void parse();
+
+ private:
+ class Mp4MetaBoxPrivate;
+ Mp4MetaBoxPrivate* d;
+ }; // Mp4MetaBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // MP4METABOX_H
diff --git a/src/metadata/m4a/mp4minfbox.cpp b/src/metadata/m4a/mp4minfbox.cpp
new file mode 100644
index 0000000..0081dda
--- /dev/null
+++ b/src/metadata/m4a/mp4minfbox.cpp
@@ -0,0 +1,104 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "tlist.h"
+#include <iostream>
+#include "mp4minfbox.h"
+#include "mp4stblbox.h"
+#include "boxfactory.h"
+#include "mp4file.h"
+
+using namespace TagLib;
+
+class MP4::Mp4MinfBox::Mp4MinfBoxPrivate
+{
+public:
+ //! container for all boxes in minf box
+ TagLib::List<Mp4IsoBox*> minfBoxes;
+ //! a box factory for creating the appropriate boxes
+ MP4::BoxFactory boxfactory;
+ //! stores the handler type of the current trak
+ MP4::Fourcc handler_type;
+}; // class Mp4MinfBoxPrivate
+
+MP4::Mp4MinfBox::Mp4MinfBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
+ : Mp4IsoBox( file, fourcc, size, offset )
+{
+ d = new MP4::Mp4MinfBox::Mp4MinfBoxPrivate();
+}
+
+MP4::Mp4MinfBox::~Mp4MinfBox()
+{
+ TagLib::List<Mp4IsoBox*>::Iterator delIter;
+ for( delIter = d->minfBoxes.begin();
+ delIter != d->minfBoxes.end();
+ delIter++ )
+ {
+ delete *delIter;
+ }
+ delete d;
+}
+
+void MP4::Mp4MinfBox::setHandlerType( MP4::Fourcc fourcc )
+{
+ d->handler_type = fourcc;
+}
+
+void MP4::Mp4MinfBox::parse()
+{
+ TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
+
+ TagLib::uint totalsize = 8;
+ // parse all contained boxes
+ TagLib::uint size;
+ MP4::Fourcc fourcc;
+
+ while( (mp4file->readSizeAndType( size, fourcc ) == true) )
+ {
+ totalsize += size;
+
+ // check for errors
+ if( totalsize > MP4::Mp4IsoBox::size() )
+ {
+ std::cerr << "Error in mp4 file " << mp4file->name() << " minf box contains bad box with name: " << fourcc.toString() << std::endl;
+ return;
+ }
+
+ // create the appropriate subclass and parse it
+ MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( mp4file, fourcc, size, mp4file->tell() );
+ if(static_cast<TagLib::uint>( fourcc ) == 0x7374626c /*stbl*/ )
+ {
+ // cast to hdlr box
+ Mp4StblBox* stblbox = dynamic_cast<Mp4StblBox*>( curbox );
+ if(!stblbox)
+ return;
+ // set handler type
+ stblbox->setHandlerType( d->handler_type );
+ }
+
+ curbox->parsebox();
+ d->minfBoxes.append( curbox );
+
+ // check for end of minf box
+ if( totalsize == MP4::Mp4IsoBox::size() )
+ break;
+ }
+}
diff --git a/src/metadata/m4a/mp4minfbox.h b/src/metadata/m4a/mp4minfbox.h
new file mode 100644
index 0000000..9195d30
--- /dev/null
+++ b/src/metadata/m4a/mp4minfbox.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef MP4MINFBOX_H
+#define MP4MINFBOX_H
+
+#include "mp4isobox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class Mp4MinfBox: public Mp4IsoBox
+ {
+ public:
+ Mp4MinfBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
+ ~Mp4MinfBox();
+
+ //! parse minf contents
+ void parse();
+ //! set the handler type - needed for stsd
+ void setHandlerType( MP4::Fourcc fourcc );
+
+ private:
+ class Mp4MinfBoxPrivate;
+ Mp4MinfBoxPrivate* d;
+ }; // Mp4MinfBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // MP4MINFBOX_H
diff --git a/src/metadata/m4a/mp4moovbox.cpp b/src/metadata/m4a/mp4moovbox.cpp
new file mode 100644
index 0000000..24826ec
--- /dev/null
+++ b/src/metadata/m4a/mp4moovbox.cpp
@@ -0,0 +1,86 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "tlist.h"
+#include <iostream>
+#include "mp4moovbox.h"
+#include "boxfactory.h"
+#include "mp4file.h"
+
+using namespace TagLib;
+
+class MP4::Mp4MoovBox::Mp4MoovBoxPrivate
+{
+public:
+ //! container for all boxes in moov box
+ TagLib::List<Mp4IsoBox*> moovBoxes;
+ //! a box factory for creating the appropriate boxes
+ MP4::BoxFactory boxfactory;
+}; // class Mp4MoovBoxPrivate
+
+MP4::Mp4MoovBox::Mp4MoovBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
+ : Mp4IsoBox( file, fourcc, size, offset )
+{
+ d = new MP4::Mp4MoovBox::Mp4MoovBoxPrivate();
+}
+
+MP4::Mp4MoovBox::~Mp4MoovBox()
+{
+ TagLib::List<Mp4IsoBox*>::Iterator delIter;
+ for( delIter = d->moovBoxes.begin();
+ delIter != d->moovBoxes.end();
+ delIter++ )
+ {
+ delete *delIter;
+ }
+ delete d;
+}
+
+void MP4::Mp4MoovBox::parse()
+{
+ TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
+
+ TagLib::uint totalsize = 8;
+ // parse all contained boxes
+ TagLib::uint size;
+ MP4::Fourcc fourcc;
+
+ while( (mp4file->readSizeAndType( size, fourcc ) == true) )
+ {
+ totalsize += size;
+
+ // check for errors
+ if( totalsize > MP4::Mp4IsoBox::size() )
+ {
+ std::cerr << "Error in mp4 file " << mp4file->name() << " moov box contains bad box with name: " << fourcc.toString() << std::endl;
+ return;
+ }
+
+ // create the appropriate subclass and parse it
+ MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( mp4file, fourcc, size, mp4file->tell() );
+ curbox->parsebox();
+ d->moovBoxes.append( curbox );
+
+ // check for end of moov box
+ if( totalsize == MP4::Mp4IsoBox::size() )
+ break;
+ }
+}
diff --git a/src/metadata/m4a/mp4moovbox.h b/src/metadata/m4a/mp4moovbox.h
new file mode 100644
index 0000000..390953f
--- /dev/null
+++ b/src/metadata/m4a/mp4moovbox.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef MP4MOOVBOX_H
+#define MP4MOOVBOX_H
+
+#include "mp4isobox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class Mp4MoovBox: public Mp4IsoBox
+ {
+ public:
+ Mp4MoovBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
+ ~Mp4MoovBox();
+
+ //! parse moov contents
+ void parse();
+
+ private:
+ class Mp4MoovBoxPrivate;
+ Mp4MoovBoxPrivate* d;
+ }; // Mp4MoovBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // MP4MOOVBOX_H
diff --git a/src/metadata/m4a/mp4mvhdbox.cpp b/src/metadata/m4a/mp4mvhdbox.cpp
new file mode 100644
index 0000000..36053e4
--- /dev/null
+++ b/src/metadata/m4a/mp4mvhdbox.cpp
@@ -0,0 +1,140 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <deque>
+#include <iostream>
+#include "mp4mvhdbox.h"
+#include "boxfactory.h"
+#include "mp4file.h"
+#include "mp4propsproxy.h"
+
+using namespace TagLib;
+
+class MP4::Mp4MvhdBox::Mp4MvhdBoxPrivate
+{
+public:
+ //! creation time of the file
+ TagLib::ulonglong creationTime;
+ //! modification time of the file - since midnight, Jan. 1, 1904, UTC-time
+ TagLib::ulonglong modificationTime;
+ //! timescale for the file - referred by all time specifications in this box
+ TagLib::uint timescale;
+ //! duration of presentation
+ TagLib::ulonglong duration;
+ //! playout speed
+ TagLib::uint rate;
+ //! volume for entire presentation
+ TagLib::uint volume;
+ //! track ID for an additional track (next new track)
+ TagLib::uint nextTrackID;
+}; // class Mp4MvhdBoxPrivate
+
+MP4::Mp4MvhdBox::Mp4MvhdBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
+ : Mp4IsoFullBox( file, fourcc, size, offset )
+{
+ d = new MP4::Mp4MvhdBox::Mp4MvhdBoxPrivate();
+}
+
+MP4::Mp4MvhdBox::~Mp4MvhdBox()
+{
+ delete d;
+}
+
+TagLib::ulonglong MP4::Mp4MvhdBox::creationTime() const
+{
+ return d->creationTime;
+}
+
+TagLib::ulonglong MP4::Mp4MvhdBox::modificationTime() const
+{
+ return d->modificationTime;
+}
+
+TagLib::uint MP4::Mp4MvhdBox::timescale() const
+{
+ return d->timescale;
+}
+
+TagLib::ulonglong MP4::Mp4MvhdBox::duration() const
+{
+ return d->duration;
+}
+
+TagLib::uint MP4::Mp4MvhdBox::rate() const
+{
+ return d->rate;
+}
+
+TagLib::uint MP4::Mp4MvhdBox::volume() const
+{
+ return d->volume;
+}
+
+TagLib::uint MP4::Mp4MvhdBox::nextTrackID() const
+{
+ return d->nextTrackID;
+}
+
+
+void MP4::Mp4MvhdBox::parse()
+{
+ TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
+
+ if( version() == 1 )
+ {
+ if( !mp4file->readLongLong( d->creationTime ) )
+ return;
+ if( !mp4file->readLongLong( d->modificationTime ) )
+ return;
+ if( !mp4file->readInt( d->timescale ) )
+ return;
+ if( !mp4file->readLongLong( d->duration ) )
+ return;
+ }
+ else
+ {
+ TagLib::uint creationTime_tmp, modificationTime_tmp, duration_tmp;
+
+ if( !mp4file->readInt( creationTime_tmp ) )
+ return;
+ if( !mp4file->readInt( modificationTime_tmp ) )
+ return;
+ if( !mp4file->readInt( d->timescale ) )
+ return;
+ if( !mp4file->readInt( duration_tmp ) )
+ return;
+
+ d->creationTime = creationTime_tmp;
+ d->modificationTime = modificationTime_tmp;
+ d->duration = duration_tmp;
+ }
+ if( !mp4file->readInt( d->rate ) )
+ return;
+ if( !mp4file->readInt( d->volume ) )
+ return;
+ // jump over unused fields
+ mp4file->seek( 68, File::Current );
+
+ if( !mp4file->readInt( d->nextTrackID ) )
+ return;
+ // register at proxy
+ mp4file->propProxy()->registerMvhd( this );
+}
diff --git a/src/metadata/m4a/mp4mvhdbox.h b/src/metadata/m4a/mp4mvhdbox.h
new file mode 100644
index 0000000..b133485
--- /dev/null
+++ b/src/metadata/m4a/mp4mvhdbox.h
@@ -0,0 +1,65 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef MP4MVHDBOX_H
+#define MP4MVHDBOX_H
+
+#include "mp4isofullbox.h"
+#include "mp4fourcc.h"
+#include "mp4file.h" // ulonglong
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class Mp4MvhdBox: public Mp4IsoFullBox
+ {
+ public:
+ Mp4MvhdBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
+ ~Mp4MvhdBox();
+
+ //! function to get the creation time of the mp4 file
+ ulonglong creationTime() const;
+ //! function to get the modification time of the mp4 file
+ ulonglong modificationTime() const;
+ //! function to get the timescale referenced by the above timestamps
+ uint timescale() const;
+ //! function to get the presentation duration in the mp4 file
+ ulonglong duration() const;
+ //! function to get the rate (playout speed) - typically 1.0;
+ uint rate() const;
+ //! function to get volume level for presentation - typically 1.0;
+ uint volume() const;
+ //! function to get the track ID for adding new tracks - useless for this lib
+ uint nextTrackID() const;
+
+ //! parse mvhd contents
+ void parse();
+
+ private:
+ class Mp4MvhdBoxPrivate;
+ Mp4MvhdBoxPrivate* d;
+ }; // Mp4MvhdBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // MP4MVHDBOX_H
diff --git a/src/metadata/m4a/mp4propsproxy.cpp b/src/metadata/m4a/mp4propsproxy.cpp
new file mode 100644
index 0000000..ebee9c2
--- /dev/null
+++ b/src/metadata/m4a/mp4propsproxy.cpp
@@ -0,0 +1,89 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "mp4propsproxy.h"
+
+using namespace TagLib;
+
+class MP4::Mp4PropsProxy::Mp4PropsProxyPrivate
+{
+public:
+ //! the movie header box
+ MP4::Mp4MvhdBox* mvhdbox;
+ //! the sample table box
+ MP4::Mp4AudioSampleEntry* audiosampleentry;
+};
+
+
+MP4::Mp4PropsProxy::Mp4PropsProxy()
+{
+ d = new MP4::Mp4PropsProxy::Mp4PropsProxyPrivate();
+ d->mvhdbox = 0;
+ d->audiosampleentry = 0;
+}
+
+MP4::Mp4PropsProxy::~Mp4PropsProxy()
+{
+ delete d;
+}
+
+TagLib::uint MP4::Mp4PropsProxy::seconds() const
+{
+ if( d->mvhdbox )
+ return static_cast<TagLib::uint>( d->mvhdbox->duration() / d->mvhdbox->timescale() );
+ else
+ return 0;
+}
+
+TagLib::uint MP4::Mp4PropsProxy::channels() const
+{
+ if( d->audiosampleentry )
+ return d->audiosampleentry->channels();
+ else
+ return 0;
+}
+
+TagLib::uint MP4::Mp4PropsProxy::sampleRate() const
+{
+ if( d->audiosampleentry )
+ return (d->audiosampleentry->samplerate()>>16);
+ else
+ return 0;
+}
+
+TagLib::uint MP4::Mp4PropsProxy::bitRate() const
+{
+ if( d->audiosampleentry )
+ return (d->audiosampleentry->bitrate());
+ else
+ return 0;
+}
+
+void MP4::Mp4PropsProxy::registerMvhd( MP4::Mp4MvhdBox* mvhdbox )
+{
+ d->mvhdbox = mvhdbox;
+}
+
+void MP4::Mp4PropsProxy::registerAudioSampleEntry( MP4::Mp4AudioSampleEntry* audioSampleEntry )
+{
+ d->audiosampleentry = audioSampleEntry;
+}
+
diff --git a/src/metadata/m4a/mp4propsproxy.h b/src/metadata/m4a/mp4propsproxy.h
new file mode 100644
index 0000000..0ea29e2
--- /dev/null
+++ b/src/metadata/m4a/mp4propsproxy.h
@@ -0,0 +1,65 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef MP4PROPSPROXY_H
+#define MP4PROPSPROXY_H MP4PROPSPROXY_H
+#include "mp4mvhdbox.h"
+#include "mp4audiosampleentry.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ //! Mp4PropsProxy is used to access the stsd box and mvhd box directly
+ /*! this class works as a shortcut to avoid stepping through all parent boxes
+ * to access the boxes in question
+ */
+ class Mp4PropsProxy
+ {
+ public:
+ //! constructor for properties proxy
+ Mp4PropsProxy();
+ //! destructor
+ ~Mp4PropsProxy();
+
+ //! function to get length of media in seconds
+ TagLib::uint seconds() const;
+ //! function to get the nunmber of channels
+ TagLib::uint channels() const;
+ //! function to get the sample rate
+ TagLib::uint sampleRate() const;
+ //! function to get the bitrate rate
+ TagLib::uint bitRate() const;
+
+ //! function to register the movie header box - mvhd
+ void registerMvhd( MP4::Mp4MvhdBox* mvhdbox );
+ //! function to register the sample description box
+ void registerAudioSampleEntry( MP4::Mp4AudioSampleEntry* audiosampleentry );
+
+ private:
+ class Mp4PropsProxyPrivate;
+ Mp4PropsProxyPrivate* d;
+
+ }; // Mp4PropsProxy
+ } // MP4
+} // TagLib
+
+#endif // MP4PROPSPROXY_H
diff --git a/src/metadata/m4a/mp4sampleentry.cpp b/src/metadata/m4a/mp4sampleentry.cpp
new file mode 100644
index 0000000..e5619ea
--- /dev/null
+++ b/src/metadata/m4a/mp4sampleentry.cpp
@@ -0,0 +1,59 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "mp4sampleentry.h"
+#include "mp4isobox.h"
+#include "mp4file.h"
+
+using namespace TagLib;
+
+class MP4::Mp4SampleEntry::Mp4SampleEntryPrivate
+{
+public:
+ TagLib::uint data_reference_index;
+};
+
+MP4::Mp4SampleEntry::Mp4SampleEntry( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
+ :Mp4IsoBox(file, fourcc, size, offset)
+{
+ d = new MP4::Mp4SampleEntry::Mp4SampleEntryPrivate();
+}
+
+MP4::Mp4SampleEntry::~Mp4SampleEntry()
+{
+ delete d;
+}
+
+//! parse the content of the box
+void MP4::Mp4SampleEntry::parse()
+{
+ TagLib::MP4::File* mp4file = dynamic_cast<TagLib::MP4::File*>(file());
+ if(!mp4file)
+ return;
+
+ // skip the first 6 bytes
+ mp4file->seek( 6, TagLib::File::Current );
+ // read data reference index
+ if(!mp4file->readShort( d->data_reference_index))
+ return;
+ parseEntry();
+}
+
diff --git a/src/metadata/m4a/mp4sampleentry.h b/src/metadata/m4a/mp4sampleentry.h
new file mode 100644
index 0000000..39475f7
--- /dev/null
+++ b/src/metadata/m4a/mp4sampleentry.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef MP4SAMPLEENTRY_H
+#define MP4SAMPLEENTRY_H
+
+#include "mp4isobox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class Mp4SampleEntry: public Mp4IsoBox
+ {
+ public:
+ Mp4SampleEntry( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
+ ~Mp4SampleEntry();
+
+ public:
+ //! parse the content of the box
+ virtual void parse();
+
+ private:
+ //! function to be implemented in subclass
+ virtual void parseEntry() = 0;
+
+ protected:
+ class Mp4SampleEntryPrivate;
+ Mp4SampleEntryPrivate* d;
+ }; // class Mp4SampleEntry
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // MP4SAMPLEENTRY_H
diff --git a/src/metadata/m4a/mp4skipbox.cpp b/src/metadata/m4a/mp4skipbox.cpp
new file mode 100644
index 0000000..8cb5218
--- /dev/null
+++ b/src/metadata/m4a/mp4skipbox.cpp
@@ -0,0 +1,50 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "mp4skipbox.h"
+#include "mp4isobox.h"
+#include "tfile.h"
+
+using namespace TagLib;
+
+class MP4::Mp4SkipBox::Mp4SkipBoxPrivate
+{
+public:
+};
+
+MP4::Mp4SkipBox::Mp4SkipBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
+ :Mp4IsoBox(file, fourcc, size, offset)
+{
+ d = new MP4::Mp4SkipBox::Mp4SkipBoxPrivate();
+}
+
+MP4::Mp4SkipBox::~Mp4SkipBox()
+{
+ delete d;
+}
+
+//! parse the content of the box
+void MP4::Mp4SkipBox::parse()
+{
+ // skip contents
+ file()->seek( size() - 8, TagLib::File::Current );
+}
+
diff --git a/src/metadata/m4a/mp4skipbox.h b/src/metadata/m4a/mp4skipbox.h
new file mode 100644
index 0000000..896fcaa
--- /dev/null
+++ b/src/metadata/m4a/mp4skipbox.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef MP4SKIPBOX_H
+#define MP4SKIPBOX_H
+
+#include "mp4isobox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class Mp4SkipBox: public Mp4IsoBox
+ {
+ public:
+ Mp4SkipBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
+ ~Mp4SkipBox();
+
+ private:
+ //! parse the content of the box
+ virtual void parse();
+
+ protected:
+ class Mp4SkipBoxPrivate;
+ Mp4SkipBoxPrivate* d;
+ }; // class Mp4SkipBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // MP4SKIPBOX_H
diff --git a/src/metadata/m4a/mp4stblbox.cpp b/src/metadata/m4a/mp4stblbox.cpp
new file mode 100644
index 0000000..f67de59
--- /dev/null
+++ b/src/metadata/m4a/mp4stblbox.cpp
@@ -0,0 +1,105 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "tlist.h"
+#include <iostream>
+#include "mp4stblbox.h"
+#include "mp4stsdbox.h"
+#include "boxfactory.h"
+#include "mp4file.h"
+
+using namespace TagLib;
+
+class MP4::Mp4StblBox::Mp4StblBoxPrivate
+{
+public:
+ //! container for all boxes in stbl box
+ TagLib::List<Mp4IsoBox*> stblBoxes;
+ //! a box factory for creating the appropriate boxes
+ MP4::BoxFactory boxfactory;
+ //! the handler type for the current trak
+ MP4::Fourcc handler_type;
+}; // class Mp4StblBoxPrivate
+
+MP4::Mp4StblBox::Mp4StblBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
+ : Mp4IsoBox( file, fourcc, size, offset )
+{
+ d = new MP4::Mp4StblBox::Mp4StblBoxPrivate();
+}
+
+MP4::Mp4StblBox::~Mp4StblBox()
+{
+ TagLib::List<Mp4IsoBox*>::Iterator delIter;
+ for( delIter = d->stblBoxes.begin();
+ delIter != d->stblBoxes.end();
+ delIter++ )
+ {
+ delete *delIter;
+ }
+ delete d;
+}
+
+void MP4::Mp4StblBox::setHandlerType( MP4::Fourcc fourcc )
+{
+ d->handler_type = fourcc;
+}
+
+void MP4::Mp4StblBox::parse()
+{
+ TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
+
+ TagLib::uint totalsize = 8;
+ // parse all contained boxes
+ TagLib::uint size;
+ MP4::Fourcc fourcc;
+
+ while( (mp4file->readSizeAndType( size, fourcc ) == true) )
+ {
+ totalsize += size;
+
+ // check for errors
+ if( totalsize > MP4::Mp4IsoBox::size() )
+ {
+ std::cerr << "Error in mp4 file " << mp4file->name() << " stbl box contains bad box with name: " << fourcc.toString() << std::endl;
+ return;
+ }
+
+ // create the appropriate subclass and parse it
+ MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( mp4file, fourcc, size, mp4file->tell() );
+
+ // check for stsd
+ if( static_cast<TagLib::uint>(fourcc) == 0x73747364 /*'stsd'*/ )
+ {
+ // cast to stsd box
+ MP4::Mp4StsdBox* stsdbox = dynamic_cast<MP4::Mp4StsdBox*>(curbox);
+ if(!stsdbox)
+ return;
+ // set the handler type
+ stsdbox->setHandlerType( d->handler_type );
+ }
+ curbox->parsebox();
+ d->stblBoxes.append( curbox );
+
+ // check for end of stbl box
+ if( totalsize == MP4::Mp4IsoBox::size() )
+ break;
+ }
+}
diff --git a/src/metadata/m4a/mp4stblbox.h b/src/metadata/m4a/mp4stblbox.h
new file mode 100644
index 0000000..39619a6
--- /dev/null
+++ b/src/metadata/m4a/mp4stblbox.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef MP4STBLBOX_H
+#define MP4STBLBOX_H
+
+#include "mp4isobox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class Mp4StblBox: public Mp4IsoBox
+ {
+ public:
+ Mp4StblBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
+ ~Mp4StblBox();
+
+ //! parse stbl contents
+ void parse();
+ //! set the handler type - needed for stsd
+ void setHandlerType( MP4::Fourcc fourcc );
+
+ private:
+ class Mp4StblBoxPrivate;
+ Mp4StblBoxPrivate* d;
+ }; // Mp4StblBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // MP4STBLBOX_H
diff --git a/src/metadata/m4a/mp4stsdbox.cpp b/src/metadata/m4a/mp4stsdbox.cpp
new file mode 100644
index 0000000..6bb8cbe
--- /dev/null
+++ b/src/metadata/m4a/mp4stsdbox.cpp
@@ -0,0 +1,91 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "tlist.h"
+#include <iostream>
+#include "mp4stsdbox.h"
+#include "mp4audiosampleentry.h"
+#include "mp4file.h"
+
+using namespace TagLib;
+
+class MP4::Mp4StsdBox::Mp4StsdBoxPrivate
+{
+public:
+ //! the handler type for the current trak
+ MP4::Fourcc handler_type;
+ //! the audio sample entry
+ MP4::Mp4AudioSampleEntry* audioSampleEntry;
+}; // class Mp4StsdBoxPrivate
+
+MP4::Mp4StsdBox::Mp4StsdBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
+ : Mp4IsoFullBox( file, fourcc, size, offset )
+{
+ d = new MP4::Mp4StsdBox::Mp4StsdBoxPrivate();
+}
+
+MP4::Mp4StsdBox::~Mp4StsdBox()
+{
+ delete d;
+}
+
+void MP4::Mp4StsdBox::setHandlerType( MP4::Fourcc fourcc )
+{
+ d->handler_type = fourcc;
+}
+
+void MP4::Mp4StsdBox::parse()
+{
+ MP4::File* mp4file = dynamic_cast<MP4::File*>( file() );
+ if(!mp4file)
+ return;
+
+ TagLib::uint totalsize = 12; // initial size of box
+
+ // check for handler type - only parse if 'soun':
+ if( static_cast<TagLib::uint>(d->handler_type) == 0x736f756e )
+ {
+ // read entry count
+ TagLib::uint entry_count;
+ if(!mp4file->readInt( entry_count ))
+ return;
+
+ // simply read first entry and skip all following
+ // read size and type
+ TagLib::uint cursize;
+ MP4::Fourcc fourcc;
+ if( !mp4file->readSizeAndType( cursize, fourcc ))
+ return;
+
+ totalsize += 12;
+ // alocate an AudioSampleEntry
+ d->audioSampleEntry = new MP4::Mp4AudioSampleEntry( mp4file, fourcc, cursize, mp4file->tell() );
+ // parse the AudioSampleEntry
+ d->audioSampleEntry->parse();
+ totalsize += cursize-8;
+ // skip the remaining box contents
+ mp4file->seek( size()-totalsize, TagLib::File::Current );
+ }
+ else
+ {
+ mp4file->seek( size()-totalsize, TagLib::File::Current );
+ }
+}
diff --git a/src/metadata/m4a/mp4stsdbox.h b/src/metadata/m4a/mp4stsdbox.h
new file mode 100644
index 0000000..90bc014
--- /dev/null
+++ b/src/metadata/m4a/mp4stsdbox.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef MP4STSDBOX_H
+#define MP4STSDBOX_H
+
+#include "mp4isofullbox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class Mp4StsdBox: public Mp4IsoFullBox
+ {
+ public:
+ Mp4StsdBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
+ ~Mp4StsdBox();
+
+ //! parse stsd contents
+ void parse();
+ //! set the handler type - needed for stsd
+ void setHandlerType( MP4::Fourcc fourcc );
+
+ private:
+ class Mp4StsdBoxPrivate;
+ Mp4StsdBoxPrivate* d;
+ }; // Mp4StsdBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // MP4STSDBOX_H
diff --git a/src/metadata/m4a/mp4tagsproxy.cpp b/src/metadata/m4a/mp4tagsproxy.cpp
new file mode 100644
index 0000000..0a77427
--- /dev/null
+++ b/src/metadata/m4a/mp4tagsproxy.cpp
@@ -0,0 +1,168 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "mp4tagsproxy.h"
+#include "itunesdatabox.h"
+
+using namespace TagLib;
+
+class MP4::Mp4TagsProxy::Mp4TagsProxyPrivate
+{
+public:
+ ITunesDataBox* titleData;
+ ITunesDataBox* artistData;
+ ITunesDataBox* albumData;
+ ITunesDataBox* coverData;
+ ITunesDataBox* genreData;
+ ITunesDataBox* yearData;
+ ITunesDataBox* trknData;
+ ITunesDataBox* commentData;
+ ITunesDataBox* groupingData;
+ ITunesDataBox* composerData;
+ ITunesDataBox* diskData;
+ ITunesDataBox* bpmData;
+};
+
+MP4::Mp4TagsProxy::Mp4TagsProxy()
+{
+ d = new MP4::Mp4TagsProxy::Mp4TagsProxyPrivate();
+ d->titleData = 0;
+ d->artistData = 0;
+ d->albumData = 0;
+ d->coverData = 0;
+ d->genreData = 0;
+ d->yearData = 0;
+ d->trknData = 0;
+ d->commentData = 0;
+ d->groupingData = 0;
+ d->composerData = 0;
+ d->diskData = 0;
+ d->bpmData = 0;
+}
+
+MP4::Mp4TagsProxy::~Mp4TagsProxy()
+{
+ delete d;
+}
+
+MP4::ITunesDataBox* MP4::Mp4TagsProxy::titleData() const
+{
+ return d->titleData;
+}
+
+MP4::ITunesDataBox* MP4::Mp4TagsProxy::artistData() const
+{
+ return d->artistData;
+}
+
+MP4::ITunesDataBox* MP4::Mp4TagsProxy::albumData() const
+{
+ return d->albumData;
+}
+
+MP4::ITunesDataBox* MP4::Mp4TagsProxy::genreData() const
+{
+ return d->genreData;
+}
+
+MP4::ITunesDataBox* MP4::Mp4TagsProxy::yearData() const
+{
+ return d->yearData;
+}
+
+MP4::ITunesDataBox* MP4::Mp4TagsProxy::trknData() const
+{
+ return d->trknData;
+}
+
+MP4::ITunesDataBox* MP4::Mp4TagsProxy::commentData() const
+{
+ return d->commentData;
+}
+
+MP4::ITunesDataBox* MP4::Mp4TagsProxy::groupingData() const
+{
+ return d->groupingData;
+}
+
+MP4::ITunesDataBox* MP4::Mp4TagsProxy::composerData() const
+{
+ return d->composerData;
+}
+
+MP4::ITunesDataBox* MP4::Mp4TagsProxy::diskData() const
+{
+ return d->diskData;
+}
+
+MP4::ITunesDataBox* MP4::Mp4TagsProxy::bpmData() const
+{
+ return d->bpmData;
+}
+
+MP4::ITunesDataBox* MP4::Mp4TagsProxy::coverData() const
+{
+ return d->coverData;
+}
+
+void MP4::Mp4TagsProxy::registerBox( EBoxType boxtype, ITunesDataBox* databox )
+{
+ switch( boxtype )
+ {
+ case title:
+ d->titleData = databox;
+ break;
+ case artist:
+ d->artistData = databox;
+ break;
+ case album:
+ d->albumData = databox;
+ break;
+ case cover:
+ d->coverData = databox;
+ break;
+ case genre:
+ d->genreData = databox;
+ break;
+ case year:
+ d->yearData = databox;
+ break;
+ case trackno:
+ d->trknData = databox;
+ break;
+ case comment:
+ d->commentData = databox;
+ break;
+ case grouping:
+ d->groupingData = databox;
+ break;
+ case composer:
+ d->composerData = databox;
+ break;
+ case disk:
+ d->diskData = databox;
+ break;
+ case bpm:
+ d->bpmData = databox;
+ break;
+ }
+}
+
diff --git a/src/metadata/m4a/mp4tagsproxy.h b/src/metadata/m4a/mp4tagsproxy.h
new file mode 100644
index 0000000..c8bcbf0
--- /dev/null
+++ b/src/metadata/m4a/mp4tagsproxy.h
@@ -0,0 +1,99 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef MP4TAGSPROXY_H
+#define MP4TAGSPROXY_H
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ // forward declaration(s)
+ class ITunesDataBox;
+ /*! proxy for mp4 itunes tag relevant boxes
+ *
+ * this class works as a proxy for the specific tag boxes
+ * in an mp4 itunes file. the boxes are mired in
+ * the mp4 file structure and stepping through all box layers
+ * is avoided by registration at the proxy object.
+ */
+ class Mp4TagsProxy
+ {
+ public:
+ /*! enum for all supported box types */
+ typedef enum
+ {
+ title = 0,
+ artist,
+ album,
+ cover,
+ genre,
+ year,
+ trackno,
+ comment,
+ grouping,
+ composer,
+ disk,
+ bpm
+ } EBoxType;
+
+ //! constructor
+ Mp4TagsProxy();
+ //! destructor
+ ~Mp4TagsProxy();
+
+ //! function to get the data box for the title
+ ITunesDataBox* titleData() const;
+ //! function to get the data box for the artist
+ ITunesDataBox* artistData() const;
+ //! function to get the data box for the album
+ ITunesDataBox* albumData() const;
+ //! function to get the data box for the genre
+ ITunesDataBox* genreData() const;
+ //! function to get the data box for the year
+ ITunesDataBox* yearData() const;
+ //! function to get the data box for the track number
+ ITunesDataBox* trknData() const;
+ //! function to get the data box for the comment
+ ITunesDataBox* commentData() const;
+ //! function to get the data box for the grouping
+ ITunesDataBox* groupingData() const;
+ //! function to get the data box for the composer
+ ITunesDataBox* composerData() const;
+ //! function to get the data box for the disk number
+ ITunesDataBox* diskData() const;
+ //! function to get the data box for the bpm
+ ITunesDataBox* bpmData() const;
+ //! function to get the data box for the cover
+ ITunesDataBox* coverData() const;
+
+ //! function to register a data box for a certain box type
+ void registerBox( EBoxType boxtype, ITunesDataBox* databox );
+
+ private:
+ class Mp4TagsProxyPrivate;
+ //! private data of tags proxy
+ Mp4TagsProxyPrivate* d;
+ }; // class Mp4TagsProxy
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // MP4TAGSPROXY_H
diff --git a/src/metadata/m4a/mp4trakbox.cpp b/src/metadata/m4a/mp4trakbox.cpp
new file mode 100644
index 0000000..c573ec7
--- /dev/null
+++ b/src/metadata/m4a/mp4trakbox.cpp
@@ -0,0 +1,86 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "tlist.h"
+#include <iostream>
+#include "mp4trakbox.h"
+#include "boxfactory.h"
+#include "mp4file.h"
+
+using namespace TagLib;
+
+class MP4::Mp4TrakBox::Mp4TrakBoxPrivate
+{
+public:
+ //! container for all boxes in trak box
+ TagLib::List<Mp4IsoBox*> trakBoxes;
+ //! a box factory for creating the appropriate boxes
+ MP4::BoxFactory boxfactory;
+}; // class Mp4TrakBoxPrivate
+
+MP4::Mp4TrakBox::Mp4TrakBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
+ : Mp4IsoBox( file, fourcc, size, offset )
+{
+ d = new MP4::Mp4TrakBox::Mp4TrakBoxPrivate();
+}
+
+MP4::Mp4TrakBox::~Mp4TrakBox()
+{
+ TagLib::List<Mp4IsoBox*>::Iterator delIter;
+ for( delIter = d->trakBoxes.begin();
+ delIter != d->trakBoxes.end();
+ delIter++ )
+ {
+ delete *delIter;
+ }
+ delete d;
+}
+
+void MP4::Mp4TrakBox::parse()
+{
+ TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
+
+ TagLib::uint totalsize = 8;
+ // parse all contained boxes
+ TagLib::uint size;
+ MP4::Fourcc fourcc;
+
+ while( (mp4file->readSizeAndType( size, fourcc ) == true) )
+ {
+ totalsize += size;
+
+ // check for errors
+ if( totalsize > MP4::Mp4IsoBox::size() )
+ {
+ std::cerr << "Error in mp4 file " << mp4file->name() << " trak box contains bad box with name: " << fourcc.toString() << std::endl;
+ return;
+ }
+
+ // create the appropriate subclass and parse it
+ MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( mp4file, fourcc, size, mp4file->tell() );
+ curbox->parsebox();
+ d->trakBoxes.append( curbox );
+
+ // check for end of trak box
+ if( totalsize == MP4::Mp4IsoBox::size() )
+ break;
+ }
+}
diff --git a/src/metadata/m4a/mp4trakbox.h b/src/metadata/m4a/mp4trakbox.h
new file mode 100644
index 0000000..b362fa3
--- /dev/null
+++ b/src/metadata/m4a/mp4trakbox.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef MP4TRAKBOX_H
+#define MP4TRAKBOX_H
+
+#include "mp4isobox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class Mp4TrakBox: public Mp4IsoBox
+ {
+ public:
+ Mp4TrakBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
+ ~Mp4TrakBox();
+
+ //! parse trak contents
+ void parse();
+
+ private:
+ class Mp4TrakBoxPrivate;
+ Mp4TrakBoxPrivate* d;
+ }; // Mp4TrakBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // MP4TRAKBOX_H
diff --git a/src/metadata/m4a/mp4udtabox.cpp b/src/metadata/m4a/mp4udtabox.cpp
new file mode 100644
index 0000000..268d1c1
--- /dev/null
+++ b/src/metadata/m4a/mp4udtabox.cpp
@@ -0,0 +1,95 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "tlist.h"
+#include <iostream>
+#include "mp4udtabox.h"
+#include "boxfactory.h"
+#include "mp4file.h"
+
+using namespace TagLib;
+
+class MP4::Mp4UdtaBox::Mp4UdtaBoxPrivate
+{
+public:
+ //! container for all boxes in udta box
+ TagLib::List<Mp4IsoBox*> udtaBoxes;
+ //! a box factory for creating the appropriate boxes
+ MP4::BoxFactory boxfactory;
+}; // class Mp4UdtaBoxPrivate
+
+MP4::Mp4UdtaBox::Mp4UdtaBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
+ : Mp4IsoBox( file, fourcc, size, offset )
+{
+ d = new MP4::Mp4UdtaBox::Mp4UdtaBoxPrivate();
+}
+
+MP4::Mp4UdtaBox::~Mp4UdtaBox()
+{
+ TagLib::List<Mp4IsoBox*>::Iterator delIter;
+ for( delIter = d->udtaBoxes.begin();
+ delIter != d->udtaBoxes.end();
+ delIter++ )
+ {
+ delete *delIter;
+ }
+ delete d;
+}
+
+void MP4::Mp4UdtaBox::parse()
+{
+#if 0
+ std::cout << " parsing udta box" << std::endl;
+#endif
+ TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
+
+ TagLib::uint totalsize = 8;
+ // parse all contained boxes
+ TagLib::uint size;
+ MP4::Fourcc fourcc;
+
+#if 0
+ std::cout << " ";
+#endif
+ while( (mp4file->readSizeAndType( size, fourcc ) == true) )
+ {
+ totalsize += size;
+
+ // check for errors
+ if( totalsize > MP4::Mp4IsoBox::size() )
+ {
+ std::cerr << "Error in mp4 file " << mp4file->name() << " udta box contains bad box with name: " << fourcc.toString() << std::endl;
+ return;
+ }
+
+ // create the appropriate subclass and parse it
+ MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( mp4file, fourcc, size, mp4file->tell() );
+ curbox->parsebox();
+ d->udtaBoxes.append( curbox );
+
+ // check for end of udta box
+ if( totalsize == MP4::Mp4IsoBox::size() )
+ break;
+#if 0
+ std::cout << " ";
+#endif
+ }
+}
diff --git a/src/metadata/m4a/mp4udtabox.h b/src/metadata/m4a/mp4udtabox.h
new file mode 100644
index 0000000..4873e32
--- /dev/null
+++ b/src/metadata/m4a/mp4udtabox.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ copyright : (C) 2002, 2003, 2006 by Jochen Issing
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef MP4UDTABOX_H
+#define MP4UDTABOX_H
+
+#include "mp4isobox.h"
+#include "mp4fourcc.h"
+
+namespace TagLib
+{
+ namespace MP4
+ {
+ class Mp4UdtaBox: public Mp4IsoBox
+ {
+ public:
+ Mp4UdtaBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
+ ~Mp4UdtaBox();
+
+ //! parse moov contents
+ void parse();
+
+ private:
+ class Mp4UdtaBoxPrivate;
+ Mp4UdtaBoxPrivate* d;
+ }; // Mp4UdtaBox
+
+ } // namespace MP4
+} // namespace TagLib
+
+#endif // MP4UDTABOX_H
diff --git a/src/metadata/m4a/taglib_mp4filetyperesolver.cpp b/src/metadata/m4a/taglib_mp4filetyperesolver.cpp
new file mode 100644
index 0000000..9566a93
--- /dev/null
+++ b/src/metadata/m4a/taglib_mp4filetyperesolver.cpp
@@ -0,0 +1,42 @@
+/***************************************************************************
+ copyright : (C) 2006 by Martin Aumueller
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "taglib_mp4filetyperesolver.h"
+#include "mp4file.h"
+
+#include <string.h>
+
+TagLib::File *MP4FileTypeResolver::createFile(const char *fileName,
+ bool readProperties,
+ TagLib::AudioProperties::ReadStyle propertiesStyle) const
+{
+// fprintf(stderr, "mp4?: %s\n", fileName);
+ const char *ext = strrchr(fileName, '.');
+ if(ext && (!strcasecmp(ext, ".m4a")
+ || !strcasecmp(ext, ".m4b") || !strcasecmp(ext, ".m4p")
+ || !strcasecmp(ext, ".mp4")
+ || !strcasecmp(ext, ".m4v") || !strcasecmp(ext, ".mp4v")))
+ {
+ return new TagLib::MP4::File(fileName, readProperties, propertiesStyle);
+ }
+
+ return 0;
+}
diff --git a/src/metadata/m4a/taglib_mp4filetyperesolver.h b/src/metadata/m4a/taglib_mp4filetyperesolver.h
new file mode 100644
index 0000000..fbc3dd4
--- /dev/null
+++ b/src/metadata/m4a/taglib_mp4filetyperesolver.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ copyright : (C) 2006 by Martin Aumueller
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef TAGLIB_MP4FILETYPERESOLVER_H
+#define TAGLIB_MP4FILETYPERESOLVER_H
+
+#include <taglib/tfile.h>
+#include <taglib/fileref.h>
+
+
+class MP4FileTypeResolver : public TagLib::FileRef::FileTypeResolver
+{
+ TagLib::File *createFile(const char *fileName,
+ bool readAudioProperties,
+ TagLib::AudioProperties::ReadStyle audioPropertiesStyle) const;
+};
+
+#endif
diff --git a/src/metadata/mp4/Makefile.am b/src/metadata/mp4/Makefile.am
new file mode 100644
index 0000000..e0779c6
--- /dev/null
+++ b/src/metadata/mp4/Makefile.am
@@ -0,0 +1,18 @@
+SUBDIRS =
+
+INCLUDES = $(all_includes) $(MP4V2_INCLUDES) $(taglib_includes)
+METASOURCES = AUTO
+libtagmp4_la_LDFLAGS = $(all_libraries) $(MP4V2_LIBS)
+noinst_LTLIBRARIES = libtagmp4.la
+
+libtagmp4_la_SOURCES = \
+ mp4properties.cpp \
+ mp4tag.cpp \
+ mp4file.cpp \
+ taglib_mp4filetyperesolver.cpp
+
+noinst_HEADERS = \
+ mp4properties.h \
+ mp4tag.h \
+ mp4file.h \
+ taglib_mp4filetyperesolver.h
diff --git a/src/metadata/optimfrog/Makefile.am b/src/metadata/optimfrog/Makefile.am
new file mode 100755
index 0000000..f2b7e6b
--- /dev/null
+++ b/src/metadata/optimfrog/Makefile.am
@@ -0,0 +1,6 @@
+INCLUDES = $(all_includes) $(taglib_includes)
+METASOURCES = AUTO
+libtagoptimfrog_la_LDFLAGS = $(all_libraries)
+noinst_LTLIBRARIES = libtagoptimfrog.la
+noinst_HEADERS = taglib_optimfrogfiletyperesolver.h
+libtagoptimfrog_la_SOURCES = taglib_optimfrogfiletyperesolver.cpp
diff --git a/src/metadata/optimfrog/taglib_optimfrogfiletyperesolver.cpp b/src/metadata/optimfrog/taglib_optimfrogfiletyperesolver.cpp
new file mode 100755
index 0000000..13cde6a
--- /dev/null
+++ b/src/metadata/optimfrog/taglib_optimfrogfiletyperesolver.cpp
@@ -0,0 +1,21 @@
+// (c) 2006 Martin Aumueller <[email protected]>
+// modified 2006 Daniel Faust <[email protected]>
+// See COPYING file for licensing information
+
+#include "taglib_optimfrogfiletyperesolver.h"
+#include <taglib/mpcfile.h>
+
+#include <string.h>
+
+TagLib::File *OptimFrogFileTypeResolver::createFile(const char *fileName,
+ bool readProperties,
+ TagLib::AudioProperties::ReadStyle propertiesStyle) const
+{
+ const char *ext = strrchr(fileName, '.');
+ if(ext && !strcasecmp(ext, ".ofr"))
+ {
+ return new TagLib::MPC::File(fileName, readProperties, propertiesStyle);
+ }
+
+ return 0;
+}
diff --git a/src/metadata/optimfrog/taglib_optimfrogfiletyperesolver.h b/src/metadata/optimfrog/taglib_optimfrogfiletyperesolver.h
new file mode 100755
index 0000000..b277ed5
--- /dev/null
+++ b/src/metadata/optimfrog/taglib_optimfrogfiletyperesolver.h
@@ -0,0 +1,19 @@
+// (c) 2006 Martin Aumueller <[email protected]>
+// modified 2006 Daniel Faust <[email protected]>
+// See COPYING file for licensing information
+
+#ifndef TAGLIB_OPTIMFROGFILETYPERESOLVER_H
+#define TAGLIB_OPTIMFROGFILETYPERESOLVER_H
+
+#include <taglib/tfile.h>
+#include <taglib/fileref.h>
+
+
+class OptimFrogFileTypeResolver : public TagLib::FileRef::FileTypeResolver
+{
+ TagLib::File *createFile(const char *fileName,
+ bool readAudioProperties,
+ TagLib::AudioProperties::ReadStyle audioPropertiesStyle) const;
+};
+
+#endif
diff --git a/src/metadata/rmff/Makefile.am b/src/metadata/rmff/Makefile.am
new file mode 100644
index 0000000..b493e66
--- /dev/null
+++ b/src/metadata/rmff/Makefile.am
@@ -0,0 +1,15 @@
+SUBDIRS =
+
+INCLUDES = $(all_includes) $(taglib_includes)
+METASOURCES = AUTO
+libtagrealmedia_la_LDFLAGS = $(all_libraries)
+noinst_LTLIBRARIES = libtagrealmedia.la
+
+libtagrealmedia_la_SOURCES = rmff.cpp \
+ taglib_realmediafile.cpp \
+ taglib_realmediafiletyperesolver.cpp
+
+noinst_HEADERS = rmff.h \
+ taglib_realmediafile.h \
+ taglib_realmediafiletyperesolver.h
+
diff --git a/src/metadata/rmff/rmff.cpp b/src/metadata/rmff/rmff.cpp
new file mode 100644
index 0000000..da0edd5
--- /dev/null
+++ b/src/metadata/rmff/rmff.cpp
@@ -0,0 +1,998 @@
+/***************************************************************************
+ copyright : (C) 2005 by Paul Cifarelli
+ ***************************************************************************/
+
+/***************************************************************************
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * 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., 51 Franklin St, 5th fl, Boston, MA 02110-1301, *
+ * USA, or check http://www.fsf.org/about/contact.html *
+ * *
+ * Note that no RealNetworks code appears or is duplicated, copied, or *
+ + used as a template in this code. The code was written from scratch *
+ * using the reference documentation found at: *
+ * *
+ * https://common.helixcommunity.org/nonav/2003/HCS_SDK_r5/helixsdk.htm *
+ * *
+ ***************************************************************************/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <taglib.h>
+#include <id3v1tag.h>
+#include <id3v2tag.h>
+#include <tfile.h>
+#include <fileref.h>
+#include <iostream>
+
+#include <string.h>
+
+#include "rmff.h"
+
+#define UNPACK4(a, buf, i) memcpy((void *)&a, (void *) &buf[i], 4),i+=4,a=ntohl(a)
+#define UNPACK2(a, buf, i) memcpy((void *)&a, (void *) &buf[i], 2),i+=2,a=ntohs(a)
+
+using namespace TagLib;
+using namespace TagLib::RealMedia;
+
+RMFFile::RMFFile(const char *filename) : File(filename), m_id3tag(0)
+{
+ if (isOpen())
+ m_id3tag = new ID3v1::Tag(this, length() - 128);
+}
+
+RMFFile::~RMFFile()
+{
+ delete m_id3tag;
+}
+
+bool RMFFile::save()
+{
+ ByteVector bv = m_id3tag->render(); //TODO finish this
+ return false;
+}
+
+
+String RealMediaFF::title () const
+{
+ return !m_err && m_id3v1tag ? m_id3v1tag->tag()->title() : "";
+}
+
+String RealMediaFF::artist () const
+{
+ return !m_err && m_id3v1tag ? m_id3v1tag->tag()->artist() : "";
+}
+
+String RealMediaFF::album () const
+{
+ return !m_err && m_id3v1tag ? m_id3v1tag->tag()->album() : "";
+}
+
+String RealMediaFF::comment() const
+{
+ return !m_err && m_id3v1tag ? m_id3v1tag->tag()->comment() : "";
+}
+
+String RealMediaFF::genre() const
+{
+ return !m_err && m_id3v1tag ? m_id3v1tag->tag()->genre() : "";
+}
+
+TagLib::uint RealMediaFF::year() const
+{
+ return !m_err && m_id3v1tag ? m_id3v1tag->tag()->year() : 0;
+}
+
+TagLib::uint RealMediaFF::track() const
+{
+ return !m_err && m_id3v1tag ? m_id3v1tag->tag()->track() : 0;
+}
+
+// properties
+int RealMediaFF::length () const
+{
+ return m_readProperties && !m_err && m_props ? m_props->duration : 0;
+}
+
+int RealMediaFF::bitrate () const
+{
+ return m_readProperties && !m_err && m_props ? m_props->avg_bit_rate : 0;
+}
+
+int RealMediaFF::sampleRate () const
+{
+ return 0;
+}
+
+int RealMediaFF::channels () const
+{
+ return 0;
+}
+
+
+RealMediaFF::RealMediaFF(const char *file, bool readProperties, AudioProperties::ReadStyle /*propertiesStyle*/)
+: m_filename(0)
+, m_head(0)
+, m_tail(0)
+, m_err(0)
+, m_hdr(0)
+, m_props(0)
+, media_hdrs(0)
+, m_contenthdr(0)
+, m_md(0)
+, m_title(0)
+, m_author(0)
+, m_copyright(0)
+, m_comment(0)
+, m_id3v1tag(0)
+, m_flipYearInMetadataSection(0)
+, m_readProperties(readProperties)
+{
+ m_filename = strdup(file);
+
+ m_fd = open(m_filename, O_RDONLY);
+ if (m_fd < 0)
+ {
+ m_err = -1;
+ return;
+ }
+
+ // ok, for RM files, the properties are embedded, so we ignore propertiesStyle
+ if (m_readProperties)
+ {
+ init();
+
+ // and now for the really complicated stuff...
+ if (initMetadataSection())
+ std::cerr << "ERROR reading Metadata\n";
+ }
+
+ // now get the ID3v1 tag at the end of this file
+ m_id3v1tag = new RMFFile(m_filename);
+}
+
+
+RealMediaFF::RealMediaFF(RealMediaFF &src)
+: m_filename(0)
+, m_head(0)
+, m_tail(0)
+, m_err(0)
+, m_hdr(0)
+, m_props(0)
+, media_hdrs(0)
+, m_contenthdr(0)
+, m_md(0)
+, m_title(0)
+, m_author(0)
+, m_copyright(0)
+, m_comment(0)
+, m_id3v1tag(0)
+, m_flipYearInMetadataSection(0)
+, m_readProperties(src.m_readProperties)
+{
+ m_filename=strdup(src.m_filename);
+
+ m_fd = open(m_filename, O_RDONLY);
+ if (m_fd < 0)
+ {
+ m_err = -1;
+ return;
+ }
+
+ // ok, for RM files, the properties are embedded, so we ignore propertiesStyle
+ if (m_readProperties)
+ {
+ init();
+
+ // and now for the really complicated stuff...
+ if (initMetadataSection())
+ std::cerr << "ERROR reading Metadata\n";
+ }
+
+ // now get the ID3v1 tag at the end of this file
+ m_id3v1tag = new RMFFile(m_filename);
+}
+
+RealMediaFF::~RealMediaFF()
+{
+ ::free(m_filename);
+
+ Collectable *hdr = m_head, *next;
+ while (hdr)
+ {
+ next = hdr->fwd;
+ delete hdr;
+ hdr = next;
+ }
+
+ delete m_id3v1tag;
+ delete m_md;
+
+ close(m_fd);
+}
+
+bool RealMediaFF::isEmpty() const
+{
+ return m_id3v1tag->tag()->isEmpty();
+}
+
+
+void RealMediaFF::saveHeader(Collectable *hdr)
+{
+ hdr->fwd = 0;
+ if (!m_head)
+ m_head = m_tail = hdr;
+ else
+ {
+ m_tail->fwd = hdr;
+ m_tail = hdr;
+ }
+}
+
+
+int RealMediaFF::init()
+{
+ int nbytes;
+ unsigned char buf[65536];
+ UINT32 object_id;
+ UINT32 sz;
+ UINT32 consumed = 0;
+
+ off_t s;
+ if ( (s = lseek(m_fd, 0, SEEK_SET)) )
+ {
+ m_err = -1;
+ return m_err;
+ }
+
+ m_hdr = new File_Header_v0_v1;
+ nbytes = getChunk(buf, 65536, m_hdr->s.object_id, m_hdr->s.size, consumed);
+ if (nbytes < 0 || m_hdr->s.size != consumed || memcmp((void *)&m_hdr->s.object_id, ".RMF", 4))
+ {
+ //std::cerr << "SERIOUS ERROR - not likely a RealMedia file\n";
+ m_err = -1;
+ return m_err;
+ }
+ if (!getRealFileHeader(m_hdr, buf, m_hdr->s.object_id, m_hdr->s.size))
+ {
+ saveHeader(m_hdr);
+ consumed = 0;
+ nbytes = getChunk(buf, 65536, object_id, sz, consumed);
+ if (nbytes < 0 || sz != consumed)
+ {
+ m_err = -1;
+ return m_err;
+ }
+
+ while (!m_err && memcmp((void *)&object_id, "DATA", 4))
+ {
+ char oid[5];
+ memcpy((void *)oid, (void *)&object_id, 4);
+ oid[4] = 0;
+ if (!memcmp((void *)&object_id, "PROP", 4))
+ {
+ m_props = new RMProperties;
+ getRealPropertyHeader(m_props, buf, object_id, sz);
+ saveHeader(m_props);
+ }
+
+ if (!memcmp((void *)&object_id, "MDPR", 4))
+ {
+ media_hdrs = new MediaProperties;
+ getMediaPropHeader(media_hdrs, buf, object_id, sz);
+ saveHeader(media_hdrs);
+ }
+
+ if (!memcmp((void *)&object_id, "CONT", 4))
+ {
+ m_contenthdr = new ContentDescription;
+ getContentDescription(m_contenthdr, buf, object_id, sz);
+ saveHeader(m_contenthdr);
+ }
+
+ consumed = 0;
+ do
+ {
+ nbytes = getChunk(buf, 65536, object_id, sz, consumed);
+ } while ( !m_err && memcmp((void *)&object_id, "DATA", 4) && (consumed < sz) );
+ }
+ }
+
+ return 0;
+}
+
+int RealMediaFF::getHdr(unsigned char *buf, size_t sz, UINT32 &fourcc, UINT32 &csz)
+{
+ int nbytes = 0, i = 0;
+
+ if (sz < (size_t)RMFF_HDR_SIZE)
+ return 0;
+
+ if ( (nbytes = read(m_fd, (void *) buf, RMFF_HDR_SIZE)) != RMFF_HDR_SIZE )
+ {
+ m_err = -1;
+
+ return (nbytes);
+ }
+
+ memcpy((void *)&fourcc, buf, 4); i+=4;
+ UNPACK4(csz,buf,i);
+
+ return nbytes;
+}
+
+int RealMediaFF::getChunk(unsigned char *buf, size_t sz, UINT32 &fourcc, UINT32 &csz, UINT32 &alreadyconsumed)
+{
+ int nbytes = 0, i = 0, readamount;
+ csz = 0;
+
+ if (!alreadyconsumed)
+ {
+ if ( (nbytes = getHdr(buf, sz, fourcc, csz)) != RMFF_HDR_SIZE )
+ {
+ m_err = -1;
+ alreadyconsumed += nbytes > 0 ? nbytes : 0;
+ return nbytes;
+ }
+ alreadyconsumed += RMFF_HDR_SIZE;
+ readamount = csz - RMFF_HDR_SIZE;
+ i = RMFF_HDR_SIZE;
+ }
+ else
+ readamount = csz - alreadyconsumed;
+
+ if ( (nbytes = read(m_fd, (void *) &buf[i], readamount > (int)sz - i ? (int)sz - i : readamount )) != readamount )
+ {
+ if (nbytes < 0)
+ {
+ m_err = -1;
+ }
+ else
+ alreadyconsumed += nbytes;
+
+ return (nbytes<0 ? i : i + nbytes);
+ }
+
+ alreadyconsumed += nbytes;
+ return (csz);
+}
+
+int RealMediaFF::getRealFileHeader(File_Header_v0_v1 *hdr, const unsigned char *buf, UINT32 object_id, int sz)
+{
+ int i = 0;
+
+ // RealMedia header
+ hdr->s.object_id = object_id;
+ hdr->s.size = sz;
+
+ i = RMFF_HDR_SIZE;
+ UNPACK2(hdr->object_version, buf, i);
+
+ if ( !strncmp((const char *) &hdr->s.object_id, ".RMF", 4) &&
+ (hdr->object_version == 0 || hdr->object_version == 1) )
+ {
+ UNPACK4(hdr->file_version, buf, i);
+ UNPACK4(hdr->num_headers, buf, i);
+ }
+ return 0;
+}
+
+int RealMediaFF::getRealPropertyHeader(RMProperties *props, const unsigned char *buf, UINT32 object_id, int sz)
+{
+ int i = 0;
+
+ // Properties
+ props->s.object_id = object_id;
+ props->s.size = sz;
+
+ i = RMFF_HDR_SIZE;
+ UNPACK2(props->object_version, buf, i);
+
+ if ( !strncmp((const char *)&props->s.object_id,"PROP",4) && (props->object_version == 0) )
+ {
+ UNPACK4(props->max_bit_rate, buf, i);
+ UNPACK4(props->avg_bit_rate, buf, i);
+ UNPACK4(props->max_packet_size, buf, i);
+ UNPACK4(props->avg_packet_size, buf, i);
+ UNPACK4(props->num_packets, buf, i);
+ UNPACK4(props->duration, buf, i);
+ UNPACK4(props->preroll, buf, i);
+ UNPACK4(props->index_offset, buf, i);
+ UNPACK4(props->data_offset, buf, i);
+ UNPACK2(props->num_streams, buf, i);
+ UNPACK2(props->flags, buf, i);
+ }
+ return 0;
+}
+
+
+int RealMediaFF::getMediaPropHeader(MediaProperties *media_hdr, const unsigned char *buf, UINT32 object_id, int sz)
+{
+ int i = 0;
+
+ // Properties
+ media_hdr->s.object_id = object_id;
+ media_hdr->s.size = sz;
+
+ i = RMFF_HDR_SIZE;
+ UNPACK2(media_hdr->object_version, buf, i);
+
+ if ( !strncmp((const char *)&media_hdr->s.object_id, "MDPR", 4) && media_hdr->object_version == 0)
+ {
+ UNPACK2(media_hdr->stream_number, buf, i);
+ UNPACK4(media_hdr->max_bit_rate, buf, i);
+ UNPACK4(media_hdr->avg_bit_rate, buf, i);
+ UNPACK4(media_hdr->max_packet_size, buf, i);
+ UNPACK4(media_hdr->avg_packet_size, buf, i);
+ UNPACK4(media_hdr->start_time, buf, i);
+ UNPACK4(media_hdr->preroll, buf, i);
+ UNPACK4(media_hdr->duration, buf, i);
+ media_hdr->stream_name_size = buf[i]; i++;
+ memcpy(media_hdr->stream_name, &buf[i], media_hdr->stream_name_size);
+ media_hdr->stream_name[media_hdr->stream_name_size] = 0;
+ i += media_hdr->stream_name_size;
+ media_hdr->mime_type_size = buf[i]; i++;
+ memcpy(media_hdr->mime_type, &buf[i], media_hdr->mime_type_size);
+ i += media_hdr->mime_type_size;
+ UNPACK4(media_hdr->type_specific_len, buf, i);
+ if (media_hdr->type_specific_len)
+ {
+ media_hdr->type_specific_data = new UINT8[media_hdr->type_specific_len];
+ memcpy(media_hdr->type_specific_data, &buf[i], media_hdr->type_specific_len);
+
+ if (!strncmp((const char *)media_hdr->mime_type, "logical-fileinfo", 16))
+ {
+ media_hdr->lstr = new LogicalStream;
+ UNPACK4(media_hdr->lstr->size, buf, i);
+ UNPACK2(media_hdr->lstr->object_version, buf, i);
+ if (media_hdr->lstr->object_version == 0)
+ {
+ UNPACK2(media_hdr->lstr->num_physical_streams, buf, i);
+ if (media_hdr->lstr->num_physical_streams > 0)
+ {
+ media_hdr->lstr->physical_stream_numbers = new UINT16[ media_hdr->lstr->num_physical_streams ];
+ media_hdr->lstr->data_offsets = new UINT32[ media_hdr->lstr->num_physical_streams ];
+ for (int j=0; j<media_hdr->lstr->num_physical_streams; j++)
+ {
+ UNPACK2(media_hdr->lstr->physical_stream_numbers[j], buf, i);
+ }
+ for (int j=0; j<media_hdr->lstr->num_physical_streams; j++)
+ {
+ UNPACK4(media_hdr->lstr->data_offsets[j], buf, i);
+ }
+ }
+
+ UNPACK2(media_hdr->lstr->num_rules, buf, i);
+ if (media_hdr->lstr->num_rules > 0)
+ {
+ media_hdr->lstr->rule_to_physical_stream_number_map = new UINT16[ media_hdr->lstr->num_rules ];
+ for (int j=0; j<media_hdr->lstr->num_rules; j++)
+ {
+ UNPACK2(media_hdr->lstr->rule_to_physical_stream_number_map[j], buf, i);
+ }
+ }
+ UNPACK2(media_hdr->lstr->num_properties, buf, i);
+ if (media_hdr->lstr->num_properties > 0)
+ {
+ media_hdr->lstr->properties = new NameValueProperty[ media_hdr->lstr->num_properties ];
+ for (int j=0; j<media_hdr->lstr->num_properties; j++)
+ {
+ UNPACK4(media_hdr->lstr->properties[j].size, buf, i);
+ UNPACK2(media_hdr->lstr->properties[j].object_version, buf, i);
+ if (media_hdr->lstr->properties[j].object_version == 0)
+ {
+ media_hdr->lstr->properties[j].name_length = buf[i]; i++;
+ if (media_hdr->lstr->properties[j].name_length)
+ {
+ media_hdr->lstr->properties[j].name = new UINT8[ media_hdr->lstr->properties[j].name_length + 1];
+ memcpy((void *)media_hdr->lstr->properties[j].name, (void *)&buf[i],
+ media_hdr->lstr->properties[j].name_length);
+ media_hdr->lstr->properties[j].name[ media_hdr->lstr->properties[j].name_length ] = 0;
+ i+=media_hdr->lstr->properties[j].name_length;
+ }
+
+ UNPACK4(media_hdr->lstr->properties[j].type, buf, i);
+ UNPACK2(media_hdr->lstr->properties[j].value_length, buf, i);
+ if (media_hdr->lstr->properties[j].value_length)
+ {
+ media_hdr->lstr->properties[j].value_data = new UINT8[ media_hdr->lstr->properties[j].value_length + 1];
+ memcpy((void *)media_hdr->lstr->properties[j].value_data, (void *)&buf[i],
+ media_hdr->lstr->properties[j].value_length);
+ media_hdr->lstr->properties[j].value_data[ media_hdr->lstr->properties[j].value_length ] = 0;
+ i+=media_hdr->lstr->properties[j].value_length;
+ }
+ }
+ }
+ }
+ }
+ else
+ media_hdr->lstr = 0;
+ }
+ }
+ else
+ media_hdr->type_specific_data = 0;
+ }
+ else
+ {
+ m_err = -1;
+ return m_err;
+ }
+
+ return 0;
+}
+
+
+int RealMediaFF::getContentDescription(ContentDescription *cont, const unsigned char *buf, UINT32 object_id, int sz)
+{
+ int i = 0;
+
+ // Properties
+ cont->s.object_id = object_id;
+ cont->s.size = sz;
+
+ i = RMFF_HDR_SIZE;
+ UNPACK2(cont->object_version, buf, i);
+
+ if ( !strncmp((const char *)&cont->s.object_id, "CONT", 4) && cont->object_version == 0)
+ {
+ UNPACK2(cont->title_len, buf, i);
+ cont->title = new UINT8[cont->title_len + 1];
+ memcpy((void *)cont->title, (void *)&buf[i], cont->title_len); i+=cont->title_len;
+ m_title = (char *)cont->title;
+ m_title[cont->title_len] = 0;
+
+ UNPACK2(cont->author_len, buf, i);
+ cont->author = new UINT8[cont->author_len + 1];
+ memcpy((void *)cont->author, (void *)&buf[i], cont->author_len); i+=cont->author_len;
+ m_author = (char *)cont->author;
+ m_author[cont->author_len] = 0;
+
+ UNPACK2(cont->copyright_len, buf, i);
+ cont->copyright = new UINT8[cont->copyright_len + 1];
+ memcpy((void *)cont->copyright, (void *)&buf[i], cont->copyright_len); i+=cont->copyright_len;
+ m_copyright = (char *)cont->copyright;
+ m_copyright[cont->copyright_len] = 0;
+
+ UNPACK2(cont->comment_len, buf, i);
+ cont->comment = new UINT8[cont->comment_len + 1];
+ memcpy((void *)cont->comment, (void *)&buf[i], cont->comment_len); i+=cont->comment_len;
+ m_comment = (char *)cont->comment;
+ m_comment[cont->comment_len] = 0;
+ }
+ else
+ {
+ m_err = -1;
+ return m_err;
+ }
+
+ return 0;
+}
+
+
+int RealMediaFF::seekChunk(UINT32 object_id)
+{
+ if (!m_err)
+ {
+ off_t s, tot;
+ UINT32 oid = 0, sz = 0;
+ unsigned char buf[255];
+ int nbytes = 0;
+
+ if ( (s = lseek(m_fd, 0, SEEK_SET)) != 0)
+ return -1;
+
+ tot = 0;
+ while( (nbytes = getHdr(buf, 255, oid, sz)) == RMFF_HDR_SIZE && memcmp((void *)&oid, (void *)&object_id, 4) )
+ {
+ tot += sz;
+ if (sz > (unsigned) RMFF_HDR_SIZE)
+ {
+ if ( (s = lseek(m_fd, sz - RMFF_HDR_SIZE, SEEK_CUR)) != tot )
+ return -1;
+ }
+ else
+ return -1; // bail in this case, since the chuck sz includes the header size
+ }
+ if ( (s = lseek(m_fd, -RMFF_HDR_SIZE, SEEK_CUR)) != tot )
+ return -1;
+
+ return s;
+ }
+ return -1;
+}
+
+int RealMediaFF::getMDProperties(MDProperties *props, const unsigned char *buf)
+{
+ int i = 0;
+
+ int start = i;
+
+ UNPACK4(props->size, buf, i);
+ UNPACK4(props->type, buf, i);
+ UNPACK4(props->flags, buf, i);
+ UNPACK4(props->value_offset, buf, i);
+ UNPACK4(props->subproperties_offset, buf, i);
+ UNPACK4(props->num_subproperties, buf, i);
+ UNPACK4(props->name_length, buf, i);
+ props->name = new UINT8[ props->name_length + 1 ];
+ memcpy((void *)props->name, (void *)&buf[i], props->name_length);
+ props->name[ props->name_length ] = 0;
+ i+=props->name_length;
+
+ i = start + props->value_offset;
+ UNPACK4(props->value_length, buf, i);
+ props->value = new UINT8[ props->value_length ];
+ memcpy( (void *) props->value, (void *)&buf[i], props->value_length );
+
+ if ( (props->type == MPT_ULONG) || (props->type == MPT_FLAG && props->value_length == 4) )
+ {
+ // wOOt! the Year is a ULONG, and its stored little endian?! my guess is this is a bug in
+ // RealPlayer 10 for Windows (where I created my test files)
+ // This hack is intended to ensure that we at least interpret the Year properly.
+ if (!strcmp((char *)props->name, "Year"))
+ {
+ if ( *(unsigned long *)props->value > 65536 )
+ {
+ *(unsigned long *)(props->value) = ntohl(*(unsigned long *)(props->value));
+ m_flipYearInMetadataSection = true;
+ }
+ else
+ m_flipYearInMetadataSection = false;
+ }
+ else
+ *(unsigned long *)(props->value) = ntohl(*(unsigned long *)(props->value));
+ }
+
+ i += props->value_length;
+
+ i = start + props->subproperties_offset;
+ props->subproperties_list = new PropListEntry[ props->num_subproperties ];
+ for (int j=0; j<(int)props->num_subproperties; j++)
+ {
+ UNPACK4(props->subproperties_list[j].offset, buf, i);
+ UNPACK4(props->subproperties_list[j].num_props_for_name, buf, i);
+ }
+
+ props->subproperties = new MDProperties[ props->num_subproperties ];
+ for (int j=0; j<(int)props->num_subproperties; j++)
+ {
+ i = start + props->subproperties_list[j].offset;
+ getMDProperties(&props->subproperties[j], &buf[i]);
+ }
+
+ return 0;
+}
+
+int RealMediaFF::initMetadataSection()
+{
+ UINT32 object_id;
+ off_t s;
+ int nbytes;
+ unsigned char buf[65536];
+ UINT32 consumed;
+
+ memcpy((void *)&object_id, "RMMD", 4);
+ if ( (s = seekChunk(object_id)) < 0 )
+ {
+ m_err = -1;
+ return m_err;
+ }
+
+ m_md = new MetadataSection;
+ consumed = 0;
+ nbytes = getChunk(buf, 65536, m_md->s.object_id, m_md->s.size, consumed);
+ if (nbytes < 0 || m_md->s.size != consumed || memcmp((void *)&m_md->s.object_id, "RMMD", 4))
+ {
+ //std::cerr << "SERIOUS ERROR - not able to find the chunk I just seek'd to!\n";
+ m_err = -1;
+ return m_err;
+ }
+ // Properties
+ int i = RMFF_HDR_SIZE;
+ memcpy((void *)&m_md->object_id, (void *)&buf[i], 4); i+=4;
+ UNPACK4(m_md->object_version, buf, i);
+ if ( !strncmp((const char *)&m_md->s.object_id, "RMMD", 4) )
+ {
+ if (!getMDProperties(&m_md->properties, &buf[i]))
+ saveHeader(m_md);
+ }
+ else
+ {
+ m_err = -1;
+ return m_err;
+ }
+
+ return 0;
+}
+
+#ifdef TESTING
+
+void RealMediaFF::printRealFileHeader(std::ostream &os)
+{
+ char object_id[5];
+
+ if (m_hdr)
+ {
+ strncpy(object_id, (const char *)&m_hdr->s.object_id, 4);
+ object_id[4]=0;
+
+ os << "HDR object_id: " << object_id << std::endl;
+ os << "HDR size: " << m_hdr->s.size << std::endl;
+ os << "HDR object version: " << m_hdr->object_version << std::endl;
+ os << "HDR file version: " << m_hdr->file_version << std::endl;
+ os << "HDR num headers: " << m_hdr->num_headers << std::endl;
+ }
+}
+
+
+void RealMediaFF::printRealPropHeader(std::ostream &os)
+{
+ char object_id[5];
+
+ if (m_props)
+ {
+ strncpy(object_id, (const char *)&m_props->s.object_id, 4);
+ object_id[4]=0;
+
+ os << "PROPS object_id: " << object_id << std::endl;
+ os << "PROPS size: " << m_props->s.size << std::endl;
+ os << "PROPS object_version: " << m_props->object_version << std::endl;
+
+ os << "PROPS max_bit_rate: " << m_props->max_bit_rate << std::endl;
+ os << "PROPS avg_bit_rate: " << m_props->avg_bit_rate << std::endl;
+ os << "PROPS max_packet_size: " << m_props->max_packet_size << std::endl;
+ os << "PROPS avg_packet_size: " << m_props->avg_packet_size << std::endl;
+ os << "PROPS num_packets: " << m_props->num_packets << std::endl;
+ os << "PROPS duration: " << m_props->duration << std::endl;
+ os << "PROPS preroll: " << m_props->preroll << std::endl;
+ os << "PROPS index_offset: " << m_props->index_offset << std::endl;
+ os << "PROPS data_offset: " << m_props->data_offset << std::endl;
+ os << "PROPS num_streams: " << m_props->num_streams << std::endl;
+ os << "PROPS flags: " << m_props->flags << std::endl;
+ }
+}
+
+
+void RealMediaFF::printMediaPropHeaders(std::ostream &os)
+{
+ int i = 0;
+ char object_id[5];
+ MediaProperties *media_hdr = (MediaProperties *)m_head;
+
+ while (media_hdr)
+ {
+ strncpy(object_id, (const char *)&media_hdr->s.object_id, 4);
+ object_id[4]=0;
+
+ if (!strncmp(object_id, "MDPR", 4))
+ {
+ os << "MEDIA HDR" << i << " object_id: " << object_id << std::endl;
+ os << "MEDIA HDR" << i << " size: " << media_hdr->s.size << std::endl;
+ os << "MEDIA HDR" << i << " max_bit_rate: " << media_hdr->max_bit_rate << std::endl;
+ os << "MEDIA HDR" << i << " avg_bit_rate: " << media_hdr->avg_bit_rate << std::endl;
+ os << "MEDIA HDR" << i << " max_packet_size: " << media_hdr->max_packet_size << std::endl;
+ os << "MEDIA HDR" << i << " avg_packet_size: " << media_hdr->avg_packet_size << std::endl;
+ os << "MEDIA HDR" << i << " start_time: " << media_hdr->start_time << std::endl;
+ os << "MEDIA HDR" << i << " preroll: " << media_hdr->preroll << std::endl;
+ os << "MEDIA HDR" << i << " duration: " << media_hdr->duration << std::endl;
+ os << "MEDIA HDR" << i << " stream_name: " << media_hdr->stream_name << std::endl;
+ os << "MEDIA HDR" << i << " mime type: " << media_hdr->mime_type << std::endl;
+
+
+ if (media_hdr->lstr)
+ {
+ os << "MEDIA HDR" << i << " LOGSTR info size: " << media_hdr->lstr->size << std::endl;
+ os << "MEDIA HDR" << i << " LOGSTR info num_physical_streams: " << media_hdr->lstr->num_physical_streams << std::endl;
+ os << "MEDIA HDR" << i << " LOGSTR info num_rules: " << media_hdr->lstr->num_rules << std::endl;
+ os << "MEDIA HDR" << i << " LOGSTR info num_properties: " << media_hdr->lstr->num_properties << std::endl;
+ for (int j=0; media_hdr->lstr->properties && j<media_hdr->lstr->num_properties; j++)
+ {
+ if (media_hdr->lstr->properties[j].name)
+ os << "MEDIA HDR" << i << " LOGSTR info prop name: " << media_hdr->lstr->properties[j].name << std::endl;
+ os << "MEDIA HDR" << i << " LOGSTR info prop type: " << media_hdr->lstr->properties[j].type << std::endl;
+ os << "MEDIA HDR" << i << " LOGSTR info prop value_length: " << media_hdr->lstr->properties[j].value_length << std::endl;
+ if (media_hdr->lstr->properties[j].value_data)
+ {
+ if (media_hdr->lstr->properties[j].type == 0)
+ os << "MEDIA HDR" << i << " LOGSTR info prop value: " <<
+ *(unsigned long *)media_hdr->lstr->properties[j].value_data << std::endl;
+ else if (media_hdr->lstr->properties[j].type == 2)
+ os << "MEDIA HDR" << i << " LOGSTR info prop value: " << media_hdr->lstr->properties[j].value_data << std::endl;
+ else
+ os << "MEDIA HDR" << i << " LOGSTR info prop value: <binary>\n";
+ }
+ }
+ }
+
+ i++;
+ }
+ media_hdr = (MediaProperties *)media_hdr->fwd;
+ }
+}
+
+
+void RealMediaFF::printContentDescription(std::ostream &os)
+{
+ char object_id[5];
+
+ if (m_contenthdr)
+ {
+ strncpy(object_id, (const char *)&m_contenthdr->s.object_id, 4);
+ object_id[4]=0;
+
+ os << "CONT object_id: " << object_id << std::endl;
+ os << "CONT title(" << m_contenthdr->title_len << "):\t\t<" << m_contenthdr->title << ">" << std::endl;
+ os << "CONT author(" << m_contenthdr->author_len << "):\t\t<" << m_contenthdr->author << ">" << std::endl;
+ os << "CONT copyright(" << m_contenthdr->copyright_len << "):\t\t<" << m_contenthdr->copyright << ">" << std::endl;
+ os << "CONT comment(" << m_contenthdr->comment_len << "):\t\t<" << m_contenthdr->comment << ">" << std::endl;
+ }
+}
+
+void RealMediaFF::printID3v1Tag(std::ostream &os)
+{
+ if (m_id3v1tag)
+ {
+ os << "ID3 tag : " << ID3v1::Tag::fileIdentifier() << std::endl;
+ os << "ID3 title : " << m_id3v1tag->tag()->title() << std::endl;
+ os << "ID3 artist : " << m_id3v1tag->tag()->artist() << std::endl;
+ os << "ID3 album : " << m_id3v1tag->tag()->album() << std::endl;
+ os << "ID3 year : " << m_id3v1tag->tag()->year() << std::endl;
+ os << "ID3 comment : " << m_id3v1tag->tag()->comment() << std::endl;
+ os << "ID3 track : " << m_id3v1tag->tag()->track() << std::endl;
+ os << "ID3 genre : " << m_id3v1tag->tag()->genre() << std::endl;
+ }
+}
+
+
+void RealMediaFF::printMDProperties(std::ostream &os, char *nam, MDProperties *props)
+{
+ char name[8192];
+
+ strcpy(name, nam);
+ os << "MDP subproperties for: " << name << std::endl;
+
+ os << "MD properties.size: " << props->size << std::endl;
+ os << "MD properties.type: " << props->type << std::endl;
+ os << "MD properties.flags: " << props->flags << std::endl;
+ os << "MD properties.value_offset: " << props->value_offset << std::endl;
+ os << "MD properties.subproperties_offset: " << props->subproperties_offset << std::endl;
+ os << "MD properties.num_subproperties: " << props->num_subproperties << std::endl;
+ os << "MD properties.name_length: " << props->name_length << std::endl;
+ os << "MD properties.name: " << (char *)props->name << std::endl;
+
+ os << "MD properties.value_length: " << props->value_length << std::endl;
+
+ switch (props->type)
+ {
+ case MPT_TEXT:
+ case MPT_TEXTLIST:
+ case MPT_URL:
+ case MPT_DATE:
+ case MPT_FILENAME:
+ os << "MD properties.value: " << (char *)props->value << std::endl;
+ break;
+ case MPT_FLAG:
+ if (props->value_length == 4)
+ os << "MD properties.value: " << *(unsigned long *)props->value << std::endl;
+ else
+ os << "MD properties.value: " << *props->value << std::endl;
+ break;
+ case MPT_ULONG:
+ os << "MD properties.value: " << *(unsigned long *)props->value << std::endl;
+ break;
+ case MPT_BINARY:
+ os << "MD properties.value: <binary>" << std::endl;
+ break;
+ case MPT_GROUPING:
+ os << "MD properties.value: <grouping>" << std::endl;
+ break;
+ case MPT_REFERENCE:
+ os << "MD properties.value: <reference>" << std::endl;
+ break;
+ }
+
+ if (props->num_subproperties)
+ {
+ strcat(name, (char *)props->name);
+ strcat(name, "/");
+ }
+ for (int j=0; j<props->num_subproperties; j++)
+ {
+ os << "MD properties.sub_properties_list[" << j << "].offset: " <<
+ props->subproperties_list[j].offset << std::endl;
+ os << "MD properties.sub_properties_list[" << j << "].num_props_for_name: " <<
+ props->subproperties_list[j].num_props_for_name << std::endl;
+
+ os << std::endl;
+
+ printMDProperties(os, name, &props->subproperties[j]);
+ }
+}
+
+
+void RealMediaFF::printMetadataSection(std::ostream &os)
+{
+ char name[8192];
+ char oid[5];
+
+ memcpy((void *)oid, (void *)&m_md->s.object_id, 4);
+ oid[4] = 0;
+
+ os << "MetadataSection: ";
+ os << "MS object_id: " << oid << std::endl;
+ os << "MS SIZE: " << m_md->s.size << std::endl;
+ os << "MD object_id: " << (char *)&m_md->object_id << std::endl;
+ os << "MD object_version: " << m_md->object_version << std::endl;
+ os << std::endl;
+
+ strcpy(name, "");
+ printMDProperties(os, name, &m_md->properties);
+}
+
+
+std::ostream &RealMediaFF::operator<<(std::ostream &os)
+{
+ if (m_readProperties)
+ {
+ printRealFileHeader(os);
+ printRealPropHeader(os);
+ printMediaPropHeaders(os);
+ printContentDescription(os);
+ printMetadataSection(os);
+ }
+ printID3v1Tag(os);
+
+ return os;
+}
+
+std::ostream &operator<<(std::ostream &os, RealMediaFF &rmff)
+{
+ rmff.operator<<(os);
+
+ return os;
+}
+
+
+int main(int argc, char *argv[])
+{
+ char *m_filen;
+
+ if (argc > 1)
+ m_filen = argv[1];
+ else
+ m_filen = "./Drown.ra";
+
+ RealMediaFF rmff(m_filen);
+
+ if (!rmff.err())
+ std::cout << rmff;
+
+ /*
+ UINT32 oid = 0;
+ memcpy( (void *)&oid, (void *) ".RMF", 4);
+ off_t pos = rmff.seekChunk(oid);
+ std::cout << "POS=" << pos << std::endl;
+
+ memcpy( (void *)&oid, (void *) "MDPR", 4);
+ pos = rmff.seekChunk(oid);
+ std::cout << "POS=" << pos << std::endl;
+
+ memcpy( (void *)&oid, (void *) "RMMD", 4);
+ pos = rmff.seekChunk(oid);
+ std::cout << "POS=" << pos << std::endl;
+ */
+}
+#endif
diff --git a/src/metadata/rmff/rmff.h b/src/metadata/rmff/rmff.h
new file mode 100644
index 0000000..326b8ae
--- /dev/null
+++ b/src/metadata/rmff/rmff.h
@@ -0,0 +1,348 @@
+/***************************************************************************
+ copyright : (C) 2005 by Paul Cifarelli
+ ***************************************************************************/
+
+/***************************************************************************
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * 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., 51 Franklin St, 5th fl, Boston, MA 02110-1301, *
+ * USA, or check http://www.fsf.org/about/contact.html *
+ * *
+ * Note that no RealNetworks code appears or is duplicated, copied, or *
+ + used as a template in this code. The code was written from scratch *
+ * using the reference documentation found at: *
+ * *
+ * https://common.helixcommunity.org/nonav/2003/HCS_SDK_r5/helixsdk.htm *
+ * *
+ ***************************************************************************/
+#ifndef _RMFF_H_INCLUDED_
+#define _RMFF_H_INCLUDED_
+
+#include <config.h>
+
+namespace TagLib
+{
+ namespace RealMedia
+ {
+#if SIZEOF_LONG == 4
+ typedef unsigned long UINT32;
+#elif SIZEOF_INT == 4
+ typedef unsigned int UINT32;
+#else
+#error At least 1 builtin type needs to be 4 bytes!!
+#endif
+ typedef unsigned short UINT16;
+ typedef unsigned char UINT8;
+
+ static const int RMFF_HDR_SIZE = 8; // packed hdr size
+
+ // some assumptions on these 2 enum defs, based solely on the order they are listed on the website
+ enum PROPERTY_TYPES
+ {
+ MPT_TEXT = 1, // The value is string data.
+ MPT_TEXTLIST, // The value is a separated list of strings,
+ // separator specified as sub-property/type descriptor.
+ MPT_FLAG, // The value is a boolean flag-either 1 byte or 4 bytes, check size value.
+ MPT_ULONG, // The value is a four-byte integer.
+ MPT_BINARY, // The value is a byte stream.
+ MPT_URL, // The value is string data.
+ MPT_DATE, // The value is a string representation of the date in the form:
+ // YYYYmmDDHHMMSS (m = month, M = minutes).
+ MPT_FILENAME, // The value is string data.
+ MPT_GROUPING, // This property has subproperties, but its own value is empty.
+ MPT_REFERENCE // The value is a large buffer of data, use sub-properties/type
+ // descriptors to identify mime-type.
+ };
+
+ enum PROPERTY_FLAGS
+ {
+ MPT_READONLY = 1, // Read only, cannot be modified.
+ MPT_PRIVATE = 2, // Private, do not expose to users.
+ MPT_TYPE_DESCRIPTOR = 4 // Type descriptor used to further define type of value.
+ };
+
+ struct Collectable
+ {
+ Collectable() : fwd(0) {}
+ virtual ~Collectable() {}
+ Collectable *fwd;
+ };
+
+ struct File_Header_Start
+ {
+ UINT32 object_id;
+ UINT32 size;
+ };
+
+ struct File_Header_v0_v1 : public Collectable
+ {
+ File_Header_Start s;
+ UINT16 object_version;
+
+ UINT32 file_version;
+ UINT32 num_headers;
+ };
+
+ struct RMProperties : public Collectable
+ {
+ File_Header_Start s;
+ UINT16 object_version;
+
+ UINT32 max_bit_rate;
+ UINT32 avg_bit_rate;
+ UINT32 max_packet_size;
+ UINT32 avg_packet_size;
+ UINT32 num_packets;
+ UINT32 duration;
+ UINT32 preroll;
+ UINT32 index_offset;
+ UINT32 data_offset;
+ UINT16 num_streams;
+ UINT16 flags;
+ };
+
+
+ struct NameValueProperty
+ {
+ NameValueProperty() : name(0), value_data(0) {}
+ virtual ~NameValueProperty() { delete [] name; delete [] value_data; }
+
+ UINT32 size;
+ UINT16 object_version;
+
+ UINT8 name_length;
+ UINT8 *name;
+ UINT32 type;
+ UINT16 value_length;
+ UINT8 *value_data;
+ };
+
+
+ struct LogicalStream
+ {
+ LogicalStream() : physical_stream_numbers(0), data_offsets(0), rule_to_physical_stream_number_map(0), properties(0) {}
+ virtual ~LogicalStream()
+ { delete [] physical_stream_numbers; delete [] data_offsets;
+ delete [] rule_to_physical_stream_number_map; delete [] properties; }
+
+ UINT32 size;
+ UINT16 object_version;
+
+ UINT16 num_physical_streams;
+ UINT16 *physical_stream_numbers;
+ UINT32 *data_offsets;
+ UINT16 num_rules;
+ UINT16 *rule_to_physical_stream_number_map;
+ UINT16 num_properties;
+ NameValueProperty *properties;
+ };
+
+ struct MediaProperties : public Collectable
+ {
+ MediaProperties() : type_specific_data(0), lstr(0) {}
+ virtual ~MediaProperties() { delete lstr; delete [] type_specific_data; }
+
+ File_Header_Start s;
+ UINT16 object_version;
+
+ UINT16 stream_number;
+ UINT32 max_bit_rate;
+ UINT32 avg_bit_rate;
+ UINT32 max_packet_size;
+ UINT32 avg_packet_size;
+ UINT32 start_time;
+ UINT32 preroll;
+ UINT32 duration;
+ UINT8 stream_name_size;
+ UINT8 stream_name[256];
+ UINT8 mime_type_size;
+ UINT8 mime_type[256];
+ UINT32 type_specific_len;
+ UINT8 *type_specific_data;
+
+ LogicalStream *lstr; // only one of these
+ };
+
+
+ struct ContentDescription : public Collectable
+ {
+ ContentDescription() : title(0), author(0), copyright(0), comment(0) {}
+ virtual ~ContentDescription() { delete [] title; delete [] author; delete [] copyright; delete [] comment; }
+
+ File_Header_Start s;
+ UINT16 object_version;
+
+ UINT16 title_len;
+ UINT8 *title;
+ UINT16 author_len;
+ UINT8 *author;
+ UINT16 copyright_len;
+ UINT8 *copyright;
+ UINT16 comment_len;
+ UINT8 *comment;
+ };
+
+
+ struct PropListEntry
+ {
+ UINT32 offset;
+ UINT32 num_props_for_name;
+ };
+
+ struct MDProperties
+ {
+ MDProperties() : name(0), value(0), subproperties(0) {}
+ virtual ~MDProperties()
+ { delete [] name; delete [] value; delete [] subproperties_list; delete [] subproperties; }
+
+ UINT32 size;
+ UINT32 type;
+ UINT32 flags;
+ UINT32 value_offset;
+ UINT32 subproperties_offset;
+ UINT32 num_subproperties;
+ UINT32 name_length;
+ UINT8 *name;
+ UINT32 value_length;
+ UINT8 *value;
+ PropListEntry *subproperties_list; // num_subproperties
+ MDProperties *subproperties; // num_subproperties
+ };
+
+ struct MetadataSection : public Collectable
+ {
+ File_Header_Start s;
+
+ UINT32 object_id;
+ UINT32 object_version;
+
+ // this is the 1 "unnamed root property"
+ MDProperties properties;
+ };
+
+ class Tag;
+ class File;
+
+ // RealMedia File Format contains a normal ID3v1 Tag at the end of the file
+ // no sense reinventing the wheel, so this class is just so we can use TagLib
+ // to manage it
+ class RMFFile : public TagLib::File
+ {
+ public:
+ RMFFile(const char *filename);
+ virtual ~RMFFile();
+ bool save();
+ TagLib::Tag *tag() const { return m_id3tag; }
+ TagLib::AudioProperties *audioProperties() const { return 0; }
+
+ private:
+ TagLib::ID3v1::Tag *m_id3tag;
+ };
+
+ class TagLib::AudioProperties;
+
+ class RealMediaFF
+ {
+ public:
+ RealMediaFF(const char *file, bool readProperties = true,
+ TagLib::AudioProperties::ReadStyle propertiesStyle = TagLib::AudioProperties::Average);
+ RealMediaFF(RealMediaFF &src);
+ ~RealMediaFF();
+
+ int err() const { return m_err; }
+ bool isEmpty() const;
+
+ // tag
+ TagLib::String title () const;
+ TagLib::String artist () const;
+ TagLib::String album () const;
+ TagLib::String comment () const;
+ TagLib::String genre () const;
+ TagLib::uint year () const;
+ TagLib::uint track () const;
+ // TODO write support
+ //void setTitle (const String &s);
+ //void setArtist (const String &s);
+ //void setAlbum (const String &s);
+ //void setComment (const String &s);
+ //void setGenre (const String &s);
+ //void setYear (uint i);
+ //void setTrack (uint i);
+
+ // properties
+ int length () const;
+ int bitrate () const;
+ int sampleRate () const;
+ int channels () const;
+
+#ifdef TESTING
+ std::ostream &operator<<(std::ostream &os);
+#endif
+
+ private:
+ RealMediaFF();
+ char *m_filename;
+ Collectable *m_head;
+ Collectable *m_tail;
+ int m_fd;
+ int m_err;
+
+ File_Header_v0_v1 *m_hdr;
+ RMProperties *m_props;
+ MediaProperties *media_hdrs;
+ ContentDescription *m_contenthdr;
+ MetadataSection *m_md;
+
+ char *m_title;
+ char *m_author;
+ char *m_copyright;
+ char *m_comment;
+
+ RMFFile *m_id3v1tag;
+
+ bool m_flipYearInMetadataSection;
+ bool m_readProperties;
+
+ int init();
+ int initMetadataSection();
+ void saveHeader(Collectable *hdr);
+ int seekChunk(UINT32 object_id);
+
+ int getHdr(unsigned char *buf, size_t sz, UINT32 &fourcc, UINT32 &csz);
+ int getChunk(unsigned char *buf, size_t sz, UINT32 &fourcc, UINT32 &csz, UINT32 &consumed);
+ int getRealFileHeader(File_Header_v0_v1 *hdr, const unsigned char *buf, UINT32 object_id, int sz);
+ int getRealPropertyHeader(RMProperties *props, const unsigned char *buf, UINT32 object_id, int sz);
+ int getMediaPropHeader(MediaProperties *mh, const unsigned char *buf, UINT32 object_id, int sz);
+ int getContentDescription(ContentDescription *cont, const unsigned char *buf, UINT32 object_id, int sz);
+ int getMDProperties(MDProperties *md, const unsigned char *buf);
+
+#ifdef TESTING
+ void printRealFileHeader(std::ostream &os);
+ void printRealPropHeader(std::ostream &os);
+ void printMediaPropHeaders(std::ostream &os);
+ void printContentDescription(std::ostream &os);
+ void printID3v1Tag(std::ostream &os);
+ void printMetadataSection(std::ostream &os);
+ void printMDProperties(std::ostream &os, char *name, MDProperties *props);
+#endif
+ };
+
+ } // namespace RealMedia
+} // namespace TagLib
+
+#ifdef TESTING
+std::ostream &operator<<(std::ostream &os, TagLib::RealMedia::RealMediaFF &rmff);
+#endif
+
+#endif
diff --git a/src/metadata/rmff/taglib_realmediafile.cpp b/src/metadata/rmff/taglib_realmediafile.cpp
new file mode 100644
index 0000000..b28c846
--- /dev/null
+++ b/src/metadata/rmff/taglib_realmediafile.cpp
@@ -0,0 +1,213 @@
+/***************************************************************************
+ copyright : (C) 2005 by Paul Cifarelli
+
+ copyright : (C) 2005 by Lukas Lalinsky
+ (portions)
+ ***************************************************************************/
+
+/***************************************************************************
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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 or higher 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., 51 Franklin St, 5th fl, Boston, MA 02110-1301, *
+ * USA, or check http://www.fsf.org/about/contact.html *
+ ***************************************************************************/
+
+#include <tfile.h>
+#include <audioproperties.h>
+#include <tstring.h>
+#include <id3v1tag.h>
+#include "rmff.h"
+#include "taglib_realmediafile.h"
+
+using namespace TagLib;
+using namespace TagLib::RealMedia;
+
+
+RealMedia::Tag::Tag(RealMediaFF *rmff, bool allocnew) : m_rmff(rmff), m_owner(allocnew)
+{
+ if (m_owner)
+ m_rmff = new RealMediaFF(*rmff);
+}
+
+RealMedia::Tag::~Tag ()
+{
+ if (m_owner)
+ delete m_rmff;
+}
+
+String RealMedia::Tag::title () const
+{
+ return m_rmff->title();
+}
+
+String RealMedia::Tag::artist () const
+{
+ return m_rmff->artist();
+}
+
+String RealMedia::Tag::album () const
+{
+ return m_rmff->album();
+}
+
+String RealMedia::Tag::comment () const
+{
+ return m_rmff->comment();
+}
+
+String RealMedia::Tag::genre () const
+{
+ return m_rmff->genre();
+}
+
+TagLib::uint RealMedia::Tag::year () const
+{
+ return m_rmff->year();
+}
+
+TagLib::uint RealMedia::Tag::track () const
+{
+ return m_rmff->track();
+}
+
+void RealMedia::Tag::setTitle (const String &)
+{
+// TODO: write support
+}
+
+void RealMedia::Tag::setArtist (const String &)
+{
+// TODO: write support
+}
+
+void RealMedia::Tag::setAlbum (const String &)
+{
+// TODO: write support
+}
+
+void RealMedia::Tag::setComment (const String &)
+{
+// TODO: write support
+}
+
+void RealMedia::Tag::setGenre (const String &)
+{
+// TODO: write support
+}
+
+void RealMedia::Tag::setYear (uint)
+{
+// TODO: write support
+}
+
+void RealMedia::Tag::setTrack (uint)
+{
+// TODO: write support
+}
+
+bool RealMedia::Tag::isEmpty() const
+{
+ return TagLib::Tag::isEmpty() && m_rmff->isEmpty();
+}
+
+void RealMedia::Tag::duplicate(const Tag *source, Tag *target, bool overwrite)
+{
+ TagLib::Tag::duplicate(source, target, overwrite);
+ if (overwrite)
+ {
+ if (target->m_owner)
+ {
+ delete target->m_rmff;
+ target->m_rmff = new RealMediaFF(*source->m_rmff);
+ }
+ else
+ target->m_rmff = source->m_rmff;
+ }
+ else
+ {
+ if (target->isEmpty())
+ if (target->m_owner)
+ {
+ delete target->m_rmff;
+ target->m_rmff = new RealMediaFF(*source->m_rmff);
+ }
+ else
+ target->m_rmff = source->m_rmff;
+ }
+}
+
+
+
+int RealMedia::Properties::length () const
+{
+ return (m_rmff->length() / 1000);
+}
+
+int RealMedia::Properties::bitrate () const
+{
+ return (m_rmff->bitrate() / 1000);
+}
+
+int RealMedia::Properties::sampleRate () const
+{
+ return m_rmff->sampleRate();
+}
+
+int RealMedia::Properties::channels () const
+{
+ return m_rmff->channels();
+}
+
+
+RealMedia::File::File(const char *file, bool readProperties, Properties::ReadStyle propertiesStyle)
+ : TagLib::File(file), m_rmfile(0), m_tag(0), m_props(0)
+{
+ m_rmfile = new RealMediaFF(file, readProperties, propertiesStyle);
+ m_tag = new RealMedia::Tag(m_rmfile);
+ m_props = new RealMedia::Properties(m_rmfile);
+}
+
+RealMedia::File::~File()
+{
+ delete m_props;
+ delete m_tag;
+ delete m_rmfile;
+}
+
+TagLib::Tag *RealMedia::File::tag() const
+{
+ return m_tag;
+}
+
+RealMedia::Tag *RealMedia::File::RealMediaTag() const
+{
+ return m_tag;
+}
+
+RealMedia::Properties *RealMedia::File::audioProperties() const
+{
+ return m_props; // m_rmfile->properties;
+}
+
+
+
+
+
diff --git a/src/metadata/rmff/taglib_realmediafile.h b/src/metadata/rmff/taglib_realmediafile.h
new file mode 100644
index 0000000..0f0ca58
--- /dev/null
+++ b/src/metadata/rmff/taglib_realmediafile.h
@@ -0,0 +1,133 @@
+/***************************************************************************
+ copyright : (C) 2005 by Paul Cifarelli
+
+ copyright : (C) 2005 by Lukas Lalinsky
+ (portions)
+ ***************************************************************************/
+
+/***************************************************************************
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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 or higher 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., 51 Franklin St, 5th fl, Boston, MA 02110-1301, *
+ * USA, or check http://www.fsf.org/about/contact.html *
+ ***************************************************************************/
+#ifndef _TAGLIB_REALMEDIAFILE_H_
+#define _TAGLIB_REALMEDIAFILE_H_
+
+#include <tfile.h>
+#include <audioproperties.h>
+#include <tag.h>
+
+#include <iostream>
+
+class RealMediaFF;
+namespace TagLib {
+
+ namespace RealMedia {
+
+ class Tag : public TagLib::Tag
+ {
+ public:
+ Tag(RealMediaFF *rmff, bool allocnew = false);
+ virtual ~Tag ();
+ virtual String title () const;
+ virtual String artist () const;
+ virtual String album () const;
+ virtual String comment () const;
+ virtual String genre () const;
+ virtual uint year () const;
+ virtual uint track () const;
+ virtual void setTitle (const String &s);
+ virtual void setArtist (const String &s);
+ virtual void setAlbum (const String &s);
+ virtual void setComment (const String &s);
+ virtual void setGenre (const String &s);
+ virtual void setYear (uint i);
+ virtual void setTrack (uint i);
+
+ bool isEmpty() const;
+ void duplicate(const Tag *source, Tag *target, bool overwrite);
+
+ private:
+ Tag();
+ RealMediaFF *m_rmff;
+ bool m_owner;
+ };
+
+
+ class Properties : public TagLib::AudioProperties
+ {
+ public:
+ Properties(RealMediaFF *rmff) : TagLib::AudioProperties(Average), m_rmff(rmff) {}
+ virtual ~Properties() {} // you don't own rmff
+ virtual int length () const;
+ virtual int bitrate () const;
+ virtual int sampleRate () const;
+ virtual int channels () const;
+
+ private:
+ Properties();
+ RealMediaFF *m_rmff;
+ };
+
+ class File : public TagLib::File
+ {
+ public:
+
+ File(const char *file, bool readProperties = true, Properties::ReadStyle propertiesStyle = Properties::Average);
+
+ virtual ~File();
+
+ /*
+ * Returns the TagLib::Tag for this file.
+ */
+ virtual TagLib::Tag *tag() const;
+
+ /*
+ * Returns the RealMedia::RealMediaTag for this file.
+ */
+ virtual Tag *RealMediaTag() const;
+
+ /*
+ * Returns the RealMedia::Properties for this file.
+ */
+ virtual Properties *audioProperties() const;
+
+
+ /*
+ * Save the file.
+ *
+ * This returns true if the save was successful.
+ */
+ virtual bool save() { return false; } // for now
+
+ private:
+
+ RealMediaFF *m_rmfile;
+ Tag *m_tag;
+ Properties *m_props;
+ };
+
+ }
+
+}
+
+#endif
diff --git a/src/metadata/rmff/taglib_realmediafiletyperesolver.cpp b/src/metadata/rmff/taglib_realmediafiletyperesolver.cpp
new file mode 100644
index 0000000..a8660a6
--- /dev/null
+++ b/src/metadata/rmff/taglib_realmediafiletyperesolver.cpp
@@ -0,0 +1,53 @@
+/***************************************************************************
+ copyright : (C) 2005 by Paul Cifarelli
+ ***************************************************************************/
+
+/***************************************************************************
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin St, 5th fl, Boston, MA 02110-1301, *
+ * USA, or check http://www.fsf.org/about/contact.html *
+ * *
+ ***************************************************************************/
+
+#include <tfile.h>
+#include <audioproperties.h>
+#include <id3v1tag.h>
+#include "taglib_realmediafiletyperesolver.h"
+#include "taglib_realmediafile.h"
+#include "rmff.h"
+
+#include <string.h>
+
+TagLib::File *RealMediaFileTypeResolver::createFile(const char *fileName,
+ bool readProperties,
+ TagLib::AudioProperties::ReadStyle propertiesStyle) const
+{
+ const char *ext = strrchr(fileName, '.');
+ if(ext && (!strcasecmp(ext, ".ra") || !strcasecmp(ext, ".rv") || !strcasecmp(ext, ".rm") ||
+ !strcasecmp(ext, ".rmj") || !strcasecmp(ext, ".rmvb") ))
+ {
+ TagLib::RealMedia::File *f = new TagLib::RealMedia::File(fileName, readProperties, propertiesStyle);
+ if(f->isValid())
+ return f;
+ else
+ {
+ delete f;
+ }
+ }
+
+ return 0;
+}
diff --git a/src/metadata/rmff/taglib_realmediafiletyperesolver.h b/src/metadata/rmff/taglib_realmediafiletyperesolver.h
new file mode 100644
index 0000000..b292e10
--- /dev/null
+++ b/src/metadata/rmff/taglib_realmediafiletyperesolver.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ copyright : (C) 2005 by Paul Cifarelli
+ ***************************************************************************/
+
+/***************************************************************************
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin St, 5th fl, Boston, MA 02110-1301, *
+ * USA, or check http://www.fsf.org/about/contact.html *
+ * *
+ ***************************************************************************/
+#ifndef _TAGLIB_REALMEDIAFILETYPERESOLVER_H_
+#define _TAGLIB_REALMEDIAFILETYPERESOLVER_H_
+
+#include <taglib/tfile.h>
+#include <taglib/fileref.h>
+
+
+class RealMediaFileTypeResolver : public TagLib::FileRef::FileTypeResolver
+{
+ TagLib::File *createFile(const char *fileName,
+ bool readAudioProperties,
+ TagLib::AudioProperties::ReadStyle audioPropertiesStyle) const;
+};
+
+#endif
diff --git a/src/metadata/speex/Makefile.am b/src/metadata/speex/Makefile.am
new file mode 100644
index 0000000..6bf01aa
--- /dev/null
+++ b/src/metadata/speex/Makefile.am
@@ -0,0 +1,16 @@
+SUBDIRS =
+
+INCLUDES = $(all_includes) $(taglib_includes)
+METASOURCES = AUTO
+libtagspeex_la_LDFLAGS = $(all_libraries)
+noinst_LTLIBRARIES = libtagspeex.la
+
+libtagspeex_la_SOURCES = \
+ speexfile.cpp \
+ speexproperties.cpp \
+ taglib_speexfiletyperesolver.cpp
+
+noinst_HEADERS = speexfile.h \
+ speexproperties.h \
+ taglib_speexfiletyperesolver.h
+
diff --git a/src/metadata/speex/speexfile.cpp b/src/metadata/speex/speexfile.cpp
new file mode 100644
index 0000000..eccaded
--- /dev/null
+++ b/src/metadata/speex/speexfile.cpp
@@ -0,0 +1,111 @@
+/***************************************************************************
+ copyright : (C) 2006 by Lukáš Lalinský
+
+ copyright : (C) 2002 by Scott Wheeler
+ (original Vorbis implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <bitset>
+
+#include <tstring.h>
+#if 0
+#include <tdebug.h>
+#endif
+
+#include "speexfile.h"
+
+using namespace TagLib;
+
+class Speex::File::FilePrivate
+{
+public:
+ FilePrivate() :
+ comment(0),
+ properties(0) {}
+
+ ~FilePrivate()
+ {
+ delete comment;
+ delete properties;
+ }
+
+ Ogg::XiphComment *comment;
+ Properties *properties;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+Speex::File::File(const char *file, bool readProperties,
+ Properties::ReadStyle propertiesStyle) : Ogg::File(file)
+{
+ d = new FilePrivate;
+ read(readProperties, propertiesStyle);
+}
+
+Speex::File::~File()
+{
+ delete d;
+}
+
+Ogg::XiphComment *Speex::File::tag() const
+{
+ return d->comment;
+}
+
+Speex::Properties *Speex::File::audioProperties() const
+{
+ return d->properties;
+}
+
+bool Speex::File::save()
+{
+ if(!d->comment)
+ d->comment = new Ogg::XiphComment;
+
+ setPacket(1, d->comment->render());
+
+ return Ogg::File::save();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// private members
+////////////////////////////////////////////////////////////////////////////////
+
+void Speex::File::read(bool readProperties, Properties::ReadStyle propertiesStyle)
+{
+ ByteVector speexHeaderData = packet(0);
+
+ if(!speexHeaderData.startsWith("Speex ")) {
+#if 0
+ debug("Speex::File::read() -- invalid Speex identification header");
+#endif
+ return;
+ }
+
+ ByteVector commentHeaderData = packet(1);
+
+ d->comment = new Ogg::XiphComment(commentHeaderData);
+
+ if(readProperties)
+ d->properties = new Properties(this, propertiesStyle);
+}
diff --git a/src/metadata/speex/speexfile.h b/src/metadata/speex/speexfile.h
new file mode 100644
index 0000000..d300ac3
--- /dev/null
+++ b/src/metadata/speex/speexfile.h
@@ -0,0 +1,93 @@
+/***************************************************************************
+ copyright : (C) 2006 by Lukáš Lalinský
+
+ copyright : (C) 2002 by Scott Wheeler
+ (original Vorbis implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef TAGLIB_SPEEXFILE_H
+#define TAGLIB_SPEEXFILE_H
+
+#include <oggfile.h>
+#include <xiphcomment.h>
+
+#include "speexproperties.h"
+
+namespace TagLib {
+
+ //! A namespace containing classes for Speex metadata
+
+ namespace Speex {
+
+ //! An implementation of Ogg::File with Speex specific methods
+
+ /*!
+ * This is the central class in the Ogg Speex metadata processing collection
+ * of classes. It's built upon Ogg::File which handles processing of the Ogg
+ * logical bitstream and breaking it down into pages which are handled by
+ * the codec implementations, in this case Speex specifically.
+ */
+
+ class File : public Ogg::File
+ {
+ public:
+ /*!
+ * Contructs a Speex 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.
+ */
+ File(const char *file, bool readProperties = true,
+ Properties::ReadStyle propertiesStyle = Properties::Average);
+
+ /*!
+ * Destroys this instance of the File.
+ */
+ virtual ~File();
+
+ /*!
+ * Returns the XiphComment for this file. XiphComment implements the tag
+ * interface, so this serves as the reimplementation of
+ * TagLib::File::tag().
+ */
+ virtual Ogg::XiphComment *tag() const;
+
+ /*!
+ * Returns the Speex::Properties for this file. If no audio properties
+ * were read then this will return a null pointer.
+ */
+ virtual Properties *audioProperties() const;
+
+ virtual bool save();
+
+ private:
+ File(const File &);
+ File &operator=(const File &);
+
+ void read(bool readProperties, Properties::ReadStyle propertiesStyle);
+
+ class FilePrivate;
+ FilePrivate *d;
+ };
+ }
+
+}
+
+#endif
diff --git a/src/metadata/speex/speexproperties.cpp b/src/metadata/speex/speexproperties.cpp
new file mode 100644
index 0000000..edd2b71
--- /dev/null
+++ b/src/metadata/speex/speexproperties.cpp
@@ -0,0 +1,171 @@
+/***************************************************************************
+ copyright : (C) 2006 by Lukáš Lalinský
+
+ copyright : (C) 2002 by Scott Wheeler
+ (original Vorbis implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <tstring.h>
+#if 0
+#include <tdebug.h>
+#endif
+
+#include <oggpageheader.h>
+
+#include "speexproperties.h"
+#include "speexfile.h"
+
+using namespace TagLib;
+
+class Speex::Properties::PropertiesPrivate
+{
+public:
+ PropertiesPrivate(File *f, ReadStyle s) :
+ file(f),
+ style(s),
+ length(0),
+ bitrate(0),
+ sampleRate(0),
+ channels(0),
+ speexVersion(0),
+ vbr(false),
+ mode(0) {}
+
+ File *file;
+ ReadStyle style;
+ int length;
+ int bitrate;
+ int sampleRate;
+ int channels;
+ int speexVersion;
+ bool vbr;
+ int mode;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+Speex::Properties::Properties(File *file, ReadStyle style) : AudioProperties(style)
+{
+ d = new PropertiesPrivate(file, style);
+ read();
+}
+
+Speex::Properties::~Properties()
+{
+ delete d;
+}
+
+int Speex::Properties::length() const
+{
+ return d->length;
+}
+
+int Speex::Properties::bitrate() const
+{
+ return int(float(d->bitrate) / float(1000) + 0.5);
+}
+
+int Speex::Properties::sampleRate() const
+{
+ return d->sampleRate;
+}
+
+int Speex::Properties::channels() const
+{
+ return d->channels;
+}
+
+int Speex::Properties::speexVersion() const
+{
+ return d->speexVersion;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// private members
+////////////////////////////////////////////////////////////////////////////////
+
+void Speex::Properties::read()
+{
+ // Get the identification header from the Ogg implementation.
+
+ ByteVector data = d->file->packet(0);
+
+ int pos = 28;
+
+ // speex_version_id; /**< Version for Speex (for checking compatibility) */
+ d->speexVersion = data.mid(pos, 4).toUInt(false);
+ pos += 4;
+
+ // header_size; /**< Total size of the header ( sizeof(SpeexHeader) ) */
+ pos += 4;
+
+ // rate; /**< Sampling rate used */
+ d->sampleRate = data.mid(pos, 4).toUInt(false);
+ pos += 4;
+
+ // mode; /**< Mode used (0 for narrowband, 1 for wideband) */
+ d->mode = data.mid(pos, 4).toUInt(false);
+ pos += 4;
+
+ // mode_bitstream_version; /**< Version ID of the bit-stream */
+ pos += 4;
+
+ // nb_channels; /**< Number of channels encoded */
+ d->channels = data.mid(pos, 4).toUInt(false);
+ pos += 4;
+
+ // bitrate; /**< Bit-rate used */
+ d->bitrate = data.mid(pos, 4).toUInt(false);
+ pos += 4;
+
+ // frame_size; /**< Size of frames */
+ //unsigned int frameSize = data.mid(pos, 4).toUInt(false);
+ pos += 4;
+
+ // vbr; /**< 1 for a VBR encoding, 0 otherwise */
+ d->vbr = data.mid(pos, 4).toUInt(false) == 1;
+ pos += 4;
+
+ // frames_per_packet; /**< Number of frames stored per Ogg packet */
+ //unsigned int framesPerPacket = data.mid(pos, 4).toUInt(false);
+
+ const Ogg::PageHeader *first = d->file->firstPageHeader();
+ const Ogg::PageHeader *last = d->file->lastPageHeader();
+
+ if(first && last) {
+ long long start = first->absoluteGranularPosition();
+ long long end = last->absoluteGranularPosition();
+
+ if(start >= 0 && end >= 0 && d->sampleRate > 0)
+ d->length = (end - start) / (long long) d->sampleRate;
+#if 0
+ else
+ debug("Speex::Properties::read() -- Either the PCM values for the start or "
+ "end of this file was incorrect or the sample rate is zero.");
+#endif
+ }
+#if 0
+ else
+ debug("Speex::Properties::read() -- Could not find valid first and last Ogg pages.");
+#endif
+}
diff --git a/src/metadata/speex/speexproperties.h b/src/metadata/speex/speexproperties.h
new file mode 100644
index 0000000..355ff3c
--- /dev/null
+++ b/src/metadata/speex/speexproperties.h
@@ -0,0 +1,83 @@
+/***************************************************************************
+ copyright : (C) 2006 by Lukáš Lalinský
+
+ copyright : (C) 2002 by Scott Wheeler
+ (original Vorbis implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef TAGLIB_SPEEXPROPERTIES_H
+#define TAGLIB_SPEEXPROPERTIES_H
+
+#include <audioproperties.h>
+
+namespace TagLib {
+
+ namespace Speex {
+
+ class File;
+
+ //! An implementation of audio property reading for Ogg Speex
+
+ /*!
+ * This reads the data from an Ogg Speex stream found in the AudioProperties
+ * API.
+ */
+
+ class Properties : public AudioProperties
+ {
+ public:
+ /*!
+ * Create an instance of Vorbis::Properties with the data read from the
+ * Vorbis::File \a file.
+ */
+ Properties(File *file, ReadStyle style = Average);
+
+ /*!
+ * Destroys this VorbisProperties instance.
+ */
+ virtual ~Properties();
+
+ // Reimplementations.
+
+ virtual int length() const;
+ virtual int bitrate() const;
+ virtual int sampleRate() const;
+ virtual int channels() const;
+
+ /*!
+ * Returns the Vorbis version, currently "0" (as specified by the spec).
+ */
+ int speexVersion() const;
+
+ private:
+ Properties(const Properties &);
+ Properties &operator=(const Properties &);
+
+ void read();
+
+ class PropertiesPrivate;
+ PropertiesPrivate *d;
+ };
+ }
+
+}
+
+#endif
diff --git a/src/metadata/speex/taglib_speexfiletyperesolver.cpp b/src/metadata/speex/taglib_speexfiletyperesolver.cpp
new file mode 100644
index 0000000..9a5de0d
--- /dev/null
+++ b/src/metadata/speex/taglib_speexfiletyperesolver.cpp
@@ -0,0 +1,44 @@
+/***************************************************************************
+ copyright : (C) 2006 by Martin Aumueller
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "taglib_speexfiletyperesolver.h"
+#include "speexfile.h"
+
+#include <string.h>
+
+TagLib::File *SpeexFileTypeResolver::createFile(const char *fileName,
+ bool readProperties,
+ TagLib::AudioProperties::ReadStyle propertiesStyle) const
+{
+ const char *ext = strrchr(fileName, '.');
+ if(ext && !strcasecmp(ext, ".spx"))
+ {
+ TagLib::Speex::File *f = new TagLib::Speex::File(fileName, readProperties, propertiesStyle);
+ if(f->isValid())
+ return f;
+ else
+ {
+ delete f;
+ }
+ }
+
+ return 0;
+}
diff --git a/src/metadata/speex/taglib_speexfiletyperesolver.h b/src/metadata/speex/taglib_speexfiletyperesolver.h
new file mode 100644
index 0000000..b5c5c2c
--- /dev/null
+++ b/src/metadata/speex/taglib_speexfiletyperesolver.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ copyright : (C) 2006 by Martin Aumueller
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef TAGLIB_SPEEXFILETYPERESOLVER_H
+#define TAGLIB_SPEEXFILETYPERESOLVER_H
+
+#include <taglib/tfile.h>
+#include <taglib/fileref.h>
+
+
+class SpeexFileTypeResolver : public TagLib::FileRef::FileTypeResolver
+{
+ TagLib::File *createFile(const char *fileName,
+ bool readAudioProperties,
+ TagLib::AudioProperties::ReadStyle audioPropertiesStyle) const;
+};
+
+#endif
diff --git a/src/metadata/tagengine.cpp b/src/metadata/tagengine.cpp
new file mode 100755
index 0000000..34abd23
--- /dev/null
+++ b/src/metadata/tagengine.cpp
@@ -0,0 +1,419 @@
+
+#include "tagengine.h"
+
+#include <qfile.h>
+
+// #include <taglib/attachedpictureframe.h>
+#include <taglib/fileref.h>
+#include <taglib/id3v1genres.h> //used to load genre list
+#include <taglib/mpegfile.h>
+#include <taglib/tag.h>
+#include <taglib/tstring.h>
+#include <taglib/tlist.h>
+#include <taglib/apetag.h>
+#include <taglib/id3v2tag.h>
+#include <taglib/id3v1tag.h>
+#include <taglib/mpcfile.h>
+#include <taglib/mpegfile.h>
+#include <taglib/oggfile.h>
+#include <taglib/oggflacfile.h>
+#include <taglib/vorbisfile.h>
+#include <taglib/flacfile.h>
+#include <taglib/textidentificationframe.h>
+#include <taglib/uniquefileidentifierframe.h>
+#include <taglib/xiphcomment.h>
+#include "wavpack/wvfile.h"
+#include "trueaudio/ttafile.h"
+
+#include <config.h>
+#ifdef HAVE_MP4V2
+#include "mp4/mp4file.h"
+#include "mp4/mp4tag.h"
+#else
+#include "m4a/mp4file.h"
+#include "m4a/mp4itunestag.h"
+#endif
+
+
+// TODO COMPILATION tag
+// FIXME BPM tag
+
+TagData::TagData( const QString& _artist, const QString& _composer,
+ const QString& _album, const QString& _title,
+ const QString& _genre, const QString& _comment,
+ int _track, int _disc, int _year,
+ int _length, int _fileSize, int _bitrate, int _samplingRate )
+{
+ artist = _artist;
+ composer = _composer;
+ album = _album;
+ title = _title;
+ genre = _genre;
+ comment = _comment;
+ track = _track;
+ disc = _disc;
+ year = _year;
+ length = _length;
+ fileSize = _fileSize;
+ bitrate = _bitrate;
+ samplingRate = _samplingRate;
+}
+
+TagData::~TagData()
+{}
+
+
+TagEngine::TagEngine()
+{
+ TagLib::StringList genres = TagLib::ID3v1::genreList();
+ for( TagLib::StringList::ConstIterator it = genres.begin(), end = genres.end(); it != end; ++it )
+ genreList += TStringToQString( (*it) );
+
+ genreList.sort();
+}
+
+TagEngine::~TagEngine()
+{}
+
+TagData* TagEngine::readTags( const QString& file )
+{
+ TagLib::FileRef fileref( QFile::encodeName(file) );
+ TagData* tagData = new TagData();
+
+ if( !fileref.isNull() )
+ {
+ TagLib::Tag *tag = fileref.tag();
+
+ tagData->track = 0;
+ tagData->year = 0;
+ tagData->disc = 0;
+ tagData->track_gain = 210588; // 0 is a valid value
+ tagData->album_gain = 210588;
+
+ if( tag )
+ {
+ tagData->title = TStringToQString( tag->title() ).stripWhiteSpace();
+ tagData->artist = TStringToQString( tag->artist() ).stripWhiteSpace();
+ tagData->album = TStringToQString( tag->album() ).stripWhiteSpace();
+ tagData->genre = TStringToQString( tag->genre() ).stripWhiteSpace();
+ tagData->comment = TStringToQString( tag->comment() ).stripWhiteSpace();
+ tagData->track = tag->track();
+ tagData->year = tag->year();
+ }
+
+ TagLib::AudioProperties *audioProperties = fileref.audioProperties();
+
+ if( audioProperties )
+ {
+ tagData->length = audioProperties->length();
+ // TODO read all information
+ //tagData->fileSize = ;
+ // = audioProperties->channels();
+ //tagData->bitrate = audioProperties->bitrate();
+ tagData->samplingRate = audioProperties->sampleRate();
+ }
+
+ QString disc;
+ QString track_gain;
+ QString album_gain;
+ if ( TagLib::MPEG::File *file = dynamic_cast<TagLib::MPEG::File *>( fileref.file() ) )
+ {
+ if ( file->ID3v2Tag() )
+ {
+ if ( !file->ID3v2Tag()->frameListMap()[ "TPOS" ].isEmpty() )
+ disc = TStringToQString( file->ID3v2Tag()->frameListMap()["TPOS"].front()->toString() ).stripWhiteSpace();
+
+ if ( !file->ID3v2Tag()->frameListMap()[ "TCOM" ].isEmpty() )
+ tagData->composer = TStringToQString( file->ID3v2Tag()->frameListMap()["TCOM"].front()->toString() ).stripWhiteSpace();
+ }
+ if ( file->APETag() )
+ {
+ if ( !file->APETag()->itemListMap()[ "REPLAYGAIN_TRACK_GAIN" ].isEmpty() )
+ track_gain = TStringToQString( file->APETag()->itemListMap()["REPLAYGAIN_TRACK_GAIN"].toString() ).stripWhiteSpace();
+
+ if ( !file->APETag()->itemListMap()[ "REPLAYGAIN_ALBUM_GAIN" ].isEmpty() )
+ album_gain = TStringToQString( file->APETag()->itemListMap()["REPLAYGAIN_ALBUM_GAIN"].toString() ).stripWhiteSpace();
+ }
+ }
+ else if ( TagLib::Ogg::Vorbis::File *file = dynamic_cast<TagLib::Ogg::Vorbis::File *>( fileref.file() ) )
+ {
+ if ( file->tag() )
+ {
+ if ( !file->tag()->fieldListMap()[ "COMPOSER" ].isEmpty() )
+ tagData->composer = TStringToQString( file->tag()->fieldListMap()["COMPOSER"].front() ).stripWhiteSpace();
+
+ if ( !file->tag()->fieldListMap()[ "DISCNUMBER" ].isEmpty() )
+ disc = TStringToQString( file->tag()->fieldListMap()["DISCNUMBER"].front() ).stripWhiteSpace();
+
+ if ( !file->tag()->fieldListMap()[ "REPLAYGAIN_TRACK_GAIN" ].isEmpty() )
+ track_gain = TStringToQString( file->tag()->fieldListMap()["REPLAYGAIN_TRACK_GAIN"].front() ).stripWhiteSpace();
+
+ if ( !file->tag()->fieldListMap()[ "REPLAYGAIN_ALBUM_GAIN" ].isEmpty() )
+ album_gain = TStringToQString( file->tag()->fieldListMap()["REPLAYGAIN_ALBUM_GAIN"].front() ).stripWhiteSpace();
+ }
+ }
+ else if ( TagLib::FLAC::File *file = dynamic_cast<TagLib::FLAC::File *>( fileref.file() ) )
+ {
+ if ( file->xiphComment() )
+ {
+ if ( !file->xiphComment()->fieldListMap()[ "COMPOSER" ].isEmpty() )
+ tagData->composer = TStringToQString( file->xiphComment()->fieldListMap()["COMPOSER"].front() ).stripWhiteSpace();
+
+ if ( !file->xiphComment()->fieldListMap()[ "DISCNUMBER" ].isEmpty() )
+ disc = TStringToQString( file->xiphComment()->fieldListMap()["DISCNUMBER"].front() ).stripWhiteSpace();
+
+ if ( !file->xiphComment()->fieldListMap()[ "REPLAYGAIN_TRACK_GAIN" ].isEmpty() )
+ track_gain = TStringToQString( file->xiphComment()->fieldListMap()["REPLAYGAIN_TRACK_GAIN"].front() ).stripWhiteSpace();
+
+ if ( !file->xiphComment()->fieldListMap()[ "REPLAYGAIN_ALBUM_GAIN" ].isEmpty() )
+ album_gain = TStringToQString( file->xiphComment()->fieldListMap()["REPLAYGAIN_ALBUM_GAIN"].front() ).stripWhiteSpace();
+ }
+
+ /*if ( file->tag() )
+ {
+ if ( !file->tag()->fieldListMap()[ "REPLAYGAIN_TRACK_GAIN" ].isEmpty() )
+ track_gain = TStringToQString( file->tag()->fieldListMap()["REPLAYGAIN_TRACK_GAIN"].front() ).stripWhiteSpace();
+
+ if ( !file->tag()->fieldListMap()[ "REPLAYGAIN_ALBUM_GAIN" ].isEmpty() )
+ album_gain = TStringToQString( file->tag()->fieldListMap()["REPLAYGAIN_ALBUM_GAIN"].front() ).stripWhiteSpace();
+ }*/
+ }
+ else if ( TagLib::MP4::File *file = dynamic_cast<TagLib::MP4::File *>( fileref.file() ) )
+ {
+ TagLib::MP4::Tag *mp4tag = dynamic_cast<TagLib::MP4::Tag *>( file->tag() );
+ if( mp4tag )
+ {
+ tagData->composer = TStringToQString( mp4tag->composer() );
+
+ disc = QString::number( mp4tag->disk() );
+ }
+ }
+/* else if ( TagLib::MPC::File *file = dynamic_cast<TagLib::MPC::File *>( fileref.file() ) )
+ {
+ if ( file->APETag() )
+ {
+ if ( !file->APETag()->itemListMap()[ "REPLAYGAIN_TRACK_GAIN" ].isEmpty() )
+ track_gain = TStringToQString( file->APETag()->itemListMap()["REPLAYGAIN_TRACK_GAIN"].toString() ).stripWhiteSpace();
+
+ if ( !file->APETag()->itemListMap()[ "REPLAYGAIN_ALBUM_GAIN" ].isEmpty() )
+ album_gain = TStringToQString( file->APETag()->itemListMap()["REPLAYGAIN_ALBUM_GAIN"].toString() ).stripWhiteSpace();
+ }
+ }*/
+ else if ( TagLib::WavPack::File *file = dynamic_cast<TagLib::WavPack::File *>( fileref.file() ) )
+ {
+ if ( file->APETag() )
+ {
+ if ( !file->APETag()->itemListMap()[ "REPLAYGAIN_TRACK_GAIN" ].isEmpty() )
+ track_gain = TStringToQString( file->APETag()->itemListMap()["REPLAYGAIN_TRACK_GAIN"].toString() ).stripWhiteSpace();
+
+ if ( !file->APETag()->itemListMap()[ "REPLAYGAIN_ALBUM_GAIN" ].isEmpty() )
+ album_gain = TStringToQString( file->APETag()->itemListMap()["REPLAYGAIN_ALBUM_GAIN"].toString() ).stripWhiteSpace();
+ }
+ }
+ else if ( TagLib::TTA::File *file = dynamic_cast<TagLib::TTA::File *>( fileref.file() ) )
+ {
+ if ( file->ID3v2Tag() )
+ {
+ if ( !file->ID3v2Tag()->frameListMap()[ "TPOS" ].isEmpty() )
+ disc = TStringToQString( file->ID3v2Tag()->frameListMap()["TPOS"].front()->toString() ).stripWhiteSpace();
+
+ if ( !file->ID3v2Tag()->frameListMap()[ "TCOM" ].isEmpty() )
+ tagData->composer = TStringToQString( file->ID3v2Tag()->frameListMap()["TCOM"].front()->toString() ).stripWhiteSpace();
+ }
+ }
+
+ if( !disc.isEmpty() )
+ {
+ int i = disc.find('/');
+ if( i != -1 )
+ // disc.right( i ).toInt() is total number of discs, we don't use this at the moment
+ tagData->disc = disc.left( i ).toInt();
+ else
+ tagData->disc = disc.toInt();
+ }
+
+ if( !track_gain.isEmpty() )
+ {
+ int i = track_gain.find(' ');
+ if( i != -1 )
+ tagData->track_gain = track_gain.left( i ).toFloat();
+ else
+ tagData->track_gain = track_gain.toFloat();
+ }
+
+ if( !album_gain.isEmpty() )
+ {
+ int i = album_gain.find(' ');
+ if( i != -1 )
+ tagData->album_gain = album_gain.left( i ).toFloat();
+ else
+ tagData->album_gain = album_gain.toFloat();
+ }
+
+ return tagData;
+ }
+
+ return 0;
+}
+
+bool TagEngine::writeTags( const QString& file, TagData* tagData )
+{
+ if( !tagData ) tagData = new TagData();
+
+ //Set default codec to UTF-8 (see bugs 111246 and 111232)
+ TagLib::ID3v2::FrameFactory::instance()->setDefaultTextEncoding( TagLib::String::UTF8 );
+
+ TagLib::FileRef fileref( QFile::encodeName(file), false );
+
+ if ( !fileref.isNull() )
+ {
+ TagLib::Tag* tag = fileref.tag();
+ if ( tag )
+ {
+ tag->setTitle( QStringToTString(tagData->title) );
+ tag->setArtist( QStringToTString(tagData->artist) );
+ tag->setAlbum( QStringToTString(tagData->album) );
+ tag->setTrack( tagData->track );
+ tag->setYear( tagData->year );
+ tag->setComment( QStringToTString(tagData->comment) );
+ tag->setGenre( QStringToTString(tagData->genre) );
+ }
+ else
+ {
+ return false;
+ }
+
+ if ( TagLib::MPEG::File *file = dynamic_cast<TagLib::MPEG::File *>( fileref.file() ) )
+ {
+ if ( file->ID3v2Tag() )
+ {
+ if ( !file->ID3v2Tag()->frameListMap()[ "TPOS" ].isEmpty() )
+ {
+ file->ID3v2Tag()->frameListMap()[ "TPOS" ].front()->setText( QStringToTString( QString::number(tagData->disc) ) );
+ }
+ else
+ {
+ TagLib::ID3v2::TextIdentificationFrame *frame = new TagLib::ID3v2::TextIdentificationFrame( "TPOS", TagLib::ID3v2::FrameFactory::instance()->defaultTextEncoding() );
+ frame->setText( QStringToTString( QString::number(tagData->disc) ) );
+ file->ID3v2Tag()->addFrame( frame );
+ }
+
+ if ( !file->ID3v2Tag()->frameListMap()[ "TCOM" ].isEmpty() )
+ {
+ file->ID3v2Tag()->frameListMap()[ "TCOM" ].front()->setText( QStringToTString( tagData->composer ) );
+ }
+ else
+ {
+ TagLib::ID3v2::TextIdentificationFrame *frame = new TagLib::ID3v2::TextIdentificationFrame( "TCOM", TagLib::ID3v2::FrameFactory::instance()->defaultTextEncoding() );
+ frame->setText( QStringToTString( tagData->composer ) );
+ file->ID3v2Tag()->addFrame( frame );
+ }
+
+ // HACK sets the id3v2 genre tag as string
+ if ( !file->ID3v2Tag()->frameListMap()[ "TCON" ].isEmpty() )
+ {
+ file->ID3v2Tag()->frameListMap()[ "TCON" ].front()->setText( QStringToTString( tagData->genre ) );
+ }
+ else
+ {
+ TagLib::ID3v2::TextIdentificationFrame *frame = new TagLib::ID3v2::TextIdentificationFrame( "TCON", TagLib::ID3v2::FrameFactory::instance()->defaultTextEncoding() );
+ frame->setText( QStringToTString( tagData->genre ) );
+ file->ID3v2Tag()->addFrame( frame );
+ }
+
+ // HACK sets the id3v2 year tag
+ if ( !file->ID3v2Tag()->frameListMap()[ "TYER" ].isEmpty() )
+ {
+ file->ID3v2Tag()->frameListMap()[ "TYER" ].front()->setText( QStringToTString( QString::number(tagData->year) ) );
+ }
+ else
+ {
+ TagLib::ID3v2::TextIdentificationFrame *frame = new TagLib::ID3v2::TextIdentificationFrame( "TYER", TagLib::ID3v2::FrameFactory::instance()->defaultTextEncoding() );
+ frame->setText( QStringToTString( QString::number(tagData->year) ) );
+ file->ID3v2Tag()->addFrame( frame );
+ }
+ }
+ }
+ else if ( TagLib::Ogg::Vorbis::File *file = dynamic_cast<TagLib::Ogg::Vorbis::File *>( fileref.file() ) )
+ {
+ if ( file->tag() )
+ {
+ file->tag()->addField( "COMPOSER", QStringToTString( tagData->composer ), true );
+
+ file->tag()->addField( "DISCNUMBER", QStringToTString( QString::number(tagData->disc) ), true );
+ }
+ }
+ else if ( TagLib::FLAC::File *file = dynamic_cast<TagLib::FLAC::File *>( fileref.file() ) )
+ {
+ if ( file->xiphComment() )
+ {
+ file->xiphComment()->addField( "COMPOSER", QStringToTString( tagData->composer ), true );
+
+ file->xiphComment()->addField( "DISCNUMBER", QStringToTString( QString::number(tagData->disc) ), true );
+ }
+ }
+ else if ( TagLib::MP4::File *file = dynamic_cast<TagLib::MP4::File *>( fileref.file() ) )
+ {
+ TagLib::MP4::Tag *mp4tag = dynamic_cast<TagLib::MP4::Tag *>( file->tag() );
+ if( mp4tag )
+ {
+ mp4tag->setComposer( QStringToTString( tagData->composer ) );
+
+ mp4tag->setDisk( tagData->disc );
+ }
+ }
+ if ( TagLib::TTA::File *file = dynamic_cast<TagLib::TTA::File *>( fileref.file() ) )
+ {
+ if ( file->ID3v2Tag() )
+ {
+ if ( !file->ID3v2Tag()->frameListMap()[ "TPOS" ].isEmpty() )
+ {
+ file->ID3v2Tag()->frameListMap()[ "TPOS" ].front()->setText( QStringToTString( QString::number(tagData->disc) ) );
+ }
+ else
+ {
+ TagLib::ID3v2::TextIdentificationFrame *frame = new TagLib::ID3v2::TextIdentificationFrame( "TPOS", TagLib::ID3v2::FrameFactory::instance()->defaultTextEncoding() );
+ frame->setText( QStringToTString( QString::number(tagData->disc) ) );
+ file->ID3v2Tag()->addFrame( frame );
+ }
+
+ if ( !file->ID3v2Tag()->frameListMap()[ "TCOM" ].isEmpty() )
+ {
+ file->ID3v2Tag()->frameListMap()[ "TCOM" ].front()->setText( QStringToTString( tagData->composer ) );
+ }
+ else
+ {
+ TagLib::ID3v2::TextIdentificationFrame *frame = new TagLib::ID3v2::TextIdentificationFrame( "TCOM", TagLib::ID3v2::FrameFactory::instance()->defaultTextEncoding() );
+ frame->setText( QStringToTString( tagData->composer ) );
+ file->ID3v2Tag()->addFrame( frame );
+ }
+ }
+ }
+
+ return fileref.save();
+ }
+ return false;
+}
+
+// bool TagEngine::canWrite( QString format )
+// {
+// format = format.lower();
+//
+// if( format == "ogg" ||
+// format == "flac" || format == "fla" ||
+// format == "mp3" || // TODO mp2 ?
+// format == "mpc" ||
+// format == "aac" ||
+// format == "ape" || format == "mac" ||
+// format == "aa" ||
+// format == "m4a" || format == "m4b" || format == "m4p" || format == "mp4" || format == "m4v" || format == "mp4v" ||
+// format == "ra" || format == "rv" || format == "rm" || format == "rmj" || format == "rmvb" ||
+// format == "wma" || format == "asf" )
+// {
+// return true;
+// }
+// else {
+// return false;
+// }
+// }
+
diff --git a/src/metadata/tagengine.h b/src/metadata/tagengine.h
new file mode 100755
index 0000000..e21a48c
--- /dev/null
+++ b/src/metadata/tagengine.h
@@ -0,0 +1,79 @@
+
+
+#ifndef TAGENGINE_H
+#define TAGENGINE_H
+
+#include <qstring.h>
+#include <qstringlist.h>
+
+/**
+ * @short All metainformation can be stored in this class
+ * @author Daniel Faust <[email protected]>
+ * @version 0.3
+ */
+class TagData
+{
+public:
+ /**
+ * Constructor
+ */
+ TagData( const QString& _artist = QString::null, const QString& _composer = QString::null,
+ const QString& _album = QString::null, const QString& _title = QString::null,
+ const QString& _genre = QString::null, const QString& _comment = QString::null,
+ int _track = 0, int _disc = 0, int _year = 0,
+ int _length = 0, int _fileSize = 0, int _bitrate = 0, int _samplingRate = 0 );
+
+ /**
+ * Destructor
+ */
+ virtual ~TagData();
+
+ /** The tags */
+ QString artist;
+ QString composer;
+ QString album;
+ QString title;
+ QString genre;
+ QString comment;
+ int track;
+ int disc;
+ int year;
+ float track_gain;
+ float album_gain;
+
+ /** The technical information */
+ int length;
+ int fileSize;
+ int bitrate;
+ int samplingRate;
+};
+
+
+/**
+ * @short Manages everything that has something to do with tags
+ * @author Daniel Faust <[email protected]>
+ * @version 0.3
+ */
+class TagEngine
+{
+public:
+ /**
+ * Constructor
+ */
+ TagEngine();
+
+ /**
+ * Destructor
+ */
+ virtual ~TagEngine();
+
+ /** A list of all genre */
+ QStringList genreList;
+
+ TagData* readTags( const QString& file );
+ bool writeTags( const QString& file, TagData* tagData );
+
+// bool canWrite( QString format ); // NOTE no const because this string is being modyfied
+};
+
+#endif // TAGENGINE_H
diff --git a/src/metadata/tplugins.cpp b/src/metadata/tplugins.cpp
new file mode 100755
index 0000000..b84d601
--- /dev/null
+++ b/src/metadata/tplugins.cpp
@@ -0,0 +1,151 @@
+/***************************************************************************
+ copyright : (C) 2005, 2006 by Martin Aumueller
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <config.h>
+// #include <debug.h>
+
+#include <qfile.h>
+#include <kmimetype.h>
+
+#include <taglib/fileref.h>
+#include <taglib/tfile.h>
+
+#ifdef HAVE_MP4V2
+#include "mp4/taglib_mp4filetyperesolver.h"
+#include "mp4/mp4file.h"
+#else
+#include "m4a/taglib_mp4filetyperesolver.h"
+#include "m4a/mp4file.h"
+#endif
+
+#include "trueaudio/taglib_trueaudiofiletyperesolver.h"
+#include "trueaudio/ttafile.h"
+#include "wavpack/taglib_wavpackfiletyperesolver.h"
+#include "wavpack/wvfile.h"
+#include "speex/taglib_speexfiletyperesolver.h"
+#include "speex/speexfile.h"
+#include "asf/taglib_asffiletyperesolver.h"
+#include "asf/asffile.h"
+#include "rmff/taglib_realmediafiletyperesolver.h"
+#include "rmff/taglib_realmediafile.h"
+#include "audible/taglib_audiblefiletyperesolver.h"
+#include "audible/taglib_audiblefile.h"
+#include "wav/wavfiletyperesolver.h"
+#include "wav/wavfile.h"
+#include "aac/aacfiletyperesolver.h"
+#include "ape/taglib_monkeysaudiofiletyperesolver.h"
+#include "optimfrog/taglib_optimfrogfiletyperesolver.h"
+
+#include <taglib/mpegfile.h>
+#include <taglib/oggfile.h>
+#include <taglib/oggflacfile.h>
+#include <taglib/vorbisfile.h>
+#include <taglib/flacfile.h>
+#include <taglib/mpcfile.h>
+
+
+class MimeTypeFileTypeResolver : public TagLib::FileRef::FileTypeResolver
+{
+ TagLib::File *createFile(const char *fileName,
+ bool readAudioProperties,
+ TagLib::AudioProperties::ReadStyle audioPropertiesStyle) const;
+};
+
+TagLib::File *MimeTypeFileTypeResolver::createFile(const char *fileName,
+ bool readProperties,
+ TagLib::AudioProperties::ReadStyle propertiesStyle) const
+{
+ QString fn = QFile::decodeName( fileName );
+ int accuracy = 0;
+
+ KMimeType::Ptr mimetype = KMimeType::findByFileContent( fn, &accuracy );
+ if( accuracy <= 0 )
+ mimetype = KMimeType::findByPath( fn );
+
+ if( mimetype->is( "audio/aac" )
+ || mimetype->is( "audio/mpeg" )
+ || mimetype->is( "audio/mpegurl" )
+ || mimetype->is( "audio/x-mpegurl" )
+ || mimetype->is( "audio/x-mp3" ))
+ {
+ return new TagLib::MPEG::File(fileName, readProperties, propertiesStyle);
+ }
+ else if( mimetype->is( "audio/mp4" ) || mimetype->is( "video/mp4" ) )
+ {
+ return new TagLib::MP4::File(fileName, readProperties, propertiesStyle);
+ }
+ else if( mimetype->is( "audio/x-ms-wma" )
+ || mimetype->is( "video/x-ms-asf" )
+ || mimetype->is( "video/x-msvideo" )
+ || mimetype->is( "video/x-ms-wmv" ) )
+ {
+ return new TagLib::ASF::File(fileName, readProperties, propertiesStyle);
+ }
+ else if( mimetype->is( "audio/vnd.rn-realaudio" )
+ || mimetype->is( "audio/x-pn-realaudio" )
+ || mimetype->is( "audio/x-pn-realaudioplugin" )
+ || mimetype->is( "audio/vnd.rn-realvideo" ) )
+ {
+ return new TagLib::RealMedia::File(fileName, readProperties, propertiesStyle);
+ }
+ else if( mimetype->is( "audio/vorbis" ) )
+ {
+ return new TagLib::Ogg::Vorbis::File(fileName, readProperties, propertiesStyle);
+ }
+ else if( mimetype->is( "audio/x-oggflac" ) )
+ {
+ return new TagLib::Ogg::FLAC::File(fileName, readProperties, propertiesStyle);
+ }
+ else if( mimetype->is( "audio/x-flac" ) )
+ {
+ return new TagLib::FLAC::File(fileName, readProperties, propertiesStyle);
+ }
+ else if( mimetype->is( "audio/x-musepack" ) )
+ {
+ return new TagLib::MPC::File(fileName, readProperties, propertiesStyle);
+ }
+ else if( mimetype->is( "audio/x-musepack" )
+ || mimetype->is( "audio/x-ape" )
+ || mimetype->is( "application/x-ofr" ) )
+ {
+ return new TagLib::MPC::File(fileName, readProperties, propertiesStyle);
+ }
+
+// debug() << "kmimetype filetype guessing failed for" << fileName << endl;
+
+ return 0;
+}
+
+void registerTaglibPlugins()
+{
+ //TagLib::FileRef::addFileTypeResolver(new MimeTypeFileTypeResolver);
+ TagLib::FileRef::addFileTypeResolver(new MP4FileTypeResolver);
+ TagLib::FileRef::addFileTypeResolver(new ASFFileTypeResolver);
+ TagLib::FileRef::addFileTypeResolver(new RealMediaFileTypeResolver);
+ TagLib::FileRef::addFileTypeResolver(new AudibleFileTypeResolver);
+ TagLib::FileRef::addFileTypeResolver(new AACFileTypeResolver);
+ TagLib::FileRef::addFileTypeResolver(new WavPackFileTypeResolver);
+ TagLib::FileRef::addFileTypeResolver(new SpeexFileTypeResolver);
+ TagLib::FileRef::addFileTypeResolver(new TTAFileTypeResolver);
+ TagLib::FileRef::addFileTypeResolver(new WavFileTypeResolver);
+ TagLib::FileRef::addFileTypeResolver(new MonkeysAudioFileTypeResolver);
+ TagLib::FileRef::addFileTypeResolver(new OptimFrogFileTypeResolver);
+}
diff --git a/src/metadata/tplugins.h b/src/metadata/tplugins.h
new file mode 100755
index 0000000..1ef356f
--- /dev/null
+++ b/src/metadata/tplugins.h
@@ -0,0 +1,27 @@
+/***************************************************************************
+ copyright : (C) 2005 by Martin Aumueller
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef METADATA_TPLUGIN_H
+#define METADATA_TPLUGIN_H
+
+void registerTaglibPlugins();
+
+#endif
diff --git a/src/metadata/trueaudio/Makefile.am b/src/metadata/trueaudio/Makefile.am
new file mode 100644
index 0000000..01af09f
--- /dev/null
+++ b/src/metadata/trueaudio/Makefile.am
@@ -0,0 +1,16 @@
+SUBDIRS =
+
+INCLUDES = $(all_includes) $(taglib_includes)
+METASOURCES = AUTO
+libtagtrueaudio_la_LDFLAGS = $(all_libraries)
+noinst_LTLIBRARIES = libtagtrueaudio.la
+
+libtagtrueaudio_la_SOURCES = \
+ ttafile.cpp \
+ ttaproperties.cpp \
+ taglib_trueaudiofiletyperesolver.cpp
+
+noinst_HEADERS = ttafile.h \
+ ttaproperties.h \
+ taglib_trueaudiofiletyperesolver.h
+
diff --git a/src/metadata/trueaudio/combinedtag.h b/src/metadata/trueaudio/combinedtag.h
new file mode 100644
index 0000000..7d530d2
--- /dev/null
+++ b/src/metadata/trueaudio/combinedtag.h
@@ -0,0 +1,171 @@
+/***************************************************************************
+ copyright : (C) 2004 by Allan Sandfeld Jensen
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef DO_NOT_DOCUMENT // Tell Doxygen not to document this header
+
+#ifndef TAGLIB_COMBINEDTAG_H
+#define TAGLIB_COMBINEDTAG_H
+
+////////////////////////////////////////////////////////////////////////////////
+// Note that this header is not installed.
+////////////////////////////////////////////////////////////////////////////////
+
+#include <tag.h>
+
+namespace TagLib {
+
+ /*!
+ * A union of two TagLib::Tags.
+ */
+ class CombinedTag : public TagLib::Tag
+ {
+ public:
+ CombinedTag(Tag *tag1 = 0, Tag *tag2 = 0)
+ : TagLib::Tag(),
+ tag1(tag1), tag2(tag2) {}
+
+ virtual String title() const {
+ if(tag1 && !tag1->title().isEmpty())
+ return tag1->title();
+
+ if(tag2)
+ return tag2->title();
+
+ return String::null;
+ }
+
+ virtual String artist() const {
+ if(tag1 && !tag1->artist().isEmpty())
+ return tag1->artist();
+
+ if(tag2)
+ return tag2->artist();
+
+ return String::null;
+ }
+
+ virtual String album() const {
+ if(tag1 && !tag1->album().isEmpty())
+ return tag1->album();
+
+ if(tag2)
+ return tag2->album();
+
+ return String::null;
+ }
+
+ virtual String comment() const {
+ if(tag1 && !tag1->comment().isEmpty())
+ return tag1->comment();
+
+ if(tag2)
+ return tag2->comment();
+
+ return String::null;
+ }
+
+ virtual String genre() const {
+ if(tag1 && !tag1->genre().isEmpty())
+ return tag1->genre();
+
+ if(tag2)
+ return tag2->genre();
+
+ return String::null;
+ }
+
+ virtual uint year() const {
+ if(tag1 && tag1->year() > 0)
+ return tag1->year();
+
+ if(tag2)
+ return tag2->year();
+
+ return 0;
+ }
+
+ virtual uint track() const {
+ if(tag1 && tag1->track() > 0)
+ return tag1->track();
+
+ if(tag2)
+ return tag2->track();
+
+ return 0;
+ }
+
+ virtual void setTitle(const String &s) {
+ if(tag1)
+ tag1->setTitle(s);
+ if(tag2)
+ tag2->setTitle(s);
+ }
+
+ virtual void setArtist(const String &s) {
+ if(tag1)
+ tag1->setArtist(s);
+ if(tag2)
+ tag2->setArtist(s);
+ }
+
+ virtual void setAlbum(const String &s) {
+ if(tag1)
+ tag1->setAlbum(s);
+ if(tag2)
+ tag2->setAlbum(s);
+ }
+
+ virtual void setComment(const String &s) {
+ if(tag1)
+ tag1->setComment(s);
+ if(tag2)
+ tag2->setComment(s);
+ }
+
+ virtual void setGenre(const String &s) {
+ if(tag1)
+ tag1->setGenre(s);
+ if(tag2)
+ tag2->setGenre(s);
+ }
+
+ virtual void setYear(uint i) {
+ if(tag1)
+ tag1->setYear(i);
+ if(tag2)
+ tag2->setYear(i);
+ }
+
+ virtual void setTrack(uint i) {
+ if(tag1)
+ tag1->setTrack(i);
+ if(tag2)
+ tag2->setTrack(i);
+ }
+
+ private:
+ Tag *tag1;
+ Tag *tag2;
+ };
+}
+
+#endif
+#endif
diff --git a/src/metadata/trueaudio/taglib_trueaudiofiletyperesolver.cpp b/src/metadata/trueaudio/taglib_trueaudiofiletyperesolver.cpp
new file mode 100644
index 0000000..e84e501
--- /dev/null
+++ b/src/metadata/trueaudio/taglib_trueaudiofiletyperesolver.cpp
@@ -0,0 +1,44 @@
+/***************************************************************************
+ copyright : (C) 2006 by Martin Aumueller
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "taglib_trueaudiofiletyperesolver.h"
+#include "ttafile.h"
+
+#include <string.h>
+
+TagLib::File *TTAFileTypeResolver::createFile(const char *fileName,
+ bool readProperties,
+ TagLib::AudioProperties::ReadStyle propertiesStyle) const
+{
+ const char *ext = strrchr(fileName, '.');
+ if(ext && !strcasecmp(ext, ".tta"))
+ {
+ TagLib::TTA::File *f = new TagLib::TTA::File(fileName, readProperties, propertiesStyle);
+ if(f->isValid())
+ return f;
+ else
+ {
+ delete f;
+ }
+ }
+
+ return 0;
+}
diff --git a/src/metadata/trueaudio/taglib_trueaudiofiletyperesolver.h b/src/metadata/trueaudio/taglib_trueaudiofiletyperesolver.h
new file mode 100644
index 0000000..e436e43
--- /dev/null
+++ b/src/metadata/trueaudio/taglib_trueaudiofiletyperesolver.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ copyright : (C) 2006 by Martin Aumueller
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef TAGLIB_TRUEAUDIOFILETYPERESOLVER_H
+#define TAGLIB_TRUEAUDIOFILETYPERESOLVER_H
+
+#include <taglib/tfile.h>
+#include <taglib/fileref.h>
+
+
+class TTAFileTypeResolver : public TagLib::FileRef::FileTypeResolver
+{
+ TagLib::File *createFile(const char *fileName,
+ bool readAudioProperties,
+ TagLib::AudioProperties::ReadStyle audioPropertiesStyle) const;
+};
+
+#endif
diff --git a/src/metadata/trueaudio/ttafile.cpp b/src/metadata/trueaudio/ttafile.cpp
new file mode 100644
index 0000000..3a02e20
--- /dev/null
+++ b/src/metadata/trueaudio/ttafile.cpp
@@ -0,0 +1,307 @@
+/***************************************************************************
+ copyright : (C) 2006 by Lukáš Lalinský
+
+ copyright : (C) 2004 by Allan Sandfeld Jensen
+ (original MPC implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <tbytevector.h>
+#include <tstring.h>
+#if 0
+#include <tdebug.h>
+#endif
+
+#include "ttafile.h"
+#include "id3v1tag.h"
+#include "id3v2tag.h"
+#include "id3v2header.h"
+#include "combinedtag.h"
+
+using namespace TagLib;
+
+class TTA::File::FilePrivate
+{
+public:
+ FilePrivate(const ID3v2::FrameFactory *frameFactory = ID3v2::FrameFactory::instance()) :
+ ID3v2FrameFactory(frameFactory),
+ ID3v2Tag(0),
+ ID3v2Location(-1),
+ ID3v2OriginalSize(0),
+ ID3v1Tag(0),
+ ID3v1Location(-1),
+ tag(0),
+ properties(0),
+ scanned(false),
+ hasID3v1(false),
+ hasID3v2(false) {}
+
+ ~FilePrivate()
+ {
+ if (tag != ID3v1Tag && tag != ID3v2Tag) delete tag;
+ delete ID3v1Tag;
+ delete ID3v2Tag;
+ delete properties;
+ }
+
+ const ID3v2::FrameFactory *ID3v2FrameFactory;
+ ID3v2::Tag *ID3v2Tag;
+ long ID3v2Location;
+ uint ID3v2OriginalSize;
+
+ ID3v1::Tag *ID3v1Tag;
+ long ID3v1Location;
+
+ Tag *tag;
+
+ Properties *properties;
+ bool scanned;
+
+ // These indicate whether the file *on disk* has these tags, not if
+ // this data structure does. This is used in computing offsets.
+
+ bool hasID3v1;
+ bool hasID3v2;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+TTA::File::File(const char *file, bool readProperties,
+ Properties::ReadStyle propertiesStyle) : TagLib::File(file)
+{
+ d = new FilePrivate;
+ if(isOpen())
+ read(readProperties, propertiesStyle);
+}
+
+TTA::File::File(const char *file, ID3v2::FrameFactory *frameFactory,
+ bool readProperties, Properties::ReadStyle propertiesStyle) :
+ TagLib::File(file)
+{
+ d = new FilePrivate(frameFactory);
+ if(isOpen())
+ read(readProperties, propertiesStyle);
+}
+
+TTA::File::~File()
+{
+ delete d;
+}
+
+TagLib::Tag *TTA::File::tag() const
+{
+ return d->tag;
+}
+
+TTA::Properties *TTA::File::audioProperties() const
+{
+ return d->properties;
+}
+
+void TTA::File::setID3v2FrameFactory(const ID3v2::FrameFactory *factory)
+{
+ d->ID3v2FrameFactory = factory;
+}
+
+bool TTA::File::save()
+{
+ if(readOnly()) {
+#if 0
+ debug("TTA::File::save() -- File is read only.");
+#endif
+ return false;
+ }
+
+ // Update ID3v2 tag
+
+ if(d->ID3v2Tag) {
+ if(!d->hasID3v2) {
+ d->ID3v2Location = 0;
+ d->ID3v2OriginalSize = 0;
+ }
+ insert(d->ID3v2Tag->render(), d->ID3v2Location, d->ID3v2OriginalSize);
+ d->hasID3v2 = true;
+ }
+ else if(d->hasID3v2) {
+ removeBlock(d->ID3v2Location, d->ID3v2OriginalSize);
+ d->hasID3v2 = false;
+ }
+
+ // Update ID3v1 tag
+
+ if(d->ID3v1Tag) {
+ if(!d->hasID3v1) {
+ seek(0, End);
+ d->ID3v1Location = tell();
+ }
+ else
+ seek(d->ID3v1Location);
+ writeBlock(d->ID3v1Tag->render());
+ d->hasID3v1 = true;
+ }
+ else if(d->hasID3v1) {
+ removeBlock(d->ID3v1Location, 128);
+ d->hasID3v1 = false;
+ }
+
+ return true;
+}
+
+ID3v1::Tag *TTA::File::ID3v1Tag(bool create)
+{
+ if(!create || d->ID3v1Tag)
+ return d->ID3v1Tag;
+
+ // no ID3v1 tag exists and we've been asked to create one
+
+ d->ID3v1Tag = new ID3v1::Tag;
+
+ if(d->ID3v2Tag)
+ d->tag = new CombinedTag(d->ID3v2Tag, d->ID3v1Tag);
+ else
+ d->tag = d->ID3v1Tag;
+
+ return d->ID3v1Tag;
+}
+
+ID3v2::Tag *TTA::File::ID3v2Tag(bool create)
+{
+ if(!create || d->ID3v2Tag)
+ return d->ID3v2Tag;
+
+ // no ID3v2 tag exists and we've been asked to create one
+
+ d->ID3v2Tag = new ID3v2::Tag;
+
+ if(d->ID3v1Tag)
+ d->tag = new CombinedTag(d->ID3v2Tag, d->ID3v1Tag);
+ else
+ d->tag = d->ID3v2Tag;
+
+ return d->ID3v2Tag;
+}
+
+void TTA::File::remove(int tags)
+{
+ if(tags & ID3v1) {
+ delete d->ID3v1Tag;
+ d->ID3v1Tag = 0;
+
+ if(d->ID3v2Tag)
+ d->tag = d->ID3v2Tag;
+ else
+ d->tag = d->ID3v2Tag = new ID3v2::Tag;
+ }
+
+ if(tags & ID3v2) {
+ delete d->ID3v2Tag;
+ d->ID3v2Tag = 0;
+
+ if(d->ID3v1Tag)
+ d->tag = d->ID3v1Tag;
+ else
+ d->tag = d->ID3v2Tag = new ID3v2::Tag;
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// private members
+////////////////////////////////////////////////////////////////////////////////
+
+void TTA::File::read(bool readProperties, Properties::ReadStyle /* propertiesStyle */)
+{
+ // Look for an ID3v2 tag
+
+ d->ID3v2Location = findID3v2();
+
+ if(d->ID3v2Location >= 0) {
+
+ d->ID3v2Tag = new ID3v2::Tag(this, d->ID3v2Location, d->ID3v2FrameFactory);
+
+ d->ID3v2OriginalSize = d->ID3v2Tag->header()->completeTagSize();
+
+ if(d->ID3v2Tag->header()->tagSize() <= 0) {
+ delete d->ID3v2Tag;
+ d->ID3v2Tag = 0;
+ }
+ else
+ d->hasID3v2 = true;
+ }
+
+ // Look for an ID3v1 tag
+
+ d->ID3v1Location = findID3v1();
+
+ if(d->ID3v1Location >= 0) {
+ d->ID3v1Tag = new ID3v1::Tag(this, d->ID3v1Location);
+ d->hasID3v1 = true;
+ }
+
+ if(d->hasID3v1 && d->hasID3v2)
+ d->tag = new CombinedTag(d->ID3v2Tag, d->ID3v1Tag);
+ else {
+ if(d->hasID3v1)
+ d->tag = d->ID3v1Tag;
+ else {
+ if(d->hasID3v2)
+ d->tag = d->ID3v2Tag;
+ else
+ d->tag = d->ID3v2Tag = new ID3v2::Tag;
+ }
+ }
+
+ // Look for TTA metadata
+
+ if(readProperties) {
+ seek(d->ID3v2Location + d->ID3v2OriginalSize);
+ d->properties = new Properties(readBlock(TTA::HeaderSize),
+ length() - d->ID3v2OriginalSize);
+ }
+}
+
+long TTA::File::findID3v1()
+{
+ if(!isValid())
+ return -1;
+
+ seek(-128, End);
+ long p = tell();
+
+ if(readBlock(3) == ID3v1::Tag::fileIdentifier())
+ return p;
+
+ return -1;
+}
+
+long TTA::File::findID3v2()
+{
+ if(!isValid())
+ return -1;
+
+ seek(0);
+
+ if(readBlock(3) == ID3v2::Header::fileIdentifier())
+ return 0;
+
+ return -1;
+}
diff --git a/src/metadata/trueaudio/ttafile.h b/src/metadata/trueaudio/ttafile.h
new file mode 100644
index 0000000..2cb0785
--- /dev/null
+++ b/src/metadata/trueaudio/ttafile.h
@@ -0,0 +1,178 @@
+/***************************************************************************
+ copyright : (C) 2006 by Lukáš Lalinský
+
+ copyright : (C) 2004 by Allan Sandfeld Jensen
+ (original MPC implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef TAGLIB_TTAFILE_H
+#define TAGLIB_TTAFILE_H
+
+#include "tfile.h"
+
+#include "ttaproperties.h"
+
+namespace TagLib {
+
+ class Tag;
+
+ namespace ID3v2 { class Tag; class FrameFactory; }
+ namespace ID3v1 { class Tag; }
+
+ //! An implementation of TTA metadata
+
+ /*!
+ * This is implementation of TTA metadata.
+ *
+ * This supports ID3v1 and ID3v2 tags as well as reading stream
+ * properties from the file.
+ */
+
+ namespace TTA {
+
+ //! An implementation of TagLib::File with TTA specific methods
+
+ /*!
+ * This implements and provides an interface for TTA files to the
+ * TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing
+ * the abstract TagLib::File API as well as providing some additional
+ * information specific to TTA files.
+ */
+
+ class File : public TagLib::File
+ {
+ public:
+ /*!
+ * This set of flags is used for various operations and is suitable for
+ * being OR-ed together.
+ */
+ enum TagTypes {
+ //! Empty set. Matches no tag types.
+ NoTags = 0x0000,
+ //! Matches ID3v1 tags.
+ ID3v1 = 0x0001,
+ //! Matches ID3v2 tags.
+ ID3v2 = 0x0002,
+ //! Matches all tag types.
+ AllTags = 0xffff
+ };
+
+ /*!
+ * Contructs an MPC 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.
+ */
+ File(const char *file, bool readProperties = true,
+ Properties::ReadStyle propertiesStyle = Properties::Average);
+
+ /*!
+ * Contructs an MPC 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. The frames will be created using
+ * \a frameFactory.
+ */
+ File(const char *file, ID3v2::FrameFactory *frameFactory,
+ bool readProperties = true,
+ Properties::ReadStyle propertiesStyle = Properties::Average);
+
+ /*!
+ * Destroys this instance of the File.
+ */
+ virtual ~File();
+
+ /*!
+ * Returns the Tag for this file. This will be an APE tag, an ID3v1 tag
+ * or a combination of the two.
+ */
+ virtual TagLib::Tag *tag() const;
+
+ /*!
+ * Returns the MPC::Properties for this file. If no audio properties
+ * were read then this will return a null pointer.
+ */
+ virtual Properties *audioProperties() const;
+
+ /*!
+ * Set the ID3v2::FrameFactory to something other than the default.
+ *
+ * \see ID3v2FrameFactory
+ */
+ void setID3v2FrameFactory(const ID3v2::FrameFactory *factory);
+
+ /*!
+ * Saves the file.
+ */
+ virtual bool save();
+
+ /*!
+ * Returns a pointer to the ID3v2 tag of the file.
+ *
+ * If \a create is false (the default) this will return a null pointer
+ * if there is no valid ID3v2 tag. If \a create is true it will create
+ * an ID3v1 tag if one does not exist. If there is already an APE tag, the
+ * new ID3v1 tag will be placed after it.
+ *
+ * \note The Tag <b>is still</b> owned by the TTA::File and should not be
+ * deleted by the user. It will be deleted when the file (object) is
+ * destroyed.
+ */
+ ID3v1::Tag *ID3v1Tag(bool create = false);
+
+ /*!
+ * Returns a pointer to the ID3v1 tag of the file.
+ *
+ * If \a create is false (the default) this will return a null pointer
+ * if there is no valid ID3v1 tag. If \a create is true it will create
+ * an ID3v1 tag if one does not exist. If there is already an APE tag, the
+ * new ID3v1 tag will be placed after it.
+ *
+ * \note The Tag <b>is still</b> owned by the TTA::File and should not be
+ * deleted by the user. It will be deleted when the file (object) is
+ * destroyed.
+ */
+ ID3v2::Tag *ID3v2Tag(bool create = false);
+
+ /*!
+ * This will remove the tags that match the OR-ed together TagTypes from the
+ * file. By default it removes all tags.
+ *
+ * \note This will also invalidate pointers to the tags
+ * as their memory will be freed.
+ * \note In order to make the removal permanent save() still needs to be called
+ */
+ void remove(int tags = AllTags);
+
+ private:
+ File(const File &);
+ File &operator=(const File &);
+
+ void read(bool readProperties, Properties::ReadStyle propertiesStyle);
+ void scan();
+ long findID3v1();
+ long findID3v2();
+
+ class FilePrivate;
+ FilePrivate *d;
+ };
+ }
+}
+
+#endif
diff --git a/src/metadata/trueaudio/ttaproperties.cpp b/src/metadata/trueaudio/ttaproperties.cpp
new file mode 100644
index 0000000..c4f6a29
--- /dev/null
+++ b/src/metadata/trueaudio/ttaproperties.cpp
@@ -0,0 +1,134 @@
+/***************************************************************************
+ copyright : (C) 2006 by Lukáš Lalinský
+
+ copyright : (C) 2004 by Allan Sandfeld Jensen
+ (original MPC implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <tstring.h>
+#if 0
+#include <tdebug.h>
+#endif
+#include <bitset>
+
+#include "ttaproperties.h"
+#include "ttafile.h"
+
+using namespace TagLib;
+
+class TTA::Properties::PropertiesPrivate
+{
+public:
+ PropertiesPrivate(const ByteVector &d, long length, ReadStyle s) :
+ data(d),
+ streamLength(length),
+ style(s),
+ version(0),
+ length(0),
+ bitrate(0),
+ sampleRate(0),
+ channels(0),
+ bitsPerSample(0) {}
+
+ ByteVector data;
+ long streamLength;
+ ReadStyle style;
+ int version;
+ int length;
+ int bitrate;
+ int sampleRate;
+ int channels;
+ int bitsPerSample;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+TTA::Properties::Properties(const ByteVector &data, long streamLength, ReadStyle style) : AudioProperties(style)
+{
+ d = new PropertiesPrivate(data, streamLength, style);
+ read();
+}
+
+TTA::Properties::~Properties()
+{
+ delete d;
+}
+
+int TTA::Properties::length() const
+{
+ return d->length;
+}
+
+int TTA::Properties::bitrate() const
+{
+ return d->bitrate;
+}
+
+int TTA::Properties::sampleRate() const
+{
+ return d->sampleRate;
+}
+
+int TTA::Properties::bitsPerSample() const
+{
+ return d->bitsPerSample;
+}
+
+int TTA::Properties::channels() const
+{
+ return d->channels;
+}
+
+int TTA::Properties::ttaVersion() const
+{
+ return d->version;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// private members
+////////////////////////////////////////////////////////////////////////////////
+
+void TTA::Properties::read()
+{
+ if(!d->data.startsWith("TTA"))
+ return;
+
+ int pos = 3;
+
+ d->version = d->data[pos] - '0';
+ pos += 1 + 2;
+
+ d->channels = d->data.mid(pos, 2).toShort(false);
+ pos += 2;
+
+ d->bitsPerSample = d->data.mid(pos, 2).toShort(false);
+ pos += 2;
+
+ d->sampleRate = d->data.mid(pos, 4).toUInt(false);
+ pos += 4;
+
+ unsigned long samples = d->data.mid(pos, 4).toUInt(false);
+ d->length = samples / d->sampleRate;
+
+ d->bitrate = d->length > 0 ? ((d->streamLength * 8L) / d->length) / 1000 : 0;
+}
diff --git a/src/metadata/trueaudio/ttaproperties.h b/src/metadata/trueaudio/ttaproperties.h
new file mode 100644
index 0000000..e694e3d
--- /dev/null
+++ b/src/metadata/trueaudio/ttaproperties.h
@@ -0,0 +1,86 @@
+/***************************************************************************
+ copyright : (C) 2006 by Lukáš Lalinský
+
+ copyright : (C) 2004 by Allan Sandfeld Jensen
+ (original MPC implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef TAGLIB_TTAPROPERTIES_H
+#define TAGLIB_TTAPROPERTIES_H
+
+#include "audioproperties.h"
+
+namespace TagLib {
+
+ namespace TTA {
+
+ class File;
+
+ static const uint HeaderSize = 18;
+
+ //! An implementation of audio property reading for TTA
+
+ /*!
+ * This reads the data from an TTA stream found in the AudioProperties
+ * API.
+ */
+
+ class Properties : public AudioProperties
+ {
+ public:
+ /*!
+ * Create an instance of TTA::Properties with the data read from the
+ * ByteVector \a data.
+ */
+ Properties(const ByteVector &data, long streamLength, ReadStyle style = Average);
+
+ /*!
+ * Destroys this TTA::Properties instance.
+ */
+ virtual ~Properties();
+
+ // Reimplementations.
+
+ virtual int length() const;
+ virtual int bitrate() const;
+ virtual int sampleRate() const;
+ virtual int channels() const;
+
+ /*!
+ * Returns number of bits per sample.
+ */
+ int bitsPerSample() const;
+
+ /*!
+ * Returns the major version number.
+ */
+ int ttaVersion() const;
+
+ private:
+ void read();
+
+ class PropertiesPrivate;
+ PropertiesPrivate *d;
+ };
+ }
+}
+
+#endif
diff --git a/src/metadata/wav/Makefile.am b/src/metadata/wav/Makefile.am
new file mode 100644
index 0000000..add569f
--- /dev/null
+++ b/src/metadata/wav/Makefile.am
@@ -0,0 +1,15 @@
+SUBDIRS =
+
+INCLUDES = $(all_includes) $(taglib_includes)
+METASOURCES = AUTO
+libtagwav_la_LDFLAGS = $(all_libraries)
+noinst_LTLIBRARIES = libtagwav.la
+
+libtagwav_la_SOURCES = wavproperties.cpp \
+ wavfile.cpp \
+ wavfiletyperesolver.cpp
+
+noinst_HEADERS = wavproperties.h \
+ wavfile.h \
+ wavfiletyperesolver.h
+
diff --git a/src/metadata/wav/wavfile.cpp b/src/metadata/wav/wavfile.cpp
new file mode 100644
index 0000000..303c5b2
--- /dev/null
+++ b/src/metadata/wav/wavfile.cpp
@@ -0,0 +1,115 @@
+/***************************************************************************
+ copyright : (C) 2006 by Martin Aumueller
+
+ copyright : (C) 2005 by Andy Leadbetter
+ (original mp4 implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <stdio.h>
+
+#include "wavfile.h"
+
+#include <taglib/tfile.h>
+#include <taglib/audioproperties.h>
+#include <taglib/tag.h>
+
+namespace TagLib {
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+Wav::File::File(const char *file,
+ bool readProperties,
+ Properties::ReadStyle propertiesStyle,
+ FILE *fp)
+ : TagLib::File(file)
+ , wavtag( NULL )
+ , properties( NULL )
+{
+
+ // debug ("Wav::File: create new file object.");
+ //debug ( file );
+
+ /**
+ * Create the Wav file.
+ */
+
+ if(fp)
+ wavfile = fp;
+ else
+ wavfile = fopen(file, "rb");
+
+ if( isOpen() )
+ {
+ read(readProperties, propertiesStyle );
+ }
+}
+
+Wav::File::~File()
+{
+ if(wavfile)
+ fclose(wavfile);
+ delete properties;
+}
+
+TagLib::Tag *Wav::File::tag() const
+{
+ return NULL;
+}
+
+TagLib::Tag *Wav::File::getWavTag() const
+{
+ return NULL;
+}
+
+Wav::Properties *Wav::File::audioProperties() const
+{
+ return properties;
+}
+
+bool Wav::File::save()
+{
+ return false;
+}
+
+bool Wav::File::isOpen()
+{
+ return wavfile != NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// private members
+////////////////////////////////////////////////////////////////////////////////
+
+void Wav::File::read(bool readProperties, Properties::ReadStyle propertiesStyle)
+{
+ properties = new Wav::Properties(propertiesStyle);
+
+ if (wavfile != NULL) {
+ if(readProperties)
+ {
+ // Parse bitrate etc.
+ properties->readWavProperties( wavfile );
+ }
+ }
+}
+
+}
diff --git a/src/metadata/wav/wavfile.h b/src/metadata/wav/wavfile.h
new file mode 100644
index 0000000..e47fdfb
--- /dev/null
+++ b/src/metadata/wav/wavfile.h
@@ -0,0 +1,92 @@
+/***************************************************************************
+ copyright : (C) 2006 by Martin Aumueller
+
+ copyright : (C) 2005 by Andy Leadbetter
+ (original mp4 implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef TAGLIB_WAVFILE_H
+#define TAGLIB_WAVFILE_H
+
+#include <taglib/tfile.h>
+#include "wavproperties.h"
+
+namespace TagLib {
+
+ namespace Wav {
+
+ class Tag;
+
+ class File : public TagLib::File
+ {
+ public:
+ /*!
+ * Contructs a Wav 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.
+ */
+ File(const char *file, bool readProperties = true,
+ Properties::ReadStyle propertiesStyle = Properties::Average,
+ FILE *fp=NULL);
+
+ /*!
+ * Destroys this instance of the File.
+ */
+ virtual ~File();
+
+
+ virtual TagLib::Tag *tag() const;
+
+ /*!
+ * Returns the Wav::Properties for this file. If no audio properties
+ * were read then this will return a null pointer.
+ */
+ virtual Wav::Properties *audioProperties() const;
+
+ /*!
+ * Save the file.
+ * This is the same as calling save(AllTags);
+ *
+ * \note As of now, saving Wav tags is not supported.
+ */
+ virtual bool save();
+
+ void read(bool readProperties, Properties::ReadStyle propertiesStyle);
+
+ TagLib::Tag *getWavTag() const;
+
+ bool isWavFile() const;
+
+ protected:
+ File(const File &);
+ File &operator=(const File &);
+ bool isOpen();
+
+
+ TagLib::Tag *wavtag;
+ Wav::Properties *properties;
+
+ FILE *wavfile;
+ };
+ }
+}
+
+#endif
diff --git a/src/metadata/wav/wavfiletyperesolver.cpp b/src/metadata/wav/wavfiletyperesolver.cpp
new file mode 100644
index 0000000..830742f
--- /dev/null
+++ b/src/metadata/wav/wavfiletyperesolver.cpp
@@ -0,0 +1,44 @@
+/***************************************************************************
+ copyright : (C) 2006 by Martin Aumueller
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <stdio.h>
+
+#include "wavfiletyperesolver.h"
+#include "wavfile.h"
+
+#include <string.h>
+
+TagLib::File *WavFileTypeResolver::createFile(const char *fileName,
+ bool readProperties,
+ TagLib::AudioProperties::ReadStyle propertiesStyle) const
+{
+ const char *ext = strrchr(fileName, '.');
+ if(ext && !strcasecmp(ext, ".wav"))
+ {
+ FILE *fp = fopen(fileName, "rb");
+ if(!fp)
+ return 0;
+
+ return new TagLib::Wav::File(fileName, readProperties, propertiesStyle, fp);
+ }
+
+ return 0;
+}
diff --git a/src/metadata/wav/wavfiletyperesolver.h b/src/metadata/wav/wavfiletyperesolver.h
new file mode 100644
index 0000000..de818c9
--- /dev/null
+++ b/src/metadata/wav/wavfiletyperesolver.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ copyright : (C) 2006 by Martin Aumueller
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef TAGLIB_WAVFILETYPERESOLVER_H
+#define TAGLIB_WAVFILETYPERESOLVER_H
+
+#include <taglib/tfile.h>
+#include <taglib/fileref.h>
+
+
+class WavFileTypeResolver : public TagLib::FileRef::FileTypeResolver
+{
+ TagLib::File *createFile(const char *fileName,
+ bool readAudioProperties,
+ TagLib::AudioProperties::ReadStyle audioPropertiesStyle) const;
+};
+
+#endif
diff --git a/src/metadata/wav/wavproperties.cpp b/src/metadata/wav/wavproperties.cpp
new file mode 100644
index 0000000..20ba1ab
--- /dev/null
+++ b/src/metadata/wav/wavproperties.cpp
@@ -0,0 +1,108 @@
+/***************************************************************************
+ copyright : (C) 2006 by Martin Aumueller
+
+ copyright : (C) 2005 by Andy Leadbetter
+ (original mp4 implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <stdio.h>
+
+#include "wavproperties.h"
+
+#include <taglib/tstring.h>
+
+#include "wavfile.h"
+
+#include <netinet/in.h> // ntohl
+
+using namespace TagLib;
+
+struct WavHeader
+{
+ uint32_t riff_id;
+ uint32_t riff_size;
+ uint32_t wave_id;
+ uint32_t format_id;
+ uint32_t format_size;
+ uint16_t format_tag;
+ uint16_t num_channels;
+ uint32_t num_samples_per_sec;
+ uint32_t num_avg_bytes_per_sec;
+ uint16_t num_block_align;
+ uint16_t bits_per_sample;
+ uint32_t data_id;
+ uint32_t num_data_bytes;
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+Wav::Properties::Properties(Properties::ReadStyle style) : AudioProperties(style)
+{
+ m_length = 0;
+ m_bitrate = 0;
+ m_sampleRate = 0;
+ m_channels = 0;
+}
+
+Wav::Properties::~Properties()
+{
+}
+
+int Wav::Properties::length() const
+{
+ return m_length;
+}
+
+int Wav::Properties::bitrate() const
+{
+ return m_bitrate;
+}
+
+int Wav::Properties::sampleRate() const
+{
+ return m_sampleRate;
+}
+
+int Wav::Properties::channels() const
+{
+ return m_channels;
+}
+
+#define swap16(x) ((((x)&0xff00)>>8) | (((x)&0x00ff)<<8))
+#define swap32(x) ((swap16((x)&0x0000ffff)<<16) | swap16(((x)&0xffff0000)>>16))
+
+void Wav::Properties::readWavProperties( FILE *fp )
+{
+ fseek(fp, 0, SEEK_SET );
+ WavHeader header;
+ if( fread(&header, sizeof(header), 1, fp) != 1 )
+ {
+ return;
+ }
+
+ m_channels = ntohs(swap16(header.num_channels));
+ m_sampleRate = ntohl(swap32(header.num_samples_per_sec));
+ m_bitrate = ntohl(swap32(header.num_avg_bytes_per_sec)) * 8 / 1000;
+ m_length = ntohl(swap32(header.num_data_bytes))/ntohl(swap32(header.num_avg_bytes_per_sec));
+}
diff --git a/src/metadata/wav/wavproperties.h b/src/metadata/wav/wavproperties.h
new file mode 100644
index 0000000..a02e734
--- /dev/null
+++ b/src/metadata/wav/wavproperties.h
@@ -0,0 +1,85 @@
+/***************************************************************************
+ copyright : (C) 2006 by Martin Aumueller
+
+ copyright : (C) 2005 by Andy Leadbetter
+ (original mp4 implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef TAGLIB_WAVPROPERTIES_H
+#define TAGLIB_WAVPROPERTIES_H
+
+#include <config.h>
+
+#include <taglib/audioproperties.h>
+#include <taglib/tstring.h>
+
+namespace TagLib {
+
+ namespace Wav {
+
+ class File;
+
+ /*!
+ * This reads the data from a Wav stream to support the
+ * AudioProperties API.
+ */
+
+ class Properties : public AudioProperties
+ {
+ public:
+ /*!
+ * Initialize this structure
+ */
+ Properties(Properties::ReadStyle style);
+
+ /*!
+ * Destroys this Wav Properties instance.
+ */
+ virtual ~Properties();
+
+ // Reimplementations.
+
+ virtual int length() const;
+ virtual int bitrate() const;
+ virtual int sampleRate() const;
+ virtual int channels() const;
+
+ void readWavProperties(FILE *file);
+
+
+ private:
+ void readAudioTrackProperties(FILE *file);
+ friend class Wav::File;
+
+ int m_length;
+ int m_bitrate;
+ int m_sampleRate;
+ int m_channels;
+
+ Properties(const Properties &);
+ Properties &operator=(const Properties &);
+
+ void read();
+ };
+ }
+}
+
+#endif
diff --git a/src/metadata/wavpack/Makefile.am b/src/metadata/wavpack/Makefile.am
new file mode 100644
index 0000000..93a98c6
--- /dev/null
+++ b/src/metadata/wavpack/Makefile.am
@@ -0,0 +1,16 @@
+SUBDIRS =
+
+INCLUDES = $(all_includes) $(taglib_includes)
+METASOURCES = AUTO
+libtagwavpack_la_LDFLAGS = $(all_libraries)
+noinst_LTLIBRARIES = libtagwavpack.la
+
+libtagwavpack_la_SOURCES = \
+ wvfile.cpp \
+ wvproperties.cpp \
+ taglib_wavpackfiletyperesolver.cpp
+
+noinst_HEADERS = wvfile.h \
+ wvproperties.h \
+ taglib_wavpackfiletyperesolver.h
+
diff --git a/src/metadata/wavpack/combinedtag.h b/src/metadata/wavpack/combinedtag.h
new file mode 100644
index 0000000..7d530d2
--- /dev/null
+++ b/src/metadata/wavpack/combinedtag.h
@@ -0,0 +1,171 @@
+/***************************************************************************
+ copyright : (C) 2004 by Allan Sandfeld Jensen
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef DO_NOT_DOCUMENT // Tell Doxygen not to document this header
+
+#ifndef TAGLIB_COMBINEDTAG_H
+#define TAGLIB_COMBINEDTAG_H
+
+////////////////////////////////////////////////////////////////////////////////
+// Note that this header is not installed.
+////////////////////////////////////////////////////////////////////////////////
+
+#include <tag.h>
+
+namespace TagLib {
+
+ /*!
+ * A union of two TagLib::Tags.
+ */
+ class CombinedTag : public TagLib::Tag
+ {
+ public:
+ CombinedTag(Tag *tag1 = 0, Tag *tag2 = 0)
+ : TagLib::Tag(),
+ tag1(tag1), tag2(tag2) {}
+
+ virtual String title() const {
+ if(tag1 && !tag1->title().isEmpty())
+ return tag1->title();
+
+ if(tag2)
+ return tag2->title();
+
+ return String::null;
+ }
+
+ virtual String artist() const {
+ if(tag1 && !tag1->artist().isEmpty())
+ return tag1->artist();
+
+ if(tag2)
+ return tag2->artist();
+
+ return String::null;
+ }
+
+ virtual String album() const {
+ if(tag1 && !tag1->album().isEmpty())
+ return tag1->album();
+
+ if(tag2)
+ return tag2->album();
+
+ return String::null;
+ }
+
+ virtual String comment() const {
+ if(tag1 && !tag1->comment().isEmpty())
+ return tag1->comment();
+
+ if(tag2)
+ return tag2->comment();
+
+ return String::null;
+ }
+
+ virtual String genre() const {
+ if(tag1 && !tag1->genre().isEmpty())
+ return tag1->genre();
+
+ if(tag2)
+ return tag2->genre();
+
+ return String::null;
+ }
+
+ virtual uint year() const {
+ if(tag1 && tag1->year() > 0)
+ return tag1->year();
+
+ if(tag2)
+ return tag2->year();
+
+ return 0;
+ }
+
+ virtual uint track() const {
+ if(tag1 && tag1->track() > 0)
+ return tag1->track();
+
+ if(tag2)
+ return tag2->track();
+
+ return 0;
+ }
+
+ virtual void setTitle(const String &s) {
+ if(tag1)
+ tag1->setTitle(s);
+ if(tag2)
+ tag2->setTitle(s);
+ }
+
+ virtual void setArtist(const String &s) {
+ if(tag1)
+ tag1->setArtist(s);
+ if(tag2)
+ tag2->setArtist(s);
+ }
+
+ virtual void setAlbum(const String &s) {
+ if(tag1)
+ tag1->setAlbum(s);
+ if(tag2)
+ tag2->setAlbum(s);
+ }
+
+ virtual void setComment(const String &s) {
+ if(tag1)
+ tag1->setComment(s);
+ if(tag2)
+ tag2->setComment(s);
+ }
+
+ virtual void setGenre(const String &s) {
+ if(tag1)
+ tag1->setGenre(s);
+ if(tag2)
+ tag2->setGenre(s);
+ }
+
+ virtual void setYear(uint i) {
+ if(tag1)
+ tag1->setYear(i);
+ if(tag2)
+ tag2->setYear(i);
+ }
+
+ virtual void setTrack(uint i) {
+ if(tag1)
+ tag1->setTrack(i);
+ if(tag2)
+ tag2->setTrack(i);
+ }
+
+ private:
+ Tag *tag1;
+ Tag *tag2;
+ };
+}
+
+#endif
+#endif
diff --git a/src/metadata/wavpack/taglib_wavpackfiletyperesolver.cpp b/src/metadata/wavpack/taglib_wavpackfiletyperesolver.cpp
new file mode 100644
index 0000000..fe289a2
--- /dev/null
+++ b/src/metadata/wavpack/taglib_wavpackfiletyperesolver.cpp
@@ -0,0 +1,44 @@
+/***************************************************************************
+ copyright : (C) 2006 by Martin Aumueller
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "taglib_wavpackfiletyperesolver.h"
+#include "wvfile.h"
+
+#include <string.h>
+
+TagLib::File *WavPackFileTypeResolver::createFile(const char *fileName,
+ bool readProperties,
+ TagLib::AudioProperties::ReadStyle propertiesStyle) const
+{
+ const char *ext = strrchr(fileName, '.');
+ if(ext && !strcasecmp(ext, ".wv"))
+ {
+ TagLib::WavPack::File *f = new TagLib::WavPack::File(fileName, readProperties, propertiesStyle);
+ if(f->isValid())
+ return f;
+ else
+ {
+ delete f;
+ }
+ }
+
+ return 0;
+}
diff --git a/src/metadata/wavpack/taglib_wavpackfiletyperesolver.h b/src/metadata/wavpack/taglib_wavpackfiletyperesolver.h
new file mode 100644
index 0000000..b9d4500
--- /dev/null
+++ b/src/metadata/wavpack/taglib_wavpackfiletyperesolver.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ copyright : (C) 2006 by Martin Aumueller
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef TAGLIB_WAVPACKFILETYPERESOLVER_H
+#define TAGLIB_WAVPACKFILETYPERESOLVER_H
+
+#include <taglib/tfile.h>
+#include <taglib/fileref.h>
+
+
+class WavPackFileTypeResolver : public TagLib::FileRef::FileTypeResolver
+{
+ TagLib::File *createFile(const char *fileName,
+ bool readAudioProperties,
+ TagLib::AudioProperties::ReadStyle audioPropertiesStyle) const;
+};
+
+#endif
diff --git a/src/metadata/wavpack/wvfile.cpp b/src/metadata/wavpack/wvfile.cpp
new file mode 100644
index 0000000..3890bc9
--- /dev/null
+++ b/src/metadata/wavpack/wvfile.cpp
@@ -0,0 +1,311 @@
+/***************************************************************************
+ copyright : (C) 2006 by Lukáš Lalinský
+
+ copyright : (C) 2004 by Allan Sandfeld Jensen
+ (original MPC implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <tbytevector.h>
+#include <tstring.h>
+#if 0
+#include <tdebug.h>
+#endif
+
+#include "wvfile.h"
+#include "id3v1tag.h"
+#include "id3v2header.h"
+#include "apetag.h"
+#include "apefooter.h"
+#include "combinedtag.h"
+
+using namespace TagLib;
+
+class WavPack::File::FilePrivate
+{
+public:
+ FilePrivate() :
+ APETag(0),
+ APELocation(-1),
+ APESize(0),
+ ID3v1Tag(0),
+ ID3v1Location(-1),
+ tag(0),
+ properties(0),
+ scanned(false),
+ hasAPE(false),
+ hasID3v1(false) {}
+
+ ~FilePrivate()
+ {
+ if (tag != ID3v1Tag && tag != APETag) delete tag;
+ delete ID3v1Tag;
+ delete APETag;
+ delete properties;
+ }
+
+ APE::Tag *APETag;
+ long APELocation;
+ uint APESize;
+
+ ID3v1::Tag *ID3v1Tag;
+ long ID3v1Location;
+
+ Tag *tag;
+
+ Properties *properties;
+ bool scanned;
+
+ // These indicate whether the file *on disk* has these tags, not if
+ // this data structure does. This is used in computing offsets.
+
+ bool hasAPE;
+ bool hasID3v1;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+WavPack::File::File(const char *file, bool readProperties,
+ Properties::ReadStyle propertiesStyle) : TagLib::File(file)
+{
+ d = new FilePrivate;
+ read(readProperties, propertiesStyle);
+}
+
+WavPack::File::~File()
+{
+ delete d;
+}
+
+TagLib::Tag *WavPack::File::tag() const
+{
+ return d->tag;
+}
+
+WavPack::Properties *WavPack::File::audioProperties() const
+{
+ return d->properties;
+}
+
+bool WavPack::File::save()
+{
+ if(readOnly()) {
+#if 0
+ debug("WavPack::File::save() -- File is read only.");
+#endif
+ return false;
+ }
+
+ // Update ID3v1 tag
+
+ if(d->ID3v1Tag) {
+ if(d->hasID3v1) {
+ seek(d->ID3v1Location);
+ writeBlock(d->ID3v1Tag->render());
+ }
+ else {
+ seek(0, End);
+ d->ID3v1Location = tell();
+ writeBlock(d->ID3v1Tag->render());
+ d->hasID3v1 = true;
+ }
+ } else
+ if(d->hasID3v1) {
+ removeBlock(d->ID3v1Location, 128);
+ d->hasID3v1 = false;
+ if(d->hasAPE) {
+ if(d->APELocation > d->ID3v1Location)
+ d->APELocation -= 128;
+ }
+ }
+
+ // Update APE tag
+
+ if(d->APETag) {
+ if(d->hasAPE)
+ insert(d->APETag->render(), d->APELocation, d->APESize);
+ else {
+ if(d->hasID3v1) {
+ insert(d->APETag->render(), d->ID3v1Location, 0);
+ d->APESize = d->APETag->footer()->completeTagSize();
+ d->hasAPE = true;
+ d->APELocation = d->ID3v1Location;
+ d->ID3v1Location += d->APESize;
+ }
+ else {
+ seek(0, End);
+ d->APELocation = tell();
+ writeBlock(d->APETag->render());
+ d->APESize = d->APETag->footer()->completeTagSize();
+ d->hasAPE = true;
+ }
+ }
+ }
+ else
+ if(d->hasAPE) {
+ removeBlock(d->APELocation, d->APESize);
+ d->hasAPE = false;
+ if(d->hasID3v1) {
+ if (d->ID3v1Location > d->APELocation)
+ d->ID3v1Location -= d->APESize;
+ }
+ }
+
+ return true;
+}
+
+ID3v1::Tag *WavPack::File::ID3v1Tag(bool create)
+{
+ if(!create || d->ID3v1Tag)
+ return d->ID3v1Tag;
+
+ // no ID3v1 tag exists and we've been asked to create one
+
+ d->ID3v1Tag = new ID3v1::Tag;
+
+ if(d->APETag)
+ d->tag = new CombinedTag(d->APETag, d->ID3v1Tag);
+ else
+ d->tag = d->ID3v1Tag;
+
+ return d->ID3v1Tag;
+}
+
+APE::Tag *WavPack::File::APETag(bool create)
+{
+ if(!create || d->APETag)
+ return d->APETag;
+
+ // no APE tag exists and we've been asked to create one
+
+ d->APETag = new APE::Tag;
+
+ if(d->ID3v1Tag)
+ d->tag = new CombinedTag(d->APETag, d->ID3v1Tag);
+ else
+ d->tag = d->APETag;
+
+ return d->APETag;
+}
+
+void WavPack::File::remove(int tags)
+{
+ if(tags & ID3v1) {
+ delete d->ID3v1Tag;
+ d->ID3v1Tag = 0;
+
+ if(d->APETag)
+ d->tag = d->APETag;
+ else
+ d->tag = d->APETag = new APE::Tag;
+ }
+
+ if(tags & APE) {
+ delete d->APETag;
+ d->APETag = 0;
+
+ if(d->ID3v1Tag)
+ d->tag = d->ID3v1Tag;
+ else
+ d->tag = d->APETag = new APE::Tag;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// private members
+////////////////////////////////////////////////////////////////////////////////
+
+void WavPack::File::read(bool readProperties, Properties::ReadStyle /* propertiesStyle */)
+{
+ // Look for an ID3v1 tag
+
+ d->ID3v1Location = findID3v1();
+
+ if(d->ID3v1Location >= 0) {
+ d->ID3v1Tag = new ID3v1::Tag(this, d->ID3v1Location);
+ d->hasID3v1 = true;
+ }
+
+ // Look for an APE tag
+
+ d->APELocation = findAPE();
+
+ if(d->APELocation >= 0) {
+ d->APETag = new APE::Tag(this, d->APELocation);
+ d->APESize = d->APETag->footer()->completeTagSize();
+ d->APELocation = d->APELocation + d->APETag->footer()->size() - d->APESize;
+ d->hasAPE = true;
+ }
+
+ if(d->hasID3v1 && d->hasAPE)
+ d->tag = new CombinedTag(d->APETag, d->ID3v1Tag);
+ else {
+ if(d->hasID3v1)
+ d->tag = d->ID3v1Tag;
+ else {
+ if(d->hasAPE)
+ d->tag = d->APETag;
+ else
+ d->tag = d->APETag = new APE::Tag;
+ }
+ }
+
+ // Look for WavPack audio properties
+
+ if(readProperties) {
+ seek(0);
+ d->properties = new Properties(readBlock(WavPack::HeaderSize),
+ length() - d->APESize);
+ }
+}
+
+long WavPack::File::findAPE()
+{
+ if(!isValid())
+ return -1;
+
+ if(d->hasID3v1)
+ seek(-160, End);
+ else
+ seek(-32, End);
+
+ long p = tell();
+
+ if(readBlock(8) == APE::Tag::fileIdentifier())
+ return p;
+
+ return -1;
+}
+
+long WavPack::File::findID3v1()
+{
+ if(!isValid())
+ return -1;
+
+ seek(-128, End);
+ long p = tell();
+
+ if(readBlock(3) == ID3v1::Tag::fileIdentifier())
+ return p;
+
+ return -1;
+}
diff --git a/src/metadata/wavpack/wvfile.h b/src/metadata/wavpack/wvfile.h
new file mode 100644
index 0000000..6c57f6d
--- /dev/null
+++ b/src/metadata/wavpack/wvfile.h
@@ -0,0 +1,160 @@
+/***************************************************************************
+ copyright : (C) 2006 by Lukáš Lalinský
+
+ copyright : (C) 2004 by Allan Sandfeld Jensen
+ (original MPC implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef TAGLIB_WVFILE_H
+#define TAGLIB_WVFILE_H
+
+#include "tfile.h"
+
+#include "wvproperties.h"
+
+namespace TagLib {
+
+ class Tag;
+
+ namespace ID3v1 { class Tag; }
+ namespace APE { class Tag; }
+
+ //! An implementation of WavPack metadata
+
+ /*!
+ * This is implementation of WavPack metadata.
+ *
+ * This supports ID3v1 and APE (v1 and v2) style comments as well as reading stream
+ * properties from the file.
+ */
+
+ namespace WavPack {
+
+ //! An implementation of TagLib::File with WavPack specific methods
+
+ /*!
+ * This implements and provides an interface for WavPack files to the
+ * TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing
+ * the abstract TagLib::File API as well as providing some additional
+ * information specific to WavPack files.
+ */
+
+ class File : public TagLib::File
+ {
+ public:
+ /*!
+ * This set of flags is used for various operations and is suitable for
+ * being OR-ed together.
+ */
+ enum TagTypes {
+ //! Empty set. Matches no tag types.
+ NoTags = 0x0000,
+ //! Matches ID3v1 tags.
+ ID3v1 = 0x0001,
+ //! Matches APE tags.
+ APE = 0x0002,
+ //! Matches all tag types.
+ AllTags = 0xffff
+ };
+
+ /*!
+ * Contructs an WavPack 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.
+ */
+ File(const char *file, bool readProperties = true,
+ Properties::ReadStyle propertiesStyle = Properties::Average);
+
+ /*!
+ * Destroys this instance of the File.
+ */
+ virtual ~File();
+
+ /*!
+ * Returns the Tag for this file. This will be an APE tag, an ID3v1 tag
+ * or a combination of the two.
+ */
+ virtual TagLib::Tag *tag() const;
+
+ /*!
+ * Returns the MPC::Properties for this file. If no audio properties
+ * were read then this will return a null pointer.
+ */
+ virtual Properties *audioProperties() const;
+
+ /*!
+ * Saves the file.
+ */
+ virtual bool save();
+
+ /*!
+ * Returns a pointer to the ID3v1 tag of the file.
+ *
+ * If \a create is false (the default) this will return a null pointer
+ * if there is no valid ID3v1 tag. If \a create is true it will create
+ * an ID3v1 tag if one does not exist. If there is already an APE tag, the
+ * new ID3v1 tag will be placed after it.
+ *
+ * \note The Tag <b>is still</b> owned by the APE::File and should not be
+ * deleted by the user. It will be deleted when the file (object) is
+ * destroyed.
+ */
+ ID3v1::Tag *ID3v1Tag(bool create = false);
+
+ /*!
+ * Returns a pointer to the APE tag of the file.
+ *
+ * If \a create is false (the default) this will return a null pointer
+ * if there is no valid APE tag. If \a create is true it will create
+ * a APE tag if one does not exist.
+ *
+ * \note The Tag <b>is still</b> owned by the APE::File and should not be
+ * deleted by the user. It will be deleted when the file (object) is
+ * destroyed.
+ */
+ APE::Tag *APETag(bool create = false);
+
+ /*!
+ * This will remove the tags that match the OR-ed together TagTypes from the
+ * file. By default it removes all tags.
+ *
+ * \note This will also invalidate pointers to the tags
+ * as their memory will be freed.
+ * \note In order to make the removal permanent save() still needs to be called
+ */
+ void remove(int tags = AllTags);
+
+ private:
+ File(const File &);
+ File &operator=(const File &);
+
+ void read(bool readProperties, Properties::ReadStyle propertiesStyle);
+ void scan();
+ long findID3v1();
+ long findAPE();
+
+ class FilePrivate;
+ FilePrivate *d;
+ };
+ }
+}
+
+#endif
diff --git a/src/metadata/wavpack/wvproperties.cpp b/src/metadata/wavpack/wvproperties.cpp
new file mode 100644
index 0000000..376824d
--- /dev/null
+++ b/src/metadata/wavpack/wvproperties.cpp
@@ -0,0 +1,141 @@
+/***************************************************************************
+ copyright : (C) 2006 by Lukáš Lalinský
+
+ copyright : (C) 2004 by Allan Sandfeld Jensen
+ (original MPC implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <tstring.h>
+#if 0
+#include <tdebug.h>
+#endif
+#include <bitset>
+
+#include "wvproperties.h"
+#include "wvfile.h"
+
+using namespace TagLib;
+
+class WavPack::Properties::PropertiesPrivate
+{
+public:
+ PropertiesPrivate(const ByteVector &d, long length, ReadStyle s) :
+ data(d),
+ streamLength(length),
+ style(s),
+ length(0),
+ bitrate(0),
+ sampleRate(0),
+ channels(0),
+ version(0),
+ bitsPerSample(0) {}
+
+ ByteVector data;
+ long streamLength;
+ ReadStyle style;
+ int length;
+ int bitrate;
+ int sampleRate;
+ int channels;
+ int version;
+ int bitsPerSample;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+WavPack::Properties::Properties(const ByteVector &data, long streamLength, ReadStyle style) : AudioProperties(style)
+{
+ d = new PropertiesPrivate(data, streamLength, style);
+ read();
+}
+
+WavPack::Properties::~Properties()
+{
+ delete d;
+}
+
+int WavPack::Properties::length() const
+{
+ return d->length;
+}
+
+int WavPack::Properties::bitrate() const
+{
+ return d->bitrate;
+}
+
+int WavPack::Properties::sampleRate() const
+{
+ return d->sampleRate;
+}
+
+int WavPack::Properties::channels() const
+{
+ return d->channels;
+}
+
+int WavPack::Properties::version() const
+{
+ return d->version;
+}
+
+int WavPack::Properties::bitsPerSample() const
+{
+ return d->bitsPerSample;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// private members
+////////////////////////////////////////////////////////////////////////////////
+
+static const unsigned int sample_rates[] = { 6000, 8000, 9600, 11025, 12000,
+ 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000, 192000 };
+
+#define BYTES_STORED 3
+#define MONO_FLAG 4
+
+#define SHIFT_LSB 13
+#define SHIFT_MASK (0x1fL << SHIFT_LSB)
+
+#define SRATE_LSB 23
+#define SRATE_MASK (0xfL << SRATE_LSB)
+
+void WavPack::Properties::read()
+{
+ if(!d->data.startsWith("wvpk"))
+ return;
+
+ d->version = d->data.mid(8, 2).toShort(false);
+
+ unsigned int flags = d->data.mid(24, 4).toUInt(false);
+ d->bitsPerSample = ((flags & BYTES_STORED) + 1) * 8 -
+ ((flags & SHIFT_MASK) >> SHIFT_LSB);
+ d->sampleRate = sample_rates[(flags & SRATE_MASK) >> SRATE_LSB];
+ d->channels = (flags & MONO_FLAG) ? 1 : 2;
+
+ unsigned int samples = d->data.mid(12, 4).toUInt(false);
+ d->length = d->sampleRate > 0 ? (samples + (d->sampleRate / 2)) / d->sampleRate : 0;
+
+ d->bitrate = d->length > 0 ? ((d->streamLength * 8L) / d->length) / 1000 : 0;
+}
+
diff --git a/src/metadata/wavpack/wvproperties.h b/src/metadata/wavpack/wvproperties.h
new file mode 100644
index 0000000..b615adf
--- /dev/null
+++ b/src/metadata/wavpack/wvproperties.h
@@ -0,0 +1,86 @@
+/***************************************************************************
+ copyright : (C) 2006 by Lukáš Lalinský
+
+ copyright : (C) 2004 by Allan Sandfeld Jensen
+ (original MPC implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef TAGLIB_WVPROPERTIES_H
+#define TAGLIB_WVPROPERTIES_H
+
+#include "audioproperties.h"
+
+namespace TagLib {
+
+ namespace WavPack {
+
+ class File;
+
+ static const uint HeaderSize = 32;
+
+ //! An implementation of audio property reading for WavPack
+
+ /*!
+ * This reads the data from an WavPack stream found in the AudioProperties
+ * API.
+ */
+
+ class Properties : public AudioProperties
+ {
+ public:
+ /*!
+ * Create an instance of WavPack::Properties with the data read from the
+ * ByteVector \a data.
+ */
+ Properties(const ByteVector &data, long streamLength, ReadStyle style = Average);
+
+ /*!
+ * Destroys this WavPack::Properties instance.
+ */
+ virtual ~Properties();
+
+ // Reimplementations.
+
+ virtual int length() const;
+ virtual int bitrate() const;
+ virtual int sampleRate() const;
+ virtual int channels() const;
+
+ /*!
+ * Returns number of bits per sample.
+ */
+ int bitsPerSample() const;
+
+ /*!
+ * Returns WavPack version.
+ */
+ int version() const;
+
+ private:
+ void read();
+
+ class PropertiesPrivate;
+ PropertiesPrivate *d;
+ };
+ }
+}
+
+#endif